From b8317b7edf8d9c72730fe1860fbb64b1027959f3 Mon Sep 17 00:00:00 2001 From: masawei <manuel.sascha.weiand@rwth-aachen.de> Date: Thu, 10 Apr 2014 16:34:20 +0200 Subject: [PATCH 01/30] Working in the new structure of the formula tree. -Done with LTL. -Working on PrCTL. Former-commit-id: 1ec3c6993adc9e76dc2246b9a4b8ab9977daffb1 --- src/formula/{abstract => }/AbstractFormula.h | 15 +- src/formula/AbstractFormulaChecker.h | 4 +- .../{abstract => }/IOptimizingOperator.h | 12 +- src/formula/Ltl/AbstractLtlFormula.h | 4 +- src/formula/Ltl/And.h | 97 ++++++++- src/formula/Ltl/Ap.h | 40 +++- src/formula/Ltl/BoundedEventually.h | 87 +++++++- src/formula/Ltl/BoundedUntil.h | 133 ++++++++++-- src/formula/Ltl/Eventually.h | 63 +++++- src/formula/Ltl/Globally.h | 62 +++++- src/formula/Ltl/Next.h | 63 +++++- src/formula/Ltl/Not.h | 61 +++++- src/formula/Ltl/Or.h | 112 ++++++++-- src/formula/Ltl/Until.h | 110 ++++++++-- src/formula/Prctl/AbstractNoBoundOperator.h | 6 +- src/formula/Prctl/AbstractPathFormula.h | 8 +- src/formula/Prctl/AbstractPrctlFormula.h | 31 --- src/formula/Prctl/AbstractStateFormula.h | 8 +- src/formula/Prctl/And.h | 96 ++++++++- src/formula/Prctl/Ap.h | 41 +++- src/formula/Prctl/Not.h | 60 +++++- src/formula/Prctl/Or.h | 101 ++++++++- .../Prctl/ProbabilisticBoundOperator.h | 1 - src/formula/abstract/And.h | 164 --------------- src/formula/abstract/Ap.h | 84 -------- src/formula/abstract/BoundedEventually.h | 151 -------------- src/formula/abstract/BoundedNaryUntil.h | 175 ---------------- src/formula/abstract/BoundedUntil.h | 182 ---------------- src/formula/abstract/CumulativeReward.h | 101 --------- src/formula/abstract/Eventually.h | 125 ----------- src/formula/abstract/Globally.h | 126 ------------ src/formula/abstract/InstantaneousReward.h | 101 --------- src/formula/abstract/Next.h | 128 ------------ src/formula/abstract/Not.h | 122 ----------- src/formula/abstract/OptimizingOperator.h | 72 ------- src/formula/abstract/Or.h | 161 --------------- src/formula/abstract/PathBoundOperator.h | 194 ------------------ src/formula/abstract/PathNoBoundOperator.h | 160 --------------- .../abstract/ProbabilisticBoundOperator.h | 114 ---------- .../abstract/ProbabilisticNoBoundOperator.h | 104 ---------- src/formula/abstract/RewardBoundOperator.h | 106 ---------- src/formula/abstract/RewardNoBoundOperator.h | 103 ---------- src/formula/abstract/StateBoundOperator.h | 174 ---------------- src/formula/abstract/StateNoBoundOperator.h | 126 ------------ .../abstract/SteadyStateBoundOperator.h | 77 ------- .../abstract/SteadyStateNoBoundOperator.h | 76 ------- src/formula/abstract/SteadyStateReward.h | 62 ------ src/formula/abstract/TimeBoundedEventually.h | 107 ---------- src/formula/abstract/TimeBoundedOperator.h | 112 ---------- src/formula/abstract/TimeBoundedUntil.h | 149 -------------- src/formula/abstract/Until.h | 159 -------------- 51 files changed, 1002 insertions(+), 3728 deletions(-) rename src/formula/{abstract => }/AbstractFormula.h (91%) rename src/formula/{abstract => }/IOptimizingOperator.h (81%) delete mode 100644 src/formula/Prctl/AbstractPrctlFormula.h delete mode 100644 src/formula/abstract/And.h delete mode 100644 src/formula/abstract/Ap.h delete mode 100644 src/formula/abstract/BoundedEventually.h delete mode 100644 src/formula/abstract/BoundedNaryUntil.h delete mode 100644 src/formula/abstract/BoundedUntil.h delete mode 100644 src/formula/abstract/CumulativeReward.h delete mode 100644 src/formula/abstract/Eventually.h delete mode 100644 src/formula/abstract/Globally.h delete mode 100644 src/formula/abstract/InstantaneousReward.h delete mode 100644 src/formula/abstract/Next.h delete mode 100644 src/formula/abstract/Not.h delete mode 100644 src/formula/abstract/OptimizingOperator.h delete mode 100644 src/formula/abstract/Or.h delete mode 100644 src/formula/abstract/PathBoundOperator.h delete mode 100644 src/formula/abstract/PathNoBoundOperator.h delete mode 100644 src/formula/abstract/ProbabilisticBoundOperator.h delete mode 100644 src/formula/abstract/ProbabilisticNoBoundOperator.h delete mode 100644 src/formula/abstract/RewardBoundOperator.h delete mode 100644 src/formula/abstract/RewardNoBoundOperator.h delete mode 100644 src/formula/abstract/StateBoundOperator.h delete mode 100644 src/formula/abstract/StateNoBoundOperator.h delete mode 100644 src/formula/abstract/SteadyStateBoundOperator.h delete mode 100644 src/formula/abstract/SteadyStateNoBoundOperator.h delete mode 100644 src/formula/abstract/SteadyStateReward.h delete mode 100644 src/formula/abstract/TimeBoundedEventually.h delete mode 100644 src/formula/abstract/TimeBoundedOperator.h delete mode 100644 src/formula/abstract/TimeBoundedUntil.h delete mode 100644 src/formula/abstract/Until.h diff --git a/src/formula/abstract/AbstractFormula.h b/src/formula/AbstractFormula.h similarity index 91% rename from src/formula/abstract/AbstractFormula.h rename to src/formula/AbstractFormula.h index ad8122b52..ebe6f6e73 100644 --- a/src/formula/abstract/AbstractFormula.h +++ b/src/formula/AbstractFormula.h @@ -5,25 +5,21 @@ * Author: Thomas Heinemann */ -#ifndef STORM_FORMULA_ABSTRACT_ABSTRACTFORMULA_H_ -#define STORM_FORMULA_ABSTRACT_ABSTRACTFORMULA_H_ +#ifndef STORM_FORMULA_ABSTRACTFORMULA_H_ +#define STORM_FORMULA_ABSTRACTFORMULA_H_ #include <string> namespace storm { namespace property { -namespace abstract { template <class T> class AbstractFormula; -} //namespace abstract } //namespace property } //namespace storm - #include "src/formula/AbstractFormulaChecker.h" namespace storm { namespace property { -namespace abstract { //abstract /*! @@ -58,7 +54,7 @@ public: virtual ~AbstractFormula() { // Intentionally left empty. } - + /*! * @brief Return string representation of this formula. * @@ -67,7 +63,7 @@ public: * @returns a string representation of the formula */ virtual std::string toString() const = 0; - + /*! * @brief Checks if all subtrees are valid in some logic. * @@ -85,8 +81,7 @@ public: virtual bool validate(const AbstractFormulaChecker<T>& checker) const = 0; }; -} // namespace abstract } // namespace property } // namespace storm -#endif /* STORM_FORMULA_ABSTRACT_ABSTRACTFORMULA_H_ */ +#endif /* STORM_FORMULA_ABSTRACTFORMULA_H_ */ diff --git a/src/formula/AbstractFormulaChecker.h b/src/formula/AbstractFormulaChecker.h index 92858bfac..0f83f3860 100644 --- a/src/formula/AbstractFormulaChecker.h +++ b/src/formula/AbstractFormulaChecker.h @@ -10,7 +10,7 @@ template <class T> class AbstractFormulaChecker; } //namespace storm -#include "src/formula/abstract/AbstractFormula.h" +#include "src/formula/AbstractFormula.h" namespace storm { namespace property { @@ -64,7 +64,7 @@ class AbstractFormulaChecker { * @param formula A pointer to some formula object. * @return true iff the formula is valid. */ - virtual bool validate(const storm::property::abstract::AbstractFormula<T>* formula) const = 0; + virtual bool validate(const AbstractFormula<T>* formula) const = 0; }; } // namespace property diff --git a/src/formula/abstract/IOptimizingOperator.h b/src/formula/IOptimizingOperator.h similarity index 81% rename from src/formula/abstract/IOptimizingOperator.h rename to src/formula/IOptimizingOperator.h index 53a5f8769..f89419d91 100644 --- a/src/formula/abstract/IOptimizingOperator.h +++ b/src/formula/IOptimizingOperator.h @@ -5,12 +5,11 @@ * Author: thomas */ -#ifndef STORM_FORMULA_ABSTRACT_IOPTIMIZINGOPERATOR_H_ -#define STORM_FORMULA_ABSTRACT_IOPTIMIZINGOPERATOR_H_ +#ifndef STORM_FORMULA_IOPTIMIZINGOPERATOR_H_ +#define STORM_FORMULA_IOPTIMIZINGOPERATOR_H_ namespace storm { namespace property { -namespace abstract { /*! * @brief Interface for optimizing operators @@ -20,6 +19,10 @@ namespace abstract { class IOptimizingOperator { public: + virtual ~IOptimizingOperator() { + // Intentionally left empty + } + /*! * Retrieves whether the operator is to be interpreted as an optimizing (i.e. min/max) operator. * @returns True if the operator is an optimizing operator. @@ -35,7 +38,6 @@ public: virtual bool isMinimumOperator() const = 0; }; -} /* namespace abstract */ } /* namespace property */ } /* namespace storm */ -#endif /* IOPTIMIZINGOPERATOR_H_ */ +#endif /* STORM_FORMULA_IOPTIMIZINGOPERATOR_H_ */ diff --git a/src/formula/Ltl/AbstractLtlFormula.h b/src/formula/Ltl/AbstractLtlFormula.h index 65c31bdef..0f03ded32 100644 --- a/src/formula/Ltl/AbstractLtlFormula.h +++ b/src/formula/Ltl/AbstractLtlFormula.h @@ -10,7 +10,7 @@ #include <vector> #include "src/modelchecker/ltl/ForwardDeclarations.h" -#include "src/formula/abstract/AbstractFormula.h" +#include "src/formula/AbstractFormula.h" // Forward declaration for formula visitor namespace storm { @@ -35,7 +35,7 @@ namespace ltl { * Interface class for all LTL root formulas. */ template <class T> -class AbstractLtlFormula : public virtual storm::property::abstract::AbstractFormula<T> { +class AbstractLtlFormula : public virtual storm::property::AbstractFormula<T> { public: /** * Empty destructor diff --git a/src/formula/Ltl/And.h b/src/formula/Ltl/And.h index f7c901de3..dee2706f6 100644 --- a/src/formula/Ltl/And.h +++ b/src/formula/Ltl/And.h @@ -9,7 +9,6 @@ #define STORM_FORMULA_LTL_AND_H_ #include "AbstractLtlFormula.h" -#include "src/formula/abstract/And.h" #include "src/formula/AbstractFormulaChecker.h" #include "src/modelchecker/ltl/ForwardDeclarations.h" #include <string> @@ -71,27 +70,29 @@ class IAndVisitor { * @see AbstractLtlFormula */ template <class T> -class And : public storm::property::abstract::And<T, AbstractLtlFormula<T>>, public AbstractLtlFormula<T> { +class And : public AbstractLtlFormula<T> { public: + /*! * Empty constructor. * Will create an AND-node without subnotes. Will not represent a complete formula! */ And() { - //intentionally left empty + left = NULL; + right = NULL; } /*! * Constructor. - * Creates an AND node with the parameters as subtrees. + * Creates an AND note with the parameters as subtrees. * * @param left The left sub formula * @param right The right sub formula */ - And(AbstractLtlFormula<T>* left, AbstractLtlFormula<T>* right) - : storm::property::abstract::And<T, AbstractLtlFormula<T>>(left, right) { - //intentionally left empty + And(AbstractLtlFormula<T>* left, AbstractLtlFormula<T>* right) { + this->left = left; + this->right = right; } /*! @@ -101,7 +102,12 @@ public: * (this behavior can be prevented by setting them to NULL before deletion) */ virtual ~And() { - //intentionally left empty + if (left != NULL) { + delete left; + } + if (right != NULL) { + delete right; + } } /*! @@ -139,6 +145,81 @@ public: visitor.template as<IAndVisitor>()->visitAnd(*this); } + /*! + * @returns a string representation of the formula + */ + virtual std::string toString() const override { + std::string result = "("; + result += left->toString(); + result += " & "; + result += right->toString(); + result += ")"; + return result; + } + + /*! + * @brief Checks if all subtrees conform to some logic. + * + * @param checker Formula checker object. + * @return true iff all subtrees conform to some logic. + */ + virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + return checker.validate(this->left) && checker.validate(this->right); + } + + + /*! + * Sets the left child node. + * + * @param newLeft the new left child. + */ + void setLeft(AbstractLtlFormula<T>* newLeft) { + left = newLeft; + } + + /*! + * Sets the right child node. + * + * @param newRight the new right child. + */ + void setRight(AbstractLtlFormula<T>* newRight) { + right = newRight; + } + + /*! + * @returns a pointer to the left child node + */ + const AbstractLtlFormula<T>& getLeft() const { + return *left; + } + + /*! + * @returns a pointer to the right child node + */ + const AbstractLtlFormula<T>& getRight() const { + return *right; + } + + /*! + * + * @return True if the left child is set, i.e. it does not point to nullptr; false otherwise + */ + bool leftIsSet() const { + return left != nullptr; + } + + /*! + * + * @return True if the right child is set, i.e. it does not point to nullptr; false otherwise + */ + bool rightIsSet() const { + return right != nullptr; + } + +private: + AbstractLtlFormula<T>* left; + AbstractLtlFormula<T>* right; + }; } //namespace ltl diff --git a/src/formula/Ltl/Ap.h b/src/formula/Ltl/Ap.h index d5a0069f8..46a5376e1 100644 --- a/src/formula/Ltl/Ap.h +++ b/src/formula/Ltl/Ap.h @@ -9,7 +9,6 @@ #define STORM_FORMULA_LTL_AP_H_ #include "AbstractLtlFormula.h" -#include "src/formula/abstract/Ap.h" namespace storm { namespace property { @@ -63,8 +62,7 @@ class IApVisitor { * @see AbstractLtlFormula */ template <class T> -class Ap: public storm::property::abstract::Ap<T>, - public storm::property::ltl::AbstractLtlFormula<T> { +class Ap: public storm::property::ltl::AbstractLtlFormula<T> { public: /*! * Empty constructor @@ -80,13 +78,13 @@ public: * * @param ap The string representing the atomic proposition */ - Ap(std::string ap) : - storm::property::abstract::Ap<T>(ap) { - // Intentionally left empty + Ap(std::string ap) { + this->ap = ap; } /*! * Destructor + * At this time, empty... */ virtual ~Ap() { // Intentionally left empty @@ -121,6 +119,36 @@ public: virtual void visit(visitor::AbstractLtlFormulaVisitor<T>& visitor) const override { visitor.template as<IApVisitor>()->visitAp(*this); } + + /*! + * @returns a string representation of the leaf. + * + */ + virtual std::string toString() const override { + return getAp(); + } + + /*! + * @brief Checks if all subtrees conform to some logic. + * + * As atomic propositions have no subformulas, we return true here. + * + * @param checker Formula checker object. + * @return true + */ + virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + return true; + } + + /*! + * @returns the name of the atomic proposition + */ + const std::string& getAp() const { + return ap; + } + +private: + std::string ap; }; } /* namespace ltl */ diff --git a/src/formula/Ltl/BoundedEventually.h b/src/formula/Ltl/BoundedEventually.h index 2cbbc4c4a..b37775a0c 100644 --- a/src/formula/Ltl/BoundedEventually.h +++ b/src/formula/Ltl/BoundedEventually.h @@ -8,7 +8,6 @@ #ifndef STORM_FORMULA_LTL_BOUNDEDEVENTUALLY_H_ #define STORM_FORMULA_LTL_BOUNDEDEVENTUALLY_H_ -#include "src/formula/abstract/BoundedEventually.h" #include "AbstractLtlFormula.h" #include "src/formula/AbstractFormulaChecker.h" #include <cstdint> @@ -72,15 +71,16 @@ class IBoundedEventuallyVisitor { * @see AbstractLtlFormula */ template <class T> -class BoundedEventually : public storm::property::abstract::BoundedEventually<T, AbstractLtlFormula<T>>, - public AbstractLtlFormula<T> { +class BoundedEventually : public AbstractLtlFormula<T> { public: + /*! * Empty constructor */ - BoundedEventually() { - //intentionally left empty + BoundedEventually() { + this->child = nullptr; + bound = 0; } /*! @@ -89,9 +89,9 @@ public: * @param child The child formula subtree * @param bound The maximal number of steps */ - BoundedEventually(AbstractLtlFormula<T>* child, uint_fast64_t bound) : - storm::property::abstract::BoundedEventually<T, AbstractLtlFormula<T>>(child, bound){ - //intentionally left empty + BoundedEventually(AbstractLtlFormula<T>* child, uint_fast64_t bound) { + this->child = child; + this->bound = bound; } /*! @@ -101,9 +101,12 @@ public: * (this behaviour can be prevented by setting the subtrees to NULL before deletion) */ virtual ~BoundedEventually() { - //intentionally left empty + if (child != nullptr) { + delete child; + } } + /*! * Clones the called object. * @@ -137,6 +140,72 @@ public: virtual void visit(visitor::AbstractLtlFormulaVisitor<T>& visitor) const override { visitor.template as<IBoundedEventuallyVisitor>()->visitBoundedEventually(*this); } + + /*! + * @returns a string representation of the formula + */ + virtual std::string toString() const override { + std::string result = "F<="; + result += std::to_string(bound); + result += " "; + result += child->toString(); + return result; + } + + /*! + * @brief Checks if the subtree conforms to some logic. + * + * @param checker Formula checker object. + * @return true iff the subtree conforms to some logic. + */ + virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + return checker.validate(this->child); + } + + /*! + * @returns the child node + */ + const AbstractLtlFormula<T>& getChild() const { + return *child; + } + + /*! + * Sets the subtree + * @param child the new child node + */ + void setChild(AbstractLtlFormula<T>* child) { + this->child = child; + } + + /*! + * + * @return True if the child is set, i.e. it does not point to nullptr; false otherwise + */ + bool childIsSet() const { + return child != nullptr; + } + + /*! + * @returns the maximally allowed number of steps for the bounded until operator + */ + uint_fast64_t getBound() const { + return bound; + } + + /*! + * Sets the maximally allowed number of steps for the bounded until operator + * + * @param bound the new bound. + */ + void setBound(uint_fast64_t bound) { + this->bound = bound; + } + + +private: + AbstractLtlFormula<T>* child; + uint_fast64_t bound; + }; } //namespace ltl diff --git a/src/formula/Ltl/BoundedUntil.h b/src/formula/Ltl/BoundedUntil.h index 8d6f2fcf3..5daf126b8 100644 --- a/src/formula/Ltl/BoundedUntil.h +++ b/src/formula/Ltl/BoundedUntil.h @@ -8,8 +8,7 @@ #ifndef STORM_FORMULA_LTL_BOUNDEDUNTIL_H_ #define STORM_FORMULA_LTL_BOUNDEDUNTIL_H_ -#include "src/formula/abstract/BoundedUntil.h" -#include "AbstractLtlFormula.h" +#include "src/formula/Ltl/AbstractLtlFormula.h" #include <cstdint> #include <string> #include "src/modelchecker/ltl/ForwardDeclarations.h" @@ -72,15 +71,17 @@ class IBoundedUntilVisitor { * @see AbstractLtlFormula */ template <class T> -class BoundedUntil : public storm::property::abstract::BoundedUntil<T, AbstractLtlFormula<T>>, - public AbstractLtlFormula<T> { +class BoundedUntil : public AbstractLtlFormula<T> { public: + /*! * Empty constructor */ BoundedUntil() { - //Intentionally left empty + this->left = NULL; + this->right = NULL; + bound = 0; } /*! @@ -91,9 +92,10 @@ public: * @param bound The maximal number of steps */ BoundedUntil(AbstractLtlFormula<T>* left, AbstractLtlFormula<T>* right, - uint_fast64_t bound) : - storm::property::abstract::BoundedUntil<T, AbstractLtlFormula<T>>(left,right,bound) { - //intentionally left empty + uint_fast64_t bound) { + this->left = left; + this->right = right; + this->bound = bound; } /*! @@ -103,19 +105,12 @@ public: * (this behaviour can be prevented by setting the subtrees to NULL before deletion) */ virtual ~BoundedUntil() { - //intentionally left empty - } - - /*! - * @brief Return string representation of this formula. - * - * In LTL, brackets are needed around the until, as Until may appear nested (in other logics, Until always is the - * root of a path formula); hence this function is overwritten in this class. - * - * @return A string representation of the formula. - */ - virtual std::string toString() const { - return "(" + storm::property::abstract::BoundedUntil<T, AbstractLtlFormula<T>>::toString() + ")"; + if (left != NULL) { + delete left; + } + if (right != NULL) { + delete right; + } } /*! @@ -154,6 +149,102 @@ public: virtual void visit(visitor::AbstractLtlFormulaVisitor<T>& visitor) const override { visitor.template as<IBoundedUntilVisitor>()->visitBoundedUntil(*this); } + + /*! + * @brief Return string representation of this formula. + * + * In LTL, brackets are needed around the until, as Until may appear nested (in other logics, Until always is the + * root of a path formula); hence this function is overwritten in this class. + * + * @return A string representation of the formula. + */ + virtual std::string toString() const override { + std::string result = "(" + left->toString(); + result += " U<="; + result += std::to_string(bound); + result += " "; + result += right->toString() + ")"; + return result; + } + + /*! + * @brief Checks if all subtrees conform to some logic. + * + * @param checker Formula checker object. + * @return true iff all subtrees conform to some logic. + */ + virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + return checker.validate(this->left) && checker.validate(this->right); + } + + /*! + * Sets the left child node. + * + * @param newLeft the new left child. + */ + void setLeft(AbstractLtlFormula<T>* newLeft) { + left = newLeft; + } + + /*! + * Sets the right child node. + * + * @param newRight the new right child. + */ + void setRight(AbstractLtlFormula<T>* newRight) { + right = newRight; + } + + /*! + * @returns a pointer to the left child node + */ + const AbstractLtlFormula<T>& getLeft() const { + return *left; + } + + /*! + * @returns a pointer to the right child node + */ + const AbstractLtlFormula<T>& getRight() const { + return *right; + } + + /*! + * + * @return True if the left child is set, i.e. it does not point to nullptr; false otherwise + */ + bool leftIsSet() const { + return left != nullptr; + } + + /*! + * + * @return True if the right child is set, i.e. it does not point to nullptr; false otherwise + */ + bool rightIsSet() const { + return right != nullptr; + } + + /*! + * @returns the maximally allowed number of steps for the bounded until operator + */ + uint_fast64_t getBound() const { + return bound; + } + + /*! + * Sets the maximally allowed number of steps for the bounded until operator + * + * @param bound the new bound. + */ + void setBound(uint_fast64_t bound) { + this->bound = bound; + } + +private: + AbstractLtlFormula<T>* left; + AbstractLtlFormula<T>* right; + uint_fast64_t bound; }; } //namespace ltl diff --git a/src/formula/Ltl/Eventually.h b/src/formula/Ltl/Eventually.h index 2ca73607c..2825292fe 100644 --- a/src/formula/Ltl/Eventually.h +++ b/src/formula/Ltl/Eventually.h @@ -8,8 +8,7 @@ #ifndef STORM_FORMULA_LTL_EVENTUALLY_H_ #define STORM_FORMULA_LTL_EVENTUALLY_H_ -#include "src/formula/abstract/Eventually.h" -#include "AbstractLtlFormula.h" +#include "src/formula/Ltl/AbstractLtlFormula.h" #include "src/modelchecker/ltl/ForwardDeclarations.h" namespace storm { @@ -69,15 +68,15 @@ class IEventuallyVisitor { * @see AbstractLtlFormula */ template <class T> -class Eventually : public storm::property::abstract::Eventually<T, AbstractLtlFormula<T>>, - public AbstractLtlFormula<T> { +class Eventually : public AbstractLtlFormula<T> { public: + /*! * Empty constructor */ Eventually() { - // Intentionally left empty + this->child = nullptr; } /*! @@ -85,9 +84,8 @@ public: * * @param child The child node */ - Eventually(AbstractLtlFormula<T>* child) - : storm::property::abstract::Eventually<T, AbstractLtlFormula<T>>(child) { - + Eventually(AbstractLtlFormula<T>* child) { + this->child = child; } /*! @@ -97,7 +95,9 @@ public: * (this behaviour can be prevented by setting the subtrees to nullptr before deletion) */ virtual ~Eventually() { - //intentionally left empty + if (child != nullptr) { + delete child; + } } /*! @@ -131,6 +131,51 @@ public: virtual void visit(visitor::AbstractLtlFormulaVisitor<T>& visitor) const override { visitor.template as<IEventuallyVisitor>()->visitEventually(*this); } + + /*! + * @returns a string representation of the formula + */ + virtual std::string toString() const override { + std::string result = "F "; + result += child->toString(); + return result; + } + + /*! + * @brief Checks if the subtree conforms to some logic. + * + * @param checker Formula checker object. + * @return true iff the subtree conforms to some logic. + */ + virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + return checker.validate(this->child); + } + + /*! + * @returns the child node + */ + const AbstractLtlFormula<T>& getChild() const { + return *child; + } + + /*! + * Sets the subtree + * @param child the new child node + */ + void setChild(AbstractLtlFormula<T>* child) { + this->child = child; + } + + /*! + * + * @return True if the child node is set, i.e. it does not point to nullptr; false otherwise + */ + bool childIsSet() const { + return child != nullptr; + } + +private: + AbstractLtlFormula<T>* child; }; } //namespace ltl diff --git a/src/formula/Ltl/Globally.h b/src/formula/Ltl/Globally.h index 21bacaf14..e4000cc53 100644 --- a/src/formula/Ltl/Globally.h +++ b/src/formula/Ltl/Globally.h @@ -8,7 +8,6 @@ #ifndef STORM_FORMULA_LTL_GLOBALLY_H_ #define STORM_FORMULA_LTL_GLOBALLY_H_ -#include "src/formula/abstract/Globally.h" #include "AbstractLtlFormula.h" #include "src/formula/AbstractFormulaChecker.h" #include "src/modelchecker/ltl/ForwardDeclarations.h" @@ -70,15 +69,15 @@ class IGloballyVisitor { * @see AbstractLtlFormula */ template <class T> -class Globally : public storm::property::abstract::Globally<T, AbstractLtlFormula<T>>, - public AbstractLtlFormula<T> { +class Globally : public AbstractLtlFormula<T> { public: + /*! * Empty constructor */ Globally() { - //intentionally left empty + this->child = nullptr; } /*! @@ -86,9 +85,8 @@ public: * * @param child The child node */ - Globally(AbstractLtlFormula<T>* child) - : storm::property::abstract::Globally<T, AbstractLtlFormula<T>>(child) { - //intentionally left empty + Globally(AbstractLtlFormula<T>* child) { + this->child = child; } /*! @@ -98,10 +96,11 @@ public: * (this behaviour can be prevented by setting the subtrees to nullptr before deletion) */ virtual ~Globally() { - //intentionally left empty + if (child != nullptr) { + delete child; + } } - /*! * Clones the called object. * @@ -133,6 +132,51 @@ public: virtual void visit(visitor::AbstractLtlFormulaVisitor<T>& visitor) const override { visitor.template as<IGloballyVisitor>()->visitGlobally(*this); } + + /*! + * @returns a string representation of the formula + */ + virtual std::string toString() const override { + std::string result = "G "; + result += child->toString(); + return result; + } + + /*! + * @brief Checks if the subtree conforms to some logic. + * + * @param checker Formula checker object. + * @return true iff the subtree conforms to some logic. + */ + virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + return checker.validate(this->child); + } + + /*! + * @returns the child node + */ + const AbstractLtlFormula<T>& getChild() const { + return *child; + } + + /*! + * Sets the subtree + * @param child the new child node + */ + void setChild(AbstractLtlFormula<T>* child) { + this->child = child; + } + + /*! + * + * @return True if the child node is set, i.e. it does not point to nullptr; false otherwise + */ + bool childIsSet() const { + return child != nullptr; + } + + private: + AbstractLtlFormula<T>* child; }; } //namespace ltl diff --git a/src/formula/Ltl/Next.h b/src/formula/Ltl/Next.h index 44d98e12f..eb2d5334a 100644 --- a/src/formula/Ltl/Next.h +++ b/src/formula/Ltl/Next.h @@ -9,7 +9,6 @@ #define STORM_FORMULA_LTL_NEXT_H_ #include "AbstractLtlFormula.h" -#include "src/formula/abstract/Next.h" #include "src/formula/AbstractFormulaChecker.h" namespace storm { @@ -69,15 +68,15 @@ class INextVisitor { * @see AbstractLtlFormula */ template <class T> -class Next : public storm::property::abstract::Next<T, AbstractLtlFormula<T>>, - public AbstractLtlFormula<T> { +class Next : public AbstractLtlFormula<T> { public: + /*! * Empty constructor */ Next() { - //intentionally left empty + this->child = NULL; } /*! @@ -85,9 +84,8 @@ public: * * @param child The child node */ - Next(AbstractLtlFormula<T>* child) - : storm::property::abstract::Next<T, AbstractLtlFormula<T>>(child) { - //intentionally left empty + Next(AbstractLtlFormula<T>* child) { + this->child = child; } /*! @@ -97,7 +95,9 @@ public: * (this behaviour can be prevented by setting the subtrees to NULL before deletion) */ virtual ~Next() { - //intentionally left empty + if (child != NULL) { + delete child; + } } /*! @@ -131,6 +131,53 @@ public: virtual void visit(visitor::AbstractLtlFormulaVisitor<T>& visitor) const override { visitor.template as<INextVisitor>()->visitNext(*this); } + + /*! + * @returns a string representation of the formula + */ + virtual std::string toString() const override { + std::string result = "("; + result += " X "; + result += child->toString(); + result += ")"; + return result; + } + + /*! + * @brief Checks if the subtree conforms to some logic. + * + * @param checker Formula checker object. + * @return true iff the subtree conforms to some logic. + */ + virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + return checker.validate(this->child); + } + + /*! + * @returns the child node + */ + const AbstractLtlFormula<T>& getChild() const { + return *child; + } + + /*! + * Sets the subtree + * @param child the new child node + */ + void setChild(AbstractLtlFormula<T>* child) { + this->child = child; + } + + /*! + * + * @return True if the child node is set, i.e. it does not point to nullptr; false otherwise + */ + bool childIsSet() const { + return child != nullptr; + } + +private: + AbstractLtlFormula<T>* child; }; } //namespace ltl diff --git a/src/formula/Ltl/Not.h b/src/formula/Ltl/Not.h index bcf510999..11cac3acf 100644 --- a/src/formula/Ltl/Not.h +++ b/src/formula/Ltl/Not.h @@ -9,7 +9,6 @@ #define STORM_FORMULA_LTL_NOT_H_ #include "AbstractLtlFormula.h" -#include "src/formula/abstract/Not.h" #include "src/formula/AbstractFormulaChecker.h" namespace storm { @@ -66,24 +65,23 @@ class INotVisitor { * @see AbstractLtlFormula */ template <class T> -class Not : public storm::property::abstract::Not<T, AbstractLtlFormula<T>>, - public AbstractLtlFormula<T> { +class Not : public AbstractLtlFormula<T> { public: + /*! * Empty constructor */ Not() { - //intentionally left empty + this->child = NULL; } /*! * Constructor * @param child The child node */ - Not(AbstractLtlFormula<T>* child) : - storm::property::abstract::Not<T, AbstractLtlFormula<T>>(child){ - //intentionally left empty + Not(AbstractLtlFormula<T>* child) { + this->child = child; } /*! @@ -93,7 +91,9 @@ public: * (this behavior can be prevented by setting them to NULL before deletion) */ virtual ~Not() { - //intentionally left empty + if (child != NULL) { + delete child; + } } /*! @@ -127,6 +127,51 @@ public: virtual void visit(visitor::AbstractLtlFormulaVisitor<T>& visitor) const override { visitor.template as<INotVisitor>()->visitNot(*this); } + + /*! + * @returns a string representation of the formula + */ + virtual std::string toString() const override { + std::string result = "!"; + result += child->toString(); + return result; + } + + /*! + * @brief Checks if the subtree conforms to some logic. + * + * @param checker Formula checker object. + * @return true iff the subtree conforms to some logic. + */ + virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + return checker.validate(this->child); + } + + /*! + * @returns The child node + */ + const AbstractLtlFormula<T>& getChild() const { + return *child; + } + + /*! + * Sets the subtree + * @param child the new child node + */ + void setChild(AbstractLtlFormula<T>* child) { + this->child = child; + } + + /*! + * + * @return True if the child node is set, i.e. it does not point to nullptr; false otherwise + */ + bool childIsSet() const { + return child != nullptr; + } + +private: + AbstractLtlFormula<T>* child; }; } //namespace ltl diff --git a/src/formula/Ltl/Or.h b/src/formula/Ltl/Or.h index 511420d5d..a11e8fc71 100644 --- a/src/formula/Ltl/Or.h +++ b/src/formula/Ltl/Or.h @@ -9,7 +9,6 @@ #define STORM_FORMULA_LTL_OR_H_ #include "AbstractLtlFormula.h" -#include "src/formula/abstract/Or.h" namespace storm { namespace property { @@ -68,34 +67,44 @@ class IOrVisitor { * @see AbstractLtlFormula */ template <class T> -class Or: public storm::property::abstract::Or<T, AbstractLtlFormula<T>>, - public storm::property::ltl::AbstractLtlFormula<T> { +class Or: public storm::property::ltl::AbstractLtlFormula<T> { + public: + /*! - * Empty constructor + * Empty constructor. + * Will create an AND-node without subnotes. Will not represent a complete formula! */ Or() { - // Intentionally left empty - + left = NULL; + right = NULL; } /*! - * Constructor - * Creates an OR node with the parameters as subtrees. + * Constructor. + * Creates an AND note with the parameters as subtrees. * - * @param left The left subformula - * @param right The right subformula + * @param left The left sub formula + * @param right The right sub formula */ - Or(AbstractLtlFormula<T>* left, AbstractLtlFormula<T>* right) - : storm::property::abstract::Or<T,AbstractLtlFormula<T>>(left, right) { - // Intentionally left empty + Or(AbstractLtlFormula<T>* left, AbstractLtlFormula<T>* right) { + this->left = left; + this->right = right; } /*! - * Destructor + * Destructor. + * + * The subtrees are deleted with the object + * (this behavior can be prevented by setting them to NULL before deletion) */ virtual ~Or() { - // Intentionally left empty + if (left != NULL) { + delete left; + } + if (right != NULL) { + delete right; + } } /*! @@ -133,6 +142,79 @@ public: visitor.template as<IOrVisitor>()->visitOr(*this); } + /*! + * @returns a string representation of the formula + */ + virtual std::string toString() const override { + std::string result = "("; + result += left->toString(); + result += " | "; + result += right->toString(); + result += ")"; + return result; + } + + /*! + * @brief Checks if all subtrees conform to some logic. + * + * @param checker Formula checker object. + * @return true iff all subtrees conform to some logic. + */ + virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + return checker.validate(this->left) && checker.validate(this->right); + } + + /*! + * Sets the left child node. + * + * @param newLeft the new left child. + */ + void setLeft(AbstractLtlFormula<T>* newLeft) { + left = newLeft; + } + + /*! + * Sets the right child node. + * + * @param newRight the new right child. + */ + void setRight(AbstractLtlFormula<T>* newRight) { + right = newRight; + } + + /*! + * @returns a pointer to the left child node + */ + const AbstractLtlFormula<T>& getLeft() const { + return *left; + } + + /*! + * @returns a pointer to the right child node + */ + const AbstractLtlFormula<T>& getRight() const { + return *right; + } + + /*! + * + * @return True if the left child is set, i.e. it does not point to nullptr; false otherwise + */ + bool leftIsSet() const { + return left != nullptr; + } + + /*! + * + * @return True if the right child is set, i.e. it does not point to nullptr; false otherwise + */ + bool rightIsSet() const { + return right != nullptr; + } + +private: + AbstractLtlFormula<T>* left; + AbstractLtlFormula<T>* right; }; } /* namespace ltl */ diff --git a/src/formula/Ltl/Until.h b/src/formula/Ltl/Until.h index 359e64a0a..596a654fe 100644 --- a/src/formula/Ltl/Until.h +++ b/src/formula/Ltl/Until.h @@ -9,7 +9,6 @@ #define STORM_FORMULA_LTL_UNTIL_H_ #include "AbstractLtlFormula.h" -#include "src/formula/abstract/Until.h" #include "src/formula/AbstractFormulaChecker.h" namespace storm { @@ -70,15 +69,16 @@ class IUntilVisitor { * @see AbstractLtlFormula */ template <class T> -class Until : public storm::property::abstract::Until<T, AbstractLtlFormula<T>>, - public AbstractLtlFormula<T> { +class Until : public AbstractLtlFormula<T> { public: + /*! * Empty constructor */ Until() { - // Intentionally left empty + this->left = NULL; + this->right = NULL; } /*! @@ -87,9 +87,9 @@ public: * @param left The left formula subtree * @param right The left formula subtree */ - Until(AbstractLtlFormula<T>* left, AbstractLtlFormula<T>* right) - : storm::property::abstract::Until<T, AbstractLtlFormula<T>>(left, right) { - // Intentionally left empty + Until(AbstractLtlFormula<T>* left, AbstractLtlFormula<T>* right) { + this->left = left; + this->right = right; } /*! @@ -99,19 +99,12 @@ public: * (this behaviour can be prevented by setting the subtrees to NULL before deletion) */ virtual ~Until() { - // Intentionally left empty - } - - /*! - * @brief Return string representation of this formula. - * - * In LTL, brackets are needed around the until, as Until may appear nested (in other logics, Until always is the - * root of a path formula); hence this function is overwritten in this class. - * - * @return A string representation of the formula. - */ - virtual std::string toString() const { - return "(" + storm::property::abstract::Until<T, AbstractLtlFormula<T>>::toString() + ")"; + if (left != NULL) { + delete left; + } + if (right != NULL) { + delete right; + } } /*! @@ -148,6 +141,83 @@ public: virtual void visit(visitor::AbstractLtlFormulaVisitor<T>& visitor) const override { visitor.template as<IUntilVisitor>()->visitUntil(*this); } + + /*! + * @brief Return string representation of this formula. + * + * In LTL, brackets are needed around the until, as Until may appear nested (in other logics, Until always is the + * root of a path formula); hence this function is overwritten in this class. + * + * @return A string representation of the formula. + */ + virtual std::string toString() const { + std::string result = "(" + left->toString(); + result += " U "; + result += right->toString() + ")"; + return result; + } + + /*! + * @brief Checks if all subtrees conform to some logic. + * + * @param checker Formula checker object. + * @return true iff all subtrees conform to some logic. + */ + virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + return checker.validate(this->left) && checker.validate(this->right); + } + + /*! + * Sets the left child node. + * + * @param newLeft the new left child. + */ + void setLeft(AbstractLtlFormula<T>* newLeft) { + left = newLeft; + } + + /*! + * Sets the right child node. + * + * @param newRight the new right child. + */ + void setRight(AbstractLtlFormula<T>* newRight) { + right = newRight; + } + + /*! + * @returns a pointer to the left child node + */ + const AbstractLtlFormula<T>& getLeft() const { + return *left; + } + + /*! + * @returns a pointer to the right child node + */ + const AbstractLtlFormula<T>& getRight() const { + return *right; + } + + /*! + * + * @return True if the left child is set, i.e. it does not point to nullptr; false otherwise + */ + bool leftIsSet() const { + return left != nullptr; + } + + /*! + * + * @return True if the right child is set, i.e. it does not point to nullptr; false otherwise + */ + bool rightIsSet() const { + return right != nullptr; + } + +private: + AbstractLtlFormula<T>* left; + AbstractLtlFormula<T>* right; }; } //namespace ltl diff --git a/src/formula/Prctl/AbstractNoBoundOperator.h b/src/formula/Prctl/AbstractNoBoundOperator.h index c73c4ed6f..4605a590d 100644 --- a/src/formula/Prctl/AbstractNoBoundOperator.h +++ b/src/formula/Prctl/AbstractNoBoundOperator.h @@ -8,7 +8,7 @@ #ifndef STORM_FORMULA_PRCTL_ABSTRACTNOBOUNDOPERATOR_H_ #define STORM_FORMULA_PRCTL_ABSTRACTNOBOUNDOPERATOR_H_ -#include "AbstractPrctlFormula.h" +#include "src/formula/AbstractFormula.h" #include "src/formula/abstract/IOptimizingOperator.h" namespace storm { @@ -42,8 +42,8 @@ public: * Interface class for all PRCTL No bound operators */ template <class T> -class AbstractNoBoundOperator: public AbstractPrctlFormula<T>, - public virtual storm::property::abstract::IOptimizingOperator { +class AbstractNoBoundOperator: public storm::property::AbstractFormula<T>, + public virtual storm::property::IOptimizingOperator { public: AbstractNoBoundOperator() { // Intentionally left empty. diff --git a/src/formula/Prctl/AbstractPathFormula.h b/src/formula/Prctl/AbstractPathFormula.h index c3c2cfc1b..c7e20b9c6 100644 --- a/src/formula/Prctl/AbstractPathFormula.h +++ b/src/formula/Prctl/AbstractPathFormula.h @@ -8,11 +8,7 @@ #ifndef STORM_FORMULA_PRCTL_ABSTRACTPATHFORMULA_H_ #define STORM_FORMULA_PRCTL_ABSTRACTPATHFORMULA_H_ -namespace storm { namespace property { namespace prctl { -template <class T> class AbstractPathFormula; -}}} - -#include "src/formula/abstract/AbstractFormula.h" +#include "src/formula/AbstractFormula.h" #include "src/modelchecker/prctl/ForwardDeclarations.h" #include <vector> @@ -35,7 +31,7 @@ namespace prctl { * @note This class is intentionally not derived from AbstractPrctlFormula, as path formulas are not complete PRCTL formulas. */ template <class T> -class AbstractPathFormula : public virtual storm::property::abstract::AbstractFormula<T> { +class AbstractPathFormula : public virtual storm::property::AbstractFormula<T> { public: /*! diff --git a/src/formula/Prctl/AbstractPrctlFormula.h b/src/formula/Prctl/AbstractPrctlFormula.h deleted file mode 100644 index 8855763a9..000000000 --- a/src/formula/Prctl/AbstractPrctlFormula.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * AbstractPrctlFormula.h - * - * Created on: 16.04.2013 - * Author: thomas - */ - -#ifndef STORM_FORMULA_PRCTL_ABSTRACTPRCTLFORMULA_H_ -#define STORM_FORMULA_PRCTL_ABSTRACTPRCTLFORMULA_H_ - -#include "src/formula/abstract/AbstractFormula.h" - -namespace storm { -namespace property { -namespace prctl { - -/*! - * Interface class for all PRCTL root formulas. - */ -template<class T> -class AbstractPrctlFormula : public virtual storm::property::abstract::AbstractFormula<T> { -public: - virtual ~AbstractPrctlFormula() { - // Intentionally left empty - } -}; - -} /* namespace prctl */ -} /* namespace property */ -} /* namespace storm */ -#endif /* ABSTRACTPRCTLFORMULA_H_ */ diff --git a/src/formula/Prctl/AbstractStateFormula.h b/src/formula/Prctl/AbstractStateFormula.h index 0a313bfd1..1142d7754 100644 --- a/src/formula/Prctl/AbstractStateFormula.h +++ b/src/formula/Prctl/AbstractStateFormula.h @@ -8,11 +8,7 @@ #ifndef STORM_FORMULA_PRCTL_ABSTRACTSTATEFORMULA_H_ #define STORM_FORMULA_PRCTL_ABSTRACTSTATEFORMULA_H_ -namespace storm { namespace property { namespace prctl { -template <class T> class AbstractStateFormula; -}}} - -#include "AbstractPrctlFormula.h" +#include "src/formula/AbstractFormula.h" #include "src/storage/BitVector.h" #include "src/modelchecker/prctl/ForwardDeclarations.h" @@ -30,7 +26,7 @@ namespace prctl { * clone(). */ template <class T> -class AbstractStateFormula : public AbstractPrctlFormula<T> { +class AbstractStateFormula : public virtual storm::property::AbstractFormula<T> { public: /*! diff --git a/src/formula/Prctl/And.h b/src/formula/Prctl/And.h index eca17d73d..dcda9e802 100644 --- a/src/formula/Prctl/And.h +++ b/src/formula/Prctl/And.h @@ -8,8 +8,7 @@ #ifndef STORM_FORMULA_PRCTL_AND_H_ #define STORM_FORMULA_PRCTL_AND_H_ -#include "AbstractStateFormula.h" -#include "src/formula/abstract/And.h" +#include "src/formula/Prctl/AbstractStateFormula.h" #include "src/formula/AbstractFormulaChecker.h" #include "src/modelchecker/prctl/ForwardDeclarations.h" #include <string> @@ -54,15 +53,17 @@ class IAndModelChecker { * @see AbstractPrctlFormula */ template <class T> -class And : public storm::property::abstract::And<T, AbstractStateFormula<T>>, public AbstractStateFormula<T> { +class And : public AbstractStateFormula<T> { public: + /*! * Empty constructor. * Will create an AND-node without subnotes. Will not represent a complete formula! */ And() { - //intentionally left empty + left = NULL; + right = NULL; } /*! @@ -72,9 +73,9 @@ public: * @param left The left sub formula * @param right The right sub formula */ - And(AbstractStateFormula<T>* left, AbstractStateFormula<T>* right) - : storm::property::abstract::And<T, AbstractStateFormula<T>>(left, right) { - //intentionally left empty + And(AbstractStateFormula<T>* left, AbstractStateFormula<T>* right) { + this->left = left; + this->right = right; } /*! @@ -84,7 +85,12 @@ public: * (this behavior can be prevented by setting them to NULL before deletion) */ virtual ~And() { - //intentionally left empty + if (left != NULL) { + delete left; + } + if (right != NULL) { + delete right; + } } /*! @@ -118,6 +124,80 @@ public: return modelChecker.template as<IAndModelChecker>()->checkAnd(*this); } + /*! + * @returns a string representation of the formula + */ + virtual std::string toString() const override { + std::string result = "("; + result += left->toString(); + result += " & "; + result += right->toString(); + result += ")"; + return result; + } + + /*! + * @brief Checks if all subtrees conform to some logic. + * + * @param checker Formula checker object. + * @return true iff all subtrees conform to some logic. + */ + virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + return checker.validate(this->left) && checker.validate(this->right); + } + + /*! + * Sets the left child node. + * + * @param newLeft the new left child. + */ + void setLeft(AbstractStateFormula<T>* newLeft) { + left = newLeft; + } + + /*! + * Sets the right child node. + * + * @param newRight the new right child. + */ + void setRight(AbstractStateFormula<T>* newRight) { + right = newRight; + } + + /*! + * @returns a pointer to the left child node + */ + const AbstractStateFormula<T>& getLeft() const { + return *left; + } + + /*! + * @returns a pointer to the right child node + */ + const AbstractStateFormula<T>& getRight() const { + return *right; + } + + /*! + * + * @return True if the left child is set, i.e. it does not point to nullptr; false otherwise + */ + bool leftIsSet() const { + return left != nullptr; + } + + /*! + * + * @return True if the right child is set, i.e. it does not point to nullptr; false otherwise + */ + bool rightIsSet() const { + return right != nullptr; + } + +private: + AbstractStateFormula<T>* left; + AbstractStateFormula<T>* right; + }; } //namespace prctl diff --git a/src/formula/Prctl/Ap.h b/src/formula/Prctl/Ap.h index d2df03951..7e234d434 100644 --- a/src/formula/Prctl/Ap.h +++ b/src/formula/Prctl/Ap.h @@ -8,8 +8,7 @@ #ifndef STORM_FORMULA_PRCTL_AP_H_ #define STORM_FORMULA_PRCTL_AP_H_ -#include "AbstractStateFormula.h" -#include "src/formula/abstract/Ap.h" +#include "src/formula/Prctl/AbstractStateFormula.h" #include "src/formula/AbstractFormulaChecker.h" #include "src/modelchecker/prctl/ForwardDeclarations.h" @@ -47,10 +46,10 @@ class IApModelChecker { * @see AbstractStateFormula */ template <class T> -class Ap : public storm::property::abstract::Ap<T>, - public AbstractStateFormula<T> { +class Ap : public AbstractStateFormula<T> { public: + /*! * Constructor * @@ -58,9 +57,8 @@ public: * * @param ap The string representing the atomic proposition */ - Ap(std::string ap) - : storm::property::abstract::Ap<T>(ap) { - // Intentionally left empty + Ap(std::string ap) { + this->ap = ap; } /*! @@ -95,6 +93,35 @@ public: return modelChecker.template as<IApModelChecker>()->checkAp(*this); } + /*! + * @brief Checks if all subtrees conform to some logic. + * + * As atomic propositions have no subformulas, we return true here. + * + * @param checker Formula checker object. + * @return true + */ + virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + return true; + } + + /*! + * @returns the name of the atomic proposition + */ + const std::string& getAp() const { + return ap; + } + + /*! + * @returns a string representation of the leaf. + * + */ + virtual std::string toString() const override { + return getAp(); + } + +private: + std::string ap; }; } //namespace abstract diff --git a/src/formula/Prctl/Not.h b/src/formula/Prctl/Not.h index 7f6a992ab..6859d97b1 100644 --- a/src/formula/Prctl/Not.h +++ b/src/formula/Prctl/Not.h @@ -9,7 +9,6 @@ #define STORM_FORMULA_PRCTL_NOT_H_ #include "AbstractStateFormula.h" -#include "src/formula/abstract/Not.h" #include "src/formula/AbstractFormulaChecker.h" #include "src/modelchecker/prctl/ForwardDeclarations.h" @@ -50,24 +49,22 @@ class INotModelChecker { * @see AbstractPrctlFormula */ template <class T> -class Not : public storm::property::abstract::Not<T, AbstractStateFormula<T>>, - public AbstractStateFormula<T> { +class Not : public AbstractStateFormula<T> { public: /*! * Empty constructor */ Not() { - //intentionally left empty + this->child = NULL; } /*! * Constructor * @param child The child node */ - Not(AbstractStateFormula<T>* child) : - storm::property::abstract::Not<T, AbstractStateFormula<T>>(child){ - //intentionally left empty + Not(AbstractStateFormula<T>* child) { + this->child = child; } /*! @@ -77,7 +74,9 @@ public: * (this behavior can be prevented by setting them to NULL before deletion) */ virtual ~Not() { - //intentionally left empty + if (child != NULL) { + delete child; + } } /*! @@ -107,6 +106,51 @@ public: virtual storm::storage::BitVector check(const storm::modelchecker::prctl::AbstractModelChecker<T>& modelChecker) const override { return modelChecker.template as<INotModelChecker>()->checkNot(*this); } + + /*! + * @returns a string representation of the formula + */ + virtual std::string toString() const override { + std::string result = "!"; + result += child->toString(); + return result; + } + + /*! + * @brief Checks if the subtree conforms to some logic. + * + * @param checker Formula checker object. + * @return true iff the subtree conforms to some logic. + */ + virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + return checker.validate(this->child); + } + + /*! + * @returns The child node + */ + const FormulaType& getChild() const { + return *child; + } + + /*! + * Sets the subtree + * @param child the new child node + */ + void setChild(FormulaType* child) { + this->child = child; + } + + /*! + * + * @return True if the child node is set, i.e. it does not point to nullptr; false otherwise + */ + bool childIsSet() const { + return child != nullptr; + } + +private: + AbstractStateFormula<T>* child; }; } //namespace prctl diff --git a/src/formula/Prctl/Or.h b/src/formula/Prctl/Or.h index a13c385e3..cbac0c655 100644 --- a/src/formula/Prctl/Or.h +++ b/src/formula/Prctl/Or.h @@ -8,8 +8,7 @@ #ifndef STORM_FORMULA_PRCTL_OR_H_ #define STORM_FORMULA_PRCTL_OR_H_ -#include "AbstractStateFormula.h" -#include "src/formula/abstract/Or.h" +#include "src/formula/Prctl/AbstractStateFormula.h" #include "src/formula/AbstractFormulaChecker.h" namespace storm { @@ -52,28 +51,28 @@ class IOrModelChecker { * @see AbstractPrctlFormula */ template <class T> -class Or : public storm::property::abstract::Or<T, AbstractStateFormula<T>>, - public AbstractStateFormula<T> { +class Or : public AbstractStateFormula<T> { public: /*! * Empty constructor. - * Will create an OR-node without subnotes. The result does not represent a complete formula! + * Will create an AND-node without subnotes. Will not represent a complete formula! */ Or() { - //intentionally left empty + left = NULL; + right = NULL; } /*! * Constructor. - * Creates an OR note with the parameters as subtrees. + * Creates an AND note with the parameters as subtrees. * * @param left The left sub formula * @param right The right sub formula */ - Or(AbstractStateFormula<T>* left, AbstractStateFormula<T>* right) : - storm::property::abstract::Or<T, AbstractStateFormula<T>>(left, right) { - //intentionally left empty + Or(FormulaType* left, FormulaType* right) { + this->left = left; + this->right = right; } /*! @@ -83,7 +82,12 @@ public: * (this behavior can be prevented by setting them to NULL before deletion) */ virtual ~Or() { - //intentionally left empty + if (left != NULL) { + delete left; + } + if (right != NULL) { + delete right; + } } /*! @@ -116,6 +120,81 @@ public: virtual storm::storage::BitVector check(const storm::modelchecker::prctl::AbstractModelChecker<T>& modelChecker) const override { return modelChecker.template as<IOrModelChecker>()->checkOr(*this); } + + /*! + * @returns a string representation of the formula + */ + virtual std::string toString() const override { + std::string result = "("; + result += left->toString(); + result += " | "; + result += right->toString(); + result += ")"; + return result; + } + + /*! + * @brief Checks if all subtrees conform to some logic. + * + * @param checker Formula checker object. + * @return true iff all subtrees conform to some logic. + */ + virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + return checker.validate(this->left) && checker.validate(this->right); + } + + /*! + * Sets the left child node. + * + * @param newLeft the new left child. + */ + void setLeft(FormulaType* newLeft) { + left = newLeft; + } + + /*! + * Sets the right child node. + * + * @param newRight the new right child. + */ + void setRight(FormulaType* newRight) { + right = newRight; + } + + /*! + * @returns a pointer to the left child node + */ + const FormulaType& getLeft() const { + return *left; + } + + /*! + * @returns a pointer to the right child node + */ + const FormulaType& getRight() const { + return *right; + } + + /*! + * + * @return True if the left child is set, i.e. it does not point to nullptr; false otherwise + */ + bool leftIsSet() const { + return left != nullptr; + } + + /*! + * + * @return True if the right child is set, i.e. it does not point to nullptr; false otherwise + */ + bool rightIsSet() const { + return right != nullptr; + } + +private: + AbstractStateFormula<T>* left; + AbstractStateFormula<T>* right; + }; } //namespace prctl diff --git a/src/formula/Prctl/ProbabilisticBoundOperator.h b/src/formula/Prctl/ProbabilisticBoundOperator.h index a2ea229aa..6e171a517 100644 --- a/src/formula/Prctl/ProbabilisticBoundOperator.h +++ b/src/formula/Prctl/ProbabilisticBoundOperator.h @@ -10,7 +10,6 @@ #include "AbstractStateFormula.h" #include "AbstractPathFormula.h" -#include "src/formula/abstract/ProbabilisticBoundOperator.h" #include "utility/constants.h" namespace storm { diff --git a/src/formula/abstract/And.h b/src/formula/abstract/And.h deleted file mode 100644 index c2739a9e4..000000000 --- a/src/formula/abstract/And.h +++ /dev/null @@ -1,164 +0,0 @@ -/* - * And.h - * - * Created on: 19.10.2012 - * Author: Thomas Heinemann - */ - -#ifndef STORM_FORMULA_ABSTRACT_AND_H_ -#define STORM_FORMULA_ABSTRACT_AND_H_ - -#include "src/formula/abstract/AbstractFormula.h" -#include "src/formula/AbstractFormulaChecker.h" -#include <string> -#include <type_traits> - -namespace storm { -namespace property { -namespace abstract { - -/*! - * @brief - * Logic-abstract Class for an abstract formula tree with AND node as root. - * - * Has two formulas as sub formulas/trees; the type is the template parameter FormulaType - * - * As AND is commutative, the order is \e theoretically not important, but will influence the order in which - * the model checker works. - * - * The subtrees are seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @see AbstractFormula - * - * @tparam FormulaType The type of the subformula. - * The instantiation of FormulaType should be a subclass of AbstractFormula, as the functions - * "toString" and "validate" of the subformulas are needed. - */ -template <class T, class FormulaType> -class And : public virtual AbstractFormula<T> { - - // Throw a compiler error when FormulaType is not a subclass of AbstractFormula. - static_assert(std::is_base_of<AbstractFormula<T>, FormulaType>::value, - "Instantiaton of FormulaType for storm::property::abstract::And<T,FormulaType> has to be a subtype of storm::property::abstract::AbstractFormula<T>"); - -public: - /*! - * Empty constructor. - * Will create an AND-node without subnotes. Will not represent a complete formula! - */ - And() { - left = NULL; - right = NULL; - } - - /*! - * Constructor. - * Creates an AND note with the parameters as subtrees. - * - * @param left The left sub formula - * @param right The right sub formula - */ - And(FormulaType* left, FormulaType* right) { - this->left = left; - this->right = right; - } - - /*! - * Destructor. - * - * The subtrees are deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - */ - virtual ~And() { - if (left != NULL) { - delete left; - } - if (right != NULL) { - delete right; - } - } - - /*! - * Sets the left child node. - * - * @param newLeft the new left child. - */ - void setLeft(FormulaType* newLeft) { - left = newLeft; - } - - /*! - * Sets the right child node. - * - * @param newRight the new right child. - */ - void setRight(FormulaType* newRight) { - right = newRight; - } - - /*! - * @returns a pointer to the left child node - */ - const FormulaType& getLeft() const { - return *left; - } - - /*! - * @returns a pointer to the right child node - */ - const FormulaType& getRight() const { - return *right; - } - - /*! - * - * @return True if the left child is set, i.e. it does not point to nullptr; false otherwise - */ - bool leftIsSet() const { - return left != nullptr; - } - - /*! - * - * @return True if the right child is set, i.e. it does not point to nullptr; false otherwise - */ - bool rightIsSet() const { - return right != nullptr; - } - - /*! - * @returns a string representation of the formula - */ - virtual std::string toString() const override { - std::string result = "("; - result += left->toString(); - result += " & "; - result += right->toString(); - result += ")"; - return result; - } - - /*! - * @brief Checks if all subtrees conform to some logic. - * - * @param checker Formula checker object. - * @return true iff all subtrees conform to some logic. - */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { - return checker.validate(this->left) && checker.validate(this->right); - } - - -private: - FormulaType* left; - FormulaType* right; -}; - -} //namespace abstract - -} //namespace property - -} //namespace storm - -#endif /* STORM_FORMULA_ABSTRACT_AND_H_ */ diff --git a/src/formula/abstract/Ap.h b/src/formula/abstract/Ap.h deleted file mode 100644 index dd0acce82..000000000 --- a/src/formula/abstract/Ap.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Ap.h - * - * Created on: 19.10.2012 - * Author: Thomas Heinemann - */ - -#ifndef STORM_FORMULA_ABSTRACT_AP_H_ -#define STORM_FORMULA_ABSTRACT_AP_H_ - -#include "src/formula/abstract/AbstractFormula.h" -#include "src/formula/AbstractFormulaChecker.h" - -namespace storm { -namespace property { -namespace abstract { - -/*! - * @brief - * Logic-abstract Class for an abstract formula tree with atomic proposition as root. - * - * This class represents the leaves in the formula tree. - * - * @see AbstractFormula - */ -template <class T> -class Ap : public virtual AbstractFormula<T> { - -public: - /*! - * Constructor - * - * Creates a new atomic proposition leaf, with the label Ap - * - * @param ap The string representing the atomic proposition - */ - Ap(std::string ap) { - this->ap = ap; - } - - /*! - * Destructor. - * At this time, empty... - */ - virtual ~Ap() { } - - /*! - * @returns the name of the atomic proposition - */ - const std::string& getAp() const { - return ap; - } - - /*! - * @returns a string representation of the leaf. - * - */ - virtual std::string toString() const override { - return getAp(); - } - - /*! - * @brief Checks if all subtrees conform to some logic. - * - * As atomic propositions have no subformulas, we return true here. - * - * @param checker Formula checker object. - * @return true - */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { - return true; - } - -private: - std::string ap; -}; - -} //namespace abstract - -} //namespace property - -} //namespace storm - -#endif /* STORM_FORMULA_ABSTRACT_ABSTRCT_AP_H_ */ diff --git a/src/formula/abstract/BoundedEventually.h b/src/formula/abstract/BoundedEventually.h deleted file mode 100644 index 2970d09d3..000000000 --- a/src/formula/abstract/BoundedEventually.h +++ /dev/null @@ -1,151 +0,0 @@ -/* - * BoundedUntil.h - * - * Created on: 27.11.2012 - * Author: Christian Dehnert - */ - -#ifndef STORM_FORMULA_ABSTRACT_BOUNDEDEVENTUALLY_H_ -#define STORM_FORMULA_ABSTRACT_BOUNDEDEVENTUALLY_H_ - -#include "src/formula/abstract/AbstractFormula.h" -#include "src/formula/AbstractFormulaChecker.h" -#include <cstdint> -#include <string> - -namespace storm { - -namespace property { - -namespace abstract { - -/*! - * @brief - * Class for an abstract (path) formula tree with a BoundedEventually node as root. - * - * Has one formula as sub formula/tree. - * - * @par Semantics - * The formula holds iff in at most \e bound steps, formula \e child holds. - * - * The subtrees are seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @tparam FormulaType The type of the subformula. - * The instantiation of FormulaType should be a subclass of AbstractFormula, as the functions - * "toString" and "validate" of the subformulas are needed. - * - * @see AbstractFormula - */ -template <class T, class FormulaType> -class BoundedEventually : public virtual AbstractFormula<T> { - - // Throw a compiler error when FormulaType is not a subclass of AbstractFormula. - static_assert(std::is_base_of<AbstractFormula<T>, FormulaType>::value, - "Instantiaton of FormulaType for storm::property::abstract::BoundedEventually<T,FormulaType> has to be a subtype of storm::property::abstract::AbstractFormula<T>"); - -public: - /*! - * Empty constructor - */ - BoundedEventually() { - this->child = nullptr; - bound = 0; - } - - /*! - * Constructor - * - * @param child The child formula subtree - * @param bound The maximal number of steps - */ - BoundedEventually(FormulaType* child, uint_fast64_t bound) { - this->child = child; - this->bound = bound; - } - - /*! - * Destructor. - * - * Also deletes the subtrees. - * (this behaviour can be prevented by setting the subtrees to NULL before deletion) - */ - virtual ~BoundedEventually() { - if (child != nullptr) { - delete child; - } - } - - /*! - * @returns the child node - */ - const FormulaType& getChild() const { - return *child; - } - - /*! - * Sets the subtree - * @param child the new child node - */ - void setChild(FormulaType* child) { - this->child = child; - } - - /*! - * - * @return True if the child is set, i.e. it does not point to nullptr; false otherwise - */ - bool childIsSet() const { - return child != nullptr; - } - - /*! - * @returns the maximally allowed number of steps for the bounded until operator - */ - uint_fast64_t getBound() const { - return bound; - } - - /*! - * Sets the maximally allowed number of steps for the bounded until operator - * - * @param bound the new bound. - */ - void setBound(uint_fast64_t bound) { - this->bound = bound; - } - - /*! - * @returns a string representation of the formula - */ - virtual std::string toString() const override { - std::string result = "F<="; - result += std::to_string(bound); - result += " "; - result += child->toString(); - return result; - } - - /*! - * @brief Checks if the subtree conforms to some logic. - * - * @param checker Formula checker object. - * @return true iff the subtree conforms to some logic. - */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { - return checker.validate(this->child); - } - - -private: - FormulaType* child; - uint_fast64_t bound; -}; - -} //namespace abstract - -} //namespace property - -} //namespace storm - -#endif /* STORM_FORMULA_ABSTRACT_BOUNDEDEVENTUALLY_H_ */ diff --git a/src/formula/abstract/BoundedNaryUntil.h b/src/formula/abstract/BoundedNaryUntil.h deleted file mode 100644 index 749f2305f..000000000 --- a/src/formula/abstract/BoundedNaryUntil.h +++ /dev/null @@ -1,175 +0,0 @@ -/* - * BoundedNaryUntil.h - * - * Created on: 19.10.2012 - * Author: Thomas Heinemann - */ - -#ifndef STORM_FORMULA_ABSTRACT_BOUNDEDNARYUNTIL_H_ -#define STORM_FORMULA_ABSTRACT_BOUNDEDNARYUNTIL_H_ - -#include "src/formula/abstract/AbstractFormula.h" -#include <cstdint> -#include <string> -#include <vector> -#include <tuple> -#include <sstream> - -namespace storm { -namespace property { -namespace abstract { - -/*! - * @brief - * Class for an abstract (path) formula tree with a BoundedNaryUntil node as root. - * - * Has at least two formulas as sub formulas and an interval - * associated with all but the first sub formula. We'll call the first one - * \e left and all other one \e right. - * - * @par Semantics - * The formula holds iff \e left holds until eventually any of the \e right - * formulas holds after a number of steps contained in the interval - * associated with this formula. - * - * The subtrees are seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @tparam FormulaType The type of the subformula. - * The instantiation of FormulaType should be a subclass of AbstractFormula, as the functions - * "toString" and "conforms" of the subformulas are needed. - * - * @see AbstractFormula - */ -template <class T, class FormulaType> -class BoundedNaryUntil : public virtual AbstractFormula<T> { - - // Throw a compiler error when FormulaType is not a subclass of AbstractFormula. - static_assert(std::is_base_of<AbstractFormula<T>, FormulaType>::value, - "Instantiaton of FormulaType for storm::property::abstract::BoundedNaryUntil<T,FormulaType> has to be a subtype of storm::property::abstract::AbstractFormula<T>"); - -public: - /*! - * Empty constructor - */ - BoundedNaryUntil() { - this->left = nullptr; - this->right = new std::vector<std::tuple<FormulaType*,T,T>>(); - } - - /*! - * Constructor - * - * @param left The left formula subtree - * @param right The left formula subtree - */ - BoundedNaryUntil(FormulaType* left, std::vector<std::tuple<FormulaType*,T,T>>* right) { - this->left = left; - this->right = right; - } - - /*! - * Destructor. - * - * Also deletes the subtrees. - * (this behaviour can be prevented by setting the subtrees to NULL before deletion) - */ - virtual ~BoundedNaryUntil() { - if (left != nullptr) { - delete left; - } - if (right != nullptr) { - delete right; - } - } - - /*! - * Sets the left child node. - * - * @param newLeft the new left child. - */ - void setLeft(FormulaType* newLeft) { - left = newLeft; - } - - void setRight(std::vector<std::tuple<FormulaType*,T,T>>* newRight) { - right = newRight; - } - - /*! - * - * @return True if the left child is set, i.e. it does not point to nullptr; false otherwise - */ - bool leftIsSet() const { - return left != nullptr; - } - - /*! - * - * @return True if the right child is set, i.e. it does not point to nullptr; false otherwise - */ - bool rightIsSet() const { - return right != nullptr; - } - - /*! - * Sets the right child node. - * - * @param newRight the new right child. - */ - void addRight(FormulaType* newRight, T upperBound, T lowerBound) { - this->right->push_back(std::tuple<FormulaType*,T,T>(newRight, upperBound, lowerBound)); - } - - /*! - * @returns a pointer to the left child node - */ - const FormulaType& getLeft() const { - return *left; - } - - /*! - * @returns a pointer to the right child nodes. - */ - const std::vector<std::tuple<FormulaType*,T,T>>& getRight() const { - return *right; - } - - /*! - * @returns a string representation of the formula - */ - virtual std::string toString() const override { - std::stringstream result; - result << "( " << left->toString(); - for (auto it = this->right->begin(); it != this->right->end(); ++it) { - result << " U[" << std::get<1>(*it) << "," << std::get<2>(*it) << "] " << std::get<0>(*it)->toString(); - } - result << ")"; - return result.str(); - } - - /*! - * @brief Checks if all subtrees conform to some logic. - * - * @param checker Formula checker object. - * @return true iff all subtrees conform to some logic. - */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { - bool res = checker.validate(this->left); - for (auto it = this->right->begin(); it != this->right->end(); ++it) { - res &= checker.validate(std::get<0>(*it)); - } - return res; - } - - -private: - FormulaType* left; - std::vector<std::tuple<FormulaType*,T,T>>* right; -}; - -} //namespace abstract -} //namespace property -} //namespace storm - -#endif /* STORM_FORMULA_ABSTRACT_BOUNDEDNARYUNTIL_H_ */ diff --git a/src/formula/abstract/BoundedUntil.h b/src/formula/abstract/BoundedUntil.h deleted file mode 100644 index 487fb0535..000000000 --- a/src/formula/abstract/BoundedUntil.h +++ /dev/null @@ -1,182 +0,0 @@ -/* - * BoundedUntil.h - * - * Created on: 19.10.2012 - * Author: Thomas Heinemann - */ - -#ifndef STORM_FORMULA_ABSTRACT_BOUNDEDUNTIL_H_ -#define STORM_FORMULA_ABSTRACT_BOUNDEDUNTIL_H_ - -#include "src/formula/abstract/AbstractFormula.h" -#include <cstdint> -#include <string> - -namespace storm { -namespace property { -namespace abstract { - -/*! - * @brief - * Class for an abstract (path) formula tree with a BoundedUntil node as root. - * - * Has two formulas as sub formulas/trees. - * - * @par Semantics - * The formula holds iff in at most \e bound steps, formula \e right (the right subtree) holds, and before, - * \e left holds. - * - * The subtrees are seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @tparam FormulaType The type of the subformula. - * The instantiation of FormulaType should be a subclass of AbstractFormula, as the functions - * "toString" and "conforms" of the subformulas are needed. - * - * @see AbstractFormula - */ -template <class T, class FormulaType> -class BoundedUntil : public virtual AbstractFormula<T> { - - // Throw a compiler error when FormulaType is not a subclass of AbstractFormula. - static_assert(std::is_base_of<AbstractFormula<T>, FormulaType>::value, - "Instantiaton of FormulaType for storm::property::abstract::BoundedUntil<T,FormulaType> has to be a subtype of storm::property::abstract::AbstractFormula<T>"); - -public: - /*! - * Empty constructor - */ - BoundedUntil() { - this->left = NULL; - this->right = NULL; - bound = 0; - } - - /*! - * Constructor - * - * @param left The left formula subtree - * @param right The left formula subtree - * @param bound The maximal number of steps - */ - BoundedUntil(FormulaType* left, FormulaType* right, - uint_fast64_t bound) { - this->left = left; - this->right = right; - this->bound = bound; - } - - /*! - * Destructor. - * - * Also deletes the subtrees. - * (this behaviour can be prevented by setting the subtrees to NULL before deletion) - */ - virtual ~BoundedUntil() { - if (left != NULL) { - delete left; - } - if (right != NULL) { - delete right; - } - } - - /*! - * Sets the left child node. - * - * @param newLeft the new left child. - */ - void setLeft(FormulaType* newLeft) { - left = newLeft; - } - - /*! - * Sets the right child node. - * - * @param newRight the new right child. - */ - void setRight(FormulaType* newRight) { - right = newRight; - } - - /*! - * @returns a pointer to the left child node - */ - const FormulaType& getLeft() const { - return *left; - } - - /*! - * @returns a pointer to the right child node - */ - const FormulaType& getRight() const { - return *right; - } - - /*! - * - * @return True if the left child is set, i.e. it does not point to nullptr; false otherwise - */ - bool leftIsSet() const { - return left != nullptr; - } - - /*! - * - * @return True if the right child is set, i.e. it does not point to nullptr; false otherwise - */ - bool rightIsSet() const { - return right != nullptr; - } - - /*! - * @returns the maximally allowed number of steps for the bounded until operator - */ - uint_fast64_t getBound() const { - return bound; - } - - /*! - * Sets the maximally allowed number of steps for the bounded until operator - * - * @param bound the new bound. - */ - void setBound(uint_fast64_t bound) { - this->bound = bound; - } - - /*! - * @returns a string representation of the formula - */ - virtual std::string toString() const override { - std::string result = left->toString(); - result += " U<="; - result += std::to_string(bound); - result += " "; - result += right->toString(); - return result; - } - - /*! - * @brief Checks if all subtrees conform to some logic. - * - * @param checker Formula checker object. - * @return true iff all subtrees conform to some logic. - */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { - return checker.validate(this->left) && checker.validate(this->right); - } - -private: - FormulaType* left; - FormulaType* right; - uint_fast64_t bound; -}; - -} //namespace abstract - -} //namespace property - -} //namespace storm - -#endif /* STORM_FORMULA_ABSTRACT_BOUNDEDUNTIL_H_ */ diff --git a/src/formula/abstract/CumulativeReward.h b/src/formula/abstract/CumulativeReward.h deleted file mode 100644 index f347ebd77..000000000 --- a/src/formula/abstract/CumulativeReward.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * InstantaneousReward.h - * - * Created on: 26.12.2012 - * Author: Christian Dehnert - */ - -#ifndef STORM_FORMULA_ABSTRACT_CUMULATIVEREWARD_H_ -#define STORM_FORMULA_ABSTRACT_CUMULATIVEREWARD_H_ - -#include "AbstractFormula.h" -#include "src/formula/AbstractFormulaChecker.h" -#include <string> - -namespace storm { -namespace property { -namespace abstract { - -/*! - * @brief - * Class for an abstract (path) formula tree with a Cumulative Reward node as root. - * - * The subtrees are seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @see AbstractPathFormula - * @see AbstractFormula - */ -template <class T> -class CumulativeReward : public virtual AbstractFormula<T> { - -public: - /*! - * Empty constructor - */ - CumulativeReward() { - bound = 0; - } - - /*! - * Constructor - * - * @param bound The time bound of the reward formula - */ - CumulativeReward(T bound) { - this->bound = bound; - } - - /*! - * Empty destructor. - */ - virtual ~CumulativeReward() { - // Intentionally left empty. - } - - /*! - * @returns the time instance for the instantaneous reward operator - */ - T getBound() const { - return bound; - } - - /*! - * Sets the the time instance for the instantaneous reward operator - * - * @param bound the new bound. - */ - void setBound(T bound) { - this->bound = bound; - } - - /*! - * @returns a string representation of the formula - */ - virtual std::string toString() const override { - std::string result = "C <= "; - result += std::to_string(bound); - return result; - } - - /*! - * @brief Checks if all subtrees conform to some logic. - * - * As CumulativeReward objects have no subformulas, we return true here. - * - * @param checker Formula checker object. - * @return true - */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { - return true; - } - -private: - T bound; -}; - -} //namespace abstract -} //namespace property -} //namespace storm - -#endif /* STORM_FORMULA_ABSTRACT_INSTANTANEOUSREWARD_H_ */ diff --git a/src/formula/abstract/Eventually.h b/src/formula/abstract/Eventually.h deleted file mode 100644 index 3171c559a..000000000 --- a/src/formula/abstract/Eventually.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Next.h - * - * Created on: 26.12.2012 - * Author: Christian Dehnert - */ - -#ifndef STORM_FORMULA_ABSTRACT_EVENTUALLY_H_ -#define STORM_FORMULA_ABSTRACT_EVENTUALLY_H_ - -#include "src/formula/abstract/AbstractFormula.h" - -namespace storm { - -namespace property { - -namespace abstract { - -/*! - * @brief - * Class for an abstract (path) formula tree with an Eventually node as root. - * - * Has one formula as sub formula/tree. - * - * @par Semantics - * The formula holds iff eventually \e child holds. - * - * The subtree is seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to nullptr before deletion) - * - * @tparam FormulaType The type of the subformula. - * The instantiation of FormulaType should be a subclass of AbstractFormula, as the functions - * "toString" and "conforms" of the subformulas are needed. - * - * @see AbstractFormula - */ -template <class T, class FormulaType> -class Eventually : public virtual AbstractFormula<T> { - - // Throw a compiler error when FormulaType is not a subclass of AbstractFormula. - static_assert(std::is_base_of<AbstractFormula<T>, FormulaType>::value, - "Instantiaton of FormulaType for storm::property::abstract::Eventually<T,FormulaType> has to be a subtype of storm::property::abstract::AbstractFormula<T>"); - -public: - /*! - * Empty constructor - */ - Eventually() { - this->child = nullptr; - } - - /*! - * Constructor - * - * @param child The child node - */ - Eventually(FormulaType* child) { - this->child = child; - } - - /*! - * Constructor. - * - * Also deletes the subtree. - * (this behaviour can be prevented by setting the subtrees to nullptr before deletion) - */ - virtual ~Eventually() { - if (child != nullptr) { - delete child; - } - } - - /*! - * @returns the child node - */ - const FormulaType& getChild() const { - return *child; - } - - /*! - * Sets the subtree - * @param child the new child node - */ - void setChild(FormulaType* child) { - this->child = child; - } - - /*! - * - * @return True if the child node is set, i.e. it does not point to nullptr; false otherwise - */ - bool childIsSet() const { - return child != nullptr; - } - - /*! - * @returns a string representation of the formula - */ - virtual std::string toString() const override { - std::string result = "F "; - result += child->toString(); - return result; - } - - /*! - * @brief Checks if the subtree conforms to some logic. - * - * @param checker Formula checker object. - * @return true iff the subtree conforms to some logic. - */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { - return checker.validate(this->child); - } - -private: - FormulaType* child; -}; - -} //namespace abstract - -} //namespace property - -} //namespace storm - -#endif /* STORM_FORMULA_ABSTRACT_EVENTUALLY_H_ */ diff --git a/src/formula/abstract/Globally.h b/src/formula/abstract/Globally.h deleted file mode 100644 index 77444c232..000000000 --- a/src/formula/abstract/Globally.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Next.h - * - * Created on: 26.12.2012 - * Author: Christian Dehnert - */ - -#ifndef STORM_FORMULA_ABSTRACT_GLOBALLY_H_ -#define STORM_FORMULA_ABSTRACT_GLOBALLY_H_ - -#include "src/formula/abstract/AbstractFormula.h" -#include "src/formula/AbstractFormulaChecker.h" - -namespace storm { - -namespace property { - -namespace abstract { - -/*! - * @brief - * Class for an abstract formula tree with a Globally node as root. - * - * Has one formula as sub formula/tree. - * - * @par Semantics - * The formula holds iff globally \e child holds. - * - * The subtree is seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to nullptr before deletion) - * - * @tparam FormulaType The type of the subformula. - * The instantiation of FormulaType should be a subclass of AbstractFormula, as the functions - * "toString" and "conforms" of the subformulas are needed. - * - * @see AbstractFormula - */ -template <class T, class FormulaType> -class Globally : public virtual AbstractFormula<T> { - - // Throw a compiler error when FormulaType is not a subclass of AbstractFormula. - static_assert(std::is_base_of<AbstractFormula<T>, FormulaType>::value, - "Instantiaton of FormulaType for storm::property::abstract::Globally<T,FormulaType> has to be a subtype of storm::property::abstract::AbstractFormula<T>"); - -public: - /*! - * Empty constructor - */ - Globally() { - this->child = nullptr; - } - - /*! - * Constructor - * - * @param child The child node - */ - Globally(FormulaType* child) { - this->child = child; - } - - /*! - * Constructor. - * - * Also deletes the subtree. - * (this behaviour can be prevented by setting the subtrees to nullptr before deletion) - */ - virtual ~Globally() { - if (child != nullptr) { - delete child; - } - } - - /*! - * @returns the child node - */ - const FormulaType& getChild() const { - return *child; - } - - /*! - * Sets the subtree - * @param child the new child node - */ - void setChild(FormulaType* child) { - this->child = child; - } - - /*! - * - * @return True if the child node is set, i.e. it does not point to nullptr; false otherwise - */ - bool childIsSet() const { - return child != nullptr; - } - - /*! - * @returns a string representation of the formula - */ - virtual std::string toString() const override { - std::string result = "G "; - result += child->toString(); - return result; - } - - /*! - * @brief Checks if the subtree conforms to some logic. - * - * @param checker Formula checker object. - * @return true iff the subtree conforms to some logic. - */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { - return checker.validate(this->child); - } - -private: - FormulaType* child; -}; - -} //namespace abstract - -} //namespace property - -} //namespace storm - -#endif /* STORM_FORMULA_ABSTRACT_GLOBALLY_H_ */ diff --git a/src/formula/abstract/InstantaneousReward.h b/src/formula/abstract/InstantaneousReward.h deleted file mode 100644 index 8e2674efb..000000000 --- a/src/formula/abstract/InstantaneousReward.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * InstantaneousReward.h - * - * Created on: 26.12.2012 - * Author: Christian Dehnert - */ - -#ifndef STORM_FORMULA_ABSTRACT_INSTANTANEOUSREWARD_H_ -#define STORM_FORMULA_ABSTRACT_INSTANTANEOUSREWARD_H_ - -#include "AbstractFormula.h" -#include "src/formula/AbstractFormulaChecker.h" -#include <cstdint> -#include <string> - -namespace storm { -namespace property { -namespace abstract { - -/*! - * @brief - * Class for an abstract (path) formula tree with a Instantaneous Reward node as root. - * - * The subtrees are seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @see AbstractFormula - */ -template <class T> -class InstantaneousReward : public virtual AbstractFormula<T> { - -public: - /*! - * Empty constructor - */ - InstantaneousReward() { - bound = 0; - } - - /*! - * Constructor - * - * @param bound The time instance of the reward formula - */ - InstantaneousReward(uint_fast64_t bound) { - this->bound = bound; - } - - /*! - * Empty destructor. - */ - virtual ~InstantaneousReward() { - // Intentionally left empty. - } - - /*! - * @returns the time instance for the instantaneous reward operator - */ - uint_fast64_t getBound() const { - return bound; - } - - /*! - * Sets the the time instance for the instantaneous reward operator - * - * @param bound the new bound. - */ - void setBound(uint_fast64_t bound) { - this->bound = bound; - } - - /*! - * @returns a string representation of the formula - */ - virtual std::string toString() const override { - std::string result = "I="; - result += std::to_string(bound); - return result; - } - - /*! - * @brief Checks if all subtrees conform to some logic. - * - * As InstantaneousReward formulas have no subformulas, we return true here. - * - * @param checker Formula checker object. - * @return true - */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { - return true; - } - -private: - uint_fast64_t bound; -}; - -} //namespace abstract -} //namespace property -} //namespace storm - -#endif /* STORM_FORMULA_ABSTRACT_INSTANTANEOUSREWARD_H_ */ diff --git a/src/formula/abstract/Next.h b/src/formula/abstract/Next.h deleted file mode 100644 index d4fc9fe94..000000000 --- a/src/formula/abstract/Next.h +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Next.h - * - * Created on: 19.10.2012 - * Author: Thomas Heinemann - */ - -#ifndef STORM_FORMULA_ABSTRACT_NEXT_H_ -#define STORM_FORMULA_ABSTRACT_NEXT_H_ - -#include "src/formula/abstract/AbstractFormula.h" -#include "src/formula/AbstractFormulaChecker.h" - -namespace storm { - -namespace property { - -namespace abstract { - -/*! - * @brief - * Class for an abstract (path) formula tree with a Next node as root. - * - * Has two formulas as sub formulas/trees. - * - * @par Semantics - * The formula holds iff in the next step, \e child holds - * - * The subtree is seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @tparam FormulaType The type of the subformula. - * The instantiation of FormulaType should be a subclass of AbstractFormula, as the functions - * "toString" and "conforms" of the subformulas are needed. - * - * @see AbstractFormula - */ -template <class T, class FormulaType> -class Next : public virtual AbstractFormula<T> { - - // Throw a compiler error when FormulaType is not a subclass of AbstractFormula. - static_assert(std::is_base_of<AbstractFormula<T>, FormulaType>::value, - "Instantiaton of FormulaType for storm::property::abstract::Next<T,FormulaType> has to be a subtype of storm::property::abstract::AbstractFormula<T>"); - -public: - /*! - * Empty constructor - */ - Next() { - this->child = NULL; - } - - /*! - * Constructor - * - * @param child The child node - */ - Next(FormulaType* child) { - this->child = child; - } - - /*! - * Constructor. - * - * Also deletes the subtree. - * (this behaviour can be prevented by setting the subtrees to NULL before deletion) - */ - virtual ~Next() { - if (child != NULL) { - delete child; - } - } - - /*! - * @returns the child node - */ - const FormulaType& getChild() const { - return *child; - } - - /*! - * Sets the subtree - * @param child the new child node - */ - void setChild(FormulaType* child) { - this->child = child; - } - - /*! - * - * @return True if the child node is set, i.e. it does not point to nullptr; false otherwise - */ - bool childIsSet() const { - return child != nullptr; - } - - /*! - * @returns a string representation of the formula - */ - virtual std::string toString() const override { - std::string result = "("; - result += " X "; - result += child->toString(); - result += ")"; - return result; - } - - /*! - * @brief Checks if the subtree conforms to some logic. - * - * @param checker Formula checker object. - * @return true iff the subtree conforms to some logic. - */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { - return checker.validate(this->child); - } - -private: - FormulaType* child; -}; - -} //namespace abstract - -} //namespace property - -} //namespace storm - -#endif /* STORM_FORMULA_ABSTRACT_NEXT_H_ */ diff --git a/src/formula/abstract/Not.h b/src/formula/abstract/Not.h deleted file mode 100644 index bfa24059d..000000000 --- a/src/formula/abstract/Not.h +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Not.h - * - * Created on: 19.10.2012 - * Author: Thomas Heinemann - */ - -#ifndef STORM_FORMULA_ABSTRACT_NOT_H_ -#define STORM_FORMULA_ABSTRACT_NOT_H_ - -#include "src/formula/abstract/AbstractFormula.h" -#include "src/formula/AbstractFormulaChecker.h" - -namespace storm { - -namespace property { - -namespace abstract { - -/*! - * @brief - * Class for an abstract formula tree with NOT node as root. - * - * Has one formula as sub formula/tree. - * - * The subtree is seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @tparam FormulaType The type of the subformula. - * The instantiation of FormulaType should be a subclass of AbstractFormula, as the functions - * "toString" and "conforms" of the subformulas are needed. - * - * @see AbstractFormula - */ -template <class T, class FormulaType> -class Not : public virtual AbstractFormula<T> { - - // Throw a compiler error if FormulaType is not a subclass of AbstractFormula. - static_assert(std::is_base_of<AbstractFormula<T>, FormulaType>::value, - "Instantiaton of FormulaType for storm::property::abstract::Not<T,FormulaType> has to be a subtype of storm::property::abstract::AbstractFormula<T>"); - -public: - /*! - * Empty constructor - */ - Not() { - this->child = NULL; - } - - /*! - * Constructor - * @param child The child node - */ - Not(FormulaType* child) { - this->child = child; - } - - /*! - * Destructor - * - * Also deletes the subtree - * (this behavior can be prevented by setting them to NULL before deletion) - */ - virtual ~Not() { - if (child != NULL) { - delete child; - } - } - - /*! - * @returns The child node - */ - const FormulaType& getChild() const { - return *child; - } - - /*! - * Sets the subtree - * @param child the new child node - */ - void setChild(FormulaType* child) { - this->child = child; - } - - /*! - * - * @return True if the child node is set, i.e. it does not point to nullptr; false otherwise - */ - bool childIsSet() const { - return child != nullptr; - } - - /*! - * @returns a string representation of the formula - */ - virtual std::string toString() const override { - std::string result = "!"; - result += child->toString(); - return result; - } - - /*! - * @brief Checks if the subtree conforms to some logic. - * - * @param checker Formula checker object. - * @return true iff the subtree conforms to some logic. - */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { - return checker.validate(this->child); - } - -private: - FormulaType* child; -}; - -} //namespace abstract - -} //namespace property - -} //namespace storm - -#endif /* STORM_FORMULA_ABSTRACT_NOT_H_ */ diff --git a/src/formula/abstract/OptimizingOperator.h b/src/formula/abstract/OptimizingOperator.h deleted file mode 100644 index 46d868a23..000000000 --- a/src/formula/abstract/OptimizingOperator.h +++ /dev/null @@ -1,72 +0,0 @@ -#ifndef STORM_FORMULA_ABSTRACT_OPTIMIZINGOPERATOR_H_ -#define STORM_FORMULA_ABSTRACT_OPTIMIZINGOPERATOR_H_ - -#include "IOptimizingOperator.h" - -namespace storm { - -namespace property { - -namespace abstract { - -/*! - * - */ -class OptimizingOperator : public virtual IOptimizingOperator { -public: - /*! - * Empty constructor - */ - OptimizingOperator() : optimalityOperator(false), minimumOperator(false) { - } - - /*! - * Constructor - * - * @param minimumOperator A flag indicating whether this operator is a minimizing or a maximizing operator. - */ - OptimizingOperator(bool minimumOperator) : optimalityOperator(true), minimumOperator(minimumOperator) { - } - - /*! - * Destructor - */ - virtual ~OptimizingOperator() { - // Intentionally left empty - } - - /*! - * Retrieves whether the operator is to be interpreted as an optimizing (i.e. min/max) operator. - * @returns True if the operator is an optimizing operator. - */ - virtual bool isOptimalityOperator() const { - return optimalityOperator; - } - - /*! - * Retrieves whether the operator is a minimizing operator given that it is an optimality - * operator. - * @returns True if the operator is an optimizing operator and it is a minimizing operator and - * false otherwise, i.e. if it is either not an optimizing operator or not a minimizing operator. - */ - virtual bool isMinimumOperator() const { - return optimalityOperator && minimumOperator; - } - -private: - // A flag that indicates whether this operator is meant as an optimizing (i.e. min/max) operator - // over a nondeterministic model. - bool optimalityOperator; - - // In the case this operator is an optimizing operator, this flag indicates whether it is - // looking for the minimum or the maximum value. - bool minimumOperator; -}; - -} //namespace abstract - -} //namespace property - -} //namespace storm - -#endif /* STORM_FORMULA_ABSTRACT_OPTIMIZINGOPERATOR_H_ */ diff --git a/src/formula/abstract/Or.h b/src/formula/abstract/Or.h deleted file mode 100644 index 67ed1e72d..000000000 --- a/src/formula/abstract/Or.h +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Or.h - * - * Created on: 19.10.2012 - * Author: Thomas Heinemann - */ - -#ifndef STORM_FORMULA_ABSTRACT_OR_H_ -#define STORM_FORMULA_ABSTRACT_OR_H_ - -#include "src/formula/abstract/AbstractFormula.h" -#include "src/formula/AbstractFormulaChecker.h" - -namespace storm { -namespace property { -namespace abstract { - -/*! - * @brief - * Class for an abstract formula tree with OR node as root. - * - * Has two formulas as sub formulas/trees. - * - * As OR is commutative, the order is \e theoretically not important, but will influence the order in which - * the model checker works. - * - * The subtrees are seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @tparam FormulaType The type of the subformula. - * The instantiation of FormulaType should be a subclass of AbstractFormula, as the functions - * "toString" and "conforms" of the subformulas are needed. - * - * @see AbstractFormula - */ -template <class T, class FormulaType> -class Or : public virtual AbstractFormula<T> { - - // Throw a compiler error if FormulaType is not a subclass of AbstractFormula. - static_assert(std::is_base_of<AbstractFormula<T>, FormulaType>::value, - "Instantiaton of FormulaType for storm::property::abstract::Or<T,FormulaType> has to be a subtype of storm::property::abstract::AbstractFormula<T>"); - -public: - /*! - * Empty constructor. - * Will create an AND-node without subnotes. Will not represent a complete formula! - */ - Or() { - left = NULL; - right = NULL; - } - - /*! - * Constructor. - * Creates an AND note with the parameters as subtrees. - * - * @param left The left sub formula - * @param right The right sub formula - */ - Or(FormulaType* left, FormulaType* right) { - this->left = left; - this->right = right; - } - - /*! - * Destructor. - * - * The subtrees are deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - */ - virtual ~Or() { - if (left != NULL) { - delete left; - } - if (right != NULL) { - delete right; - } - } - - /*! - * Sets the left child node. - * - * @param newLeft the new left child. - */ - void setLeft(FormulaType* newLeft) { - left = newLeft; - } - - /*! - * Sets the right child node. - * - * @param newRight the new right child. - */ - void setRight(FormulaType* newRight) { - right = newRight; - } - - /*! - * @returns a pointer to the left child node - */ - const FormulaType& getLeft() const { - return *left; - } - - /*! - * @returns a pointer to the right child node - */ - const FormulaType& getRight() const { - return *right; - } - - /*! - * - * @return True if the left child is set, i.e. it does not point to nullptr; false otherwise - */ - bool leftIsSet() const { - return left != nullptr; - } - - /*! - * - * @return True if the right child is set, i.e. it does not point to nullptr; false otherwise - */ - bool rightIsSet() const { - return right != nullptr; - } - - /*! - * @returns a string representation of the formula - */ - virtual std::string toString() const override { - std::string result = "("; - result += left->toString(); - result += " | "; - result += right->toString(); - result += ")"; - return result; - } - - /*! - * @brief Checks if all subtrees conform to some logic. - * - * @param checker Formula checker object. - * @return true iff all subtrees conform to some logic. - */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { - return checker.validate(this->left) && checker.validate(this->right); - } - -private: - FormulaType* left; - FormulaType* right; -}; - -} //namespace abstract - -} //namespace property - -} //namespace storm - -#endif /* STORM_FORMULA_ABSTRACT_OR_H_ */ diff --git a/src/formula/abstract/PathBoundOperator.h b/src/formula/abstract/PathBoundOperator.h deleted file mode 100644 index f6c1cd956..000000000 --- a/src/formula/abstract/PathBoundOperator.h +++ /dev/null @@ -1,194 +0,0 @@ -/* - * PathBoundOperator.h - * - * Created on: 27.12.2012 - * Author: Christian Dehnert - */ - -#ifndef STORM_FORMULA_ABSTRACT_PATHBOUNDOPERATOR_H_ -#define STORM_FORMULA_ABSTRACT_PATHBOUNDOPERATOR_H_ - -#include "src/formula/abstract/AbstractFormula.h" -#include "src/formula/abstract/AbstractFormula.h" -#include "src/formula/AbstractFormulaChecker.h" -#include "src/formula/ComparisonType.h" - -#include "src/formula/abstract/OptimizingOperator.h" - -#include "src/utility/constants.h" - -namespace storm { - -namespace property { - -namespace abstract { - -/*! - * @brief - * Class for an abstract formula tree with a P (probablistic) operator node over a probability interval - * as root. - * - * Has one formula as sub formula/tree. - * - * @par Semantics - * The formula holds iff the probability that the path formula holds is inside the bounds - * specified in this operator - * - * The subtree is seen as part of the object and deleted with it - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @tparam FormulaType The type of the subformula. - * The instantiation of FormulaType should be a subclass of AbstractFormula, as the functions - * "toString" and "conforms" of the subformulas are needed. - * - * @see AbstractFormula - * @see PathNoBoundOperator - */ -template<class T, class FormulaType> -class PathBoundOperator : public virtual AbstractFormula<T>, public OptimizingOperator { - - // Throw a compiler error if FormulaType is not a subclass of AbstractFormula. - static_assert(std::is_base_of<AbstractFormula<T>, FormulaType>::value, - "Instantiaton of FormulaType for storm::property::abstract::PathBoundOperator<T,FormulaType> has to be a subtype of storm::property::abstract::AbstractFormula<T>"); - -public: - /*! - * Constructor for non-optimizing operator. - * - * @param comparisonOperator The relation for the bound. - * @param bound The bound for the probability - * @param pathFormula The child node - */ - PathBoundOperator(storm::property::ComparisonType comparisonOperator, T bound, FormulaType* pathFormula) - : comparisonOperator(comparisonOperator), bound(bound), pathFormula(pathFormula) { - // Intentionally left empty - } - - /*! - * Constructor for optimizing operator. - * - * @param comparisonOperator The relation for the bound. - * @param bound The bound for the probability - * @param pathFormula The child node - * @param minimumOperator Indicator, if operator should be minimum or maximum operator. - */ - PathBoundOperator(storm::property::ComparisonType comparisonOperator, T bound, FormulaType* pathFormula, bool minimumOperator) - : OptimizingOperator(minimumOperator), comparisonOperator(comparisonOperator), bound(bound), pathFormula(pathFormula) { - // Intentionally left empty - } - - /*! - * Destructor - * - * The subtree is deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - */ - virtual ~PathBoundOperator() { - if (pathFormula != nullptr) { - delete pathFormula; - } - } - - /*! - * @returns the child node (representation of a formula) - */ - const FormulaType& getPathFormula () const { - return *pathFormula; - } - - /*! - * Sets the child node - * - * @param pathFormula the path formula that becomes the new child node - */ - void setPathFormula(FormulaType* pathFormula) { - this->pathFormula = pathFormula; - } - - /*! - * - * @return True if the path formula is set, i.e. it does not point to nullptr; false otherwise - */ - bool pathFormulaIsSet() const { - return pathFormula != nullptr; - } - - /*! - * @returns the comparison relation - */ - const storm::property::ComparisonType getComparisonOperator() const { - return comparisonOperator; - } - - void setComparisonOperator(storm::property::ComparisonType comparisonOperator) { - this->comparisonOperator = comparisonOperator; - } - - /*! - * @returns the bound for the measure - */ - const T& getBound() const { - return bound; - } - - /*! - * Sets the interval in which the probability that the path formula holds may lie in. - * - * @param bound The bound for the measure - */ - void setBound(T bound) { - this->bound = bound; - } - - /*! - * @returns a string representation of the formula - */ - virtual std::string toString() const override { - std::string result = ""; - switch (comparisonOperator) { - case LESS: result += "<"; break; - case LESS_EQUAL: result += "<="; break; - case GREATER: result += ">"; break; - case GREATER_EQUAL: result += ">="; break; - } - result += " "; - result += std::to_string(bound); - result += " ["; - result += pathFormula->toString(); - result += "]"; - return result; - } - - bool meetsBound(T value) const { - switch (comparisonOperator) { - case LESS: return value < bound; break; - case LESS_EQUAL: return value <= bound; break; - case GREATER: return value > bound; break; - case GREATER_EQUAL: return value >= bound; break; - default: return false; - } - } - - /*! - * @brief Checks if the subtree conforms to some logic. - * - * @param checker Formula checker object. - * @return true iff the subtree conforms to some logic. - */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { - return checker.validate(this->pathFormula); - } - -private: - storm::property::ComparisonType comparisonOperator; - T bound; - FormulaType* pathFormula; -}; - -} //namespace abstract - -} //namespace property - -} //namespace storm - -#endif /* STORM_FORMULA_ABSTRACT_PATHBOUNDOPERATOR_H_ */ diff --git a/src/formula/abstract/PathNoBoundOperator.h b/src/formula/abstract/PathNoBoundOperator.h deleted file mode 100644 index 1b0af8d1e..000000000 --- a/src/formula/abstract/PathNoBoundOperator.h +++ /dev/null @@ -1,160 +0,0 @@ -/* - * PathNoBoundOperator.h - * - * Created on: 27.12.2012 - * Author: Christian Dehnert - */ - -#ifndef STORM_FORMULA_ABSTRACT_NOBOUNDOPERATOR_H_ -#define STORM_FORMULA_ABSTRACT_NOBOUNDOPERATOR_H_ - -#include "src/formula/abstract/AbstractFormula.h" -#include "src/formula/AbstractFormulaChecker.h" -#include "src/formula/abstract/OptimizingOperator.h" - - -namespace storm { - -namespace property { - -namespace abstract { -/*! - * @brief - * Class for an abstract formula tree with a P (probablistic) operator without declaration of probabilities - * as root. - * - * Checking a formula with this operator as root returns the probabilities that the path formula holds - * (for each state) - * - * Has one formula as sub formula/tree. - * - * @note - * This class is a hybrid of a state and path formula, and may only appear as the outermost operator. - * Hence, it is seen as neither a state nor a path formula, but is directly derived from AbstractFormula. - * - * @note - * This class does not contain a check() method like the other formula classes. - * The check method should only be called by the model checker to infer the correct check function for sub - * formulas. As this operator can only appear at the root, the method is not useful here. - * Use the checkProbabilisticNoBoundOperator method from the DtmcPrctlModelChecker class instead. - * - * The subtree is seen as part of the object and deleted with it - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @tparam FormulaType The type of the subformula. - * The instantiation of FormulaType should be a subclass of AbstractFormula, as the functions - * "toString" and "conforms" of the subformulas are needed. - * - * @see AbstractFormula - * @see PathBoundOperator - */ -template <class T, class FormulaType> -class PathNoBoundOperator: public virtual AbstractFormula<T>, public OptimizingOperator { - - // Throw a compiler error if FormulaType is not a subclass of AbstractFormula. - static_assert(std::is_base_of<AbstractFormula<T>, FormulaType>::value, - "Instantiaton of FormulaType for storm::property::abstract::PathNoBoundOperator<T,FormulaType> has to be a subtype of storm::property::abstract::AbstractFormula<T>"); - - -public: - /*! - * Empty constructor - */ - PathNoBoundOperator() : - OptimizingOperator(false) { - this->pathFormula = nullptr; - } - - /*! - * Constructor - * - * @param pathFormula The child node. - */ - PathNoBoundOperator(FormulaType* pathFormula) { - this->pathFormula = pathFormula; - } - - /*! - * Constructor - * - * @param pathFormula The child node. - * @param minimumOperator A flag indicating whether this operator is a minimizing or a - * maximizing operator. - */ - PathNoBoundOperator(FormulaType* pathFormula, bool minimumOperator) - : OptimizingOperator(minimumOperator) { - this->pathFormula = pathFormula; - } - - /*! - * Destructor - */ - virtual ~PathNoBoundOperator() { - if (pathFormula != NULL) { - delete pathFormula; - } - } - - /*! - * @returns the child node (representation of an abstract path formula) - */ - const FormulaType& getPathFormula () const { - return *pathFormula; - } - - /*! - * Sets the child node - * - * @param pathFormula the path formula that becomes the new child node - */ - void setPathFormula(FormulaType* pathFormula) { - this->pathFormula = pathFormula; - } - - /*! - * - * @return True if the path formula is set, i.e. it does not point to nullptr; false otherwise - */ - bool pathFormulaIsSet() const { - return pathFormula != nullptr; - } - - /*! - * @returns a string representation of the formula - */ - virtual std::string toString() const override { - std::string result; - if (this->isOptimalityOperator()) { - if (this->isMinimumOperator()) { - result += "min"; - } else { - result += "max"; - } - } - result += " = ? ["; - result += this->getPathFormula().toString(); - result += "]"; - return result; - } - - /*! - * @brief Checks if the subtree conforms to some logic. - * - * @param checker Formula checker object. - * @return true iff the subtree conforms to some logic. - */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { - return checker.validate(this->pathFormula); - } - -private: - FormulaType* pathFormula; -}; - -} //namespace abstract - -} //namespace property - -} //namespace storm - -#endif /* STORM_FORMULA_ABSTRACT_NOBOUNDOPERATOR_H_ */ diff --git a/src/formula/abstract/ProbabilisticBoundOperator.h b/src/formula/abstract/ProbabilisticBoundOperator.h deleted file mode 100644 index b326e1c05..000000000 --- a/src/formula/abstract/ProbabilisticBoundOperator.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - * ProbabilisticBoundOperator.h - * - * Created on: 19.10.2012 - * Author: Thomas Heinemann - */ - -#ifndef STORM_FORMULA_ABSTRACT_PROBABILISTICBOUNDOPERATOR_H_ -#define STORM_FORMULA_ABSTRACT_PROBABILISTICBOUNDOPERATOR_H_ - -#include "src/formula/abstract/AbstractFormula.h" -#include "src/formula/abstract/PathBoundOperator.h" -#include "src/formula/abstract/OptimizingOperator.h" -#include "utility/constants.h" - -namespace storm { -namespace property { -namespace abstract { - -/*! - * @brief - * Class for an abstract formula tree with a P (probablistic) operator node over a probability interval - * as root. - * - * Has one Abstract path formula as sub formula/tree. - * - * @par Semantics - * The formula holds iff the probability that the path formula holds is inside the bounds - * specified in this operator - * - * The subtree is seen as part of the object and deleted with it - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @tparam FormulaType The type of the subformula. - * The instantiation of FormulaType should be a subclass of AbstractFormula, as the functions - * "toString" and "conforms" of the subformulas are needed. - * - * @see AbstractFormula - * @see AbstractFormula - * @see ProbabilisticOperator - * @see ProbabilisticNoBoundsOperator - * @see AbstractFormula - */ -template<class T, class FormulaType> -class ProbabilisticBoundOperator : public PathBoundOperator<T, FormulaType> { - - // Throw a compiler error if FormulaType is not a subclass of AbstractFormula. - static_assert(std::is_base_of<AbstractFormula<T>, FormulaType>::value, - "Instantiaton of FormulaType for storm::property::abstract::ProbabilisticBoundOperator<T,FormulaType> has to be a subtype of storm::property::abstract::AbstractFormula<T>"); - -public: - /*! - * Empty constructor - */ - ProbabilisticBoundOperator() : PathBoundOperator<T, FormulaType> - (LESS_EQUAL, storm::utility::constantZero<T>(), nullptr) { - // Intentionally left empty - } - - - /*! - * Constructor - * - * @param comparisonRelation The relation to compare the actual value and the bound - * @param bound The bound for the probability - * @param pathFormula The child node - */ - ProbabilisticBoundOperator( - storm::property::ComparisonType comparisonRelation, - T bound, - FormulaType* pathFormula) - : PathBoundOperator<T, FormulaType>(comparisonRelation, bound, pathFormula) { - // Intentionally left empty - } - - /*! - * Constructor - * - * @param comparisonRelation - * @param bound - * @param pathFormula - * @param minimumOperator - */ - ProbabilisticBoundOperator( - storm::property::ComparisonType comparisonRelation, - T bound, - FormulaType* pathFormula, - bool minimumOperator) - : PathBoundOperator<T, FormulaType>(comparisonRelation, bound, pathFormula, minimumOperator){ - // Intentionally left empty - } - - /*! - * Destructor - */ - virtual ~ProbabilisticBoundOperator() { - // Intentionally left empty - } - - /*! - * @returns a string representation of the formula - */ - virtual std::string toString() const override { - std::string result = "P "; - result += PathBoundOperator<T, FormulaType>::toString(); - return result; - } -}; - -} //namespace abstract -} //namespace property -} //namespace storm - -#endif /* STORM_FORMULA_ABSTRACT_PROBABILISTICBOUNDOPERATOR_H_ */ diff --git a/src/formula/abstract/ProbabilisticNoBoundOperator.h b/src/formula/abstract/ProbabilisticNoBoundOperator.h deleted file mode 100644 index 7bf01422e..000000000 --- a/src/formula/abstract/ProbabilisticNoBoundOperator.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * ProbabilisticNoBoundOperator.h - * - * Created on: 12.12.2012 - * Author: Thomas Heinemann - */ - -#ifndef STORM_FORMULA_ABSTRACT_PROBABILISTICNOBOUNDOPERATOR_H_ -#define STORM_FORMULA_ABSTRACT_PROBABILISTICNOBOUNDOPERATOR_H_ - -#include "AbstractFormula.h" -#include "src/formula/abstract/AbstractFormula.h" -#include "PathNoBoundOperator.h" - -namespace storm { -namespace property { -namespace abstract { - -/*! - * @brief - * Class for an abstract formula tree with a P (probablistic) operator without declaration of probabilities - * as root. - * - * Checking a formula with this operator as root returns the probabilities that the path formula holds - * (for each state) - * - * Has one Abstract path formula as sub formula/tree. - * - * @note - * This class is a hybrid of a state and path formula, and may only appear as the outermost operator. - * Hence, it is seen as neither a state nor a path formula, but is directly derived from AbstractFormula. - * - * @note - * This class does not contain a check() method like the other formula classes. - * The check method should only be called by the model checker to infer the correct check function for sub - * formulas. As this operator can only appear at the root, the method is not useful here. - * Use the checkProbabilisticNoBoundOperator method from the DtmcPrctlModelChecker class instead. - * - * The subtree is seen as part of the object and deleted with it - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @tparam FormulaType The type of the subformula. - * The instantiation of FormulaType should be a subclass of AbstractFormula, as the functions - * "toString" and "conforms" of the subformulas are needed. - * - * @see AbstractFormula - * @see PathNoBoundOperator - * @see ProbabilisticBoundOperator - */ -template <class T, class FormulaType> -class ProbabilisticNoBoundOperator: public PathNoBoundOperator<T, FormulaType> { - - // Throw a compiler error if FormulaType is not a subclass of AbstractFormula. - static_assert(std::is_base_of<AbstractFormula<T>, FormulaType>::value, - "Instantiaton of FormulaType for storm::property::abstract::ProbabilisticNoBoundOperator<T,FormulaType> has to be a subtype of storm::property::abstract::AbstractFormula<T>"); - -public: - /*! - * Empty constructor - */ - ProbabilisticNoBoundOperator() : PathNoBoundOperator<T, FormulaType>(nullptr) { - // Intentionally left empty - } - - /*! - * Constructor - * - * @param pathFormula The child node. - */ - ProbabilisticNoBoundOperator(FormulaType* pathFormula) : PathNoBoundOperator<T, FormulaType>(pathFormula) { - // Intentionally left empty - } - - /*! - * Destructor - */ - virtual ~ProbabilisticNoBoundOperator() { - // Intentionally left empty - } - - /*! - * Constructor - * - * @param pathFormula The child node. - */ - ProbabilisticNoBoundOperator(FormulaType* pathFormula, bool minimumOperator) : PathNoBoundOperator<T, FormulaType>(pathFormula, minimumOperator) { - // Intentionally left empty - } - - /*! - * @returns a string representation of the formula - */ - virtual std::string toString() const override { - std::string result = "P"; - result += PathNoBoundOperator<T, FormulaType>::toString(); - return result; - } -}; - -} //namespace abstract -} //namespace property -} //namespace storm - -#endif /* STORM_FORMULA_ABSTRACT_PROBABILISTICNOBOUNDOPERATOR_H_ */ diff --git a/src/formula/abstract/RewardBoundOperator.h b/src/formula/abstract/RewardBoundOperator.h deleted file mode 100644 index 30d2f3221..000000000 --- a/src/formula/abstract/RewardBoundOperator.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * RewardBoundOperator.h - * - * Created on: 19.10.2012 - * Author: Thomas Heinemann - */ - -#ifndef STORM_FORMULA_ABSTRACT_REWARDBOUNDOPERATOR_H_ -#define STORM_FORMULA_ABSTRACT_REWARDBOUNDOPERATOR_H_ - -#include "PathBoundOperator.h" -#include "utility/constants.h" - -namespace storm { -namespace property { -namespace abstract { - -/*! - * @brief - * Class for an abstract formula tree with a R (reward) operator node over a reward interval as root. - * - * Has a reward path formula as sub formula/tree. - * - * @par Semantics - * The formula holds iff the reward of the reward path formula is inside the bounds - * specified in this operator - * - * The subtree is seen as part of the object and deleted with it - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @tparam FormulaType The type of the subformula. - * The instantiation of FormulaType should be a subclass of AbstractFormula, as the functions - * "toString" and "conforms" of the subformulas are needed. - * - * @see AbstractFormula - * @see PathBoundOperator - * @see RewardNoBoundOperator - */ -template<class T, class FormulaType> -class RewardBoundOperator : public PathBoundOperator<T, FormulaType> { - - // Throw a compiler error if FormulaType is not a subclass of AbstractFormula. - static_assert(std::is_base_of<AbstractFormula<T>, FormulaType>::value, - "Instantiaton of FormulaType for storm::property::abstract::RewardBoundOperator<T,FormulaType> has to be a subtype of storm::property::abstract::AbstractFormula<T>"); - -public: - /*! - * Empty constructor - */ - RewardBoundOperator() : PathBoundOperator<T, FormulaType>(LESS_EQUAL, storm::utility::constantZero<T>(), nullptr) { - // Intentionally left empty - } - - /*! - * Constructor - * - * @param comparisonRelation The relation to compare the actual value and the bound - * @param bound The bound for the probability - * @param pathFormula The child node - */ - RewardBoundOperator( - storm::property::ComparisonType comparisonRelation, - T bound, - FormulaType* pathFormula) : - PathBoundOperator<T, FormulaType>(comparisonRelation, bound, pathFormula) { - // Intentionally left empty - } - - /*! - * Constructor - * @param comparisonRelation - * @param bound - * @param pathFormula - * @param minimumOperator - */ - RewardBoundOperator( - storm::property::ComparisonType comparisonRelation, - T bound, - FormulaType* pathFormula, - bool minimumOperator) - : PathBoundOperator<T, FormulaType>(comparisonRelation, bound, pathFormula, minimumOperator) { - // Intentionally left empty - } - - /*! - * Destructor - */ - virtual ~RewardBoundOperator() { - // Intentionally left empty - } - - /*! - * @returns a string representation of the formula - */ - virtual std::string toString() const override { - std::string result = "R "; - result += PathBoundOperator<T, FormulaType>::toString(); - return result; - } -}; - -} //namespace abstract -} //namespace property -} //namespace storm - -#endif /* STORM_FORMULA_ABSTRACT_REWARDBOUNDOPERATOR_H_ */ diff --git a/src/formula/abstract/RewardNoBoundOperator.h b/src/formula/abstract/RewardNoBoundOperator.h deleted file mode 100644 index a147502d8..000000000 --- a/src/formula/abstract/RewardNoBoundOperator.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * RewardNoBoundOperator.h - * - * Created on: 25.12.2012 - * Author: Christian Dehnert - */ - -#ifndef STORM_FORMULA_ABSTRACT_REWARDNOBOUNDOPERATOR_H_ -#define STORM_FORMULA_ABSTRACT_REWARDNOBOUNDOPERATOR_H_ - -#include "AbstractFormula.h" -#include "PathNoBoundOperator.h" - -namespace storm { -namespace property { -namespace abstract { - -/*! - * @brief - * Class for an abstract formula tree with a R (reward) operator without declaration of reward values - * as root. - * - * Checking a formula with this operator as root returns the reward for the reward path formula for - * each state - * - * Has one formula as sub formula/tree. - * - * @note - * This class is a hybrid of a state and path formula, and may only appear as the outermost operator. - * Hence, it is seen as neither a state nor a path formula, but is directly derived from AbstractFormula. - * - * @note - * This class does not contain a check() method like the other formula classes. - * The check method should only be called by the model checker to infer the correct check function for sub - * formulas. As this operator can only appear at the root, the method is not useful here. - * Use the checkRewardNoBoundOperator method from the DtmcPrctlModelChecker class instead. - * - * The subtree is seen as part of the object and deleted with it - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @tparam FormulaType The type of the subformula. - * The instantiation of FormulaType should be a subclass of AbstractFormula, as the functions - * "toString" and "conforms" of the subformulas are needed. - * - * @see AbstractFormula - * @see PathNoBoundOperator - * @see RewardBoundOperator - */ -template <class T, class FormulaType> -class RewardNoBoundOperator: public PathNoBoundOperator<T, FormulaType> { - - // Throw a compiler error if FormulaType is not a subclass of AbstractFormula. - static_assert(std::is_base_of<AbstractFormula<T>, FormulaType>::value, - "Instantiaton of FormulaType for storm::property::abstract::RewardNoBoundOperator<T,FormulaType> has to be a subtype of storm::property::abstract::AbstractFormula<T>"); - -public: - /*! - * Empty constructor - */ - RewardNoBoundOperator() : PathNoBoundOperator<T, FormulaType>(nullptr) { - // Intentionally left empty - } - - /*! - * Constructor - * - * @param pathFormula The child node. - */ - RewardNoBoundOperator(FormulaType* pathFormula) : PathNoBoundOperator<T, FormulaType>(pathFormula) { - // Intentionally left empty - } - - /*! - * Constructor - * - * @param pathFormula The child node. - */ - RewardNoBoundOperator(FormulaType* pathFormula, bool minimumOperator) : PathNoBoundOperator<T, FormulaType>(pathFormula, minimumOperator) { - // Intentionally left empty - } - - /*! - * Destructor - */ - virtual ~RewardNoBoundOperator() { - // Intentionally left empty - } - - /*! - * @returns a string representation of the formula - */ - virtual std::string toString() const override { - std::string result = "R"; - result += PathNoBoundOperator<T, FormulaType>::toString(); - return result; - } -}; - -} //namespace abstract -} //namespace property -} //namespace storm - -#endif /* STORM_FORMULA_ABSTRACT_REWARDNOBOUNDOPERATOR_H_ */ diff --git a/src/formula/abstract/StateBoundOperator.h b/src/formula/abstract/StateBoundOperator.h deleted file mode 100644 index c274bd2b3..000000000 --- a/src/formula/abstract/StateBoundOperator.h +++ /dev/null @@ -1,174 +0,0 @@ -/* - * BoundOperator.h - * - * Created on: 27.12.2012 - * Author: Christian Dehnert - */ - -#ifndef STORM_FORMULA_ABSTRACT_STATEBOUNDOPERATOR_H_ -#define STORM_FORMULA_ABSTRACT_STATEBOUNDOPERATOR_H_ - -#include "src/formula/abstract/AbstractFormula.h" -#include "src/formula/abstract/AbstractFormula.h" -#include "src/formula/AbstractFormulaChecker.h" -#include "src/formula/ComparisonType.h" -#include "src/utility/constants.h" - -namespace storm { -namespace property { -namespace abstract { - -/*! - * @brief - * Class for an abstract formula tree with a P (probablistic) operator node over a probability interval - * as root. - * - * Has one formula as sub formula/tree. - * - * @par Semantics - * The formula holds iff the probability that the state formula holds is inside the bounds - * specified in this operator - * - * The subtree is seen as part of the object and deleted with it - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @tparam FormulaType The type of the subformula. - * The instantiation of FormulaType should be a subclass of AbstractFormula, as the functions - * "toString" and "conforms" of the subformulas are needed. - * - * @see AbstractFormula - * @see StateNoBoundOperator - */ -template<class T, class FormulaType> -class StateBoundOperator : public virtual AbstractFormula<T> { - - // Throw a compiler error if FormulaType is not a subclass of AbstractFormula. - static_assert(std::is_base_of<AbstractFormula<T>, FormulaType>::value, - "Instantiaton of FormulaType for storm::property::abstract::StateBoundOperator<T,FormulaType> has to be a subtype of storm::property::abstract::AbstractFormula<T>"); - -public: - - /*! - * Constructor - * - * @param comparisonOperator The relation for the bound. - * @param bound The bound for the probability - * @param stateFormula The child node - */ - StateBoundOperator(storm::property::ComparisonType comparisonOperator, T bound, FormulaType* stateFormula) - : comparisonOperator(comparisonOperator), bound(bound), stateFormula(stateFormula) { - // Intentionally left empty - } - - /*! - * Destructor - * - * The subtree is deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - */ - virtual ~StateBoundOperator() { - if (stateFormula != nullptr) { - delete stateFormula; - } - } - - /*! - * @returns the child node (representation of a formula) - */ - const FormulaType& getStateFormula () const { - return *stateFormula; - } - - /*! - * Sets the child node - * - * @param stateFormula the state formula that becomes the new child node - */ - void setStateFormula(FormulaType* stateFormula) { - this->stateFormula = stateFormula; - } - - /*! - * - * @return True if the state formula is set, i.e. it does not point to nullptr; false otherwise - */ - bool stateFormulaIsSet() const { - return stateFormula != nullptr; - } - - /*! - * @returns the comparison relation - */ - const ComparisonType getComparisonOperator() const { - return comparisonOperator; - } - - void setComparisonOperator(ComparisonType comparisonOperator) { - this->comparisonOperator = comparisonOperator; - } - - /*! - * @returns the bound for the measure - */ - const T& getBound() const { - return bound; - } - - /*! - * Sets the interval in which the probability that the path formula holds may lie in. - * - * @param bound The bound for the measure - */ - void setBound(T bound) { - this->bound = bound; - } - - /*! - * @returns a string representation of the formula - */ - virtual std::string toString() const override { - std::string result = " "; - switch (comparisonOperator) { - case LESS: result += "< "; break; - case LESS_EQUAL: result += "<= "; break; - case GREATER: result += "> "; break; - case GREATER_EQUAL: result += ">= "; break; - } - result += std::to_string(bound); - result += " ["; - result += stateFormula->toString(); - result += "]"; - return result; - } - - bool meetsBound(T value) const { - switch (comparisonOperator) { - case LESS: return value < bound; break; - case LESS_EQUAL: return value <= bound; break; - case GREATER: return value > bound; break; - case GREATER_EQUAL: return value >= bound; break; - default: return false; - } - } - - /*! - * @brief Checks if the subtree conforms to some logic. - * - * @param checker Formula checker object. - * @return true iff the subtree conforms to some logic. - */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { - return checker.validate(this->stateFormula); - } - -private: - ComparisonType comparisonOperator; - T bound; - FormulaType* stateFormula; -}; - -} //namespace abstract -} //namespace property -} //namespace storm - -#endif /* STORM_FORMULA_ABSTRACT_STATEBOUNDOPERATOR_H_ */ diff --git a/src/formula/abstract/StateNoBoundOperator.h b/src/formula/abstract/StateNoBoundOperator.h deleted file mode 100644 index 4780f2587..000000000 --- a/src/formula/abstract/StateNoBoundOperator.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - * StateNoBoundOperator.h - * - * Created on: 09.04.2013 - * Author: Thomas Heinemann - */ - -#ifndef STORM_FORMULA_ABSTRACT_STATENOBOUNDOPERATOR_H_ -#define STORM_FORMULA_ABSTRACT_STATENOBOUNDOPERATOR_H_ - -#include "AbstractFormula.h" -#include "src/formula/AbstractFormulaChecker.h" - - -namespace storm { -namespace property { -namespace abstract { - -/*! - * @brief - * Class for an abstract formula tree with an operator without declaration of bounds. - * as root. - * - * Checking a formula with this operator as root returns the probabilities that the path formula holds - * (for each state) - * - * Has one formula as sub formula/tree. - * - * @note - * This class is a hybrid of a state and path formula, and may only appear as the outermost operator. - * Hence, it is seen as neither a state nor a path formula, but is directly derived from AbstractFormula. - * - * @note - * This class does not contain a check() method like the other formula classes. - * The check method should only be called by the model checker to infer the correct check function for sub - * formulas. As this operator can only appear at the root, the method is not useful here. - * Use the checkProbabilisticNoBoundOperator method from the DtmcPrctlModelChecker class instead. - * - * The subtree is seen as part of the object and deleted with it - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @tparam FormulaType The type of the subformula. - * The instantiation of FormulaType should be a subclass of AbstractFormula, as the functions - * "toString" and "conforms" of the subformulas are needed. - * - * @see AbstractFormula - * @see StateBoundOperator - */ -template <class T, class FormulaType> -class StateNoBoundOperator: public virtual AbstractFormula<T>, public OptimizingOperator { - - // Throw a compiler error if FormulaType is not a subclass of AbstractFormula. - static_assert(std::is_base_of<AbstractFormula<T>, FormulaType>::value, - "Instantiaton of FormulaType for storm::property::abstract::StateNoBoundOperator<T,FormulaType> has to be a subtype of storm::property::abstract::AbstractFormula<T>"); - -public: - /*! - * Empty constructor - */ - StateNoBoundOperator() { - stateFormula = nullptr; - } - - /*! - * Constructor - */ - StateNoBoundOperator(FormulaType* stateFormula) { - this->stateFormula = stateFormula; - } - - /*! - * Destructor - * - * Deletes the subtree - */ - virtual ~StateNoBoundOperator() { - if (stateFormula != nullptr) { - delete stateFormula; - } - } - - const FormulaType& getStateFormula() const { - return *(this->stateFormula); - } - - void setStateFormula(FormulaType* stateFormula) { - this->stateFormula = stateFormula; - } - - /*! - * - * @return True if the state formula is set, i.e. it does not point to nullptr; false otherwise - */ - bool stateFormulaIsSet() const { - return stateFormula != nullptr; - } - - /*! - * @returns a string representation of the formula - */ - virtual std::string toString() const override { - std::string result; - result += " = ? ["; - result += this->getStateFormula().toString(); - result += "]"; - return result; - } - - /*! - * @brief Checks if the subtree conforms to some logic. - * - * @param checker Formula checker object. - * @return true iff the subtree conforms to some logic. - */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { - return checker.validate(this->stateFormula); - } - -private: - FormulaType* stateFormula; -}; - -} //namespace abstract -} //namespace property -} //namespace storm -#endif /* STORM_FORMULA_ABSTRACT_STATENOBOUNDOPERATOR_H_ */ diff --git a/src/formula/abstract/SteadyStateBoundOperator.h b/src/formula/abstract/SteadyStateBoundOperator.h deleted file mode 100644 index a25e7d280..000000000 --- a/src/formula/abstract/SteadyStateBoundOperator.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * SteadyState.h - * - * Created on: 19.10.2012 - * Author: Thomas Heinemann - */ - -#ifndef STORM_FORMULA_ABSTRACT_STEADYSTATEOPERATOR_H_ -#define STORM_FORMULA_ABSTRACT_STEADYSTATEOPERATOR_H_ - -#include "StateBoundOperator.h" -#include "src/formula/AbstractFormulaChecker.h" - -namespace storm { -namespace property { -namespace abstract { - -/*! - * @brief - * Class for an Abstract (path) formula tree with a SteadyStateOperator node as root. - * - * Has two formulas as sub formulas/trees. - * - * @par Semantics - * The formula holds iff \e child holds SteadyStateOperator step, \e child holds - * - * The subtree is seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @see AbstractFormula - */ -template <class T, class FormulaType> -class SteadyStateBoundOperator : public StateBoundOperator<T, FormulaType> { - - // Throw a compiler error if FormulaType is not a subclass of AbstractFormula. - static_assert(std::is_base_of<AbstractFormula<T>, FormulaType>::value, - "Instantiaton of FormulaType for storm::property::abstract::SteadyStateBoundOperator<T,FormulaType> has to be a subtype of storm::property::abstract::AbstractFormula<T>"); - -public: - /*! - * Empty constructor - */ - SteadyStateBoundOperator() : StateBoundOperator<T, FormulaType> - (LESS_EQUAL, storm::utility::constantZero<T>(), nullptr) { - // Intentionally left empty - } - - /*! - * Constructor - * - * @param stateFormula The child node - */ - SteadyStateBoundOperator( - storm::property::ComparisonType comparisonRelation, T bound, FormulaType* stateFormula) : - StateBoundOperator<T, FormulaType>(comparisonRelation, bound, stateFormula) { - } - - /*! - * Destructor - */ - virtual ~SteadyStateBoundOperator() { - // Intentionally left empty - } - - /*! - * @returns a string representation of the formula - */ - virtual std::string toString() const override { - return "S" + StateBoundOperator<T, FormulaType>::toString(); - } -}; - -} //namespace abstract -} //namespace property -} //namespace storm - -#endif /* STORM_FORMULA_ABSTRACT_STEADYSTATEOPERATOR_H_ */ diff --git a/src/formula/abstract/SteadyStateNoBoundOperator.h b/src/formula/abstract/SteadyStateNoBoundOperator.h deleted file mode 100644 index 6e544d207..000000000 --- a/src/formula/abstract/SteadyStateNoBoundOperator.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * SteadyStateNoBoundOperator.h - * - * Created on: 09.04.2013 - * Author: thomas - */ - -#ifndef STORM_FORMULA_ABSTRACT_STEADYSTATENOBOUNDOPERATOR_H_ -#define STORM_FORMULA_ABSTRACT_STEADYSTATENOBOUNDOPERATOR_H_ - -#include "StateNoBoundOperator.h" - -namespace storm { -namespace property { -namespace abstract { - -/*! - * @brief - * Class for an abstract formula tree with a steady state operator as root, without explicit declaration of bounds. - * - * Checking a formula with this operator as root returns the exact bound parameter for the corresponding subformula. - * (for each state) - * - * Has one formula as sub formula/tree. - * - * @tparam FormulaType The type of the subformula. - * The instantiation of FormulaType should be a subclass of AbstractFormula, as the functions - * "toString" and "conforms" of the subformulas are needed. - */ -template <class T, class FormulaType> -class SteadyStateNoBoundOperator: public StateNoBoundOperator<T, FormulaType> { - - // Throw a compiler error if FormulaType is not a subclass of AbstractFormula. - static_assert(std::is_base_of<AbstractFormula<T>, FormulaType>::value, - "Instantiaton of FormulaType for storm::property::abstract::SteadyStateNoBoundOperator<T,FormulaType> has to be a subtype of storm::property::abstract::AbstractFormula<T>"); - -public: - /*! - * Empty constructor - */ - SteadyStateNoBoundOperator() : StateNoBoundOperator<T, FormulaType>() { - // Intentionally left empty - - } - - /*! - * Constructor - * - * @param stateFormula The state formula that forms the subtree - */ - SteadyStateNoBoundOperator(FormulaType* stateFormula) - : StateNoBoundOperator<T, FormulaType>(stateFormula) { - // Intentionally left empty - } - - /*! - * Destructor - */ - virtual ~SteadyStateNoBoundOperator() { - // Intentionally left empty - } - - /*! - * @returns a string representation of the formula - */ - virtual std::string toString() const override { - return "S" + StateNoBoundOperator<T, FormulaType>::toString(); - } - -}; - -} /* namespace abstract */ -} /* namespace property */ -} /* namespace storm */ - -#endif /* STORM_FORMULA_ABSTRACT_STEADYSTATENOBOUNDOPERATOR_H_ */ diff --git a/src/formula/abstract/SteadyStateReward.h b/src/formula/abstract/SteadyStateReward.h deleted file mode 100644 index d5f344752..000000000 --- a/src/formula/abstract/SteadyStateReward.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * SteadyStateReward.h - * - * Created on: 08.04.2013 - * Author: Thomas Heinemann - */ - -#ifndef STORM_FORMULA_ABSTRACT_STEADYSTATEREWARD_H_ -#define STORM_FORMULA_ABSTRACT_STEADYSTATEREWARD_H_ - -#include "AbstractFormula.h" -#include "src/formula/AbstractFormulaChecker.h" -#include <string> - -namespace storm { -namespace property { -namespace abstract { - -/*! - * @brief - * Class for an abstract (path) formula tree with a Steady State Reward node as root. - * - * @see AbstractFormula - */ -template <class T> -class SteadyStateReward: public virtual AbstractFormula<T> { -public: - /*! - * Empty constructor - */ - SteadyStateReward() { - // Intentionally left empty - - } - virtual ~SteadyStateReward() { - // Intentionally left empty - } - - /*! - * @returns a string representation of the formula - */ - virtual std::string toString() const override { - return "S"; - } - - /*! - * @brief Checks if all subtrees conform to some logic. - * - * As SteadyStateReward objects have no subformulas, we return true here. - * - * @param checker Formula checker object. - * @return true - */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { - return true; - } -}; - -} //namespace abstract -} //namespace property -} //namespace storm -#endif /* STORM_FORMULA_ABSTRACT_STEADYSTATEREWARD_H_ */ diff --git a/src/formula/abstract/TimeBoundedEventually.h b/src/formula/abstract/TimeBoundedEventually.h deleted file mode 100644 index eaecaa868..000000000 --- a/src/formula/abstract/TimeBoundedEventually.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - * TimeBoundedEventually.h - * - * Created on: 10.04.2013 - * Author: thomas - */ - -#ifndef STORM_FORMULA_ABSTRACT_TIMEBOUNDEDEVENTUALLY_H_ -#define STORM_FORMULA_ABSTRACT_TIMEBOUNDEDEVENTUALLY_H_ - -#include "TimeBoundedOperator.h" - -namespace storm { -namespace property { -namespace abstract { - -/*! - * Class for a formula tree with a time bounded eventually operator as root. - * - * Has two subformulas. - * - * @tparam FormulaType The type of the subformula. - * The instantiation of FormulaType should be a subclass of AbstractFormula, as the functions - * "toString" and "conforms" of the subformulas are needed. - */ -template<class T, class FormulaType> -class TimeBoundedEventually: public storm::property::abstract::TimeBoundedOperator<T> { - - // Throw a compiler error if FormulaType is not a subclass of AbstractFormula. - static_assert(std::is_base_of<AbstractFormula<T>, FormulaType>::value, - "Instantiaton of FormulaType for storm::property::abstract::TimeBoundedEventually<T,FormulaType> has to be a subtype of storm::property::abstract::AbstractFormula<T>"); - -public: - /** - * Simple constructor: Only sets the bounds - * - * @param lowerBound - * @param upperBound - */ - TimeBoundedEventually(T lowerBound, T upperBound) : TimeBoundedOperator<T>(lowerBound, upperBound) { - child = nullptr; - } - - TimeBoundedEventually(T lowerBound, T upperBound, FormulaType* child) : - TimeBoundedOperator<T>(lowerBound, upperBound) { - this->child = child; - } - - virtual ~TimeBoundedEventually() { - if (child != nullptr) { - delete child; - } - } - - /*! - * @returns the child node - */ - const FormulaType& getChild() const { - return *child; - } - - /*! - * Sets the subtree - * @param child the new child node - */ - void setChild(FormulaType* child) { - this->child = child; - } - - /*! - * - * @return True if the child is set, i.e. it does not point to nullptr; false otherwise - */ - bool childIsSet() const { - return child != nullptr; - } - - /*! - * @returns a string representation of the formula - */ - virtual std::string toString() const override { - std::string result = "F"; - result += TimeBoundedOperator<T>::toString(); - result += " "; - result += child->toString(); - return result; - } - - /*! - * @brief Checks if the subtree conforms to some logic. - * - * @param checker Formula checker object. - * @return true iff the subtree conforms to some logic. - */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { - return checker.validate(this->child); - } - -private: - FormulaType* child; -}; - -} /* namespace abstract */ -} /* namespace property */ -} /* namespace storm */ - -#endif /* STORM_FORMULA_ABSTRACT_TIMEBOUNDEDEVENTUALLY_H_ */ diff --git a/src/formula/abstract/TimeBoundedOperator.h b/src/formula/abstract/TimeBoundedOperator.h deleted file mode 100644 index d26fea552..000000000 --- a/src/formula/abstract/TimeBoundedOperator.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * TimeBoundedOperator.h - * - * Created on: 10.04.2013 - * Author: thomas - */ - -#ifndef STORM_FORMULA_ABSTRACT_TIMEBOUNDEDOPERATOR_H_ -#define STORM_FORMULA_ABSTRACT_TIMEBOUNDEDOPERATOR_H_ - -#include <limits> - -#include "src/formula/abstract/AbstractFormula.h" -#include "exceptions/InvalidArgumentException.h" - -namespace storm { -namespace property { -namespace abstract { - -/*! - * @brief - * Class for an abstract formula tree with a operator node as root that uses a time interval - * (with upper and lower bound) - * - * This class does not provide support for sub formulas; this has to be done in concrete subclasses of this abstract class. - * - * - * @see AbstractFormula - * @see AbstractFormula - * @see AbstractFormula - */ -template<class T> -class TimeBoundedOperator: public virtual AbstractFormula<T> { -public: - /** - * Constructor - * - * @param lowerBound The lower bound - * @param upperBound The upper bound - * @throw InvalidArgumentException if the lower bound is larger than the upper bound. - */ - TimeBoundedOperator(T lowerBound, T upperBound) { - setInterval(lowerBound, upperBound); - } - - /** - * Destructor - */ - virtual ~TimeBoundedOperator() { - // Intentionally left empty - } - - /** - * Getter for lowerBound attribute - * - * @return lower bound of the operator. - */ - T getLowerBound() const { - return lowerBound; - } - - /** - * Getter for upperBound attribute - * @return upper bound of the operator. - */ - T getUpperBound() const { - return upperBound; - } - - /** - * Set the time interval for the time bounded operator - * - * @param lowerBound - * @param upperBound - * @throw InvalidArgumentException if the lower bound is larger than the upper bound. - */ - void setInterval(T lowerBound, T upperBound) { - if (lowerBound > upperBound) { - throw new storm::exceptions::InvalidArgumentException("Lower bound is larger than upper bound"); - } - this->lowerBound = lowerBound; - this->upperBound = upperBound; - } - - - /*! - * @returns a string representation of the Interval of the formula - * May be used in subclasses to simplify string output. - */ - virtual std::string toString() const override { - std::string result = ""; - if (upperBound == std::numeric_limits<double>::infinity()) { - result = ">=" + std::to_string(lowerBound); - } else { - result = "["; - result += std::to_string(lowerBound); - result += ","; - result += std::to_string(upperBound); - result += "]"; - } - return result; - } - -private: - T lowerBound, upperBound; -}; - -} //namespace abstract -} //namespace property -} //namespace storm - -#endif /* STORM_FORMULA_ABSTRACT_TIMEBOUNDEDOPERATOR_H_ */ diff --git a/src/formula/abstract/TimeBoundedUntil.h b/src/formula/abstract/TimeBoundedUntil.h deleted file mode 100644 index 936baeef4..000000000 --- a/src/formula/abstract/TimeBoundedUntil.h +++ /dev/null @@ -1,149 +0,0 @@ -/* - * TimeBoundedUntil.h - * - * Created on: 10.04.2013 - * Author: thomas - */ - -#ifndef STORM_FORMULA_ABSTRACT_TIMEBOUNDEDUNTIL_H_ -#define STORM_FORMULA_ABSTRACT_TIMEBOUNDEDUNTIL_H_ - -#include "TimeBoundedOperator.h" - -namespace storm { -namespace property { -namespace abstract { - - -/** - * @brief - * Class for an abstract formula tree with an time bounded until operator as root. - * - * @tparam FormulaType The type of the subformula. - * The instantiation of FormulaType should be a subclass of AbstractFormula, as the functions - * "toString" and "conforms" of the subformulas are needed. - */ -template <class T, class FormulaType> -class TimeBoundedUntil: public TimeBoundedOperator<T> { - - // Throw a compiler error if FormulaType is not a subclass of AbstractFormula. - static_assert(std::is_base_of<AbstractFormula<T>, FormulaType>::value, - "Instantiaton of FormulaType for storm::property::abstract::TimeBoundedUntil<T,FormulaType> has to be a subtype of storm::property::abstract::AbstractFormula<T>"); - -public: - /** - * Constructor providing bounds only; - * Sub formulas are set to null. - * - * @param lowerBound - * @param upperBound - */ - TimeBoundedUntil(T lowerBound, T upperBound) : - TimeBoundedOperator<T>(lowerBound, upperBound) { - this->left = nullptr; - this->right = nullptr; - } - - - /** - * Full constructor - * @param lowerBound - * @param upperBound - * @param left - * @param right - */ - TimeBoundedUntil(T lowerBound, T upperBound, FormulaType* left, FormulaType* right) : - TimeBoundedOperator<T>(lowerBound, upperBound) { - this->left = left; - this->right = right; - } - - virtual ~TimeBoundedUntil() { - if (left != nullptr) { - delete left; - } - if (right != nullptr) { - delete right; - } - } - - /*! - * Sets the left child node. - * - * @param newLeft the new left child. - */ - void setLeft(FormulaType* newLeft) { - left = newLeft; - } - - /*! - * Sets the right child node. - * - * @param newRight the new right child. - */ - void setRight(FormulaType* newRight) { - right = newRight; - } - - /*! - * @returns a pointer to the left child node - */ - const FormulaType& getLeft() const { - return *left; - } - - /*! - * @returns a pointer to the right child node - */ - const FormulaType& getRight() const { - return *right; - } - - /*! - * - * @return True if the left child is set, i.e. it does not point to nullptr; false otherwise - */ - bool leftIsSet() const { - return left != nullptr; - } - - /*! - * - * @return True if the right child is set, i.e. it does not point to nullptr; false otherwise - */ - bool rightIsSet() const { - return right != nullptr; - } - - /*! - * @returns a string representation of the formula - */ - virtual std::string toString() const override { - std::string result = left->toString(); - result += " U"; - result += TimeBoundedOperator<T>::toString(); - result += " "; - result += right->toString(); - return result; - } - - /*! - * @brief Checks if the subtree conforms to some logic. - * - * @param checker Formula checker object. - * @return true iff the subtree conforms to some logic. - */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { - return checker.validate(this->left) && checker.validate(this->right); - } - -private: - FormulaType* left; - FormulaType* right; -}; - -} /* namespace abstract */ -} /* namespace property */ -} /* namespace storm */ - -#endif /* STORM_FORMULA_ABSTRACT_TIMEBOUNDEDUNTIL_H_ */ diff --git a/src/formula/abstract/Until.h b/src/formula/abstract/Until.h deleted file mode 100644 index dd093de88..000000000 --- a/src/formula/abstract/Until.h +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Until.h - * - * Created on: 19.10.2012 - * Author: Thomas Heinemann - */ - -#ifndef STORM_FORMULA_ABSTRACT_UNTIL_H_ -#define STORM_FORMULA_ABSTRACT_UNTIL_H_ - -#include "src/formula/abstract/AbstractFormula.h" -#include "src/formula/abstract/AbstractFormula.h" -#include "src/formula/AbstractFormulaChecker.h" - -namespace storm { -namespace property { -namespace abstract { - -/*! - * @brief - * Class for an abstract (path) formula tree with an Until node as root. - * - * Has two formulas as sub formulas/trees. - * - * @par Semantics - * The formula holds iff eventually, formula \e right (the right subtree) holds, and before, - * \e left holds always. - * - * The subtrees are seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @tparam FormulaType The type of the subformula. - * The instantiation of FormulaType should be a subclass of AbstractFormula, as the functions - * "toString" and "conforms" of the subformulas are needed. - * - * @see AbstractFormula - */ -template <class T, class FormulaType> -class Until : public virtual AbstractFormula<T> { - - // Throw a compiler error if FormulaType is not a subclass of AbstractFormula. - static_assert(std::is_base_of<AbstractFormula<T>, FormulaType>::value, - "Instantiaton of FormulaType for storm::property::abstract::Until<T,FormulaType> has to be a subtype of storm::property::abstract::AbstractFormula<T>"); - -public: - /*! - * Empty constructor - */ - Until() { - this->left = NULL; - this->right = NULL; - } - - /*! - * Constructor - * - * @param left The left formula subtree - * @param right The left formula subtree - */ - Until(FormulaType* left, FormulaType* right) { - this->left = left; - this->right = right; - } - - /*! - * Destructor. - * - * Also deletes the subtrees. - * (this behaviour can be prevented by setting the subtrees to NULL before deletion) - */ - virtual ~Until() { - if (left != NULL) { - delete left; - } - if (right != NULL) { - delete right; - } - } - - /*! - * Sets the left child node. - * - * @param newLeft the new left child. - */ - void setLeft(FormulaType* newLeft) { - left = newLeft; - } - - /*! - * Sets the right child node. - * - * @param newRight the new right child. - */ - void setRight(FormulaType* newRight) { - right = newRight; - } - - /*! - * @returns a pointer to the left child node - */ - const FormulaType& getLeft() const { - return *left; - } - - /*! - * @returns a pointer to the right child node - */ - const FormulaType& getRight() const { - return *right; - } - - /*! - * - * @return True if the left child is set, i.e. it does not point to nullptr; false otherwise - */ - bool leftIsSet() const { - return left != nullptr; - } - - /*! - * - * @return True if the right child is set, i.e. it does not point to nullptr; false otherwise - */ - bool rightIsSet() const { - return right != nullptr; - } - - /*! - * @returns a string representation of the formula - */ - virtual std::string toString() const override { - std::string result = left->toString(); - result += " U "; - result += right->toString(); - return result; - } - - /*! - * @brief Checks if all subtrees conform to some logic. - * - * @param checker Formula checker object. - * @return true iff all subtrees conform to some logic. - */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { - return checker.validate(this->left) && checker.validate(this->right); - } - -private: - FormulaType* left; - FormulaType* right; -}; - -} //namespace abstract - -} //namespace property - -} //namespace storm - -#endif /* STORM_FORMULA_ABSTRACT_UNTIL_H_ */ From 0b9198122ff565b6321ca63eb0006a51121b0445 Mon Sep 17 00:00:00 2001 From: masawei <manuel.sascha.weiand@rwth-aachen.de> Date: Sat, 12 Apr 2014 21:18:26 +0200 Subject: [PATCH 02/30] Done with PrCTL. - Began removing NoBoundFormulas, since they might not be needed anymore. This task will be taken over by filters if they are to be implemented. Next up: CSL Former-commit-id: 6164f737376915c44af1c70d0420f051c4016598 --- src/formula/Prctl.h | 3 - src/formula/Prctl/AbstractNoBoundOperator.h | 83 ----------- src/formula/Prctl/AbstractPathFormula.h | 4 +- src/formula/Prctl/AbstractPrctlFormula.h | 31 ++++ src/formula/Prctl/AbstractStateFormula.h | 4 +- src/formula/Prctl/BoundedEventually.h | 81 ++++++++-- src/formula/Prctl/BoundedNaryUntil.h | 105 +++++++++++-- src/formula/Prctl/BoundedUntil.h | 116 ++++++++++++-- src/formula/Prctl/CumulativeReward.h | 51 ++++++- src/formula/Prctl/Eventually.h | 63 ++++++-- src/formula/Prctl/Globally.h | 63 ++++++-- src/formula/Prctl/InstantaneousReward.h | 54 ++++++- src/formula/Prctl/Next.h | 67 +++++++-- src/formula/Prctl/Not.h | 4 +- src/formula/Prctl/Or.h | 10 +- .../Prctl/ProbabilisticBoundOperator.h | 141 ++++++++++++++---- .../Prctl/ProbabilisticNoBoundOperator.h | 115 -------------- src/formula/Prctl/ReachabilityReward.h | 58 ++++++- src/formula/Prctl/RewardBoundOperator.h | 133 ++++++++++++++--- src/formula/Prctl/RewardNoBoundOperator.h | 108 -------------- src/formula/Prctl/SteadyStateReward.h | 23 ++- src/formula/Prctl/Until.h | 93 ++++++++++-- src/modelchecker/prctl/AbstractModelChecker.h | 1 - 23 files changed, 945 insertions(+), 466 deletions(-) delete mode 100644 src/formula/Prctl/AbstractNoBoundOperator.h create mode 100644 src/formula/Prctl/AbstractPrctlFormula.h delete mode 100644 src/formula/Prctl/ProbabilisticNoBoundOperator.h delete mode 100644 src/formula/Prctl/RewardNoBoundOperator.h diff --git a/src/formula/Prctl.h b/src/formula/Prctl.h index 87466f55f..5f12911ea 100644 --- a/src/formula/Prctl.h +++ b/src/formula/Prctl.h @@ -17,7 +17,6 @@ #include "Prctl/Next.h" #include "Prctl/Not.h" #include "Prctl/Or.h" -#include "Prctl/ProbabilisticNoBoundOperator.h" #include "Prctl/ProbabilisticBoundOperator.h" #include "Prctl/Until.h" @@ -29,12 +28,10 @@ #include "Prctl/CumulativeReward.h" #include "Prctl/ReachabilityReward.h" #include "Prctl/RewardBoundOperator.h" -#include "Prctl/RewardNoBoundOperator.h" #include "Prctl/SteadyStateReward.h" #include "Prctl/AbstractPrctlFormula.h" #include "Prctl/AbstractStateFormula.h" -#include "Prctl/AbstractNoBoundOperator.h" #include "Prctl/AbstractPathFormula.h" #include "modelchecker/prctl/AbstractModelChecker.h" diff --git a/src/formula/Prctl/AbstractNoBoundOperator.h b/src/formula/Prctl/AbstractNoBoundOperator.h deleted file mode 100644 index 4605a590d..000000000 --- a/src/formula/Prctl/AbstractNoBoundOperator.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * AbstractNoBoundOperator.h - * - * Created on: 16.04.2013 - * Author: thomas - */ - -#ifndef STORM_FORMULA_PRCTL_ABSTRACTNOBOUNDOPERATOR_H_ -#define STORM_FORMULA_PRCTL_ABSTRACTNOBOUNDOPERATOR_H_ - -#include "src/formula/AbstractFormula.h" -#include "src/formula/abstract/IOptimizingOperator.h" - -namespace storm { -namespace property { -namespace prctl { - -template <class T> -class AbstractNoBoundOperator; - -/*! - * @brief Interface class for model checkers that support PathNoBoundOperator. - * - * All model checkers that support the formula class NoBoundOperator must inherit - * this pure virtual class. - */ -template <class T> -class INoBoundOperatorModelChecker { -public: - /*! - * @brief Evaluates NoBoundOperator formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual std::vector<T> checkNoBoundOperator(const AbstractNoBoundOperator<T>& obj) const = 0; - - -}; - -/*! - * Interface class for all PRCTL No bound operators - */ -template <class T> -class AbstractNoBoundOperator: public storm::property::AbstractFormula<T>, - public virtual storm::property::IOptimizingOperator { -public: - AbstractNoBoundOperator() { - // Intentionally left empty. - - } - virtual ~AbstractNoBoundOperator() { - // Intentionally left empty - } - - /*! - * Clones the called object. - * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones - * - * @note This function is not implemented in this class. - * @returns a new AND-object that is identical the called object. - */ - virtual AbstractNoBoundOperator<T>* clone() const = 0; - - /*! - * Calls the model checker to check this formula. - * Needed to infer the correct type of formula class. - * - * @note This function should only be called in a generic check function of a model checker class. For other uses, - * the methods of the model checker should be used. - * - * @note This function is not implemented in this class. - * - * @returns A vector indicating the probability that the formula holds for each state. - */ - virtual std::vector<T> check(const storm::modelchecker::prctl::AbstractModelChecker<T>& modelChecker, bool qualitative=false) const = 0; -}; - -} /* namespace prctl */ -} /* namespace property */ -} /* namespace storm */ -#endif /* STORM_FORMULA_PRCTL_ABSTRACTNOBOUNDOPERATOR_H_ */ diff --git a/src/formula/Prctl/AbstractPathFormula.h b/src/formula/Prctl/AbstractPathFormula.h index c7e20b9c6..1c0be2dd6 100644 --- a/src/formula/Prctl/AbstractPathFormula.h +++ b/src/formula/Prctl/AbstractPathFormula.h @@ -8,7 +8,7 @@ #ifndef STORM_FORMULA_PRCTL_ABSTRACTPATHFORMULA_H_ #define STORM_FORMULA_PRCTL_ABSTRACTPATHFORMULA_H_ -#include "src/formula/AbstractFormula.h" +#include "src/formula/Prctl/AbstractPrctlFormula.h" #include "src/modelchecker/prctl/ForwardDeclarations.h" #include <vector> @@ -31,7 +31,7 @@ namespace prctl { * @note This class is intentionally not derived from AbstractPrctlFormula, as path formulas are not complete PRCTL formulas. */ template <class T> -class AbstractPathFormula : public virtual storm::property::AbstractFormula<T> { +class AbstractPathFormula : public virtual storm::property::prctl::AbstractPrctlFormula<T> { public: /*! diff --git a/src/formula/Prctl/AbstractPrctlFormula.h b/src/formula/Prctl/AbstractPrctlFormula.h new file mode 100644 index 000000000..3beddb206 --- /dev/null +++ b/src/formula/Prctl/AbstractPrctlFormula.h @@ -0,0 +1,31 @@ +/* + * AbstractPrctlFormula.h + * + * Created on: 16.04.2013 + * Author: thomas + */ + +#ifndef STORM_FORMULA_PRCTL_ABSTRACTPRCTLFORMULA_H_ +#define STORM_FORMULA_PRCTL_ABSTRACTPRCTLFORMULA_H_ + +#include "src/formula/AbstractFormula.h" + +namespace storm { +namespace property { +namespace prctl { + +/*! + * Interface class for all PRCTL root formulas. + */ +template<class T> +class AbstractPrctlFormula : public virtual storm::property::AbstractFormula<T> { +public: + virtual ~AbstractPrctlFormula() { + // Intentionally left empty + } +}; + +} /* namespace prctl */ +} /* namespace property */ +} /* namespace storm */ +#endif /* ABSTRACTPRCTLFORMULA_H_ */ diff --git a/src/formula/Prctl/AbstractStateFormula.h b/src/formula/Prctl/AbstractStateFormula.h index 1142d7754..b10a9e92a 100644 --- a/src/formula/Prctl/AbstractStateFormula.h +++ b/src/formula/Prctl/AbstractStateFormula.h @@ -8,7 +8,7 @@ #ifndef STORM_FORMULA_PRCTL_ABSTRACTSTATEFORMULA_H_ #define STORM_FORMULA_PRCTL_ABSTRACTSTATEFORMULA_H_ -#include "src/formula/AbstractFormula.h" +#include "src/formula/Prctl/AbstractPrctlFormula.h" #include "src/storage/BitVector.h" #include "src/modelchecker/prctl/ForwardDeclarations.h" @@ -26,7 +26,7 @@ namespace prctl { * clone(). */ template <class T> -class AbstractStateFormula : public virtual storm::property::AbstractFormula<T> { +class AbstractStateFormula : public virtual storm::property::prctl::AbstractPrctlFormula<T> { public: /*! diff --git a/src/formula/Prctl/BoundedEventually.h b/src/formula/Prctl/BoundedEventually.h index 870d88e1d..0da53493f 100644 --- a/src/formula/Prctl/BoundedEventually.h +++ b/src/formula/Prctl/BoundedEventually.h @@ -8,7 +8,6 @@ #ifndef STORM_FORMULA_PRCTL_BOUNDEDEVENTUALLY_H_ #define STORM_FORMULA_PRCTL_BOUNDEDEVENTUALLY_H_ -#include "src/formula/abstract/BoundedEventually.h" #include "src/formula/Prctl/AbstractPathFormula.h" #include "src/formula/Prctl/AbstractStateFormula.h" #include "src/formula/AbstractFormulaChecker.h" @@ -56,15 +55,14 @@ class IBoundedEventuallyModelChecker { * @see AbstractPrctlFormula */ template <class T> -class BoundedEventually : public storm::property::abstract::BoundedEventually<T, AbstractStateFormula<T>>, - public AbstractPathFormula<T> { +class BoundedEventually : public AbstractPathFormula<T> { public: /*! * Empty constructor */ - BoundedEventually() { - //intentionally left empty + BoundedEventually() : child(nullptr), bound(0){ + // Intentionally left empty. } /*! @@ -73,9 +71,8 @@ public: * @param child The child formula subtree * @param bound The maximal number of steps */ - BoundedEventually(AbstractStateFormula<T>* child, uint_fast64_t bound) : - storm::property::abstract::BoundedEventually<T, AbstractStateFormula<T>>(child, bound){ - //intentionally left empty + BoundedEventually(AbstractStateFormula<T>* child, uint_fast64_t bound) : child(child), bound(bound){ + // Intentionally left empty. } /*! @@ -85,7 +82,9 @@ public: * (this behaviour can be prevented by setting the subtrees to NULL before deletion) */ virtual ~BoundedEventually() { - //intentionally left empty + if (child != nullptr) { + delete child; + } } /*! @@ -117,6 +116,70 @@ public: virtual std::vector<T> check(const storm::modelchecker::prctl::AbstractModelChecker<T>& modelChecker, bool qualitative) const override { return modelChecker.template as<IBoundedEventuallyModelChecker>()->checkBoundedEventually(*this, qualitative); } + + /*! + * @returns a string representation of the formula + */ + virtual std::string toString() const override { + std::string result = "F<="; + result += std::to_string(bound); + result += " "; + result += child->toString(); + return result; + } + + /*! + * @brief Checks if the subtree conforms to some logic. + * + * @param checker Formula checker object. + * @return true iff the subtree conforms to some logic. + */ + virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + return checker.validate(this->child); + } + + /*! + * @returns the child node + */ + const AbstractStateFormula<T>& getChild() const { + return *child; + } + + /*! + * Sets the subtree + * @param child the new child node + */ + void setChild(AbstractStateFormula<T>* child) { + this->child = child; + } + + /*! + * + * @return True if the child is set, i.e. it does not point to nullptr; false otherwise + */ + bool childIsSet() const { + return child != nullptr; + } + + /*! + * @returns the maximally allowed number of steps for the bounded until operator + */ + uint_fast64_t getBound() const { + return bound; + } + + /*! + * Sets the maximally allowed number of steps for the bounded until operator + * + * @param bound the new bound. + */ + void setBound(uint_fast64_t bound) { + this->bound = bound; + } + +private: + AbstractStateFormula<T>* child; + uint_fast64_t bound; }; } //namespace prctl diff --git a/src/formula/Prctl/BoundedNaryUntil.h b/src/formula/Prctl/BoundedNaryUntil.h index e01169496..f59431447 100644 --- a/src/formula/Prctl/BoundedNaryUntil.h +++ b/src/formula/Prctl/BoundedNaryUntil.h @@ -8,7 +8,6 @@ #ifndef STORM_FORMULA_PRCTL_BOUNDEDNARYUNTIL_H_ #define STORM_FORMULA_PRCTL_BOUNDEDNARYUNTIL_H_ -#include "src/formula/abstract/BoundedNaryUntil.h" #include "src/formula/Prctl/AbstractPathFormula.h" #include "src/formula/Prctl/AbstractStateFormula.h" #include <cstdint> @@ -63,15 +62,16 @@ class IBoundedNaryUntilModelChecker { * @see AbstractPrctlFormula */ template <class T> -class BoundedNaryUntil : public storm::property::abstract::BoundedNaryUntil<T, AbstractStateFormula<T>>, - public AbstractPathFormula<T> { +class BoundedNaryUntil : public AbstractPathFormula<T> { public: + /*! * Empty constructor */ BoundedNaryUntil() { - + this->left = nullptr; + this->right = new std::vector<std::tuple<AbstractStateFormula<T>*,T,T>>(); } /*! @@ -80,9 +80,9 @@ public: * @param left The left formula subtree * @param right The left formula subtree */ - BoundedNaryUntil(AbstractStateFormula<T>* left, std::vector<std::tuple<AbstractStateFormula<T>*,T,T>>* right) : - storm::property::abstract::BoundedNaryUntil<T, AbstractStateFormula<T>>(left, right){ - + BoundedNaryUntil(AbstractStateFormula<T>* left, std::vector<std::tuple<AbstractStateFormula<T>*,T,T>>* right) { + this->left = left; + this->right = right; } /*! @@ -92,10 +92,14 @@ public: * (this behaviour can be prevented by setting the subtrees to NULL before deletion) */ virtual ~BoundedNaryUntil() { - //intentionally left empty + if (left != nullptr) { + delete left; + } + if (right != nullptr) { + delete right; + } } - /*! * Clones the called object. * @@ -132,6 +136,89 @@ public: return modelChecker.template as<IBoundedNaryUntilModelChecker>()->checkBoundedNaryUntil(*this, qualitative); } + /*! + * @returns a string representation of the formula + */ + virtual std::string toString() const override { + std::stringstream result; + result << "( " << left->toString(); + for (auto it = this->right->begin(); it != this->right->end(); ++it) { + result << " U[" << std::get<1>(*it) << "," << std::get<2>(*it) << "] " << std::get<0>(*it)->toString(); + } + result << ")"; + return result.str(); + } + + /*! + * @brief Checks if all subtrees conform to some logic. + * + * @param checker Formula checker object. + * @return true iff all subtrees conform to some logic. + */ + virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + bool res = checker.validate(this->left); + for (auto it = this->right->begin(); it != this->right->end(); ++it) { + res &= checker.validate(std::get<0>(*it)); + } + return res; + } + + /*! + * Sets the left child node. + * + * @param newLeft the new left child. + */ + void setLeft(AbstractStateFormula<T>* newLeft) { + left = newLeft; + } + + void setRight(std::vector<std::tuple<AbstractStateFormula<T>*,T,T>>* newRight) { + right = newRight; + } + + /*! + * + * @return True if the left child is set, i.e. it does not point to nullptr; false otherwise + */ + bool leftIsSet() const { + return left != nullptr; + } + + /*! + * + * @return True if the right child is set, i.e. it does not point to nullptr; false otherwise + */ + bool rightIsSet() const { + return right != nullptr; + } + + /*! + * Sets the right child node. + * + * @param newRight the new right child. + */ + void addRight(AbstractStateFormula<T>* newRight, T upperBound, T lowerBound) { + this->right->push_back(std::tuple<AbstractStateFormula<T>*,T,T>(newRight, upperBound, lowerBound)); + } + + /*! + * @returns a pointer to the left child node + */ + const AbstractStateFormula<T>& getLeft() const { + return *left; + } + + /*! + * @returns a pointer to the right child nodes. + */ + const std::vector<std::tuple<AbstractStateFormula<T>*,T,T>>& getRight() const { + return *right; + } + + +private: + AbstractStateFormula<T>* left; + std::vector<std::tuple<AbstractStateFormula<T>*,T,T>>* right; }; } //namespace prctl diff --git a/src/formula/Prctl/BoundedUntil.h b/src/formula/Prctl/BoundedUntil.h index f17c9b743..d7c9d28ca 100644 --- a/src/formula/Prctl/BoundedUntil.h +++ b/src/formula/Prctl/BoundedUntil.h @@ -8,7 +8,6 @@ #ifndef STORM_FORMULA_PRCTL_BOUNDEDUNTIL_H_ #define STORM_FORMULA_PRCTL_BOUNDEDUNTIL_H_ -#include "src/formula/abstract/BoundedUntil.h" #include "src/formula/Prctl/AbstractPathFormula.h" #include "src/formula/Prctl/AbstractStateFormula.h" #include <cstdint> @@ -56,15 +55,15 @@ class IBoundedUntilModelChecker { * @see AbstractPrctlFormula */ template <class T> -class BoundedUntil : public storm::property::abstract::BoundedUntil<T, AbstractStateFormula<T>>, - public AbstractPathFormula<T> { +class BoundedUntil : public AbstractPathFormula<T> { public: + /*! * Empty constructor */ - BoundedUntil() { - //Intentionally left empty + BoundedUntil() : left(nullptr), right(nullptr), bound(0){ + // Intentionally left empty. } /*! @@ -74,12 +73,11 @@ public: * @param right The left formula subtree * @param bound The maximal number of steps */ - BoundedUntil(AbstractStateFormula<T>* left, AbstractStateFormula<T>* right, - uint_fast64_t bound) : - storm::property::abstract::BoundedUntil<T, AbstractStateFormula<T>>(left,right,bound) { - //intentionally left empty + BoundedUntil(AbstractStateFormula<T>* left, AbstractStateFormula<T>* right, uint_fast64_t bound) { + this->left = left; + this->right = right; + this->bound = bound; } - /*! * Destructor. * @@ -87,7 +85,12 @@ public: * (this behaviour can be prevented by setting the subtrees to NULL before deletion) */ virtual ~BoundedUntil() { - //intentionally left empty + if (left != NULL) { + delete left; + } + if (right != NULL) { + delete right; + } } /*! @@ -122,6 +125,97 @@ public: virtual std::vector<T> check(const storm::modelchecker::prctl::AbstractModelChecker<T>& modelChecker, bool qualitative) const override { return modelChecker.template as<IBoundedUntilModelChecker>()->checkBoundedUntil(*this, qualitative); } + + /*! + * @returns a string representation of the formula + */ + virtual std::string toString() const override { + std::string result = left->toString(); + result += " U<="; + result += std::to_string(bound); + result += " "; + result += right->toString(); + return result; + } + + /*! + * @brief Checks if all subtrees conform to some logic. + * + * @param checker Formula checker object. + * @return true iff all subtrees conform to some logic. + */ + virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + return checker.validate(this->left) && checker.validate(this->right); + } + + /*! + * Sets the left child node. + * + * @param newLeft the new left child. + */ + void setLeft(AbstractStateFormula<T>* newLeft) { + left = newLeft; + } + + /*! + * Sets the right child node. + * + * @param newRight the new right child. + */ + void setRight(AbstractStateFormula<T>* newRight) { + right = newRight; + } + + /*! + * @returns a pointer to the left child node + */ + const AbstractStateFormula<T>& getLeft() const { + return *left; + } + + /*! + * @returns a pointer to the right child node + */ + const AbstractStateFormula<T>& getRight() const { + return *right; + } + + /*! + * + * @return True if the left child is set, i.e. it does not point to nullptr; false otherwise + */ + bool leftIsSet() const { + return left != nullptr; + } + + /*! + * + * @return True if the right child is set, i.e. it does not point to nullptr; false otherwise + */ + bool rightIsSet() const { + return right != nullptr; + } + + /*! + * @returns the maximally allowed number of steps for the bounded until operator + */ + uint_fast64_t getBound() const { + return bound; + } + + /*! + * Sets the maximally allowed number of steps for the bounded until operator + * + * @param bound the new bound. + */ + void setBound(uint_fast64_t bound) { + this->bound = bound; + } + +private: + AbstractStateFormula<T>* left; + AbstractStateFormula<T>* right; + uint_fast64_t bound; }; } //namespace prctl diff --git a/src/formula/Prctl/CumulativeReward.h b/src/formula/Prctl/CumulativeReward.h index e1db7cb21..a31f75a5d 100644 --- a/src/formula/Prctl/CumulativeReward.h +++ b/src/formula/Prctl/CumulativeReward.h @@ -10,7 +10,6 @@ #include "AbstractPathFormula.h" #include "AbstractStateFormula.h" -#include "src/formula/abstract/CumulativeReward.h" #include "src/formula/AbstractFormulaChecker.h" #include <string> @@ -49,14 +48,13 @@ class ICumulativeRewardModelChecker { * @see AbstractPrctlFormula */ template <class T> -class CumulativeReward : public storm::property::abstract::CumulativeReward<T>, - public AbstractPathFormula<T> { +class CumulativeReward : public AbstractPathFormula<T> { public: /*! * Empty constructor */ - CumulativeReward() { + CumulativeReward() : bound(0){ // Intentionally left empty } @@ -65,9 +63,8 @@ public: * * @param bound The time bound of the reward formula */ - CumulativeReward(T bound) : - storm::property::abstract::CumulativeReward<T>(bound) { - // Intentionally left empty + CumulativeReward(T bound) : bound(bound){ + // Intentionally left empty. } /*! @@ -101,6 +98,46 @@ public: virtual std::vector<T> check(const storm::modelchecker::prctl::AbstractModelChecker<T>& modelChecker, bool qualitative) const override { return modelChecker.template as<ICumulativeRewardModelChecker>()->checkCumulativeReward(*this, qualitative); } + + /*! + * @returns a string representation of the formula + */ + virtual std::string toString() const override { + std::string result = "C <= "; + result += std::to_string(bound); + return result; + } + + /*! + * @brief Checks if all subtrees conform to some logic. + * + * As CumulativeReward objects have no subformulas, we return true here. + * + * @param checker Formula checker object. + * @return true + */ + virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + return true; + } + + /*! + * @returns the time instance for the instantaneous reward operator + */ + T getBound() const { + return bound; + } + + /*! + * Sets the the time instance for the instantaneous reward operator + * + * @param bound the new bound. + */ + void setBound(T bound) { + this->bound = bound; + } + +private: + T bound; }; } //namespace prctl diff --git a/src/formula/Prctl/Eventually.h b/src/formula/Prctl/Eventually.h index 4a0624df6..733fc924b 100644 --- a/src/formula/Prctl/Eventually.h +++ b/src/formula/Prctl/Eventually.h @@ -8,7 +8,6 @@ #ifndef STORM_FORMULA_PRCTL_EVENTUALLY_H_ #define STORM_FORMULA_PRCTL_EVENTUALLY_H_ -#include "src/formula/abstract/Eventually.h" #include "src/formula/Prctl/AbstractPathFormula.h" #include "src/formula/Prctl/AbstractStateFormula.h" #include "src/modelchecker/prctl/ForwardDeclarations.h" @@ -53,15 +52,15 @@ class IEventuallyModelChecker { * @see AbstractPrctlFormula */ template <class T> -class Eventually : public storm::property::abstract::Eventually<T, AbstractStateFormula<T>>, - public AbstractPathFormula<T> { +class Eventually : public AbstractPathFormula<T> { public: + /*! * Empty constructor */ - Eventually() { - // Intentionally left empty + Eventually() : child(nullptr) { + // Intentionally left empty. } /*! @@ -69,9 +68,8 @@ public: * * @param child The child node */ - Eventually(AbstractStateFormula<T>* child) - : storm::property::abstract::Eventually<T, AbstractStateFormula<T>>(child) { - + Eventually(AbstractStateFormula<T>* child) : child(child){ + // Intentionally left empty. } /*! @@ -81,7 +79,9 @@ public: * (this behaviour can be prevented by setting the subtrees to nullptr before deletion) */ virtual ~Eventually() { - //intentionally left empty + if (child != nullptr) { + delete child; + } } /*! @@ -111,6 +111,51 @@ public: virtual std::vector<T> check(const storm::modelchecker::prctl::AbstractModelChecker<T>& modelChecker, bool qualitative) const override { return modelChecker.template as<IEventuallyModelChecker>()->checkEventually(*this, qualitative); } + + /*! + * @returns a string representation of the formula + */ + virtual std::string toString() const override { + std::string result = "F "; + result += child->toString(); + return result; + } + + /*! + * @brief Checks if the subtree conforms to some logic. + * + * @param checker Formula checker object. + * @return true iff the subtree conforms to some logic. + */ + virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + return checker.validate(this->child); + } + + /*! + * @returns the child node + */ + const AbstractStateFormula<T>& getChild() const { + return *child; + } + + /*! + * Sets the subtree + * @param child the new child node + */ + void setChild(AbstractStateFormula<T>* child) { + this->child = child; + } + + /*! + * + * @return True if the child node is set, i.e. it does not point to nullptr; false otherwise + */ + bool childIsSet() const { + return child != nullptr; + } + +private: + AbstractStateFormula<T>* child; }; } //namespace prctl diff --git a/src/formula/Prctl/Globally.h b/src/formula/Prctl/Globally.h index 272bbab26..eeb52e37f 100644 --- a/src/formula/Prctl/Globally.h +++ b/src/formula/Prctl/Globally.h @@ -8,7 +8,6 @@ #ifndef STORM_FORMULA_PRCTL_GLOBALLY_H_ #define STORM_FORMULA_PRCTL_GLOBALLY_H_ -#include "src/formula/abstract/Globally.h" #include "AbstractPathFormula.h" #include "AbstractStateFormula.h" #include "src/formula/AbstractFormulaChecker.h" @@ -54,15 +53,15 @@ class IGloballyModelChecker { * @see AbstractPrctlFormula */ template <class T> -class Globally : public storm::property::abstract::Globally<T, AbstractStateFormula<T>>, - public AbstractPathFormula<T> { +class Globally : public AbstractPathFormula<T> { public: + /*! * Empty constructor */ - Globally() { - //intentionally left empty + Globally() : child(nullptr){ + // Intentionally left empty. } /*! @@ -70,9 +69,8 @@ public: * * @param child The child node */ - Globally(AbstractStateFormula<T>* child) - : storm::property::abstract::Globally<T, AbstractStateFormula<T>>(child) { - //intentionally left empty + Globally(AbstractStateFormula<T>* child) : child(child){ + // Intentionally left empty. } /*! @@ -82,7 +80,9 @@ public: * (this behaviour can be prevented by setting the subtrees to nullptr before deletion) */ virtual ~Globally() { - //intentionally left empty + if (child != nullptr) { + delete child; + } } @@ -113,6 +113,51 @@ public: virtual std::vector<T> check(const storm::modelchecker::prctl::AbstractModelChecker<T>& modelChecker, bool qualitative) const override { return modelChecker.template as<IGloballyModelChecker>()->checkGlobally(*this, qualitative); } + + /*! + * @returns a string representation of the formula + */ + virtual std::string toString() const override { + std::string result = "G "; + result += child->toString(); + return result; + } + + /*! + * @brief Checks if the subtree conforms to some logic. + * + * @param checker Formula checker object. + * @return true iff the subtree conforms to some logic. + */ + virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + return checker.validate(this->child); + } + + /*! + * @returns the child node + */ + const AbstractStateFormula<T>& getChild() const { + return *child; + } + + /*! + * Sets the subtree + * @param child the new child node + */ + void setChild(AbstractStateFormula<T>* child) { + this->child = child; + } + + /*! + * + * @return True if the child node is set, i.e. it does not point to nullptr; false otherwise + */ + bool childIsSet() const { + return child != nullptr; + } + +private: + AbstractStateFormula<T>* child; }; } //namespace prctl diff --git a/src/formula/Prctl/InstantaneousReward.h b/src/formula/Prctl/InstantaneousReward.h index b28effffe..774d07e5e 100644 --- a/src/formula/Prctl/InstantaneousReward.h +++ b/src/formula/Prctl/InstantaneousReward.h @@ -10,7 +10,6 @@ #include "AbstractPathFormula.h" #include "AbstractStateFormula.h" -#include "src/formula/abstract/InstantaneousReward.h" #include "src/formula/AbstractFormulaChecker.h" #include <cstdint> #include <string> @@ -50,15 +49,15 @@ class IInstantaneousRewardModelChecker { * @see AbstractPrctlFormula */ template <class T> -class InstantaneousReward : public storm::property::abstract::InstantaneousReward<T>, - public AbstractPathFormula<T> { +class InstantaneousReward : public AbstractPathFormula<T> { public: + /*! * Empty constructor */ - InstantaneousReward() { - //intentionally left empty + InstantaneousReward() : bound(0) { + // Intentionally left empty. } /*! @@ -66,9 +65,8 @@ public: * * @param bound The time instance of the reward formula */ - InstantaneousReward(uint_fast64_t bound) : - storm::property::abstract::InstantaneousReward<T>(bound) { - //intentionally left empty + InstantaneousReward(uint_fast64_t bound) : bound(bound) { + // Intentionally left empty. } /*! @@ -102,6 +100,46 @@ public: virtual std::vector<T> check(const storm::modelchecker::prctl::AbstractModelChecker<T>& modelChecker, bool qualitative) const override { return modelChecker.template as<IInstantaneousRewardModelChecker>()->checkInstantaneousReward(*this, qualitative); } + + /*! + * @returns a string representation of the formula + */ + virtual std::string toString() const override { + std::string result = "I="; + result += std::to_string(bound); + return result; + } + + /*! + * @brief Checks if all subtrees conform to some logic. + * + * As InstantaneousReward formulas have no subformulas, we return true here. + * + * @param checker Formula checker object. + * @return true + */ + virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + return true; + } + + /*! + * @returns the time instance for the instantaneous reward operator + */ + uint_fast64_t getBound() const { + return bound; + } + + /*! + * Sets the the time instance for the instantaneous reward operator + * + * @param bound the new bound. + */ + void setBound(uint_fast64_t bound) { + this->bound = bound; + } + +private: + uint_fast64_t bound; }; } //namespace prctl diff --git a/src/formula/Prctl/Next.h b/src/formula/Prctl/Next.h index 7197da30c..a50cfd005 100644 --- a/src/formula/Prctl/Next.h +++ b/src/formula/Prctl/Next.h @@ -10,7 +10,6 @@ #include "AbstractPathFormula.h" #include "AbstractStateFormula.h" -#include "src/formula/abstract/Next.h" #include "src/formula/AbstractFormulaChecker.h" namespace storm { @@ -53,15 +52,15 @@ class INextModelChecker { * @see AbstractPrctlFormula */ template <class T> -class Next : public storm::property::abstract::Next<T, AbstractStateFormula<T>>, - public AbstractPathFormula<T> { +class Next : public AbstractPathFormula<T> { public: + /*! * Empty constructor */ - Next() { - //intentionally left empty + Next() : child(nullptr){ + // Intentionally left empty. } /*! @@ -69,19 +68,20 @@ public: * * @param child The child node */ - Next(AbstractStateFormula<T>* child) - : storm::property::abstract::Next<T, AbstractStateFormula<T>>(child) { - //intentionally left empty + Next(AbstractStateFormula<T>* child) : child(child){ + // Intentionally left empty. } /*! * Constructor. * * Also deletes the subtree. - * (this behaviour can be prevented by setting the subtrees to NULL before deletion) + * (this behavior can be prevented by setting the subtrees to NULL before deletion) */ virtual ~Next() { - //intentionally left empty + if (child != NULL) { + delete child; + } } /*! @@ -111,6 +111,53 @@ public: virtual std::vector<T> check(const storm::modelchecker::prctl::AbstractModelChecker<T>& modelChecker, bool qualitative) const override { return modelChecker.template as<INextModelChecker>()->checkNext(*this, qualitative); } + + /*! + * @returns a string representation of the formula + */ + virtual std::string toString() const override { + std::string result = "("; + result += " X "; + result += child->toString(); + result += ")"; + return result; + } + + /*! + * @brief Checks if the subtree conforms to some logic. + * + * @param checker Formula checker object. + * @return true iff the subtree conforms to some logic. + */ + virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + return checker.validate(this->child); + } + + /*! + * @returns the child node + */ + const AbstractStateFormula<T>& getChild() const { + return *child; + } + + /*! + * Sets the subtree + * @param child the new child node + */ + void setChild(AbstractStateFormula<T>* child) { + this->child = child; + } + + /*! + * + * @return True if the child node is set, i.e. it does not point to nullptr; false otherwise + */ + bool childIsSet() const { + return child != nullptr; + } + +private: + AbstractStateFormula<T>* child; }; } //namespace prctl diff --git a/src/formula/Prctl/Not.h b/src/formula/Prctl/Not.h index 6859d97b1..231ced8d9 100644 --- a/src/formula/Prctl/Not.h +++ b/src/formula/Prctl/Not.h @@ -129,7 +129,7 @@ public: /*! * @returns The child node */ - const FormulaType& getChild() const { + const AbstractStateFormula<T>& getChild() const { return *child; } @@ -137,7 +137,7 @@ public: * Sets the subtree * @param child the new child node */ - void setChild(FormulaType* child) { + void setChild(AbstractStateFormula<T>* child) { this->child = child; } diff --git a/src/formula/Prctl/Or.h b/src/formula/Prctl/Or.h index cbac0c655..3f1b83f36 100644 --- a/src/formula/Prctl/Or.h +++ b/src/formula/Prctl/Or.h @@ -70,7 +70,7 @@ public: * @param left The left sub formula * @param right The right sub formula */ - Or(FormulaType* left, FormulaType* right) { + Or(AbstractStateFormula<T>* left, AbstractStateFormula<T>* right) { this->left = left; this->right = right; } @@ -148,7 +148,7 @@ public: * * @param newLeft the new left child. */ - void setLeft(FormulaType* newLeft) { + void setLeft(AbstractStateFormula<T>* newLeft) { left = newLeft; } @@ -157,21 +157,21 @@ public: * * @param newRight the new right child. */ - void setRight(FormulaType* newRight) { + void setRight(AbstractStateFormula<T>* newRight) { right = newRight; } /*! * @returns a pointer to the left child node */ - const FormulaType& getLeft() const { + const AbstractStateFormula<T>& getLeft() const { return *left; } /*! * @returns a pointer to the right child node */ - const FormulaType& getRight() const { + const AbstractStateFormula<T>& getRight() const { return *right; } diff --git a/src/formula/Prctl/ProbabilisticBoundOperator.h b/src/formula/Prctl/ProbabilisticBoundOperator.h index 6e171a517..9cbcee34c 100644 --- a/src/formula/Prctl/ProbabilisticBoundOperator.h +++ b/src/formula/Prctl/ProbabilisticBoundOperator.h @@ -11,6 +11,7 @@ #include "AbstractStateFormula.h" #include "AbstractPathFormula.h" #include "utility/constants.h" +#include "src/formula/ComparisonType.h" namespace storm { namespace property { @@ -52,54 +53,39 @@ class IProbabilisticBoundOperatorModelChecker { * @see AbstractPrctlFormula */ template<class T> -class ProbabilisticBoundOperator : public storm::property::abstract::ProbabilisticBoundOperator<T, AbstractPathFormula<T>>, - public AbstractStateFormula<T> { +class ProbabilisticBoundOperator : public AbstractStateFormula<T> { public: + /*! * Empty constructor */ - ProbabilisticBoundOperator() { - // Intentionally left empty + ProbabilisticBoundOperator() : comparisonOperator(LESS), bound(0), pathFormula(nullptr) { + // Intentionally left empty. } - /*! - * Constructor + * Constructor for non-optimizing operator. * - * @param comparisonRelation The relation to compare the actual value and the bound + * @param comparisonOperator The relation for the bound. * @param bound The bound for the probability * @param pathFormula The child node */ - ProbabilisticBoundOperator( - storm::property::ComparisonType comparisonRelation, - T bound, - AbstractPathFormula<T>* pathFormula) - : storm::property::abstract::ProbabilisticBoundOperator<T, AbstractPathFormula<T>>(comparisonRelation, bound, pathFormula) { - // Intentionally left empty - } - - /*! - * - * @param comparisonRelation - * @param bound - * @param pathFormula - * @param minimumOperator - */ - ProbabilisticBoundOperator( - storm::property::ComparisonType comparisonRelation, - T bound, - AbstractPathFormula<T>* pathFormula, - bool minimumOperator) - : storm::property::abstract::ProbabilisticBoundOperator<T, AbstractPathFormula<T>>(comparisonRelation, bound, pathFormula, minimumOperator){ - // Intentionally left empty + ProbabilisticBoundOperator(storm::property::ComparisonType comparisonOperator, T bound, AbstractPathFormula<T>* pathFormula) + : comparisonOperator(comparisonOperator), bound(bound), pathFormula(pathFormula) { + // Intentionally left empty. } /*! + * Destructor * + * The subtree is deleted with the object + * (this behavior can be prevented by setting them to NULL before deletion) */ virtual ~ProbabilisticBoundOperator() { - // Intentionally left empty + if (pathFormula != nullptr) { + delete pathFormula; + } } /*! @@ -129,6 +115,101 @@ public: virtual storm::storage::BitVector check(const storm::modelchecker::prctl::AbstractModelChecker<T>& modelChecker) const override { return modelChecker.template as<IProbabilisticBoundOperatorModelChecker>()->checkProbabilisticBoundOperator(*this); } + + /*! + * @brief Checks if the subtree conforms to some logic. + * + * @param checker Formula checker object. + * @return true iff the subtree conforms to some logic. + */ + virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + return checker.validate(this->pathFormula); + } + + /*! + * @returns a string representation of the formula + */ + virtual std::string toString() const override { + std::string result = "P "; + switch (comparisonOperator) { + case LESS: result += "<"; break; + case LESS_EQUAL: result += "<="; break; + case GREATER: result += ">"; break; + case GREATER_EQUAL: result += ">="; break; + } + result += " "; + result += std::to_string(bound); + result += " ["; + result += pathFormula->toString(); + result += "]"; + return result; + } + + /*! + * @returns the child node (representation of a formula) + */ + const AbstractPathFormula<T>& getPathFormula () const { + return *pathFormula; + } + + /*! + * Sets the child node + * + * @param pathFormula the path formula that becomes the new child node + */ + void setPathFormula(AbstractPathFormula<T>* pathFormula) { + this->pathFormula = pathFormula; + } + + /*! + * + * @return True if the path formula is set, i.e. it does not point to nullptr; false otherwise + */ + bool pathFormulaIsSet() const { + return pathFormula != nullptr; + } + + /*! + * @returns the comparison relation + */ + const storm::property::ComparisonType getComparisonOperator() const { + return comparisonOperator; + } + + void setComparisonOperator(storm::property::ComparisonType comparisonOperator) { + this->comparisonOperator = comparisonOperator; + } + + /*! + * @returns the bound for the measure + */ + const T& getBound() const { + return bound; + } + + /*! + * Sets the interval in which the probability that the path formula holds may lie in. + * + * @param bound The bound for the measure + */ + void setBound(T bound) { + this->bound = bound; + } + + bool meetsBound(T value) const { + switch (comparisonOperator) { + case LESS: return value < bound; break; + case LESS_EQUAL: return value <= bound; break; + case GREATER: return value > bound; break; + case GREATER_EQUAL: return value >= bound; break; + default: return false; + } + } + +private: + storm::property::ComparisonType comparisonOperator; + T bound; + AbstractPathFormula<T>* pathFormula; }; } //namespace prctl diff --git a/src/formula/Prctl/ProbabilisticNoBoundOperator.h b/src/formula/Prctl/ProbabilisticNoBoundOperator.h deleted file mode 100644 index 5591a9555..000000000 --- a/src/formula/Prctl/ProbabilisticNoBoundOperator.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * ProbabilisticNoBoundOperator.h - * - * Created on: 12.12.2012 - * Author: thomas - */ - -#ifndef STORM_FORMULA_PRCTL_PROBABILISTICNOBOUNDOPERATOR_H_ -#define STORM_FORMULA_PRCTL_PROBABILISTICNOBOUNDOPERATOR_H_ - -#include "AbstractPathFormula.h" -#include "AbstractNoBoundOperator.h" -#include "src/formula/abstract/ProbabilisticNoBoundOperator.h" - -namespace storm { -namespace property { -namespace prctl { - -/*! - * @brief - * Class for an abstract formula tree with a P (probablistic) operator without declaration of probabilities - * as root. - * - * Checking a formula with this operator as root returns the probabilities that the path formula holds - * (for each state) - * - * Has one Abstract path formula as sub formula/tree. - * - * @note - * This class is a hybrid of a state and path formula, and may only appear as the outermost operator. - * Hence, it is seen as neither a state nor a path formula, but is directly derived from AbstractFormula. - * - * @note - * This class does not contain a check() method like the other formula classes. - * The check method should only be called by the model checker to infer the correct check function for sub - * formulas. As this operator can only appear at the root, the method is not useful here. - * Use the checkProbabilisticNoBoundOperator method from the DtmcPrctlModelChecker class instead. - * - * The subtree is seen as part of the object and deleted with it - * (this behavior can be prevented by setting them to NULL before deletion) - * - * - * @see AbstractStateFormula - * @see AbstractPathFormula - * @see ProbabilisticOperator - * @see ProbabilisticIntervalOperator - * @see AbstractPrctlFormula - */ -template <class T> -class ProbabilisticNoBoundOperator: public storm::property::abstract::ProbabilisticNoBoundOperator<T, AbstractPathFormula<T>>, - public AbstractNoBoundOperator<T> { -public: - /*! - * Empty constructor - */ - ProbabilisticNoBoundOperator() { - // Intentionally left empty - } - - /*! - * Constructor - * - * @param pathFormula The child node. - */ - ProbabilisticNoBoundOperator(AbstractPathFormula<T>* pathFormula) - : storm::property::abstract::ProbabilisticNoBoundOperator<T, AbstractPathFormula<T>>(pathFormula) { - // Intentionally left empty - } - - /*! - * Constructor - * - * @param pathFormula The child node. - */ - ProbabilisticNoBoundOperator(AbstractPathFormula<T>* pathFormula, bool minimumOperator) - : storm::property::abstract::ProbabilisticNoBoundOperator<T, AbstractPathFormula<T>>(pathFormula, minimumOperator) { - // Intentionally left empty - } - - /*! - * Destructor - */ - virtual ~ProbabilisticNoBoundOperator() { - // Intentionally left empty - } - - virtual AbstractNoBoundOperator<T>* clone() const override { - ProbabilisticNoBoundOperator<T>* result = new ProbabilisticNoBoundOperator<T>(); - if (this->pathFormulaIsSet()) { - result->setPathFormula(this->getPathFormula().clone()); - } - return result; - } - - /*! - * Calls the model checker to check this formula. - * Needed to infer the correct type of formula class. - * - * @note This function should only be called in a generic check function of a model checker class. For other uses, - * the methods of the model checker should be used. - * - * @note This function is not implemented in this class. - * - * @returns A vector indicating the probability that the formula holds for each state. - */ - virtual std::vector<T> check(const storm::modelchecker::prctl::AbstractModelChecker<T>& modelChecker, bool qualitative=false) const override { - return this->getPathFormula().check(modelChecker, qualitative); - } -}; - -} //namespace prctl -} //namespace property -} //namespace storm - -#endif /* STORM_FORMULA_PRCTL_PROBABILISTICNOBOUNDOPERATOR_H_ */ diff --git a/src/formula/Prctl/ReachabilityReward.h b/src/formula/Prctl/ReachabilityReward.h index d0bcdfc69..0368b4ba9 100644 --- a/src/formula/Prctl/ReachabilityReward.h +++ b/src/formula/Prctl/ReachabilityReward.h @@ -10,7 +10,6 @@ #include "AbstractPathFormula.h" #include "AbstractStateFormula.h" -#include "../abstract/Eventually.h" #include "src/formula/AbstractFormulaChecker.h" namespace storm { @@ -50,14 +49,13 @@ class IReachabilityRewardModelChecker { * @see AbstractPrctlFormula */ template <class T> -class ReachabilityReward : public storm::property::abstract::Eventually<T, AbstractStateFormula<T>>, - public AbstractPathFormula<T> { +class ReachabilityReward : public AbstractPathFormula<T> { public: /*! * Empty constructor */ - ReachabilityReward() { + ReachabilityReward() : child(nullptr){ // Intentionally left empty } @@ -66,8 +64,7 @@ public: * * @param child The child node */ - ReachabilityReward(AbstractStateFormula<T>* child) : - storm::property::abstract::Eventually<T, AbstractStateFormula<T>>(child){ + ReachabilityReward(AbstractStateFormula<T>* child) : child(child){ // Intentionally left empty } @@ -78,7 +75,9 @@ public: * (this behaviour can be prevented by setting the subtrees to nullptr before deletion) */ virtual ~ReachabilityReward() { - // Intentionally left empty + if (child != nullptr) { + delete child; + } } /*! @@ -108,6 +107,51 @@ public: virtual std::vector<T> check(const storm::modelchecker::prctl::AbstractModelChecker<T>& modelChecker, bool qualitative) const override { return modelChecker.template as<IReachabilityRewardModelChecker>()->checkReachabilityReward(*this, qualitative); } + + /*! + * @returns a string representation of the formula + */ + virtual std::string toString() const override { + std::string result = "F "; + result += child->toString(); + return result; + } + + /*! + * @brief Checks if the subtree conforms to some logic. + * + * @param checker Formula checker object. + * @return true iff the subtree conforms to some logic. + */ + virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + return checker.validate(this->child); + } + + /*! + * @returns the child node + */ + const AbstractStateFormula<T>& getChild() const { + return *child; + } + + /*! + * Sets the subtree + * @param child the new child node + */ + void setChild(AbstractStateFormula<T>* child) { + this->child = child; + } + + /*! + * + * @return True if the child node is set, i.e. it does not point to nullptr; false otherwise + */ + bool childIsSet() const { + return child != nullptr; + } + +private: + AbstractStateFormula<T>* child; }; } //namespace prctl diff --git a/src/formula/Prctl/RewardBoundOperator.h b/src/formula/Prctl/RewardBoundOperator.h index 4c5cf19d3..73dea7ab3 100644 --- a/src/formula/Prctl/RewardBoundOperator.h +++ b/src/formula/Prctl/RewardBoundOperator.h @@ -10,8 +10,8 @@ #include "AbstractPathFormula.h" #include "AbstractStateFormula.h" -#include "src/formula/abstract/RewardBoundOperator.h" #include "utility/constants.h" +#include "src/formula/ComparisonType.h" namespace storm { namespace property { @@ -52,48 +52,38 @@ class IRewardBoundOperatorModelChecker { * @see AbstractPrctlFormula */ template<class T> -class RewardBoundOperator : public storm::property::abstract::RewardBoundOperator<T, AbstractPathFormula<T>>, - public AbstractStateFormula<T> { +class RewardBoundOperator : public AbstractStateFormula<T> { public: /*! * Empty constructor */ - RewardBoundOperator() { + RewardBoundOperator() : comparisonOperator(LESS), bound(0), pathFormula(nullptr){ // Intentionally left empty } /*! - * Constructor + * Constructor for non-optimizing operator. * - * @param comparisonRelation The relation to compare the actual value and the bound + * @param comparisonOperator The relation for the bound. * @param bound The bound for the probability * @param pathFormula The child node */ - RewardBoundOperator( - storm::property::ComparisonType comparisonRelation, - T bound, - AbstractPathFormula<T>* pathFormula) : - storm::property::abstract::RewardBoundOperator<T, AbstractPathFormula<T>>(comparisonRelation, bound, pathFormula) { + RewardBoundOperator(storm::property::ComparisonType comparisonOperator, T bound, AbstractPathFormula<T>* pathFormula) + : comparisonOperator(comparisonOperator), bound(bound), pathFormula(pathFormula) { // Intentionally left empty } - /*! - * Constructor + * Destructor * - * @param comparisonRelation - * @param bound - * @param pathFormula - * @param minimumOperator + * The subtree is deleted with the object + * (this behavior can be prevented by setting them to NULL before deletion) */ - RewardBoundOperator( - storm::property::ComparisonType comparisonRelation, - T bound, - AbstractPathFormula<T>* pathFormula, - bool minimumOperator) - : storm::property::abstract::RewardBoundOperator<T, AbstractPathFormula<T>>(comparisonRelation, bound, pathFormula, minimumOperator) { - // Intentionally left empty + virtual ~RewardBoundOperator() { + if (pathFormula != nullptr) { + delete pathFormula; + } } /*! @@ -123,6 +113,101 @@ public: virtual storm::storage::BitVector check(const storm::modelchecker::prctl::AbstractModelChecker<T>& modelChecker) const override { return modelChecker.template as<IRewardBoundOperatorModelChecker>()->checkRewardBoundOperator(*this); } + + /*! + * @brief Checks if the subtree conforms to some logic. + * + * @param checker Formula checker object. + * @return true iff the subtree conforms to some logic. + */ + virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + return checker.validate(this->pathFormula); + } + + /*! + * @returns a string representation of the formula + */ + virtual std::string toString() const override { + std::string result = "R "; + switch (comparisonOperator) { + case LESS: result += "<"; break; + case LESS_EQUAL: result += "<="; break; + case GREATER: result += ">"; break; + case GREATER_EQUAL: result += ">="; break; + } + result += " "; + result += std::to_string(bound); + result += " ["; + result += pathFormula->toString(); + result += "]"; + return result; + } + + /*! + * @returns the child node (representation of a formula) + */ + const AbstractPathFormula<T>& getPathFormula () const { + return *pathFormula; + } + + /*! + * Sets the child node + * + * @param pathFormula the path formula that becomes the new child node + */ + void setPathFormula(AbstractPathFormula<T>* pathFormula) { + this->pathFormula = pathFormula; + } + + /*! + * + * @return True if the path formula is set, i.e. it does not point to nullptr; false otherwise + */ + bool pathFormulaIsSet() const { + return pathFormula != nullptr; + } + + /*! + * @returns the comparison relation + */ + const storm::property::ComparisonType getComparisonOperator() const { + return comparisonOperator; + } + + void setComparisonOperator(storm::property::ComparisonType comparisonOperator) { + this->comparisonOperator = comparisonOperator; + } + + /*! + * @returns the bound for the measure + */ + const T& getBound() const { + return bound; + } + + /*! + * Sets the interval in which the probability that the path formula holds may lie in. + * + * @param bound The bound for the measure + */ + void setBound(T bound) { + this->bound = bound; + } + + bool meetsBound(T value) const { + switch (comparisonOperator) { + case LESS: return value < bound; break; + case LESS_EQUAL: return value <= bound; break; + case GREATER: return value > bound; break; + case GREATER_EQUAL: return value >= bound; break; + default: return false; + } + } + +private: + storm::property::ComparisonType comparisonOperator; + T bound; + AbstractPathFormula<T>* pathFormula; }; } //namespace prctl diff --git a/src/formula/Prctl/RewardNoBoundOperator.h b/src/formula/Prctl/RewardNoBoundOperator.h deleted file mode 100644 index 97a8dfeaa..000000000 --- a/src/formula/Prctl/RewardNoBoundOperator.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * RewardNoBoundOperator.h - * - * Created on: 25.12.2012 - * Author: Christian Dehnert - */ - -#ifndef STORM_FORMULA_PRCTL_REWARDNOBOUNDOPERATOR_H_ -#define STORM_FORMULA_PRCTL_REWARDNOBOUNDOPERATOR_H_ - -#include "AbstractNoBoundOperator.h" -#include "AbstractPathFormula.h" -#include "src/formula/abstract/RewardNoBoundOperator.h" - -namespace storm { -namespace property { -namespace prctl { - -/*! - * @brief - * Class for an abstract formula tree with a R (reward) operator without declaration of reward values - * as root. - * - * Checking a formula with this operator as root returns the reward for the reward path formula for - * each state - * - * Has one Abstract path formula as sub formula/tree. - * - * @note - * This class is a hybrid of a state and path formula, and may only appear as the outermost operator. - * Hence, it is seen as neither a state nor a path formula, but is directly derived from AbstractFormula. - * - * @note - * This class does not contain a check() method like the other formula classes. - * The check method should only be called by the model checker to infer the correct check function for sub - * formulas. As this operator can only appear at the root, the method is not useful here. - * Use the checkRewardNoBoundOperator method from the DtmcPrctlModelChecker class instead. - * - * The subtree is seen as part of the object and deleted with it - * (this behavior can be prevented by setting them to NULL before deletion) - * - * - * @see AbstractStateFormula - * @see AbstractPathFormula - * @see ProbabilisticOperator - * @see ProbabilisticIntervalOperator - * @see AbstractPrctlFormula - */ -template <class T> -class RewardNoBoundOperator: public storm::property::abstract::RewardNoBoundOperator<T, AbstractPathFormula<T>>, - public storm::property::prctl::AbstractNoBoundOperator<T> { -public: - /*! - * Empty constructor - */ - RewardNoBoundOperator() { - // Intentionally left empty - } - - /*! - * Constructor - * - * @param pathFormula The child node. - */ - RewardNoBoundOperator(AbstractPathFormula<T>* pathFormula) - : storm::property::abstract::RewardNoBoundOperator<T, AbstractPathFormula<T>>(pathFormula) { - // Intentionally left empty - } - - /*! - * Constructor - * - * @param pathFormula The child node. - */ - RewardNoBoundOperator(AbstractPathFormula<T>* pathFormula, bool minimumOperator) - : storm::property::abstract::RewardNoBoundOperator<T, AbstractPathFormula<T>>(pathFormula, minimumOperator) { - // Intentionally left empty - } - - virtual AbstractNoBoundOperator<T>* clone() const override { - RewardNoBoundOperator<T>* result = new RewardNoBoundOperator<T>(); - if (this->pathFormulaIsSet()) { - result->setPathFormula(this->getPathFormula().clone()); - } - return result; - } - - /*! - * Calls the model checker to check this formula. - * Needed to infer the correct type of formula class. - * - * @note This function should only be called in a generic check function of a model checker class. For other uses, - * the methods of the model checker should be used. - * - * @note This function is not implemented in this class. - * - * @returns A vector indicating the probability that the formula holds for each state. - */ - virtual std::vector<T> check(const storm::modelchecker::prctl::AbstractModelChecker<T>& modelChecker, bool qualitative=false) const override { - return this->getPathFormula().check(modelChecker, qualitative); - } -}; - -} //namespace prctl -} //namespace property -} //namespace storm - -#endif /* STORM_FORMULA_PRCTL_REWARDNOBOUNDOPERATOR_H_ */ diff --git a/src/formula/Prctl/SteadyStateReward.h b/src/formula/Prctl/SteadyStateReward.h index f7c87e90d..f850988fa 100644 --- a/src/formula/Prctl/SteadyStateReward.h +++ b/src/formula/Prctl/SteadyStateReward.h @@ -10,7 +10,6 @@ #include "AbstractPathFormula.h" #include "AbstractStateFormula.h" -#include "src/formula/abstract/SteadyStateReward.h" #include "src/formula/AbstractFormulaChecker.h" #include <string> @@ -46,8 +45,7 @@ class ISteadyStateRewardModelChecker { * @see AbstractPrctlFormula */ template <class T> -class SteadyStateReward: public storm::property::abstract::SteadyStateReward<T>, - public AbstractPathFormula<T> { +class SteadyStateReward: public AbstractPathFormula<T> { public: /*! * Empty constructor @@ -83,6 +81,25 @@ public: virtual std::vector<T> check(const storm::modelchecker::prctl::AbstractModelChecker<T>& modelChecker, bool qualitative) const override { return modelChecker.template as<ISteadyStateRewardModelChecker>()->checkSteadyStateReward(*this, qualitative); } + + /*! + * @returns a string representation of the formula + */ + virtual std::string toString() const override { + return "S"; + } + + /*! + * @brief Checks if all subtrees conform to some logic. + * + * As SteadyStateReward objects have no subformulas, we return true here. + * + * @param checker Formula checker object. + * @return true + */ + virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + return true; + } }; } //namespace prctl diff --git a/src/formula/Prctl/Until.h b/src/formula/Prctl/Until.h index 53fb92f6b..1bca7037b 100644 --- a/src/formula/Prctl/Until.h +++ b/src/formula/Prctl/Until.h @@ -10,7 +10,6 @@ #include "AbstractPathFormula.h" #include "AbstractStateFormula.h" -#include "src/formula/abstract/Until.h" #include "src/formula/AbstractFormulaChecker.h" namespace storm { @@ -54,15 +53,15 @@ class IUntilModelChecker { * @see AbstractPrctlFormula */ template <class T> -class Until : public storm::property::abstract::Until<T, AbstractStateFormula<T>>, - public AbstractPathFormula<T> { +class Until : public AbstractPathFormula<T> { public: + /*! * Empty constructor */ - Until() { - // Intentionally left empty + Until() : left(nullptr), right(nullptr){ + // Intentionally left empty. } /*! @@ -71,9 +70,8 @@ public: * @param left The left formula subtree * @param right The left formula subtree */ - Until(AbstractStateFormula<T>* left, AbstractStateFormula<T>* right) - : storm::property::abstract::Until<T, AbstractStateFormula<T>>(left, right) { - // Intentionally left empty + Until(AbstractStateFormula<T>* left, AbstractStateFormula<T>* right) : left(left), right(right){ + // Intentionally left empty. } /*! @@ -83,7 +81,12 @@ public: * (this behaviour can be prevented by setting the subtrees to NULL before deletion) */ virtual ~Until() { - // Intentionally left empty + if (left != NULL) { + delete left; + } + if (right != NULL) { + delete right; + } } /*! @@ -116,6 +119,78 @@ public: virtual std::vector<T> check(const storm::modelchecker::prctl::AbstractModelChecker<T>& modelChecker, bool qualitative) const override { return modelChecker.template as<IUntilModelChecker>()->checkUntil(*this, qualitative); } + + /*! + * @returns a string representation of the formula + */ + virtual std::string toString() const override { + std::string result = left->toString(); + result += " U "; + result += right->toString(); + return result; + } + + /*! + * @brief Checks if all subtrees conform to some logic. + * + * @param checker Formula checker object. + * @return true iff all subtrees conform to some logic. + */ + virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + return checker.validate(this->left) && checker.validate(this->right); + } + + /*! + * Sets the left child node. + * + * @param newLeft the new left child. + */ + void setLeft(AbstractStateFormula<T>* newLeft) { + left = newLeft; + } + + /*! + * Sets the right child node. + * + * @param newRight the new right child. + */ + void setRight(AbstractStateFormula<T>* newRight) { + right = newRight; + } + + /*! + * @returns a pointer to the left child node + */ + const AbstractStateFormula<T>& getLeft() const { + return *left; + } + + /*! + * @returns a pointer to the right child node + */ + const AbstractStateFormula<T>& getRight() const { + return *right; + } + + /*! + * + * @return True if the left child is set, i.e. it does not point to nullptr; false otherwise + */ + bool leftIsSet() const { + return left != nullptr; + } + + /*! + * + * @return True if the right child is set, i.e. it does not point to nullptr; false otherwise + */ + bool rightIsSet() const { + return right != nullptr; + } + +private: + AbstractStateFormula<T>* left; + AbstractStateFormula<T>* right; }; } //namespace prctl diff --git a/src/modelchecker/prctl/AbstractModelChecker.h b/src/modelchecker/prctl/AbstractModelChecker.h index 5862fe9c9..888721a56 100644 --- a/src/modelchecker/prctl/AbstractModelChecker.h +++ b/src/modelchecker/prctl/AbstractModelChecker.h @@ -56,7 +56,6 @@ class AbstractModelChecker : public virtual storm::property::prctl::INextModelChecker<Type>, public virtual storm::property::prctl::IBoundedUntilModelChecker<Type>, public virtual storm::property::prctl::IBoundedEventuallyModelChecker<Type>, - public virtual storm::property::prctl::INoBoundOperatorModelChecker<Type>, public virtual storm::property::prctl::IProbabilisticBoundOperatorModelChecker<Type>, public virtual storm::property::prctl::IRewardBoundOperatorModelChecker<Type>, public virtual storm::property::prctl::IReachabilityRewardModelChecker<Type>, From 6025dce14440191483d87b4d98d608af5dbd5787 Mon Sep 17 00:00:00 2001 From: masawei <manuel.sascha.weiand@rwth-aachen.de> Date: Wed, 16 Apr 2014 23:44:14 +0200 Subject: [PATCH 03/30] Further work on the formuolas. - Finished the third and last logic: Csl. - Note that nothing compiles as of yet. This is due to the removal of the NoBoundOperators wich are expected to be replaced by filters. Former-commit-id: d26ae768f753bde3bc71b79472e821905673e62d --- src/formula/Csl.h | 2 - src/formula/Csl/AbstractCslFormula.h | 4 +- src/formula/Csl/AbstractNoBoundOperator.h | 83 ---------- src/formula/Csl/AbstractPathFormula.h | 4 +- src/formula/Csl/AbstractStateFormula.h | 12 +- src/formula/Csl/And.h | 96 +++++++++++- src/formula/Csl/Ap.h | 42 +++++- src/formula/Csl/Eventually.h | 63 ++++++-- src/formula/Csl/Globally.h | 68 +++++++-- src/formula/Csl/Next.h | 71 +++++++-- src/formula/Csl/Not.h | 63 ++++++-- src/formula/Csl/Or.h | 140 +++++++++++++---- src/formula/Csl/ProbabilisticBoundOperator.h | 136 ++++++++++++++--- .../Csl/ProbabilisticNoBoundOperator.h | 115 -------------- src/formula/Csl/SteadyStateBoundOperator.h | 121 +++++++++++++-- src/formula/Csl/SteadyStateNoBoundOperator.h | 100 ------------ src/formula/Csl/TimeBoundedEventually.h | 111 ++++++++++++-- src/formula/Csl/TimeBoundedUntil.h | 142 ++++++++++++++++-- src/formula/Csl/Until.h | 96 ++++++++++-- src/formula/Prctl/AbstractStateFormula.h | 2 +- src/formula/Prctl/Globally.h | 5 +- src/formula/Prctl/Next.h | 4 +- src/formula/Prctl/Not.h | 1 + src/formula/Prctl/Or.h | 5 +- src/modelchecker/csl/AbstractModelChecker.h | 1 - 25 files changed, 1011 insertions(+), 476 deletions(-) delete mode 100644 src/formula/Csl/AbstractNoBoundOperator.h delete mode 100644 src/formula/Csl/ProbabilisticNoBoundOperator.h delete mode 100644 src/formula/Csl/SteadyStateNoBoundOperator.h diff --git a/src/formula/Csl.h b/src/formula/Csl.h index a6a6c4e67..8e856f459 100644 --- a/src/formula/Csl.h +++ b/src/formula/Csl.h @@ -15,9 +15,7 @@ #include "Csl/Next.h" #include "Csl/Not.h" #include "Csl/Or.h" -#include "Csl/ProbabilisticNoBoundOperator.h" #include "Csl/ProbabilisticBoundOperator.h" -#include "Csl/SteadyStateNoBoundOperator.h" #include "Csl/SteadyStateBoundOperator.h" #include "Csl/Until.h" diff --git a/src/formula/Csl/AbstractCslFormula.h b/src/formula/Csl/AbstractCslFormula.h index 1c8503180..7de783d96 100644 --- a/src/formula/Csl/AbstractCslFormula.h +++ b/src/formula/Csl/AbstractCslFormula.h @@ -8,7 +8,7 @@ #ifndef ABSTRACTCSLFORMULA_H_ #define ABSTRACTCSLFORMULA_H_ -#include "src/formula/abstract/AbstractFormula.h" +#include "src/formula/AbstractFormula.h" namespace storm { namespace property { @@ -18,7 +18,7 @@ namespace csl { * Abstract base class for all CSL root formulas. */ template <class T> -class AbstractCslFormula : public virtual storm::property::abstract::AbstractFormula<T>{ +class AbstractCslFormula : public virtual storm::property::AbstractFormula<T>{ public: virtual ~AbstractCslFormula() { // Intentionally left empty diff --git a/src/formula/Csl/AbstractNoBoundOperator.h b/src/formula/Csl/AbstractNoBoundOperator.h deleted file mode 100644 index 9960e8de2..000000000 --- a/src/formula/Csl/AbstractNoBoundOperator.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * AbstractNoBoundOperator.h - * - * Created on: 16.04.2013 - * Author: thomas - */ - -#ifndef STORM_FORMULA_CSL_ABSTRACTNOBOUNDOPERATOR_H_ -#define STORM_FORMULA_CSL_ABSTRACTNOBOUNDOPERATOR_H_ - -#include "AbstractCslFormula.h" -#include "src/formula/abstract/IOptimizingOperator.h" - -namespace storm { -namespace property { -namespace csl { - -template <class T> -class AbstractNoBoundOperator; - -/*! - * @brief Interface class for model checkers that support PathNoBoundOperator. - * - * All model checkers that support the formula class NoBoundOperator must inherit - * this pure virtual class. - */ -template <class T> -class INoBoundOperatorModelChecker { -public: - /*! - * @brief Evaluates NoBoundOperator formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual std::vector<T> checkNoBoundOperator(const AbstractNoBoundOperator<T>& obj) const = 0; - - -}; - -/*! - * Interface class for all CSL No Bound operators. - */ -template <class T> -class AbstractNoBoundOperator: public AbstractCslFormula<T>, - public virtual storm::property::abstract::IOptimizingOperator { -public: - AbstractNoBoundOperator() { - // Intentionally left empty - - } - virtual ~AbstractNoBoundOperator() { - // Intentionally left empty - } - - /*! - * Clones the called object. - * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones - * - * @note This function is not implemented in this class. - * @returns a new AND-object that is identical the called object. - */ - virtual AbstractNoBoundOperator<T>* clone() const = 0; - - /*! - * Calls the model checker to check this formula. - * Needed to infer the correct type of formula class. - * - * @note This function should only be called in a generic check function of a model checker class. For other uses, - * the methods of the model checker should be used. - * - * @note This function is not implemented in this class. - * - * @returns A vector indicating the probability that the formula holds for each state. - */ - virtual std::vector<T> check(const storm::modelchecker::csl::AbstractModelChecker<T>& modelChecker, bool qualitative=false) const = 0; -}; - -} /* namespace csl */ -} /* namespace property */ -} /* namespace storm */ -#endif /* STORM_FORMULA_CSL_ABSTRACTNOBOUNDOPERATOR_H_ */ diff --git a/src/formula/Csl/AbstractPathFormula.h b/src/formula/Csl/AbstractPathFormula.h index a61cab96f..951bc6f41 100644 --- a/src/formula/Csl/AbstractPathFormula.h +++ b/src/formula/Csl/AbstractPathFormula.h @@ -16,7 +16,7 @@ template<class T> class AbstractPathFormula; } //namespace property } //namespace storm -#include "src/formula/abstract/AbstractFormula.h" +#include "src/formula/Csl/AbstractCslFormula.h" #include "src/modelchecker/csl/ForwardDeclarations.h" #include <vector> @@ -40,7 +40,7 @@ namespace csl { * This class is intentionally not derived from AbstractCslFormula, as a path formula is not a complete CSL formula. */ template <class T> -class AbstractPathFormula : public virtual storm::property::abstract::AbstractFormula<T> { +class AbstractPathFormula : public virtual storm::property::csl::AbstractCslFormula<T> { public: /*! diff --git a/src/formula/Csl/AbstractStateFormula.h b/src/formula/Csl/AbstractStateFormula.h index c54d318d5..2bd16471b 100644 --- a/src/formula/Csl/AbstractStateFormula.h +++ b/src/formula/Csl/AbstractStateFormula.h @@ -8,15 +8,7 @@ #ifndef STORM_FORMULA_CSL_ABSTRACTSTATEFORMULA_H_ #define STORM_FORMULA_CSL_ABSTRACTSTATEFORMULA_H_ -namespace storm { -namespace property { -namespace csl { -template<class T> class AbstractStateFormula; -} -} -} - -#include "AbstractCslFormula.h" +#include "src/formula/Csl/AbstractCslFormula.h" #include "src/storage/BitVector.h" #include "src/modelchecker/csl/ForwardDeclarations.h" @@ -34,7 +26,7 @@ namespace csl { * clone(). */ template <class T> -class AbstractStateFormula : public AbstractCslFormula<T> { +class AbstractStateFormula : public storm::property::csl::AbstractCslFormula<T> { public: /*! diff --git a/src/formula/Csl/And.h b/src/formula/Csl/And.h index efed92f17..1453cc30b 100644 --- a/src/formula/Csl/And.h +++ b/src/formula/Csl/And.h @@ -8,8 +8,7 @@ #ifndef STORM_FORMULA_CSL_AND_H_ #define STORM_FORMULA_CSL_AND_H_ -#include "AbstractStateFormula.h" -#include "src/formula/abstract/And.h" +#include "src/formula/Csl/AbstractStateFormula.h" #include "src/formula/AbstractFormulaChecker.h" #include "src/modelchecker/csl/ForwardDeclarations.h" #include <string> @@ -54,15 +53,17 @@ class IAndModelChecker { * @see AbstractCslFormula */ template <class T> -class And : public storm::property::abstract::And<T, AbstractStateFormula<T>>, public AbstractStateFormula<T> { +class And : public AbstractStateFormula<T> { public: + /*! * Empty constructor. * Will create an AND-node without subnotes. Will not represent a complete formula! */ And() { - //intentionally left empty + left = NULL; + right = NULL; } /*! @@ -72,9 +73,9 @@ public: * @param left The left sub formula * @param right The right sub formula */ - And(AbstractStateFormula<T>* left, AbstractStateFormula<T>* right) - : storm::property::abstract::And<T, AbstractStateFormula<T>>(left, right) { - //intentionally left empty + And(AbstractStateFormula<T>* left, AbstractStateFormula<T>* right) { + this->left = left; + this->right = right; } /*! @@ -84,7 +85,12 @@ public: * (this behavior can be prevented by setting them to NULL before deletion) */ virtual ~And() { - //intentionally left empty + if (left != NULL) { + delete left; + } + if (right != NULL) { + delete right; + } } /*! @@ -118,6 +124,80 @@ public: return modelChecker.template as<IAndModelChecker>()->checkAnd(*this); } + /*! + * @returns a string representation of the formula + */ + virtual std::string toString() const override { + std::string result = "("; + result += left->toString(); + result += " & "; + result += right->toString(); + result += ")"; + return result; + } + + /*! + * @brief Checks if all subtrees conform to some logic. + * + * @param checker Formula checker object. + * @return true iff all subtrees conform to some logic. + */ + virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + return checker.validate(this->left) && checker.validate(this->right); + } + + /*! + * Sets the left child node. + * + * @param newLeft the new left child. + */ + void setLeft(AbstractStateFormula<T>* newLeft) { + left = newLeft; + } + + /*! + * Sets the right child node. + * + * @param newRight the new right child. + */ + void setRight(AbstractStateFormula<T>* newRight) { + right = newRight; + } + + /*! + * @returns a pointer to the left child node + */ + const AbstractStateFormula<T>& getLeft() const { + return *left; + } + + /*! + * @returns a pointer to the right child node + */ + const AbstractStateFormula<T>& getRight() const { + return *right; + } + + /*! + * + * @return True if the left child is set, i.e. it does not point to nullptr; false otherwise + */ + bool leftIsSet() const { + return left != nullptr; + } + + /*! + * + * @return True if the right child is set, i.e. it does not point to nullptr; false otherwise + */ + bool rightIsSet() const { + return right != nullptr; + } + +private: + AbstractStateFormula<T>* left; + AbstractStateFormula<T>* right; + }; } //namespace csl diff --git a/src/formula/Csl/Ap.h b/src/formula/Csl/Ap.h index cebd9aa49..66f49c503 100644 --- a/src/formula/Csl/Ap.h +++ b/src/formula/Csl/Ap.h @@ -8,8 +8,7 @@ #ifndef STORM_FORMULA_CSL_AP_H_ #define STORM_FORMULA_CSL_AP_H_ -#include "AbstractStateFormula.h" -#include "src/formula/abstract/Ap.h" +#include "src/formula/Csl/AbstractStateFormula.h" #include "src/formula/AbstractFormulaChecker.h" #include "src/modelchecker/csl/ForwardDeclarations.h" @@ -47,10 +46,10 @@ class IApModelChecker { * @see AbstractStateFormula */ template <class T> -class Ap : public storm::property::abstract::Ap<T>, - public AbstractStateFormula<T> { +class Ap : public AbstractStateFormula<T> { public: + /*! * Constructor * @@ -58,9 +57,8 @@ public: * * @param ap The string representing the atomic proposition */ - Ap(std::string ap) - : storm::property::abstract::Ap<T>(ap) { - // Intentionally left empty + Ap(std::string ap) { + this->ap = ap; } /*! @@ -95,6 +93,36 @@ public: return modelChecker.template as<IApModelChecker>()->checkAp(*this); } + /*! + * @brief Checks if all subtrees conform to some logic. + * + * As atomic propositions have no subformulas, we return true here. + * + * @param checker Formula checker object. + * @return true + */ + virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + return true; + } + + /*! + * @returns the name of the atomic proposition + */ + const std::string& getAp() const { + return ap; + } + + /*! + * @returns a string representation of the leaf. + * + */ + virtual std::string toString() const override { + return getAp(); + } + +private: + std::string ap; + }; } //namespace abstract diff --git a/src/formula/Csl/Eventually.h b/src/formula/Csl/Eventually.h index 5553d16c7..1d1f1a358 100644 --- a/src/formula/Csl/Eventually.h +++ b/src/formula/Csl/Eventually.h @@ -8,7 +8,6 @@ #ifndef STORM_FORMULA_CSL_EVENTUALLY_H_ #define STORM_FORMULA_CSL_EVENTUALLY_H_ -#include "src/formula/abstract/Eventually.h" #include "src/formula/Csl/AbstractPathFormula.h" #include "src/formula/Csl/AbstractStateFormula.h" #include "src/modelchecker/csl/ForwardDeclarations.h" @@ -53,15 +52,15 @@ class IEventuallyModelChecker { * @see AbstractCslFormula */ template <class T> -class Eventually : public storm::property::abstract::Eventually<T, AbstractStateFormula<T>>, - public AbstractPathFormula<T> { +class Eventually : public AbstractPathFormula<T> { public: + /*! * Empty constructor */ - Eventually() { - // Intentionally left empty + Eventually() : child(nullptr) { + // Intentionally left empty. } /*! @@ -69,9 +68,8 @@ public: * * @param child The child node */ - Eventually(AbstractStateFormula<T>* child) - : storm::property::abstract::Eventually<T, AbstractStateFormula<T>>(child) { - + Eventually(AbstractStateFormula<T>* child) : child(child){ + // Intentionally left empty. } /*! @@ -81,7 +79,9 @@ public: * (this behaviour can be prevented by setting the subtrees to nullptr before deletion) */ virtual ~Eventually() { - //intentionally left empty + if (child != nullptr) { + delete child; + } } /*! @@ -111,6 +111,51 @@ public: virtual std::vector<T> check(const storm::modelchecker::csl::AbstractModelChecker<T>& modelChecker, bool qualitative) const override { return modelChecker.template as<IEventuallyModelChecker>()->checkEventually(*this, qualitative); } + + /*! + * @returns a string representation of the formula + */ + virtual std::string toString() const override { + std::string result = "F "; + result += child->toString(); + return result; + } + + /*! + * @brief Checks if the subtree conforms to some logic. + * + * @param checker Formula checker object. + * @return true iff the subtree conforms to some logic. + */ + virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + return checker.validate(this->child); + } + + /*! + * @returns the child node + */ + const AbstractStateFormula<T>& getChild() const { + return *child; + } + + /*! + * Sets the subtree + * @param child the new child node + */ + void setChild(AbstractStateFormula<T>* child) { + this->child = child; + } + + /*! + * + * @return True if the child node is set, i.e. it does not point to nullptr; false otherwise + */ + bool childIsSet() const { + return child != nullptr; + } + +private: + AbstractStateFormula<T>* child; }; } //namespace csl diff --git a/src/formula/Csl/Globally.h b/src/formula/Csl/Globally.h index 954b59fd4..85cd32396 100644 --- a/src/formula/Csl/Globally.h +++ b/src/formula/Csl/Globally.h @@ -8,9 +8,8 @@ #ifndef STORM_FORMULA_CSL_GLOBALLY_H_ #define STORM_FORMULA_CSL_GLOBALLY_H_ -#include "src/formula/abstract/Globally.h" -#include "AbstractPathFormula.h" -#include "AbstractStateFormula.h" +#include "src/formula/Csl/AbstractPathFormula.h" +#include "src/formula/Csl/AbstractStateFormula.h" #include "src/formula/AbstractFormulaChecker.h" #include "src/modelchecker/csl/ForwardDeclarations.h" @@ -54,15 +53,15 @@ class IGloballyModelChecker { * @see AbstractCslFormula */ template <class T> -class Globally : public storm::property::abstract::Globally<T, AbstractStateFormula<T>>, - public AbstractPathFormula<T> { +class Globally : public AbstractPathFormula<T> { public: + /*! * Empty constructor */ - Globally() { - //intentionally left empty + Globally() : child(nullptr){ + // Intentionally left empty. } /*! @@ -70,9 +69,8 @@ public: * * @param child The child node */ - Globally(AbstractStateFormula<T>* child) - : storm::property::abstract::Globally<T, AbstractStateFormula<T>>(child) { - //intentionally left empty + Globally(AbstractStateFormula<T>* child) : child(child){ + // Intentionally left empty. } /*! @@ -82,10 +80,11 @@ public: * (this behaviour can be prevented by setting the subtrees to nullptr before deletion) */ virtual ~Globally() { - //intentionally left empty + if (child != nullptr) { + delete child; + } } - /*! * Clones the called object. * @@ -113,6 +112,51 @@ public: virtual std::vector<T> check(const storm::modelchecker::csl::AbstractModelChecker<T>& modelChecker, bool qualitative) const override { return modelChecker.template as<IGloballyModelChecker>()->checkGlobally(*this, qualitative); } + + /*! + * @returns a string representation of the formula + */ + virtual std::string toString() const override { + std::string result = "G "; + result += child->toString(); + return result; + } + + /*! + * @brief Checks if the subtree conforms to some logic. + * + * @param checker Formula checker object. + * @return true iff the subtree conforms to some logic. + */ + virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + return checker.validate(this->child); + } + + /*! + * @returns the child node + */ + const AbstractStateFormula<T>& getChild() const { + return *child; + } + + /*! + * Sets the subtree + * @param child the new child node + */ + void setChild(AbstractStateFormula<T>* child) { + this->child = child; + } + + /*! + * + * @return True if the child node is set, i.e. it does not point to nullptr; false otherwise + */ + bool childIsSet() const { + return child != nullptr; + } + +private: + AbstractStateFormula<T>* child; }; } //namespace csl diff --git a/src/formula/Csl/Next.h b/src/formula/Csl/Next.h index 338d119e5..f014190aa 100644 --- a/src/formula/Csl/Next.h +++ b/src/formula/Csl/Next.h @@ -8,9 +8,8 @@ #ifndef STORM_FORMULA_CSL_NEXT_H_ #define STORM_FORMULA_CSL_NEXT_H_ -#include "AbstractPathFormula.h" -#include "AbstractStateFormula.h" -#include "src/formula/abstract/Next.h" +#include "src/formula/Csl/AbstractPathFormula.h" +#include "src/formula/Csl/AbstractStateFormula.h" #include "src/formula/AbstractFormulaChecker.h" namespace storm { @@ -53,15 +52,15 @@ class INextModelChecker { * @see AbstractCslFormula */ template <class T> -class Next : public storm::property::abstract::Next<T, AbstractStateFormula<T>>, - public AbstractPathFormula<T> { +class Next : public AbstractPathFormula<T> { public: + /*! * Empty constructor */ - Next() { - //intentionally left empty + Next() : child(nullptr){ + // Intentionally left empty. } /*! @@ -69,19 +68,20 @@ public: * * @param child The child node */ - Next(AbstractStateFormula<T>* child) - : storm::property::abstract::Next<T, AbstractStateFormula<T>>(child) { - //intentionally left empty + Next(AbstractStateFormula<T>* child) : child(child){ + // Intentionally left empty. } /*! * Constructor. * * Also deletes the subtree. - * (this behaviour can be prevented by setting the subtrees to NULL before deletion) + * (this behavior can be prevented by setting the subtrees to NULL before deletion) */ virtual ~Next() { - //intentionally left empty + if (child != NULL) { + delete child; + } } /*! @@ -111,6 +111,53 @@ public: virtual std::vector<T> check(const storm::modelchecker::csl::AbstractModelChecker<T>& modelChecker, bool qualitative) const override { return modelChecker.template as<INextModelChecker>()->checkNext(*this, qualitative); } + + /*! + * @returns a string representation of the formula + */ + virtual std::string toString() const override { + std::string result = "("; + result += " X "; + result += child->toString(); + result += ")"; + return result; + } + + /*! + * @brief Checks if the subtree conforms to some logic. + * + * @param checker Formula checker object. + * @return true iff the subtree conforms to some logic. + */ + virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + return checker.validate(this->child); + } + + /*! + * @returns the child node + */ + const AbstractStateFormula<T>& getChild() const { + return *child; + } + + /*! + * Sets the subtree + * @param child the new child node + */ + void setChild(AbstractStateFormula<T>* child) { + this->child = child; + } + + /*! + * + * @return True if the child node is set, i.e. it does not point to nullptr; false otherwise + */ + bool childIsSet() const { + return child != nullptr; + } + +private: + AbstractStateFormula<T>* child; }; } //namespace csl diff --git a/src/formula/Csl/Not.h b/src/formula/Csl/Not.h index dd0c2a705..58ca37299 100644 --- a/src/formula/Csl/Not.h +++ b/src/formula/Csl/Not.h @@ -8,8 +8,7 @@ #ifndef STORM_FORMULA_CSL_NOT_H_ #define STORM_FORMULA_CSL_NOT_H_ -#include "AbstractStateFormula.h" -#include "src/formula/abstract/Not.h" +#include "src/formula/Csl/AbstractStateFormula.h" #include "src/formula/AbstractFormulaChecker.h" #include "src/modelchecker/csl/ForwardDeclarations.h" @@ -50,24 +49,23 @@ class INotModelChecker { * @see AbstractCslFormula */ template <class T> -class Not : public storm::property::abstract::Not<T, AbstractStateFormula<T>>, - public AbstractStateFormula<T> { +class Not : public AbstractStateFormula<T> { public: + /*! * Empty constructor */ Not() { - //intentionally left empty + this->child = NULL; } /*! * Constructor * @param child The child node */ - Not(AbstractStateFormula<T>* child) : - storm::property::abstract::Not<T, AbstractStateFormula<T>>(child){ - //intentionally left empty + Not(AbstractStateFormula<T>* child) { + this->child = child; } /*! @@ -77,7 +75,9 @@ public: * (this behavior can be prevented by setting them to NULL before deletion) */ virtual ~Not() { - //intentionally left empty + if (child != NULL) { + delete child; + } } /*! @@ -107,6 +107,51 @@ public: virtual storm::storage::BitVector check(const storm::modelchecker::csl::AbstractModelChecker<T>& modelChecker) const override { return modelChecker.template as<INotModelChecker>()->checkNot(*this); } + + /*! + * @returns a string representation of the formula + */ + virtual std::string toString() const override { + std::string result = "!"; + result += child->toString(); + return result; + } + + /*! + * @brief Checks if the subtree conforms to some logic. + * + * @param checker Formula checker object. + * @return true iff the subtree conforms to some logic. + */ + virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + return checker.validate(this->child); + } + + /*! + * @returns The child node + */ + const AbstractStateFormula<T>& getChild() const { + return *child; + } + + /*! + * Sets the subtree + * @param child the new child node + */ + void setChild(AbstractStateFormula<T>* child) { + this->child = child; + } + + /*! + * + * @return True if the child node is set, i.e. it does not point to nullptr; false otherwise + */ + bool childIsSet() const { + return child != nullptr; + } + +private: + AbstractStateFormula<T>* child; }; } //namespace csl diff --git a/src/formula/Csl/Or.h b/src/formula/Csl/Or.h index 29add98cc..9533b873a 100644 --- a/src/formula/Csl/Or.h +++ b/src/formula/Csl/Or.h @@ -8,8 +8,7 @@ #ifndef STORM_FORMULA_CSL_OR_H_ #define STORM_FORMULA_CSL_OR_H_ -#include "AbstractStateFormula.h" -#include "src/formula/abstract/Or.h" +#include "src/formula/Csl/AbstractStateFormula.h" #include "src/formula/AbstractFormulaChecker.h" namespace storm { @@ -52,39 +51,45 @@ class IOrModelChecker { * @see AbstractCslFormula */ template <class T> -class Or : public storm::property::abstract::Or<T, AbstractStateFormula<T>>, - public AbstractStateFormula<T> { +class Or : public AbstractStateFormula<T> { public: - /*! - * Empty constructor. - * Will create an OR-node without subnotes. The result does not represent a complete formula! - */ - Or() { - //intentionally left empty - } /*! - * Constructor. - * Creates an OR note with the parameters as subtrees. - * - * @param left The left sub formula - * @param right The right sub formula - */ - Or(AbstractStateFormula<T>* left, AbstractStateFormula<T>* right) : - storm::property::abstract::Or<T, AbstractStateFormula<T>>(left, right) { - //intentionally left empty - } + * Empty constructor. + * Will create an OR-node without subnotes. Will not represent a complete formula! + */ + Or() { + left = NULL; + right = NULL; + } - /*! - * Destructor. - * - * The subtrees are deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - */ - virtual ~Or() { - //intentionally left empty - } + /*! + * Constructor. + * Creates an OR note with the parameters as subtrees. + * + * @param left The left sub formula + * @param right The right sub formula + */ + Or(AbstractStateFormula<T>* left, AbstractStateFormula<T>* right) { + this->left = left; + this->right = right; + } + + /*! + * Destructor. + * + * The subtrees are deleted with the object + * (this behavior can be prevented by setting them to NULL before deletion) + */ + virtual ~Or() { + if (left != NULL) { + delete left; + } + if (right != NULL) { + delete right; + } + } /*! * Clones the called object. @@ -116,6 +121,81 @@ public: virtual storm::storage::BitVector check(const storm::modelchecker::csl::AbstractModelChecker<T>& modelChecker) const override { return modelChecker.template as<IOrModelChecker>()->checkOr(*this); } + + /*! + * @returns a string representation of the formula + */ + virtual std::string toString() const override { + std::string result = "("; + result += left->toString(); + result += " | "; + result += right->toString(); + result += ")"; + return result; + } + + /*! + * @brief Checks if all subtrees conform to some logic. + * + * @param checker Formula checker object. + * @return true iff all subtrees conform to some logic. + */ + virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + return checker.validate(this->left) && checker.validate(this->right); + } + + /*! + * Sets the left child node. + * + * @param newLeft the new left child. + */ + void setLeft(AbstractStateFormula<T>* newLeft) { + left = newLeft; + } + + /*! + * Sets the right child node. + * + * @param newRight the new right child. + */ + void setRight(AbstractStateFormula<T>* newRight) { + right = newRight; + } + + /*! + * @returns a pointer to the left child node + */ + const AbstractStateFormula<T>& getLeft() const { + return *left; + } + + /*! + * @returns a pointer to the right child node + */ + const AbstractStateFormula<T>& getRight() const { + return *right; + } + + /*! + * + * @return True if the left child is set, i.e. it does not point to nullptr; false otherwise + */ + bool leftIsSet() const { + return left != nullptr; + } + + /*! + * + * @return True if the right child is set, i.e. it does not point to nullptr; false otherwise + */ + bool rightIsSet() const { + return right != nullptr; + } + +private: + AbstractStateFormula<T>* left; + AbstractStateFormula<T>* right; + }; } //namespace csl diff --git a/src/formula/Csl/ProbabilisticBoundOperator.h b/src/formula/Csl/ProbabilisticBoundOperator.h index 28937fab4..4b4e5d937 100644 --- a/src/formula/Csl/ProbabilisticBoundOperator.h +++ b/src/formula/Csl/ProbabilisticBoundOperator.h @@ -8,9 +8,9 @@ #ifndef STORM_FORMULA_CSL_PROBABILISTICBOUNDOPERATOR_H_ #define STORM_FORMULA_CSL_PROBABILISTICBOUNDOPERATOR_H_ -#include "AbstractStateFormula.h" -#include "AbstractPathFormula.h" -#include "src/formula/abstract/ProbabilisticBoundOperator.h" +#include "src/formula/Csl/AbstractStateFormula.h" +#include "src/formula/Csl/AbstractPathFormula.h" +#include "src/formula/ComparisonType.h" #include "utility/constants.h" namespace storm { @@ -53,36 +53,39 @@ class IProbabilisticBoundOperatorModelChecker { * @see AbstractCslFormula */ template<class T> -class ProbabilisticBoundOperator : public storm::property::abstract::ProbabilisticBoundOperator<T, AbstractPathFormula<T>>, - public AbstractStateFormula<T> { +class ProbabilisticBoundOperator : public AbstractStateFormula<T> { public: + /*! * Empty constructor */ - ProbabilisticBoundOperator() : storm::property::abstract::ProbabilisticBoundOperator<T, AbstractPathFormula<T>> - (LESS_EQUAL, storm::utility::constantZero<T>(), nullptr) { - // Intentionally left empty + ProbabilisticBoundOperator() : comparisonOperator(LESS), bound(0), pathFormula(nullptr) { + // Intentionally left empty. } - /*! - * Constructor + * Constructor for non-optimizing operator. * - * @param comparisonRelation The relation to compare the actual value and the bound + * @param comparisonOperator The relation for the bound. * @param bound The bound for the probability * @param pathFormula The child node */ - ProbabilisticBoundOperator( - storm::property::ComparisonType comparisonRelation, T bound, AbstractPathFormula<T>* pathFormula) - : storm::property::abstract::ProbabilisticBoundOperator<T, AbstractPathFormula<T>>(comparisonRelation, bound, pathFormula) { - // Intentionally left empty + ProbabilisticBoundOperator(storm::property::ComparisonType comparisonOperator, T bound, AbstractPathFormula<T>* pathFormula) + : comparisonOperator(comparisonOperator), bound(bound), pathFormula(pathFormula) { + // Intentionally left empty. } - ProbabilisticBoundOperator( - storm::property::ComparisonType comparisonRelation, T bound, AbstractPathFormula<T>* pathFormula, bool minimumOperator) - : storm::property::abstract::ProbabilisticBoundOperator<T, AbstractPathFormula<T>>(comparisonRelation, bound, pathFormula, minimumOperator){ - // Intentionally left empty + /*! + * Destructor + * + * The subtree is deleted with the object + * (this behavior can be prevented by setting them to NULL before deletion) + */ + virtual ~ProbabilisticBoundOperator() { + if (pathFormula != nullptr) { + delete pathFormula; + } } /*! @@ -112,6 +115,101 @@ public: virtual storm::storage::BitVector check(const storm::modelchecker::csl::AbstractModelChecker<T>& modelChecker) const override { return modelChecker.template as<IProbabilisticBoundOperatorModelChecker>()->checkProbabilisticBoundOperator(*this); } + + /*! + * @brief Checks if the subtree conforms to some logic. + * + * @param checker Formula checker object. + * @return true iff the subtree conforms to some logic. + */ + virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + return checker.validate(this->pathFormula); + } + + /*! + * @returns a string representation of the formula + */ + virtual std::string toString() const override { + std::string result = "P "; + switch (comparisonOperator) { + case LESS: result += "<"; break; + case LESS_EQUAL: result += "<="; break; + case GREATER: result += ">"; break; + case GREATER_EQUAL: result += ">="; break; + } + result += " "; + result += std::to_string(bound); + result += " ["; + result += pathFormula->toString(); + result += "]"; + return result; + } + + /*! + * @returns the child node (representation of a formula) + */ + const AbstractPathFormula<T>& getPathFormula () const { + return *pathFormula; + } + + /*! + * Sets the child node + * + * @param pathFormula the path formula that becomes the new child node + */ + void setPathFormula(AbstractPathFormula<T>* pathFormula) { + this->pathFormula = pathFormula; + } + + /*! + * + * @return True if the path formula is set, i.e. it does not point to nullptr; false otherwise + */ + bool pathFormulaIsSet() const { + return pathFormula != nullptr; + } + + /*! + * @returns the comparison relation + */ + const storm::property::ComparisonType getComparisonOperator() const { + return comparisonOperator; + } + + void setComparisonOperator(storm::property::ComparisonType comparisonOperator) { + this->comparisonOperator = comparisonOperator; + } + + /*! + * @returns the bound for the measure + */ + const T& getBound() const { + return bound; + } + + /*! + * Sets the interval in which the probability that the path formula holds may lie in. + * + * @param bound The bound for the measure + */ + void setBound(T bound) { + this->bound = bound; + } + + bool meetsBound(T value) const { + switch (comparisonOperator) { + case LESS: return value < bound; break; + case LESS_EQUAL: return value <= bound; break; + case GREATER: return value > bound; break; + case GREATER_EQUAL: return value >= bound; break; + default: return false; + } + } + +private: + storm::property::ComparisonType comparisonOperator; + T bound; + AbstractPathFormula<T>* pathFormula; }; } //namespace csl diff --git a/src/formula/Csl/ProbabilisticNoBoundOperator.h b/src/formula/Csl/ProbabilisticNoBoundOperator.h deleted file mode 100644 index 63c9a501e..000000000 --- a/src/formula/Csl/ProbabilisticNoBoundOperator.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * ProbabilisticNoBoundOperator.h - * - * Created on: 12.12.2012 - * Author: thomas - */ - -#ifndef STORM_FORMULA_CSL_PROBABILISTICNOBOUNDOPERATOR_H_ -#define STORM_FORMULA_CSL_PROBABILISTICNOBOUNDOPERATOR_H_ - -#include "AbstractPathFormula.h" -#include "AbstractNoBoundOperator.h" -#include "src/formula/abstract/ProbabilisticNoBoundOperator.h" - -namespace storm { -namespace property { -namespace csl { - -/*! - * @brief - * Class for an abstract formula tree with a P (probablistic) operator without declaration of probabilities - * as root. - * - * Checking a formula with this operator as root returns the probabilities that the path formula holds - * (for each state) - * - * Has one Abstract path formula as sub formula/tree. - * - * @note - * This class is a hybrid of a state and path formula, and may only appear as the outermost operator. - * Hence, it is seen as neither a state nor a path formula, but is directly derived from AbstractFormula. - * - * @note - * This class does not contain a check() method like the other formula classes. - * The check method should only be called by the model checker to infer the correct check function for sub - * formulas. As this operator can only appear at the root, the method is not useful here. - * Use the checkProbabilisticNoBoundOperator method from the DtmccslModelChecker class instead. - * - * The subtree is seen as part of the object and deleted with it - * (this behavior can be prevented by setting them to NULL before deletion) - * - * - * @see AbstractStateFormula - * @see AbstractPathFormula - * @see ProbabilisticOperator - * @see ProbabilisticIntervalOperator - * @see AbstractCslFormula - */ -template <class T> -class ProbabilisticNoBoundOperator: public storm::property::abstract::ProbabilisticNoBoundOperator<T, AbstractPathFormula<T>>, - public AbstractNoBoundOperator<T> { -public: - /*! - * Empty constructor - */ - ProbabilisticNoBoundOperator() { - // Intentionally left empty - } - - /*! - * Constructor - * - * @param pathFormula The child node. - */ - ProbabilisticNoBoundOperator(AbstractPathFormula<T>* pathFormula) - : storm::property::abstract::ProbabilisticNoBoundOperator<T, AbstractPathFormula<T>>(pathFormula) { - // Intentionally left empty - } - - /*! - * Constructor - * - * @param pathFormula The child node. - */ - ProbabilisticNoBoundOperator(AbstractPathFormula<T>* pathFormula, bool minimumOperator) - : storm::property::abstract::ProbabilisticNoBoundOperator<T, AbstractPathFormula<T>>(pathFormula, minimumOperator) { - // Intentionally left empty - } - - /*! - * Destructor - */ - virtual ~ProbabilisticNoBoundOperator() { - // Intentionally left empty - } - - virtual AbstractNoBoundOperator<T>* clone() const override { - ProbabilisticNoBoundOperator<T>* result = new ProbabilisticNoBoundOperator<T>(); - if (this->pathFormulaIsSet()) { - result->setPathFormula(this->getPathFormula().clone()); - } - return result; - } - - /*! - * Calls the model checker to check this formula. - * Needed to infer the correct type of formula class. - * - * @note This function should only be called in a generic check function of a model checker class. For other uses, - * the methods of the model checker should be used. - * - * @note This function is not implemented in this class. - * - * @returns A vector indicating the probability that the formula holds for each state. - */ - virtual std::vector<T> check(const storm::modelchecker::csl::AbstractModelChecker<T>& modelChecker, bool qualitative=false) const override { - return this->getPathFormula().check(modelChecker, qualitative); - } -}; - -} //namespace csl -} //namespace property -} //namespace storm - -#endif /* STORM_FORMULA_CSL_PROBABILISTICNOBOUNDOPERATOR_H_ */ diff --git a/src/formula/Csl/SteadyStateBoundOperator.h b/src/formula/Csl/SteadyStateBoundOperator.h index ddd9be3b2..c8d9e8de4 100644 --- a/src/formula/Csl/SteadyStateBoundOperator.h +++ b/src/formula/Csl/SteadyStateBoundOperator.h @@ -9,13 +9,11 @@ #define STORM_FORMULA_CSL_STEADYSTATEOPERATOR_H_ #include "AbstractStateFormula.h" -#include "src/formula/abstract/SteadyStateBoundOperator.h" #include "src/formula/AbstractFormulaChecker.h" +#include "src/formula/ComparisonType.h" namespace storm { - namespace property { - namespace csl { template <class T> class SteadyStateBoundOperator; @@ -54,33 +52,39 @@ class ISteadyStateBoundOperatorModelChecker { * @see AbstractCslFormula */ template <class T> -class SteadyStateBoundOperator : public storm::property::abstract::SteadyStateBoundOperator<T, AbstractStateFormula<T>>, - public AbstractStateFormula<T> { +class SteadyStateBoundOperator : public AbstractStateFormula<T> { public: + /*! * Empty constructor */ - SteadyStateBoundOperator() : storm::property::abstract::SteadyStateBoundOperator<T, AbstractStateFormula<T>> - (LESS_EQUAL, storm::utility::constantZero<T>(), nullptr) { + SteadyStateBoundOperator() : comparisonOperator(LESS), bound(storm::utility::constantZero<T>()), stateFormula(nullptr) { // Intentionally left empty } /*! * Constructor * + * @param comparisonOperator The relation for the bound. + * @param bound The bound for the probability * @param stateFormula The child node */ - SteadyStateBoundOperator( - storm::property::ComparisonType comparisonRelation, T bound, AbstractStateFormula<T>* stateFormula) : - storm::property::abstract::SteadyStateBoundOperator<T, AbstractStateFormula<T>>(comparisonRelation, bound, stateFormula) { + SteadyStateBoundOperator(storm::property::ComparisonType comparisonOperator, T bound, AbstractStateFormula<T>* stateFormula) + : comparisonOperator(comparisonOperator), bound(bound), stateFormula(stateFormula) { + // Intentionally left empty } /*! * Destructor + * + * The subtree is deleted with the object + * (this behavior can be prevented by setting them to NULL before deletion) */ virtual ~SteadyStateBoundOperator() { - // Intentionally left empty + if (stateFormula != nullptr) { + delete stateFormula; + } } /*! @@ -108,7 +112,100 @@ public: virtual storm::storage::BitVector check(const storm::modelchecker::csl::AbstractModelChecker<T>& modelChecker) const override { return modelChecker.template as<ISteadyStateBoundOperatorModelChecker>()->checkSteadyStateBoundOperator(*this); } - + + /*! + * @brief Checks if the subtree conforms to some logic. + * + * @param checker Formula checker object. + * @return true iff the subtree conforms to some logic. + */ + virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + return checker.validate(this->stateFormula); + } + + /*! + * @returns a string representation of the formula + */ + virtual std::string toString() const override { + std::string result = "S "; + switch (comparisonOperator) { + case LESS: result += "< "; break; + case LESS_EQUAL: result += "<= "; break; + case GREATER: result += "> "; break; + case GREATER_EQUAL: result += ">= "; break; + } + result += std::to_string(bound); + result += " ["; + result += stateFormula->toString(); + result += "]"; + return result; + } + + /*! + * @returns the child node (representation of a formula) + */ + const AbstractStateFormula<T>& getStateFormula () const { + return *stateFormula; + } + + /*! + * Sets the child node + * + * @param stateFormula the state formula that becomes the new child node + */ + void setStateFormula(AbstractStateFormula<T>* stateFormula) { + this->stateFormula = stateFormula; + } + + /*! + * + * @return True if the state formula is set, i.e. it does not point to nullptr; false otherwise + */ + bool stateFormulaIsSet() const { + return stateFormula != nullptr; + } + + /*! + * @returns the comparison relation + */ + const ComparisonType getComparisonOperator() const { + return comparisonOperator; + } + + void setComparisonOperator(ComparisonType comparisonOperator) { + this->comparisonOperator = comparisonOperator; + } + + /*! + * @returns the bound for the measure + */ + const T& getBound() const { + return bound; + } + + /*! + * Sets the interval in which the probability that the path formula holds may lie in. + * + * @param bound The bound for the measure + */ + void setBound(T bound) { + this->bound = bound; + } + + bool meetsBound(T value) const { + switch (comparisonOperator) { + case LESS: return value < bound; break; + case LESS_EQUAL: return value <= bound; break; + case GREATER: return value > bound; break; + case GREATER_EQUAL: return value >= bound; break; + default: return false; + } + } + +private: + ComparisonType comparisonOperator; + T bound; + AbstractStateFormula<T>* stateFormula; }; } //namespace csl diff --git a/src/formula/Csl/SteadyStateNoBoundOperator.h b/src/formula/Csl/SteadyStateNoBoundOperator.h deleted file mode 100644 index b92526d47..000000000 --- a/src/formula/Csl/SteadyStateNoBoundOperator.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * SteadyStateNoBoundOperator.h - * - * Created on: 09.04.2013 - * Author: thomas - */ - -#ifndef STORM_FORMULA_CSL_STEADYSTATENOBOUNDOPERATOR_H_ -#define STORM_FORMULA_CSL_STEADYSTATENOBOUNDOPERATOR_H_ - -#include "AbstractStateFormula.h" -#include "AbstractNoBoundOperator.h" -#include "src/formula/abstract/SteadyStateNoBoundOperator.h" - -namespace storm { -namespace property { -namespace csl { - -template <class T> class SteadyStateNoBoundOperator; - -/*! - * @brief Interface class for model checkers that support SteadyStateOperator. - * - * All model checkers that support the formula class SteadyStateOperator must inherit - * this pure virtual class. - */ -template <class T> -class ISteadyStateNoBoundOperatorModelChecker { - public: - /*! - * @brief Evaluates SteadyStateOperator formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual std::vector<T> checkSteadyStateNoBoundOperator(const SteadyStateNoBoundOperator<T>& obj) const = 0; -}; - -template <class T> -class SteadyStateNoBoundOperator: public storm::property::abstract::SteadyStateNoBoundOperator<T, AbstractStateFormula<T>>, - public AbstractNoBoundOperator<T> { -public: - /*! - * Empty constructor - */ - SteadyStateNoBoundOperator() : storm::property::abstract::SteadyStateNoBoundOperator<T, AbstractStateFormula<T>>() { - // Intentionally left empty - - } - - /*! - * Constructor - * - * @param stateFormula The state formula that forms the subtree - */ - SteadyStateNoBoundOperator(AbstractStateFormula<T>* stateFormula) - : storm::property::abstract::SteadyStateNoBoundOperator<T, AbstractStateFormula<T>>(stateFormula) { - // Intentionally left empty - } - - /*! - * Destructor - */ - ~SteadyStateNoBoundOperator() { - // Intentionally left empty - } - - /*! - * Clones the called object. - * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones - * - * @returns a new BoundedUntil-object that is identical the called object. - */ - virtual AbstractNoBoundOperator <T>* clone() const override { - SteadyStateNoBoundOperator<T>* result = new SteadyStateNoBoundOperator<T>(); - result->setStateFormula(this->getStateFormula().clone()); - return result; - } - - /*! - * Calls the model checker to check this formula. - * Needed to infer the correct type of formula class. - * - * @note This function should only be called in a generic check function of a model checker class. For other uses, - * the methods of the model checker should be used. - * - * @returns A vector indicating the probability that the formula holds for each state. - */ - virtual std::vector<T> check(const storm::modelchecker::csl::AbstractModelChecker<T>& modelChecker, bool qualitative=false) const override { - return modelChecker.template as<ISteadyStateNoBoundOperatorModelChecker>()->checkSteadyStateNoBoundOperator(*this); - } - -}; - -} /* namespace csl */ -} /* namespace property */ -} /* namespace storm */ - -#endif /* STORM_FORMULA_CSL_STEADYSTATENOBOUNDOPERATOR_H_ */ diff --git a/src/formula/Csl/TimeBoundedEventually.h b/src/formula/Csl/TimeBoundedEventually.h index 3b443938a..ac601b7d8 100644 --- a/src/formula/Csl/TimeBoundedEventually.h +++ b/src/formula/Csl/TimeBoundedEventually.h @@ -8,9 +8,8 @@ #ifndef STORM_FORMULA_CSL_TIMEBOUNDEDEVENTUALLY_H_ #define STORM_FORMULA_CSL_TIMEBOUNDEDEVENTUALLY_H_ -#include "src/formula/abstract/TimeBoundedEventually.h" -#include "AbstractPathFormula.h" -#include "AbstractStateFormula.h" +#include "src/formula/Csl/AbstractPathFormula.h" +#include "src/formula/Csl/AbstractStateFormula.h" namespace storm { namespace property { @@ -38,27 +37,27 @@ class ITimeBoundedEventuallyModelChecker { template<class T> -class TimeBoundedEventually: public storm::property::abstract::TimeBoundedEventually<T, AbstractStateFormula<T>>, - public AbstractPathFormula<T> { +class TimeBoundedEventually: public AbstractPathFormula<T> { public: + /** * Simple constructor: Only sets the bounds * * @param lowerBound * @param upperBound */ - TimeBoundedEventually(T lowerBound, T upperBound) - : storm::property::abstract::TimeBoundedEventually<T, AbstractStateFormula<T>>(lowerBound, upperBound) { - // Intentionally left empty + TimeBoundedEventually(T lowerBound, T upperBound) : child(nullptr) { + setInterval(lowerBound, upperBound); } - TimeBoundedEventually(T lowerBound, T upperBound, AbstractStateFormula<T>* child) - : storm::property::abstract::TimeBoundedEventually<T, AbstractStateFormula<T>>(lowerBound, upperBound, child) { - // Intentionally left empty + TimeBoundedEventually(T lowerBound, T upperBound, AbstractStateFormula<T>* child) : child(nullptr) { + setInterval(lowerBound, upperBound); } virtual ~TimeBoundedEventually() { - // Intentionally left empty + if (child != nullptr) { + delete child; + } } /*! @@ -88,6 +87,94 @@ public: virtual std::vector<T> check(const storm::modelchecker::csl::AbstractModelChecker<T>& modelChecker, bool qualitative) const override { return modelChecker.template as<ITimeBoundedEventuallyModelChecker>()->checkTimeBoundedEventually(*this, qualitative); } + + /*! + * @brief Checks if the subtree conforms to some logic. + * + * @param checker Formula checker object. + * @return true iff the subtree conforms to some logic. + */ + virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + return checker.validate(this->child); + } + + /*! + * @returns a string representation of the formula + */ + virtual std::string toString() const override { + std::string result = "F"; + if (upperBound == std::numeric_limits<double>::infinity()) { + result = ">=" + std::to_string(lowerBound); + } else { + result = "["; + result += std::to_string(lowerBound); + result += ","; + result += std::to_string(upperBound); + result += "]"; + } + result += " "; + result += child->toString(); + return result; + } + + /*! + * @returns the child node + */ + const AbstractStateFormula<T>& getChild() const { + return *child; + } + + /*! + * Sets the subtree + * @param child the new child node + */ + void setChild(AbstractStateFormula<T>* child) { + this->child = child; + } + + /*! + * + * @return True if the child is set, i.e. it does not point to nullptr; false otherwise + */ + bool childIsSet() const { + return child != nullptr; + } + + /** + * Getter for lowerBound attribute + * + * @return lower bound of the operator. + */ + T getLowerBound() const { + return lowerBound; + } + + /** + * Getter for upperBound attribute + * @return upper bound of the operator. + */ + T getUpperBound() const { + return upperBound; + } + + /** + * Set the time interval for the time bounded operator + * + * @param lowerBound + * @param upperBound + * @throw InvalidArgumentException if the lower bound is larger than the upper bound. + */ + void setInterval(T lowerBound, T upperBound) { + if (lowerBound > upperBound) { + throw new storm::exceptions::InvalidArgumentException("Lower bound is larger than upper bound"); + } + this->lowerBound = lowerBound; + this->upperBound = upperBound; + } + +private: + AbstractStateFormula<T>* child; + T lowerBound, upperBound; }; } /* namespace csl */ diff --git a/src/formula/Csl/TimeBoundedUntil.h b/src/formula/Csl/TimeBoundedUntil.h index 7b2044daa..560bb8df8 100644 --- a/src/formula/Csl/TimeBoundedUntil.h +++ b/src/formula/Csl/TimeBoundedUntil.h @@ -8,9 +8,8 @@ #ifndef STORM_FORMULA_CSL_TIMEBOUNDEDUNTIL_H_ #define STORM_FORMULA_CSL_TIMEBOUNDEDUNTIL_H_ -#include "AbstractPathFormula.h" -#include "AbstractStateFormula.h" -#include "src/formula/abstract/TimeBoundedUntil.h" +#include "src/formula/Csl/AbstractPathFormula.h" +#include "src/formula/Csl/AbstractStateFormula.h" namespace storm { namespace property { @@ -37,9 +36,9 @@ class ITimeBoundedUntilModelChecker { }; template <class T> -class TimeBoundedUntil: public storm::property::abstract::TimeBoundedUntil<T, AbstractStateFormula<T>>, - public AbstractPathFormula<T> { +class TimeBoundedUntil: public AbstractPathFormula<T> { public: + /** * Constructor providing bounds only; * Sub formulas are set to null. @@ -47,11 +46,11 @@ public: * @param lowerBound * @param upperBound */ - TimeBoundedUntil(T lowerBound, T upperBound) : - storm::property::abstract::TimeBoundedUntil<T, AbstractStateFormula<T>>(lowerBound, upperBound) { - // Intentionally left empty + TimeBoundedUntil(T lowerBound, T upperBound) : left(nullptr), right(nullptr) { + setInterval(lowerBound, upperBound); } + /** * Full constructor * @param lowerBound @@ -59,16 +58,20 @@ public: * @param left * @param right */ - TimeBoundedUntil(T lowerBound, T upperBound, AbstractStateFormula<T>* left, AbstractStateFormula<T>* right) : - storm::property::abstract::TimeBoundedUntil<T, AbstractStateFormula<T>>(lowerBound, upperBound, left, right) { - + TimeBoundedUntil(T lowerBound, T upperBound, AbstractStateFormula<T>* left, AbstractStateFormula<T>* right) : left(left), right(right) { + setInterval(lowerBound, upperBound); } /*! * Destructor */ virtual ~TimeBoundedUntil() { - // Intentionally left empty + if (left != nullptr) { + delete left; + } + if (right != nullptr) { + delete right; + } } /*! @@ -102,6 +105,121 @@ public: virtual std::vector<T> check(const storm::modelchecker::csl::AbstractModelChecker<T>& modelChecker, bool qualitative) const override { return modelChecker.template as<ITimeBoundedUntilModelChecker>()->checkTimeBoundedUntil(*this, qualitative); } + + /*! + * @brief Checks if the subtree conforms to some logic. + * + * @param checker Formula checker object. + * @return true iff the subtree conforms to some logic. + */ + virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + return checker.validate(this->left) && checker.validate(this->right); + } + + /*! + * @returns a string representation of the formula + */ + virtual std::string toString() const override { + std::string result = left->toString(); + result += " U"; + if (upperBound == std::numeric_limits<double>::infinity()) { + result = ">=" + std::to_string(lowerBound); + } else { + result = "["; + result += std::to_string(lowerBound); + result += ","; + result += std::to_string(upperBound); + result += "]"; + } + result += " "; + result += right->toString(); + return result; + } + + /*! + * Sets the left child node. + * + * @param newLeft the new left child. + */ + void setLeft(AbstractStateFormula<T>* newLeft) { + left = newLeft; + } + + /*! + * Sets the right child node. + * + * @param newRight the new right child. + */ + void setRight(AbstractStateFormula<T>* newRight) { + right = newRight; + } + + /*! + * @returns a pointer to the left child node + */ + const AbstractStateFormula<T>& getLeft() const { + return *left; + } + + /*! + * @returns a pointer to the right child node + */ + const AbstractStateFormula<T>& getRight() const { + return *right; + } + + /*! + * + * @return True if the left child is set, i.e. it does not point to nullptr; false otherwise + */ + bool leftIsSet() const { + return left != nullptr; + } + + /*! + * + * @return True if the right child is set, i.e. it does not point to nullptr; false otherwise + */ + bool rightIsSet() const { + return right != nullptr; + } + + /** + * Getter for lowerBound attribute + * + * @return lower bound of the operator. + */ + T getLowerBound() const { + return lowerBound; + } + + /** + * Getter for upperBound attribute + * @return upper bound of the operator. + */ + T getUpperBound() const { + return upperBound; + } + + /** + * Set the time interval for the time bounded operator + * + * @param lowerBound + * @param upperBound + * @throw InvalidArgumentException if the lower bound is larger than the upper bound. + */ + void setInterval(T lowerBound, T upperBound) { + if (lowerBound > upperBound) { + throw new storm::exceptions::InvalidArgumentException("Lower bound is larger than upper bound"); + } + this->lowerBound = lowerBound; + this->upperBound = upperBound; + } + +private: + AbstractStateFormula<T>* left; + AbstractStateFormula<T>* right; + T lowerBound, upperBound; }; } /* namespace csl */ diff --git a/src/formula/Csl/Until.h b/src/formula/Csl/Until.h index 6f6d68086..34b44b780 100644 --- a/src/formula/Csl/Until.h +++ b/src/formula/Csl/Until.h @@ -8,9 +8,8 @@ #ifndef STORM_FORMULA_CSL_UNTIL_H_ #define STORM_FORMULA_CSL_UNTIL_H_ -#include "AbstractPathFormula.h" -#include "AbstractStateFormula.h" -#include "src/formula/abstract/Until.h" +#include "src/formula/Csl/AbstractPathFormula.h" +#include "src/formula/Csl/AbstractStateFormula.h" #include "src/formula/AbstractFormulaChecker.h" namespace storm { @@ -54,15 +53,14 @@ class IUntilModelChecker { * @see AbstractCslFormula */ template <class T> -class Until : public storm::property::abstract::Until<T, AbstractStateFormula<T>>, - public AbstractPathFormula<T> { +class Until : public AbstractPathFormula<T> { public: /*! * Empty constructor */ - Until() { - // Intentionally left empty + Until() : left(nullptr), right(nullptr){ + // Intentionally left empty. } /*! @@ -71,9 +69,8 @@ public: * @param left The left formula subtree * @param right The left formula subtree */ - Until(AbstractStateFormula<T>* left, AbstractStateFormula<T>* right) - : storm::property::abstract::Until<T, AbstractStateFormula<T>>(left, right) { - // Intentionally left empty + Until(AbstractStateFormula<T>* left, AbstractStateFormula<T>* right) : left(left), right(right){ + // Intentionally left empty. } /*! @@ -83,7 +80,12 @@ public: * (this behaviour can be prevented by setting the subtrees to NULL before deletion) */ virtual ~Until() { - // Intentionally left empty + if (left != NULL) { + delete left; + } + if (right != NULL) { + delete right; + } } /*! @@ -116,6 +118,78 @@ public: virtual std::vector<T> check(const storm::modelchecker::csl::AbstractModelChecker<T>& modelChecker, bool qualitative) const override { return modelChecker.template as<IUntilModelChecker>()->checkUntil(*this, qualitative); } + + /*! + * @returns a string representation of the formula + */ + virtual std::string toString() const override { + std::string result = left->toString(); + result += " U "; + result += right->toString(); + return result; + } + + /*! + * @brief Checks if all subtrees conform to some logic. + * + * @param checker Formula checker object. + * @return true iff all subtrees conform to some logic. + */ + virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + return checker.validate(this->left) && checker.validate(this->right); + } + + /*! + * Sets the left child node. + * + * @param newLeft the new left child. + */ + void setLeft(AbstractStateFormula<T>* newLeft) { + left = newLeft; + } + + /*! + * Sets the right child node. + * + * @param newRight the new right child. + */ + void setRight(AbstractStateFormula<T>* newRight) { + right = newRight; + } + + /*! + * @returns a pointer to the left child node + */ + const AbstractStateFormula<T>& getLeft() const { + return *left; + } + + /*! + * @returns a pointer to the right child node + */ + const AbstractStateFormula<T>& getRight() const { + return *right; + } + + /*! + * + * @return True if the left child is set, i.e. it does not point to nullptr; false otherwise + */ + bool leftIsSet() const { + return left != nullptr; + } + + /*! + * + * @return True if the right child is set, i.e. it does not point to nullptr; false otherwise + */ + bool rightIsSet() const { + return right != nullptr; + } + +private: + AbstractStateFormula<T>* left; + AbstractStateFormula<T>* right; }; } //namespace csl diff --git a/src/formula/Prctl/AbstractStateFormula.h b/src/formula/Prctl/AbstractStateFormula.h index b10a9e92a..7eed7fb6a 100644 --- a/src/formula/Prctl/AbstractStateFormula.h +++ b/src/formula/Prctl/AbstractStateFormula.h @@ -26,7 +26,7 @@ namespace prctl { * clone(). */ template <class T> -class AbstractStateFormula : public virtual storm::property::prctl::AbstractPrctlFormula<T> { +class AbstractStateFormula : public storm::property::prctl::AbstractPrctlFormula<T> { public: /*! diff --git a/src/formula/Prctl/Globally.h b/src/formula/Prctl/Globally.h index eeb52e37f..67a824254 100644 --- a/src/formula/Prctl/Globally.h +++ b/src/formula/Prctl/Globally.h @@ -8,8 +8,8 @@ #ifndef STORM_FORMULA_PRCTL_GLOBALLY_H_ #define STORM_FORMULA_PRCTL_GLOBALLY_H_ -#include "AbstractPathFormula.h" -#include "AbstractStateFormula.h" +#include "src/formula/Prctl/AbstractPathFormula.h" +#include "src/formula/Prctl/AbstractStateFormula.h" #include "src/formula/AbstractFormulaChecker.h" #include "src/modelchecker/prctl/ForwardDeclarations.h" @@ -85,7 +85,6 @@ public: } } - /*! * Clones the called object. * diff --git a/src/formula/Prctl/Next.h b/src/formula/Prctl/Next.h index a50cfd005..776195903 100644 --- a/src/formula/Prctl/Next.h +++ b/src/formula/Prctl/Next.h @@ -8,8 +8,8 @@ #ifndef STORM_FORMULA_PRCTL_NEXT_H_ #define STORM_FORMULA_PRCTL_NEXT_H_ -#include "AbstractPathFormula.h" -#include "AbstractStateFormula.h" +#include "src/formula/Prctl/AbstractPathFormula.h" +#include "src/formula/Prctl/AbstractStateFormula.h" #include "src/formula/AbstractFormulaChecker.h" namespace storm { diff --git a/src/formula/Prctl/Not.h b/src/formula/Prctl/Not.h index 231ced8d9..65a06be3a 100644 --- a/src/formula/Prctl/Not.h +++ b/src/formula/Prctl/Not.h @@ -52,6 +52,7 @@ template <class T> class Not : public AbstractStateFormula<T> { public: + /*! * Empty constructor */ diff --git a/src/formula/Prctl/Or.h b/src/formula/Prctl/Or.h index 3f1b83f36..dc92ee10a 100644 --- a/src/formula/Prctl/Or.h +++ b/src/formula/Prctl/Or.h @@ -54,9 +54,10 @@ template <class T> class Or : public AbstractStateFormula<T> { public: + /*! * Empty constructor. - * Will create an AND-node without subnotes. Will not represent a complete formula! + * Will create an OR-node without subnotes. Will not represent a complete formula! */ Or() { left = NULL; @@ -65,7 +66,7 @@ public: /*! * Constructor. - * Creates an AND note with the parameters as subtrees. + * Creates an OR note with the parameters as subtrees. * * @param left The left sub formula * @param right The right sub formula diff --git a/src/modelchecker/csl/AbstractModelChecker.h b/src/modelchecker/csl/AbstractModelChecker.h index d1d3bc1dc..36499884a 100644 --- a/src/modelchecker/csl/AbstractModelChecker.h +++ b/src/modelchecker/csl/AbstractModelChecker.h @@ -46,7 +46,6 @@ class AbstractModelChecker : public virtual storm::property::csl::INextModelChecker<Type>, public virtual storm::property::csl::ITimeBoundedUntilModelChecker<Type>, public virtual storm::property::csl::ITimeBoundedEventuallyModelChecker<Type>, - public virtual storm::property::csl::INoBoundOperatorModelChecker<Type>, public virtual storm::property::csl::IProbabilisticBoundOperatorModelChecker<Type> { public: From 299390cef5148cf96503fc2aa55ef6f33ba56d12 Mon Sep 17 00:00:00 2001 From: masawei <manuel.sascha.weiand@rwth-aachen.de> Date: Sat, 26 Apr 2014 20:50:39 +0200 Subject: [PATCH 04/30] Started on the filters. - Got the general structure down. - Now writing the output functions. Next up: Finish the basic filter functionality. Former-commit-id: 91daa0a9f72fedaad13298da3b7bf43e7fed2922 --- src/formula/AbstractFilter.h | 79 +++++++++++++++++ src/formula/Actions/Action.h | 52 +++++++++++ src/formula/Actions/RangeAction.h | 74 ++++++++++++++++ src/formula/Prctl/PrctlFilter.h | 142 ++++++++++++++++++++++++++++++ 4 files changed, 347 insertions(+) create mode 100644 src/formula/AbstractFilter.h create mode 100644 src/formula/Actions/Action.h create mode 100644 src/formula/Actions/RangeAction.h create mode 100644 src/formula/Prctl/PrctlFilter.h diff --git a/src/formula/AbstractFilter.h b/src/formula/AbstractFilter.h new file mode 100644 index 000000000..6e73913c8 --- /dev/null +++ b/src/formula/AbstractFilter.h @@ -0,0 +1,79 @@ +/* + * Filter.h + * + * Created on: Apr 26, 2014 + * Author: Manuel Sascha Weiand + */ + +#ifndef STORM_FORMULA_ABSTRACTFILTER_H_ +#define STORM_FORMULA_ABSTRACTFILTER_H_ + +#include <vector> +#include "src/formula/AbstractFormula.h" +#include "src/formula/Actions/Action.h" + +namespace storm { +namespace property { + +template <class T> +class AbstractFilter { + +public: + + AbstractFilter() { + // Intentionally left empty. + } + + AbstractFilter(action::Action<T>* action) { + actions.push_back(action); + } + + AbstractFilter(std::vector<action::Action<T>*> actions) : actions(actions) { + // Intentionally left empty. + } + + virtual ~AbstractFilter() { + actions.clear(); + } + + std::string toFormulaString() const { + std::string desc = "filter("; + return desc; + } + + std::string toString() const { + std::string desc = "Filter: "; + desc += "\nActions:"; + for(auto action : actions) { + desc += "\n\t" + action.toString(); + } + return desc; + } + + void addAction(action::Action<T>* action) { + actions.push_back(action); + } + + void removeAction() { + actions.pop_back(); + } + + action::Action<T>* getAction(uint_fast64_t pos) const { + return actions[pos]; + } + + uint_fast64_t getActionCount() const { + return actions.size(); + } + +protected: + + std::vector<action::Action<T>*> actions; +}; + +} //namespace property +} //namespace storm + + + +#endif /* STORM_FORMULA_ABSTRACTFILTER_H_ */ diff --git a/src/formula/Actions/Action.h b/src/formula/Actions/Action.h new file mode 100644 index 000000000..f435859b9 --- /dev/null +++ b/src/formula/Actions/Action.h @@ -0,0 +1,52 @@ +/* + * Action.h + * + * Created on: Apr 26, 2014 + * Author: Manuel Sascha Weiand + */ + +#ifndef STORM_FORMULA_ACTION_ACTION_H_ +#define STORM_FORMULA_ACTION_ACTION_H_ + +#include <vector> +#include "src/storage/BitVector.h" + +namespace storm { +namespace property { +namespace action { + +template <class T> +class Action { + +public: + + /*! + * Virtual destructor + * To ensure that the right destructor is called + */ + virtual ~Action() { + //Intentionally left empty + } + + /*! + * + */ + virtual std::vector<T> evaluate(std::vector<T> input) const = 0; + + /*! + * + */ + virtual storm::storage::BitVector<T> evaluate(storm::storage::BitVector<T> input) const = 0; + + /*! + * + */ + virtual std::string toString() const = 0; +}; + +} //namespace action +} //namespace property +} //namespace storm + + +#endif /* STORM_FORMULA_ACTION_ACTION_H_ */ diff --git a/src/formula/Actions/RangeAction.h b/src/formula/Actions/RangeAction.h new file mode 100644 index 000000000..183ad6a13 --- /dev/null +++ b/src/formula/Actions/RangeAction.h @@ -0,0 +1,74 @@ +/* + * RangeAction.h + * + * Created on: Apr 26, 2014 + * Author: Manuel Sascha Weiand + */ + +#ifndef STORM_FORMULA_ACTION_RANGEACTION_H_ +#define STORM_FORMULA_ACTION_RANGEACTION_H_ + +#include "src/formula/Actions/Action.h" + +namespace storm { +namespace property { +namespace action { + +template <class T> +class RangeAction : Action<T> { + +public: + + RangeAction() : from(0), to(0) { + //Intentionally left empty. + } + + RangeAction(uint_fast64_t from, uint_fast64_t to) : from(from), to(to) { + //Intentionally left empty. + } + + /*! + * Virtual destructor + * To ensure that the right destructor is called + */ + virtual ~RangeAction() { + //Intentionally left empty + } + + /*! + * + */ + virtual std::vector<T> evaluate(std::vector<T> input) const override { + // The range constructor is used here instead of manipulating the incoming vector. + // While deleting the element at the end of the vector is efficient, deleting elements at any position but the end is not. + // Also this leaves the incoming vector unchanged. + std::vector<T> out(input.begin() + from, input.begin() + to); + return out; + } + + /*! + * + */ + virtual storm::storage::BitVector<T> evaluate(storm::storage::BitVector<T> input) const override { + storm::storage::BitVector<T> out(to - from + 1, input.begin() + from, input.begin() + to); + return out; + } + + /*! + * + */ + virtual std::string toString() const override { + return "range, " + from + ", " + to; + } + +private: + uint_fast64_t from; + uint_fast64_t to; + +}; + +} //namespace action +} //namespace property +} //namespace storm + +#endif /* STORM_FORMULA_ACTION_RANGEACTION_H_ */ diff --git a/src/formula/Prctl/PrctlFilter.h b/src/formula/Prctl/PrctlFilter.h new file mode 100644 index 000000000..5cf154e6f --- /dev/null +++ b/src/formula/Prctl/PrctlFilter.h @@ -0,0 +1,142 @@ +/* + * PrctlFilter.h + * + * Created on: Apr 26, 2014 + * Author: Manuel Sascha Weiand + */ + +#ifndef STORM_FORMULA_PRCTL_PRCTLFILTER_H_ +#define STORM_FORMULA_PRCTL_PRCTLFILTER_H_ + +#include "src/formula/AbstractFilter.h" +#include "src/formula/Prctl/AbstractPrctlFormula.h" +#include "src/formula/Prctl/AbstractPathFormula.h" +#include "src/formula/Prctl/AbstractStateFormula.h" + +namespace storm { +namespace property { +namespace prctl { + +template <class T> +class PrctlFilter : storm::property::AbstractFilter<T> { + +public: + + PrctlFilter() : child(nullptr) { + // Intentionally left empty. + } + + PrctlFilter(AbstractFormula* child) : child(child) { + // Intentionally left empty. + } + + PrctlFilter(AbstractFormula* child, action::Action<T>* action) : child(child) { + actions.push_back(action); + } + + PrctlFilter(AbstractFormula* child, std::vector<action::Action<T>*> actions) : child(child), actions(actions) { + // Intentionally left empty. + } + + virtual ~PrctlFilter() { + actions.clear(); + delete child; + } + + void check(AbstractModelChecker& modelchecker) const { + + // Do a dynamic cast to test for the actual formula type and call the correct evaluation function. + if(dynamic_cast<AbstractStateFormula<T>*>(child) != nullptr) { + // Check the formula and apply the filter actions. + storm::storage::BitVector result = evaluate(modelchecker, static_cast<AbstractStateFormula<T>*>(child)); + + // Now write out the result. + + } + else if (dynamic_cast<AbstractPathFormula<T>*>(child) != nullptr) { + // Check the formula and apply the filter actions. + std::vector<T> result = evaluate(modelchecker, static_cast<AbstractPathFormula<T>*>(child)); + + // Now write out the result. + } + else { + // This branch should be unreachable. If you ended up here, something strange has happened. + //TODO: Error here. + } + } + + bool validate() const { + // Test whether the stored filter actions are consistent in relation to themselves and to the ingoing modelchecking result. + + // Do a dynamic cast to test for the actual formula type. + if(dynamic_cast<AbstractStateFormula<T>*>(child) != nullptr) { + //TODO: Actual validation. + } + else if (dynamic_cast<AbstractPathFormula<T>*>(child) != nullptr) { + //TODO: Actual validation. + } + else { + // This branch should be unreachable. If you ended up here, something strange has happened. + //TODO: Error here. + } + + return true; + } + + std::string toFormulaString() const { + std::string desc = "filter("; + return desc; + } + + std::string toString() const { + std::string desc = "Filter: "; + desc += "\nActions:"; + for(auto action : actions) { + desc += "\n\t" + action.toString(); + } + desc += "\nFormula:\n\t" + child->toString(); + return desc; + } + + void setChild(AbstractFormula* child) { + this->child = child; + } + + AbstractFormula* getChild() const { + return child; + } + +private: + + BitVector<T> evaluate(AbstractModelChecker& modelchecker, AbstractStateFormula<T>* formula) const { + // First, get the model checking result. + BitVector result = formula->check(modelchecker); + + // Now apply all filter actions and return the result. + for(auto action : actions) { + result = action->evaluate(result); + } + return result; + } + + std::vector<T> evaluate(AbstractModelChecker& modelchecker, AbstractPathFormula<T>* formula) const { + // First, get the model checking result. + std::vector<T> result = formula->check(modelchecker); + + // Now apply all filter actions and return the result. + for(auto action : actions) { + result = action->evaluate(result); + } + return result; + } + + AbstractPrctlFormula* child; +}; + +} //namespace prctl +} //namespace property +} //namespace storm + + + +#endif /* STORM_FORMULA_PRCTL_PRCTLFILTER_H_ */ From 2f5f8c0918ca5a1b33bccfe7739fc7c59b7749e6 Mon Sep 17 00:00:00 2001 From: masawei <manuel.sascha.weiand@rwth-aachen.de> Date: Wed, 30 Apr 2014 22:31:10 +0200 Subject: [PATCH 05/30] PrctlFilter is operational but not yet complete (proper standard output missing). - General function of the filters: The filter as an abstraction layer between the control flow and the formula/modelchecker. |- It has a formula as child but is not a formula itself. |- It invokes the modelchecking process on the child formula and manipulates the result. |- For the purpose of result manipulation it keeps a list of filter actions. |- Each action manipulates the result in a certain way. For example: It returns only the results for states 25 to 140. |- Furthermore the printing of the result to standard out and the log is no longer done by the modelchecker but by the filter. |- That way the tasks of each class becomes more clear: Modelchecker to compute the results, filter to prepare the computed results for write out. - Battled with a major design problem: How to integrate the optimizing operator (aka. min or max probs for non-det. models) into the filter scheme. |- It is now integrated as a separate filter action, which does not touch the results but hold the flag determining whether to maximize or to minimize. |- This action must be the innermost filter action (i.e. the first list entry) to have any effect. |- This is combined with a special fuction of the modelchecker that manipulates the mutable minimizationStack calculates the modelchecking result and resets the stack to its original state. |- This way the information whether to min, to max or not to try is managed by the filter and propagated as needed. |- Remark: Fixed a major risk of undefined behavior in the SparseMdpPrctlModelChecker. |- If the formula to be checked did not have a NoBoundFormula as root then the minimumOperatorStack would be empty and minimumOperatorStack.top() would result in undefined behavior. |- Added tests whether the stack is empty before trying to read out the possibly non existant top element. Next up: Implement similar filters for LTL and CSL and try to get it compiled. Former-commit-id: 577998e02775bf5775d7fea094192dbed76d197a --- src/formula/Actions/Action.h | 13 ++- src/formula/Actions/MinMaxAction.h | 60 ++++++++++ src/formula/Actions/RangeAction.h | 7 ++ src/formula/Prctl/PrctlFilter.h | 85 ++++++++++++-- src/modelchecker/prctl/AbstractModelChecker.h | 104 +++++++----------- .../prctl/SparseDtmcPrctlModelChecker.h | 51 ++++++--- .../prctl/SparseMdpPrctlModelChecker.h | 79 ++++++++----- 7 files changed, 281 insertions(+), 118 deletions(-) create mode 100644 src/formula/Actions/MinMaxAction.h diff --git a/src/formula/Actions/Action.h b/src/formula/Actions/Action.h index f435859b9..dd7bd3502 100644 --- a/src/formula/Actions/Action.h +++ b/src/formula/Actions/Action.h @@ -31,17 +31,26 @@ public: /*! * */ - virtual std::vector<T> evaluate(std::vector<T> input) const = 0; + virtual std::vector<T> evaluate(std::vector<T> input) const { + return input; + } /*! * */ - virtual storm::storage::BitVector<T> evaluate(storm::storage::BitVector<T> input) const = 0; + virtual storm::storage::BitVector<T> evaluate(storm::storage::BitVector<T> input) const { + return input; + } /*! * */ virtual std::string toString() const = 0; + + /*! + * + */ + virtual std::string toFormulaString() const = 0; }; } //namespace action diff --git a/src/formula/Actions/MinMaxAction.h b/src/formula/Actions/MinMaxAction.h new file mode 100644 index 000000000..2c32bd964 --- /dev/null +++ b/src/formula/Actions/MinMaxAction.h @@ -0,0 +1,60 @@ +/* + * MinMaxAction.h + * + * Created on: Apr 30, 2014 + * Author: Manuel Sascha Weiand + */ + +#ifndef STORM_FORMULA_ACTION_MINMAXACTION_H_ +#define STORM_FORMULA_ACTION_MINMAXACTION_H_ + +#include "src/formula/Actions/Action.h" + +namespace storm { +namespace property { +namespace action { + +template <class T> +class MinMaxAction : Action<T> { + +public: + + MinMaxAction() : minimize(true) { + //Intentionally left empty. + } + + explicit MinMaxAction(bool minimize) : minimize(minimize) { + //Intentionally left empty. + } + + /*! + * + */ + virtual std::string toString() const override { + return minimize ? "min" : "max"; + } + + /*! + * + */ + virtual std::string toFormulaString() const override { + return minimize ? "min" : "max"; + } + + /*! + * + */ + bool getMinimize() { + return minimize; + } + +private: + bool minimize; + +}; + +} //namespace action +} //namespace property +} //namespace storm + +#endif /* STORM_FORMULA_ACTION_MINMAXACTION_H_ */ diff --git a/src/formula/Actions/RangeAction.h b/src/formula/Actions/RangeAction.h index 183ad6a13..58a44aa0e 100644 --- a/src/formula/Actions/RangeAction.h +++ b/src/formula/Actions/RangeAction.h @@ -61,6 +61,13 @@ public: return "range, " + from + ", " + to; } + /*! + * + */ + virtual std::string toFormulaString() const override { + return "\"range\", " + from + ", " + to; + } + private: uint_fast64_t from; uint_fast64_t to; diff --git a/src/formula/Prctl/PrctlFilter.h b/src/formula/Prctl/PrctlFilter.h index 5cf154e6f..f01c0b4b9 100644 --- a/src/formula/Prctl/PrctlFilter.h +++ b/src/formula/Prctl/PrctlFilter.h @@ -43,21 +43,77 @@ public: delete child; } - void check(AbstractModelChecker& modelchecker) const { + void check(AbstractModelChecker const & modelchecker) const { + + // Write out the formula to be checked. + std::cout << std::endl; + LOG4CPLUS_INFO(logger, "Model checking formula\t" << this->toFormulaString()); + std::cout << "Model checking formula:\t" << this->toFormulaString() << std::endl; // Do a dynamic cast to test for the actual formula type and call the correct evaluation function. if(dynamic_cast<AbstractStateFormula<T>*>(child) != nullptr) { + // Check the formula and apply the filter actions. - storm::storage::BitVector result = evaluate(modelchecker, static_cast<AbstractStateFormula<T>*>(child)); + storm::storage::BitVector result; + + try { + result = evaluate(modelchecker, static_cast<AbstractStateFormula<T>*>(child)); + } catch (std::exception& e) { + std::cout << "Error during computation: " << e.what() << "Skipping property." << std::endl; + LOG4CPLUS_ERROR(logger, "Error during computation: " << e.what() << "Skipping property."); + std::cout << std::endl << "-------------------------------------------" << std::endl; + + return; + } // Now write out the result. + if(actions.empty()) { + + // There is no filter action given. So provide legacy support: + // Return the results for all states labeled with "init". + LOG4CPLUS_INFO(logger, "Result for initial states:"); + std::cout << "Result for initial states:" << std::endl; + for (auto initialState : modelchecker.getModel<storm::models::AbstractModel<T>>().getInitialStates()) { + LOG4CPLUS_INFO(logger, "\t" << initialState << ": " << (result.get(initialState) ? "satisfied" : "not satisfied")); + std::cout << "\t" << initialState << ": " << result.get(initialState) << std::endl; + } + } + + std::cout << std::endl << "-------------------------------------------" << std::endl; + } else if (dynamic_cast<AbstractPathFormula<T>*>(child) != nullptr) { + // Check the formula and apply the filter actions. - std::vector<T> result = evaluate(modelchecker, static_cast<AbstractPathFormula<T>*>(child)); + std::vector<T> result; + + try { + result = evaluate(modelchecker, static_cast<AbstractPathFormula<T>*>(child)); + } catch (std::exception& e) { + std::cout << "Error during computation: " << e.what() << "Skipping property." << std::endl; + LOG4CPLUS_ERROR(logger, "Error during computation: " << e.what() << "Skipping property."); + std::cout << std::endl << "-------------------------------------------" << std::endl; + + return; + } // Now write out the result. + + if(actions.empty()) { + + // There is no filter action given. So provide legacy support: + // Return the results for all states labeled with "init". + LOG4CPLUS_INFO(logger, "Result for initial states:"); + std::cout << "Result for initial states:" << std::endl; + for (auto initialState : modelchecker.getModel<storm::models::AbstractModel<T>>().getInitialStates()) { + LOG4CPLUS_INFO(logger, "\t" << initialState << ": " << result[initialState]); + std::cout << "\t" << initialState << ": " << result[initialState] << std::endl; + } + } + + std::cout << std::endl << "-------------------------------------------" << std::endl; + } else { // This branch should be unreachable. If you ended up here, something strange has happened. @@ -108,9 +164,17 @@ public: private: - BitVector<T> evaluate(AbstractModelChecker& modelchecker, AbstractStateFormula<T>* formula) const { + BitVector<T> evaluate(AbstractModelChecker const & modelchecker, AbstractStateFormula<T>* formula) const { // First, get the model checking result. - BitVector result = formula->check(modelchecker); + BitVector result = modelchecker.checkMinMaxOperator(formula); + + if(getActionCount() != 0 && dynamic_cast<MinMaxAction<T>*>(getAction(0)) != nullptr) { + // If there is an action specifying that min/max probabilities should be computed, call the appropriate method of the model checker. + result = modelchecker.checkMinMaxOperator(formula, static_cast<MinMaxAction<T>*>(getAction(0))->getMinimize()); + } else { + result = formula->check(modelchecker); + } + // Now apply all filter actions and return the result. for(auto action : actions) { @@ -119,9 +183,16 @@ private: return result; } - std::vector<T> evaluate(AbstractModelChecker& modelchecker, AbstractPathFormula<T>* formula) const { + std::vector<T> evaluate(AbstractModelChecker const & modelchecker, AbstractPathFormula<T>* formula) const { // First, get the model checking result. - std::vector<T> result = formula->check(modelchecker); + std::vector<T> result; + + if(getActionCount() != 0 && dynamic_cast<MinMaxAction<T>*>(getAction(0)) != nullptr) { + // If there is an action specifying that min/max probabilities should be computed, call the appropriate method of the model checker. + result = modelchecker.checkMinMaxOperator(formula, static_cast<MinMaxAction<T>*>(getAction(0))->getMinimize()); + } else { + result = formula->check(modelchecker, false); + } // Now apply all filter actions and return the result. for(auto action : actions) { diff --git a/src/modelchecker/prctl/AbstractModelChecker.h b/src/modelchecker/prctl/AbstractModelChecker.h index 888721a56..cbf5830e4 100644 --- a/src/modelchecker/prctl/AbstractModelChecker.h +++ b/src/modelchecker/prctl/AbstractModelChecker.h @@ -17,6 +17,7 @@ namespace prctl { } } +#include <stack> #include "src/exceptions/InvalidPropertyException.h" #include "src/formula/Prctl.h" #include "src/storage/BitVector.h" @@ -119,73 +120,6 @@ public: throw bc; } } - - /*! - * Checks the given abstract prctl formula on the model and prints the result (depending on the actual type of the formula) - * for all initial states, i.e. states that carry the atomic proposition "init". - * - * @param formula The formula to be checked. - */ - void check(storm::property::prctl::AbstractPrctlFormula<Type> const& formula) const { - if (dynamic_cast<storm::property::prctl::AbstractStateFormula<Type> const*>(&formula) != nullptr) { - this->check(static_cast<storm::property::prctl::AbstractStateFormula<Type> const&>(formula)); - } else if (dynamic_cast<storm::property::prctl::AbstractNoBoundOperator<Type> const*>(&formula) != nullptr) { - this->check(static_cast<storm::property::prctl::AbstractNoBoundOperator<Type> const&>(formula)); - } - } - - /*! - * Checks the given state formula on the model and prints the result (true/false) for all initial states, i.e. - * states that carry the atomic proposition "init". - * - * @param stateFormula The formula to be checked. - */ - void check(storm::property::prctl::AbstractStateFormula<Type> const& stateFormula) const { - std::cout << std::endl; - LOG4CPLUS_INFO(logger, "Model checking formula\t" << stateFormula.toString()); - std::cout << "Model checking formula:\t" << stateFormula.toString() << std::endl; - storm::storage::BitVector result; - try { - result = stateFormula.check(*this); - LOG4CPLUS_INFO(logger, "Result for initial states:"); - std::cout << "Result for initial states:" << std::endl; - for (auto initialState : model.getInitialStates()) { - LOG4CPLUS_INFO(logger, "\t" << initialState << ": " << (result.get(initialState) ? "satisfied" : "not satisfied")); - std::cout << "\t" << initialState << ": " << result.get(initialState) << std::endl; - } - } catch (std::exception& e) { - std::cout << "Error during computation: " << e.what() << "Skipping property." << std::endl; - LOG4CPLUS_ERROR(logger, "Error during computation: " << e.what() << "Skipping property."); - } - - std::cout << std::endl << "-------------------------------------------" << std::endl; - } - - /*! - * Checks the given formula (with no bound) on the model and prints the result (probability/rewards) for all - * initial states, i.e. states that carry the atomic proposition "init". - * - * @param noBoundFormula The formula to be checked. - */ - void check(storm::property::prctl::AbstractNoBoundOperator<Type> const& noBoundFormula) const { - std::cout << std::endl; - LOG4CPLUS_INFO(logger, "Model checking formula\t" << noBoundFormula.toString()); - std::cout << "Model checking formula:\t" << noBoundFormula.toString() << std::endl; - std::vector<Type> result; - try { - result = this->checkNoBoundOperator(noBoundFormula); - LOG4CPLUS_INFO(logger, "Result for initial states:"); - std::cout << "Result for initial states:" << std::endl; - for (auto initialState : model.getInitialStates()) { - LOG4CPLUS_INFO(logger, "\t" << initialState << ": " << result[initialState]); - std::cout << "\t" << initialState << ": " << result[initialState] << std::endl; - } - } catch (std::exception& e) { - std::cout << "Error during computation: " << e.what() << " Skipping property." << std::endl; - LOG4CPLUS_ERROR(logger, "Error during computation: " << e.what() << "Skipping property."); - } - std::cout << std::endl << "-------------------------------------------" << std::endl; - } /*! * Checks the given formula consisting of a single atomic proposition. @@ -295,6 +229,42 @@ public: return result; } + /*! + * Checks the given formula and determines whether minimum or maximum probabilities or rewards are to be computed for the formula. + * + * @param formula The formula to check. + * @param minimumOperator True iff minimum probabilities/rewards are to be computed. + * @returns The probabilities to satisfy the formula or the rewards accumulated by it, represented by a vector. + */ + virtual std::vector<Type> checkMinMaxOperator(storm::property::prctl::AbstractPathFormula<Type> const & formula, bool minimumOperator) const { + minimumOperatorStack.push(minimumOperator); + std::vector<Type> result = formula.check(*this, false); + minimumOperatorStack.pop(); + return result; + } + + /*! + * Checks the given formula and determines whether minimum or maximum probabilities or rewards are to be computed for the formula. + * + * @param formula The formula to check. + * @param minimumOperator True iff minimum probabilities/rewards are to be computed. + * @returns The set of states satisfying the formula represented by a bit vector. + */ + virtual std::vector<Type> checkMinMaxOperator(storm::property::prctl::AbstractStateFormula<Type> const & formula, bool minimumOperator) const { + minimumOperatorStack.push(minimumOperator); + std::vector<Type> result = formula.check(*this); + minimumOperatorStack.pop(); + return result; + } + +protected: + + /*! + * A stack used for storing whether we are currently computing min or max probabilities or rewards, respectively. + * The topmost element is true if and only if we are currently computing minimum probabilities or rewards. + */ + mutable std::stack<bool> minimumOperatorStack; + private: /*! diff --git a/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h b/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h index 2f03603d8..40994ce78 100644 --- a/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h +++ b/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h @@ -60,21 +60,6 @@ public: return AbstractModelChecker<Type>::template getModel<storm::models::Dtmc<Type>>(); } - /*! - * Checks the given formula that is a P/R operator without a bound. - * - * @param formula The formula to check. - * @returns The set of states satisfying the formula represented by a bit vector. - */ - std::vector<Type> checkNoBoundOperator(storm::property::prctl::AbstractNoBoundOperator<Type> const& formula) const { - // Check if the operator was an optimality operator and report a warning in that case. - if (formula.isOptimalityOperator()) { - LOG4CPLUS_WARN(logger, "Formula contains min/max operator, which is not meaningful over deterministic models."); - } - return formula.check(*this, false); - } - - /*! * Checks the given formula that is a bounded-until formula. * @@ -497,6 +482,42 @@ public: return result; } + /*! + * Checks the given formula. + * @note This methods overrides the method of the base class to give an additional warning that declaring that minimal or maximal probabilities + * should be computed for the formula makes no sense in the context of a deterministic model. + * + * @param formula The formula to check. + * @param minimumOperator True iff minimum probabilities/rewards are to be computed. + * @returns The probabilities to satisfy the formula or the rewards accumulated by it, represented by a vector. + */ + virtual std::vector<Type> checkMinMaxOperator(storm::property::prctl::AbstractPathFormula<Type> const & formula, bool minimumOperator) const override { + + LOG4CPLUS_WARN(logger, "Formula contains min/max operator, which is not meaningful over deterministic models."); + + std::vector<Type> result = formula.check(*this, false); + + return result; + } + + /*! + * Checks the given formula and determines whether minimum or maximum probabilities or rewards are to be computed for the formula. + * @note This methods overrides the method of the base class to give an additional warning that declaring that minimal or maximal probabilities + * should be computed for the formula makes no sense in the context of a deterministic model. + * + * @param formula The formula to check. + * @param minimumOperator True iff minimum probabilities/rewards are to be computed. + * @returns The set of states satisfying the formula represented by a bit vector. + */ + virtual std::vector<Type> checkMinMaxOperator(storm::property::prctl::AbstractStateFormula<Type> const & formula, bool minimumOperator) const override { + + LOG4CPLUS_WARN(logger, "Formula contains min/max operator, which is not meaningful over deterministic models."); + + std::vector<Type> result = formula.check(*this); + + return result; + } + private: // An object that is used for solving linear equations and performing matrix-vector multiplication. std::unique_ptr<storm::solver::LinearEquationSolver<Type>> linearEquationSolver; diff --git a/src/modelchecker/prctl/SparseMdpPrctlModelChecker.h b/src/modelchecker/prctl/SparseMdpPrctlModelChecker.h index 868f78722..1a34b1f3d 100644 --- a/src/modelchecker/prctl/SparseMdpPrctlModelChecker.h +++ b/src/modelchecker/prctl/SparseMdpPrctlModelChecker.h @@ -55,6 +55,13 @@ namespace storm { // Intentionally left empty. } + /*! + * Virtual destructor. Needs to be virtual, because this class has virtual methods. + */ + virtual ~SparseMdpPrctlModelChecker() { + // Intentionally left empty. + } + /*! * Returns a constant reference to the MDP associated with this model checker. * @returns A constant reference to the MDP associated with this model checker. @@ -62,25 +69,7 @@ namespace storm { storm::models::Mdp<Type> const& getModel() const { return AbstractModelChecker<Type>::template getModel<storm::models::Mdp<Type>>(); } - - /*! - * Checks the given formula that is a P/R operator without a bound. - * - * @param formula The formula to check. - * @returns The set of states satisfying the formula represented by a bit vector. - */ - virtual std::vector<Type> checkNoBoundOperator(const storm::property::prctl::AbstractNoBoundOperator<Type>& formula) const { - // Check if the operator was an non-optimality operator and report an error in that case. - if (!formula.isOptimalityOperator()) { - LOG4CPLUS_ERROR(logger, "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."); - throw storm::exceptions::InvalidArgumentException() << "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."; - } - minimumOperatorStack.push(formula.isMinimumOperator()); - std::vector<Type> result = formula.check(*this, false); - minimumOperatorStack.pop(); - return result; - } - + /*! * Computes the probability to satisfy phi until psi within a limited number of steps for each state. * @@ -95,7 +84,13 @@ namespace storm { * If the qualitative flag is set, exact probabilities might not be computed. */ std::vector<Type> checkBoundedUntil(storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, uint_fast64_t stepBound, bool qualitative) const { - std::vector<Type> result(this->getModel().getNumberOfStates()); + // First test if it is specified if the minimum or maximum probabilities are to be computed. + if(this->minimumOperatorStack.empty()) { + LOG4CPLUS_ERROR(logger, "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."); + throw storm::exceptions::InvalidArgumentException() << "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."; + } + + std::vector<Type> result(this->getModel().getNumberOfStates()); // Determine the states that have 0 probability of reaching the target states. storm::storage::BitVector statesWithProbabilityGreater0; @@ -166,6 +161,12 @@ namespace storm { * qualitative flag is set, exact probabilities might not be computed. */ virtual std::vector<Type> checkNext(storm::storage::BitVector const& nextStates, bool qualitative) const { + // First test if it is specified if the minimum or maximum probabilities are to be computed. + if(this->minimumOperatorStack.empty()) { + LOG4CPLUS_ERROR(logger, "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."); + throw storm::exceptions::InvalidArgumentException() << "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."; + } + // Create the vector with which to multiply and initialize it correctly. std::vector<Type> result(this->getModel().getNumberOfStates()); storm::utility::vector::setVectorValues(result, nextStates, storm::utility::constantOne<Type>()); @@ -260,6 +261,12 @@ namespace storm { * checker. If the qualitative flag is set, exact probabilities might not be computed. */ virtual std::vector<Type> checkUntil(const storm::property::prctl::Until<Type>& formula, bool qualitative) const { + // First test if it is specified if the minimum or maximum probabilities are to be computed. + if(this->minimumOperatorStack.empty()) { + LOG4CPLUS_ERROR(logger, "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."); + throw storm::exceptions::InvalidArgumentException() << "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."; + } + return this->checkUntil(this->minimumOperatorStack.top(), formula.getLeft().check(*this), formula.getRight().check(*this), qualitative).first; } @@ -365,6 +372,12 @@ namespace storm { throw storm::exceptions::InvalidPropertyException() << "Missing (state-based) reward model for formula."; } + // Now test whether it is specified if the minimum or maximum probabilities are to be computed. + if(this->minimumOperatorStack.empty()) { + LOG4CPLUS_ERROR(logger, "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."); + throw storm::exceptions::InvalidArgumentException() << "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."; + } + // Initialize result to state rewards of the model. std::vector<Type> result(this->getModel().getStateRewardVector()); @@ -391,6 +404,12 @@ namespace storm { throw storm::exceptions::InvalidPropertyException() << "Missing reward model for formula."; } + // Now test whether it is specified if the minimum or maximum probabilities are to be computed. + if(this->minimumOperatorStack.empty()) { + LOG4CPLUS_ERROR(logger, "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."); + throw storm::exceptions::InvalidArgumentException() << "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."; + } + // Compute the reward vector to add in each step based on the available reward models. std::vector<Type> totalRewardVector; if (this->getModel().hasTransitionRewards()) { @@ -427,6 +446,12 @@ namespace storm { * checker. If the qualitative flag is set, exact values might not be computed. */ virtual std::vector<Type> checkReachabilityReward(const storm::property::prctl::ReachabilityReward<Type>& formula, bool qualitative) const { + // First test whether it is specified if the minimum or maximum probabilities are to be computed. + if(this->minimumOperatorStack.empty()) { + LOG4CPLUS_ERROR(logger, "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."); + throw storm::exceptions::InvalidArgumentException() << "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."; + } + return this->checkReachabilityReward(this->minimumOperatorStack.top(), formula.getChild().check(*this), qualitative).first; } @@ -452,6 +477,12 @@ namespace storm { throw storm::exceptions::InvalidPropertyException() << "Missing reward model for formula."; } + // Also test whether it is specified if the minimum or maximum probabilities are to be computed. + if(this->minimumOperatorStack.empty()) { + LOG4CPLUS_ERROR(logger, "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."); + throw storm::exceptions::InvalidArgumentException() << "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."; + } + // Determine which states have a reward of infinity by definition. storm::storage::BitVector infinityStates; storm::storage::BitVector trueStates(this->getModel().getNumberOfStates(), true); @@ -570,13 +601,7 @@ namespace storm { return storm::storage::TotalScheduler(choices); } - - /*! - * A stack used for storing whether we are currently computing min or max probabilities or rewards, respectively. - * The topmost element is true if and only if we are currently computing minimum probabilities or rewards. - */ - mutable std::stack<bool> minimumOperatorStack; - + /*! * A solver that is used for solving systems of linear equations that are the result of nondeterministic choices. */ From a6f20400dfd707a3b8045883899a0e3de91b739f Mon Sep 17 00:00:00 2001 From: masawei <manuel.sascha.weiand@rwth-aachen.de> Date: Wed, 7 May 2014 22:00:18 +0200 Subject: [PATCH 06/30] Added similar filters for Ltl and Csl. - Fixed similar undefined behavior for the MarkovAutomaton Csl modelchecker. Next up: Make necessary changes to the formula parsers. Former-commit-id: e8765fe58be01788fda3ff7d97c3eefd7fcdb3d2 --- src/formula/Csl/CslFilter.h | 211 ++++++++++++++++++ src/formula/Ltl/LtlFilter.h | 138 ++++++++++++ src/formula/Prctl/PrctlFilter.h | 10 +- src/modelchecker/csl/AbstractModelChecker.h | 108 ++++----- .../SparseMarkovAutomatonCslModelChecker.h | 51 +++-- src/modelchecker/ltl/AbstractModelChecker.h | 26 --- src/modelchecker/prctl/AbstractModelChecker.h | 8 +- .../prctl/SparseDtmcPrctlModelChecker.h | 4 +- .../prctl/SparseMdpPrctlModelChecker.h | 7 +- 9 files changed, 428 insertions(+), 135 deletions(-) create mode 100644 src/formula/Csl/CslFilter.h create mode 100644 src/formula/Ltl/LtlFilter.h diff --git a/src/formula/Csl/CslFilter.h b/src/formula/Csl/CslFilter.h new file mode 100644 index 000000000..db59a59a7 --- /dev/null +++ b/src/formula/Csl/CslFilter.h @@ -0,0 +1,211 @@ +/* + * CslFilter.h + * + * Created on: May 7, 2014 + * Author: Manuel Sascha Weiand + */ + +#ifndef STORM_FORMULA_PRCTL_CSLFILTER_H_ +#define STORM_FORMULA_PRCTL_CSLFILTER_H_ + +#include "src/formula/AbstractFilter.h" +#include "src/formula/Csl/AbstractCslFormula.h" +#include "src/formula/Csl/AbstractPathFormula.h" +#include "src/formula/Csl/AbstractStateFormula.h" + +namespace storm { +namespace property { +namespace csl { + +template <class T> +class CslFilter : storm::property::AbstractFilter<T> { + +public: + + CslFilter() : child(nullptr) { + // Intentionally left empty. + } + + CslFilter(AbstractCslFormula* child) : child(child) { + // Intentionally left empty. + } + + CslFilter(AbstractCslFormula* child, action::Action<T>* action) : child(child) { + actions.push_back(action); + } + + CslFilter(AbstractCslFormula* child, std::vector<action::Action<T>*> actions) : child(child), actions(actions) { + // Intentionally left empty. + } + + virtual ~CslFilter() { + actions.clear(); + delete child; + } + + void check(AbstractModelChecker const & modelchecker) const { + + // Write out the formula to be checked. + std::cout << std::endl; + LOG4CPLUS_INFO(logger, "Model checking formula\t" << this->toFormulaString()); + std::cout << "Model checking formula:\t" << this->toFormulaString() << std::endl; + + // Do a dynamic cast to test for the actual formula type and call the correct evaluation function. + if(dynamic_cast<AbstractStateFormula<T>*>(child) != nullptr) { + + // Check the formula and apply the filter actions. + storm::storage::BitVector result; + + try { + result = evaluate(modelchecker, static_cast<AbstractStateFormula<T>*>(child)); + } catch (std::exception& e) { + std::cout << "Error during computation: " << e.what() << "Skipping property." << std::endl; + LOG4CPLUS_ERROR(logger, "Error during computation: " << e.what() << "Skipping property."); + std::cout << std::endl << "-------------------------------------------" << std::endl; + + return; + } + + // Now write out the result. + + if(actions.empty()) { + + // There is no filter action given. So provide legacy support: + // Return the results for all states labeled with "init". + LOG4CPLUS_INFO(logger, "Result for initial states:"); + std::cout << "Result for initial states:" << std::endl; + for (auto initialState : modelchecker.getModel<storm::models::AbstractModel<T>>().getInitialStates()) { + LOG4CPLUS_INFO(logger, "\t" << initialState << ": " << (result.get(initialState) ? "satisfied" : "not satisfied")); + std::cout << "\t" << initialState << ": " << result.get(initialState) << std::endl; + } + } + + std::cout << std::endl << "-------------------------------------------" << std::endl; + + } + else if (dynamic_cast<AbstractPathFormula<T>*>(child) != nullptr) { + + // Check the formula and apply the filter actions. + std::vector<T> result; + + try { + result = evaluate(modelchecker, static_cast<AbstractPathFormula<T>*>(child)); + } catch (std::exception& e) { + std::cout << "Error during computation: " << e.what() << "Skipping property." << std::endl; + LOG4CPLUS_ERROR(logger, "Error during computation: " << e.what() << "Skipping property."); + std::cout << std::endl << "-------------------------------------------" << std::endl; + + return; + } + + // Now write out the result. + + if(actions.empty()) { + + // There is no filter action given. So provide legacy support: + // Return the results for all states labeled with "init". + LOG4CPLUS_INFO(logger, "Result for initial states:"); + std::cout << "Result for initial states:" << std::endl; + for (auto initialState : modelchecker.getModel<storm::models::AbstractModel<T>>().getInitialStates()) { + LOG4CPLUS_INFO(logger, "\t" << initialState << ": " << result[initialState]); + std::cout << "\t" << initialState << ": " << result[initialState] << std::endl; + } + } + + std::cout << std::endl << "-------------------------------------------" << std::endl; + + } + else { + // This branch should be unreachable. If you ended up here, something strange has happened. + //TODO: Error here. + } + } + + bool validate() const { + // Test whether the stored filter actions are consistent in relation to themselves and to the ingoing modelchecking result. + + // Do a dynamic cast to test for the actual formula type. + if(dynamic_cast<AbstractStateFormula<T>*>(child) != nullptr) { + //TODO: Actual validation. + } + else if (dynamic_cast<AbstractPathFormula<T>*>(child) != nullptr) { + //TODO: Actual validation. + } + else { + // This branch should be unreachable. If you ended up here, something strange has happened. + //TODO: Error here. + } + + return true; + } + + std::string toFormulaString() const { + std::string desc = "filter("; + return desc; + } + + std::string toString() const { + std::string desc = "Filter: "; + desc += "\nActions:"; + for(auto action : actions) { + desc += "\n\t" + action.toString(); + } + desc += "\nFormula:\n\t" + child->toString(); + return desc; + } + + void setChild(AbstractCslFormula* child) { + this->child = child; + } + + AbstractFormula* getChild() const { + return child; + } + +private: + + BitVector evaluate(AbstractModelChecker const & modelchecker, AbstractStateFormula<T>* formula) const { + // First, get the model checking result. + BitVector result = modelchecker.checkMinMaxOperator(formula); + + if(getActionCount() != 0 && dynamic_cast<MinMaxAction<T>*>(getAction(0)) != nullptr) { + // If there is an action specifying that min/max probabilities should be computed, call the appropriate method of the model checker. + result = modelchecker.checkMinMaxOperator(formula, static_cast<MinMaxAction<T>*>(getAction(0))->getMinimize()); + } else { + result = formula->check(modelchecker); + } + + + // Now apply all filter actions and return the result. + for(auto action : actions) { + result = action->evaluate(result); + } + return result; + } + + std::vector<T> evaluate(AbstractModelChecker const & modelchecker, AbstractPathFormula<T>* formula) const { + // First, get the model checking result. + std::vector<T> result; + + if(getActionCount() != 0 && dynamic_cast<MinMaxAction<T>*>(getAction(0)) != nullptr) { + // If there is an action specifying that min/max probabilities should be computed, call the appropriate method of the model checker. + result = modelchecker.checkMinMaxOperator(formula, static_cast<MinMaxAction<T>*>(getAction(0))->getMinimize()); + } else { + result = formula->check(modelchecker, false); + } + + // Now apply all filter actions and return the result. + for(auto action : actions) { + result = action->evaluate(result); + } + return result; + } + + AbstractCslFormula* child; +}; + +} //namespace csl +} //namespace property +} //namespace storm + +#endif /* STORM_FORMULA_CSL_CSLFILTER_H_ */ diff --git a/src/formula/Ltl/LtlFilter.h b/src/formula/Ltl/LtlFilter.h new file mode 100644 index 000000000..6fbb6398e --- /dev/null +++ b/src/formula/Ltl/LtlFilter.h @@ -0,0 +1,138 @@ +/* + * LtlFilter.h + * + * Created on: May 7, 2014 + * Author: Manuel Sascha Weiand + */ + +#ifndef STORM_FORMULA_LTL_LTLFILTER_H_ +#define STORM_FORMULA_LTL_LTLFILTER_H_ + +namespace storm { +namespace property { +namespace ltl { + +template <class T> +class LtlFilter : storm::property::AbstractFilter<T> { + +public: + + LtlFilter() : child(nullptr) { + // Intentionally left empty. + } + + LtlFilter(AbstractLtlFormula* child) : child(child) { + // Intentionally left empty. + } + + LtlFilter(AbstractLtlFormula* child, action::Action<T>* action) : child(child) { + actions.push_back(action); + } + + LtlFilter(AbstractLtlFormula* child, std::vector<action::Action<T>*> actions) : child(child), actions(actions) { + // Intentionally left empty. + } + + virtual ~LtlFilter() { + actions.clear(); + delete child; + } + + + /*!Description copied from the MC. + * Checks the given state formula on the model and prints the result (true/false) for all initial states, i.e. + * states that carry the atomic proposition "init". + * + * @param stateFormula The formula to be checked. + */ + void check(AbstractModelChecker const & modelchecker) const { + + // Write out the formula to be checked. + std::cout << std::endl; + LOG4CPLUS_INFO(logger, "Model checking formula\t" << this->toFormulaString()); + std::cout << "Model checking formula:\t" << this->toFormulaString() << std::endl; + + + // Check the formula and apply the filter actions. + storm::storage::BitVector result; + + try { + result = evaluate(modelchecker, child); + } catch (std::exception& e) { + std::cout << "Error during computation: " << e.what() << "Skipping property." << std::endl; + LOG4CPLUS_ERROR(logger, "Error during computation: " << e.what() << "Skipping property."); + std::cout << std::endl << "-------------------------------------------" << std::endl; + + return; + } + + // Now write out the result. + + if(actions.empty()) { + + // There is no filter action given. So provide legacy support: + // Return the results for all states labeled with "init". + LOG4CPLUS_INFO(logger, "Result for initial states:"); + std::cout << "Result for initial states:" << std::endl; + for (auto initialState : modelchecker.getModel<storm::models::AbstractModel<T>>().getInitialStates()) { + LOG4CPLUS_INFO(logger, "\t" << initialState << ": " << (result.get(initialState) ? "satisfied" : "not satisfied")); + std::cout << "\t" << initialState << ": " << result.get(initialState) << std::endl; + } + } + + std::cout << std::endl << "-------------------------------------------" << std::endl; + } + + bool validate() const { + // Test whether the stored filter actions are consistent in relation to themselves and to the ingoing modelchecking result. + + //TODO: Actual validation. + + return true; + } + + std::string toFormulaString() const { + std::string desc = "filter("; + return desc; + } + + std::string toString() const { + std::string desc = "Filter: "; + desc += "\nActions:"; + for(auto action : actions) { + desc += "\n\t" + action.toString(); + } + desc += "\nFormula:\n\t" + child->toString(); + return desc; + } + + void setChild(AbstractLtlFormula* child) { + this->child = child; + } + + AbstractFormula* getChild() const { + return child; + } + +private: + + storm::storage::BitVector evaluate(AbstractModelChecker const & modelchecker, AbstractLtlFormula<T>* formula) const { + // First, get the model checking result. + storm::storage::BitVector result = formula->check(modelchecker); + + // Now apply all filter actions and return the result. + for(auto action : actions) { + result = action->evaluate(result); + } + return result; + } + + AbstractLtlFormula* child; +}; + + +} //namespace ltl +} //namespace property +} //namespace storm + +#endif /* STORM_FORMULA_LTL_LTLFILTER_H_ */ diff --git a/src/formula/Prctl/PrctlFilter.h b/src/formula/Prctl/PrctlFilter.h index f01c0b4b9..9af9dc39a 100644 --- a/src/formula/Prctl/PrctlFilter.h +++ b/src/formula/Prctl/PrctlFilter.h @@ -26,15 +26,15 @@ public: // Intentionally left empty. } - PrctlFilter(AbstractFormula* child) : child(child) { + PrctlFilter(AbstractPrctlFormula* child) : child(child) { // Intentionally left empty. } - PrctlFilter(AbstractFormula* child, action::Action<T>* action) : child(child) { + PrctlFilter(AbstractPrctlFormula* child, action::Action<T>* action) : child(child) { actions.push_back(action); } - PrctlFilter(AbstractFormula* child, std::vector<action::Action<T>*> actions) : child(child), actions(actions) { + PrctlFilter(AbstractPrctlFormula* child, std::vector<action::Action<T>*> actions) : child(child), actions(actions) { // Intentionally left empty. } @@ -154,7 +154,7 @@ public: return desc; } - void setChild(AbstractFormula* child) { + void setChild(AbstractPrctlFormula* child) { this->child = child; } @@ -164,7 +164,7 @@ public: private: - BitVector<T> evaluate(AbstractModelChecker const & modelchecker, AbstractStateFormula<T>* formula) const { + BitVector evaluate(AbstractModelChecker const & modelchecker, AbstractStateFormula<T>* formula) const { // First, get the model checking result. BitVector result = modelchecker.checkMinMaxOperator(formula); diff --git a/src/modelchecker/csl/AbstractModelChecker.h b/src/modelchecker/csl/AbstractModelChecker.h index 36499884a..a80b39445 100644 --- a/src/modelchecker/csl/AbstractModelChecker.h +++ b/src/modelchecker/csl/AbstractModelChecker.h @@ -8,6 +8,7 @@ #ifndef STORM_MODELCHECKER_CSL_ABSTRACTMODELCHECKER_H_ #define STORM_MODELCHECKER_CSL_ABSTRACTMODELCHECKER_H_ +#include <stack> #include "src/exceptions/InvalidPropertyException.h" #include "src/formula/Csl.h" #include "src/storage/BitVector.h" @@ -52,14 +53,14 @@ public: /*! * Constructs an AbstractModelChecker with the given model. */ - explicit AbstractModelChecker(storm::models::AbstractModel<Type> const& model) : model(model) { + explicit AbstractModelChecker(storm::models::AbstractModel<Type> const& model) : minimumOperatorStack(), model(model) { // Intentionally left empty. } /*! * Copy constructs an AbstractModelChecker from the given model checker. In particular, this means that the newly * constructed model checker will have the model of the given model checker as its associated model. */ - explicit AbstractModelChecker(AbstractModelChecker<Type> const& modelchecker) : model(modelchecker.model) { + explicit AbstractModelChecker(AbstractModelChecker<Type> const& modelchecker) : minimumOperatorStack(), model(modelchecker.model) { // Intentionally left empty. } @@ -105,71 +106,6 @@ public: } } - /*! - * Checks the given abstract prctl formula on the model and prints the result (depending on the actual type of the formula) - * for all initial states, i.e. states that carry the atomic proposition "init". - * - * @param formula The formula to be checked. - */ - void check(storm::property::csl::AbstractCslFormula<Type> const& formula) const { - if (dynamic_cast<storm::property::csl::AbstractStateFormula<Type> const*>(&formula) != nullptr) { - this->check(static_cast<storm::property::csl::AbstractStateFormula<Type> const&>(formula)); - } else if (dynamic_cast<storm::property::csl::AbstractNoBoundOperator<Type> const*>(&formula) != nullptr) { - this->check(static_cast<storm::property::csl::AbstractNoBoundOperator<Type> const&>(formula)); - } - } - - /*! - * Checks the given state formula on the model and prints the result (true/false) for all initial states, i.e. - * states that carry the atomic proposition "init". - * - * @param stateFormula The formula to be checked. - */ - void check(storm::property::csl::AbstractStateFormula<Type> const& stateFormula) const { - std::cout << std::endl; - LOG4CPLUS_INFO(logger, "Model checking formula\t" << stateFormula.toString()); - std::cout << "Model checking formula:\t" << stateFormula.toString() << std::endl; - storm::storage::BitVector result; - try { - result = stateFormula.check(*this); - LOG4CPLUS_INFO(logger, "Result for initial states:"); - std::cout << "Result for initial states:" << std::endl; - for (auto initialState : model.getInitialStates()) { - LOG4CPLUS_INFO(logger, "\t" << initialState << ": " << (result.get(initialState) ? "satisfied" : "not satisfied")); - std::cout << "\t" << initialState << ": " << result.get(initialState) << std::endl; - } - } catch (std::exception& e) { - std::cout << "Error during computation: " << e.what() << "Skipping property." << std::endl; - LOG4CPLUS_ERROR(logger, "Error during computation: " << e.what() << "Skipping property."); - } - std::cout << std::endl << "-------------------------------------------" << std::endl; - } - - /*! - * Checks the given formula (with no bound) on the model and prints the result (probability/rewards) for all - * initial states, i.e. states that carry the atomic proposition "init". - * - * @param noBoundFormula The formula to be checked. - */ - void check(storm::property::csl::AbstractNoBoundOperator<Type> const& noBoundFormula) const { - std::cout << std::endl; - LOG4CPLUS_INFO(logger, "Model checking formula\t" << noBoundFormula.toString()); - std::cout << "Model checking formula:\t" << noBoundFormula.toString() << std::endl; - std::vector<Type> result; - try { - result = this->checkNoBoundOperator(noBoundFormula); - LOG4CPLUS_INFO(logger, "Result for initial states:"); - std::cout << "Result for initial states:" << std::endl; - for (auto initialState : model.getInitialStates()) { - LOG4CPLUS_INFO(logger, "\t" << initialState << ": " << (*result)[initialState]); - std::cout << "\t" << initialState << ": " << (*result)[initialState] << std::endl; - } - } catch (std::exception& e) { - std::cout << "Error during computation: " << e.what() << " Skipping property." << std::endl; - } - std::cout << std::endl << "-------------------------------------------" << std::endl; - } - /*! * Checks the given formula consisting of a single atomic proposition. * @@ -254,6 +190,42 @@ public: return result; } + /*! + * Checks the given formula and determines whether minimum or maximum probabilities or rewards are to be computed for the formula. + * + * @param formula The formula to check. + * @param minimumOperator True iff minimum probabilities/rewards are to be computed. + * @returns The probabilities to satisfy the formula or the rewards accumulated by it, represented by a vector. + */ + virtual std::vector<Type> checkMinMaxOperator(storm::property::csl::AbstractPathFormula<Type> const & formula, bool minimumOperator) const { + minimumOperatorStack.push(minimumOperator); + std::vector<Type> result = formula.check(*this, false); + minimumOperatorStack.pop(); + return result; + } + + /*! + * Checks the given formula and determines whether minimum or maximum probabilities or rewards are to be computed for the formula. + * + * @param formula The formula to check. + * @param minimumOperator True iff minimum probabilities/rewards are to be computed. + * @returns The set of states satisfying the formula represented by a bit vector. + */ + virtual storm::storage::BitVector checkMinMaxOperator(storm::property::csl::AbstractStateFormula<Type> const & formula, bool minimumOperator) const { + minimumOperatorStack.push(minimumOperator); + storm::storage::BitVector result = formula.check(*this); + minimumOperatorStack.pop(); + return result; + } + +protected: + + /*! + * A stack used for storing whether we are currently computing min or max probabilities or rewards, respectively. + * The topmost element is true if and only if we are currently computing minimum probabilities or rewards. + */ + mutable std::stack<bool> minimumOperatorStack; + private: /*! @@ -269,4 +241,4 @@ private: } // namespace modelchecker } // namespace storm -#endif /* STORM_MODELCHECKER_CSL_DTMCPRCTLMODELCHECKER_H_ */ +#endif /* STORM_MODELCHECKER_CSL_ABSTRACTMODELCHECKER_H_ */ diff --git a/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h b/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h index a4cd0844a..629e809af 100644 --- a/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h +++ b/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h @@ -1,7 +1,6 @@ #ifndef STORM_MODELCHECKER_CSL_SPARSEMARKOVAUTOMATONCSLMODELCHECKER_H_ #define STORM_MODELCHECKER_CSL_SPARSEMARKOVAUTOMATONCSLMODELCHECKER_H_ -#include <stack> #include <utility> #include "src/modelchecker/csl/AbstractModelChecker.h" @@ -22,7 +21,7 @@ namespace storm { template<typename ValueType> class SparseMarkovAutomatonCslModelChecker : public AbstractModelChecker<ValueType> { public: - explicit SparseMarkovAutomatonCslModelChecker(storm::models::MarkovAutomaton<ValueType> const& model, std::shared_ptr<storm::solver::NondeterministicLinearEquationSolver<ValueType>> nondeterministicLinearEquationSolver) : AbstractModelChecker<ValueType>(model), minimumOperatorStack(), nondeterministicLinearEquationSolver(nondeterministicLinearEquationSolver) { + explicit SparseMarkovAutomatonCslModelChecker(storm::models::MarkovAutomaton<ValueType> const& model, std::shared_ptr<storm::solver::NondeterministicLinearEquationSolver<ValueType>> nondeterministicLinearEquationSolver) : AbstractModelChecker<ValueType>(model), nondeterministicLinearEquationSolver(nondeterministicLinearEquationSolver) { // Intentionally left empty. } @@ -30,7 +29,7 @@ namespace storm { This Second constructor is NEEDED and a workaround for a common Bug in C++ with nested templates See: http://stackoverflow.com/questions/14401308/visual-c-cannot-deduce-given-template-arguments-for-function-used-as-defaul */ - explicit SparseMarkovAutomatonCslModelChecker(storm::models::MarkovAutomaton<ValueType> const& model) : AbstractModelChecker<ValueType>(model), minimumOperatorStack(), nondeterministicLinearEquationSolver(storm::utility::solver::getNondeterministicLinearEquationSolver<ValueType>()) { + explicit SparseMarkovAutomatonCslModelChecker(storm::models::MarkovAutomaton<ValueType> const& model) : AbstractModelChecker<ValueType>(model), nondeterministicLinearEquationSolver(storm::utility::solver::getNondeterministicLinearEquationSolver<ValueType>()) { // Intentionally left empty. } @@ -43,9 +42,15 @@ namespace storm { } std::vector<ValueType> checkUntil(storm::property::csl::Until<ValueType> const& formula, bool qualitative) const { - storm::storage::BitVector leftStates = formula.getLeft().check(*this); + // Test whether it is specified if the minimum or maximum probabilities are to be computed. + if(this->minimumOperatorStack.empty()) { + LOG4CPLUS_ERROR(logger, "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."); + throw storm::exceptions::InvalidArgumentException() << "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."; + } + + storm::storage::BitVector leftStates = formula.getLeft().check(*this); storm::storage::BitVector rightStates = formula.getRight().check(*this); - return computeUnboundedUntilProbabilities(minimumOperatorStack.top(), leftStates, rightStates, qualitative).first; + return computeUnboundedUntilProbabilities(this->minimumOperatorStack.top(), leftStates, rightStates, qualitative).first; } std::pair<std::vector<ValueType>, storm::storage::TotalScheduler> computeUnboundedUntilProbabilities(bool min, storm::storage::BitVector const& leftStates, storm::storage::BitVector const& rightStates, bool qualitative) const { @@ -57,7 +62,13 @@ namespace storm { } std::vector<ValueType> checkTimeBoundedEventually(storm::property::csl::TimeBoundedEventually<ValueType> const& formula, bool qualitative) const { - storm::storage::BitVector goalStates = formula.getChild().check(*this); + // Test whether it is specified if the minimum or maximum probabilities are to be computed. + if(this->minimumOperatorStack.empty()) { + LOG4CPLUS_ERROR(logger, "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."); + throw storm::exceptions::InvalidArgumentException() << "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."; + } + + storm::storage::BitVector goalStates = formula.getChild().check(*this); return this->checkTimeBoundedEventually(this->minimumOperatorStack.top(), goalStates, formula.getLowerBound(), formula.getUpperBound()); } @@ -66,26 +77,20 @@ namespace storm { } std::vector<ValueType> checkEventually(storm::property::csl::Eventually<ValueType> const& formula, bool qualitative) const { - storm::storage::BitVector subFormulaStates = formula.getChild().check(*this); - return computeUnboundedUntilProbabilities(minimumOperatorStack.top(), storm::storage::BitVector(this->getModel().getNumberOfStates(), true), subFormulaStates, qualitative).first; + // Test whether it is specified if the minimum or maximum probabilities are to be computed. + if(this->minimumOperatorStack.empty()) { + LOG4CPLUS_ERROR(logger, "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."); + throw storm::exceptions::InvalidArgumentException() << "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."; + } + + storm::storage::BitVector subFormulaStates = formula.getChild().check(*this); + return computeUnboundedUntilProbabilities(this->minimumOperatorStack.top(), storm::storage::BitVector(this->getModel().getNumberOfStates(), true), subFormulaStates, qualitative).first; } std::vector<ValueType> checkNext(storm::property::csl::Next<ValueType> const& formula, bool qualitative) const { throw storm::exceptions::NotImplementedException() << "Model checking Next formulas on Markov automata is not yet implemented."; } - std::vector<ValueType> checkNoBoundOperator(storm::property::csl::AbstractNoBoundOperator<ValueType> const& formula) const { - // Check if the operator was an non-optimality operator and report an error in that case. - if (!formula.isOptimalityOperator()) { - LOG4CPLUS_ERROR(logger, "Formula does not specify neither min nor max optimality, which is not meaningful for nondeterministic models."); - throw storm::exceptions::InvalidArgumentException() << "Formula does not specify neither min nor max optimality, which is not meaningful for nondeterministic models."; - } - minimumOperatorStack.push(formula.isMinimumOperator()); - std::vector<ValueType> result = formula.check(*this, false); - minimumOperatorStack.pop(); - return result; - } - static void computeBoundedReachabilityProbabilities(bool min, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRates, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& goalStates, storm::storage::BitVector const& markovianNonGoalStates, storm::storage::BitVector const& probabilisticNonGoalStates, std::vector<ValueType>& markovianNonGoalValues, std::vector<ValueType>& probabilisticNonGoalValues, ValueType delta, uint_fast64_t numberOfSteps) { // Start by computing four sparse matrices: // * a matrix aMarkovian with all (discretized) transitions from Markovian non-goal states to all Markovian non-goal states. @@ -580,12 +585,6 @@ namespace storm { return result; } - /*! - * A stack used for storing whether we are currently computing min or max probabilities or rewards, respectively. - * The topmost element is true if and only if we are currently computing minimum probabilities or rewards. - */ - mutable std::stack<bool> minimumOperatorStack; - /*! * A solver that is used for solving systems of linear equations that are the result of nondeterministic choices. */ diff --git a/src/modelchecker/ltl/AbstractModelChecker.h b/src/modelchecker/ltl/AbstractModelChecker.h index 8cc06cdbd..03284fed6 100644 --- a/src/modelchecker/ltl/AbstractModelChecker.h +++ b/src/modelchecker/ltl/AbstractModelChecker.h @@ -104,32 +104,6 @@ public: } } - /*! - * Checks the given state formula on the model and prints the result (true/false) for all initial states, i.e. - * states that carry the atomic proposition "init". - * - * @param stateFormula The formula to be checked. - */ - void check(storm::property::ltl::AbstractLtlFormula<Type> const& ltlFormula) const { - std::cout << std::endl; - LOG4CPLUS_INFO(logger, "Model checking formula\t" << ltlFormula.toString()); - std::cout << "Model checking formula:\t" << ltlFormula.toString() << std::endl; - storm::storage::BitVector result; - try { - result = ltlFormula.check(*this); - LOG4CPLUS_INFO(logger, "Result for initial states:"); - std::cout << "Result for initial states:" << std::endl; - for (auto initialState : model.getInitialStates()) { - LOG4CPLUS_INFO(logger, "\t" << initialState << ": " << (result.get(initialState) ? "satisfied" : "not satisfied")); - std::cout << "\t" << initialState << ": " << result.get(initialState) << std::endl; - } - } catch (std::exception& e) { - std::cout << "Error during computation: " << e.what() << "Skipping property." << std::endl; - LOG4CPLUS_ERROR(logger, "Error during computation: " << e.what() << "Skipping property."); - } - std::cout << std::endl << "-------------------------------------------" << std::endl; - } - /*! * Checks the given formula consisting of a single atomic proposition. * diff --git a/src/modelchecker/prctl/AbstractModelChecker.h b/src/modelchecker/prctl/AbstractModelChecker.h index cbf5830e4..5eaa14f80 100644 --- a/src/modelchecker/prctl/AbstractModelChecker.h +++ b/src/modelchecker/prctl/AbstractModelChecker.h @@ -67,14 +67,14 @@ public: /*! * Constructs an AbstractModelChecker with the given model. */ - explicit AbstractModelChecker(storm::models::AbstractModel<Type> const& model) : model(model){ + explicit AbstractModelChecker(storm::models::AbstractModel<Type> const& model) : minimumOperatorStack(), model(model) { // Intentionally left empty. } /*! * Copy constructs an AbstractModelChecker from the given model checker. In particular, this means that the newly * constructed model checker will have the model of the given model checker as its associated model. */ - explicit AbstractModelChecker(AbstractModelChecker<Type> const& modelchecker) : model(modelchecker.model) { + explicit AbstractModelChecker(AbstractModelChecker<Type> const& modelchecker) : minimumOperatorStack(), model(modelchecker.model) { // Intentionally left empty. } @@ -250,9 +250,9 @@ public: * @param minimumOperator True iff minimum probabilities/rewards are to be computed. * @returns The set of states satisfying the formula represented by a bit vector. */ - virtual std::vector<Type> checkMinMaxOperator(storm::property::prctl::AbstractStateFormula<Type> const & formula, bool minimumOperator) const { + virtual storm::storage::BitVector checkMinMaxOperator(storm::property::prctl::AbstractStateFormula<Type> const & formula, bool minimumOperator) const { minimumOperatorStack.push(minimumOperator); - std::vector<Type> result = formula.check(*this); + storm::storage::BitVector result = formula.check(*this); minimumOperatorStack.pop(); return result; } diff --git a/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h b/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h index 40994ce78..ba61201c7 100644 --- a/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h +++ b/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h @@ -509,11 +509,11 @@ public: * @param minimumOperator True iff minimum probabilities/rewards are to be computed. * @returns The set of states satisfying the formula represented by a bit vector. */ - virtual std::vector<Type> checkMinMaxOperator(storm::property::prctl::AbstractStateFormula<Type> const & formula, bool minimumOperator) const override { + virtual storm::storage::BitVector checkMinMaxOperator(storm::property::prctl::AbstractStateFormula<Type> const & formula, bool minimumOperator) const override { LOG4CPLUS_WARN(logger, "Formula contains min/max operator, which is not meaningful over deterministic models."); - std::vector<Type> result = formula.check(*this); + storm::storage::BitVector result = formula.check(*this); return result; } diff --git a/src/modelchecker/prctl/SparseMdpPrctlModelChecker.h b/src/modelchecker/prctl/SparseMdpPrctlModelChecker.h index 1a34b1f3d..7a9c7c29c 100644 --- a/src/modelchecker/prctl/SparseMdpPrctlModelChecker.h +++ b/src/modelchecker/prctl/SparseMdpPrctlModelChecker.h @@ -9,7 +9,6 @@ #define STORM_MODELCHECKER_PRCTL_SPARSEMDPPRCTLMODELCHECKER_H_ #include <vector> -#include <stack> #include <fstream> #include "src/modelchecker/prctl/AbstractModelChecker.h" @@ -38,11 +37,11 @@ namespace storm { * * @param model The MDP to be checked. */ - explicit SparseMdpPrctlModelChecker(storm::models::Mdp<Type> const& model) : AbstractModelChecker<Type>(model), minimumOperatorStack(), nondeterministicLinearEquationSolver(storm::utility::solver::getNondeterministicLinearEquationSolver<Type>()) { + explicit SparseMdpPrctlModelChecker(storm::models::Mdp<Type> const& model) : AbstractModelChecker<Type>(model), nondeterministicLinearEquationSolver(storm::utility::solver::getNondeterministicLinearEquationSolver<Type>()) { // Intentionally left empty. } - explicit SparseMdpPrctlModelChecker(storm::models::Mdp<Type> const& model, std::shared_ptr<storm::solver::NondeterministicLinearEquationSolver<Type>> nondeterministicLinearEquationSolver) : AbstractModelChecker<Type>(model), minimumOperatorStack(), nondeterministicLinearEquationSolver(nondeterministicLinearEquationSolver) { + explicit SparseMdpPrctlModelChecker(storm::models::Mdp<Type> const& model, std::shared_ptr<storm::solver::NondeterministicLinearEquationSolver<Type>> nondeterministicLinearEquationSolver) : AbstractModelChecker<Type>(model), nondeterministicLinearEquationSolver(nondeterministicLinearEquationSolver) { // Intentionally left empty. } @@ -51,7 +50,7 @@ namespace storm { * constructed model checker will have the model of the given model checker as its associated model. */ explicit SparseMdpPrctlModelChecker(storm::modelchecker::prctl::SparseMdpPrctlModelChecker<Type> const& modelchecker) - : AbstractModelChecker<Type>(modelchecker), minimumOperatorStack(), nondeterministicLinearEquationSolver(storm::utility::solver::getNondeterministicLinearEquationSolver<Type>()) { + : AbstractModelChecker<Type>(modelchecker), nondeterministicLinearEquationSolver(storm::utility::solver::getNondeterministicLinearEquationSolver<Type>()) { // Intentionally left empty. } From 0a2f9749837cd4d4c00601e323ccfb98860cb353 Mon Sep 17 00:00:00 2001 From: masawei <manuel.sascha.weiand@rwth-aachen.de> Date: Thu, 8 May 2014 12:07:22 +0200 Subject: [PATCH 07/30] Added rules to the prctl parser to support filters. Next up: Make rules for legacy support, make parser static. Former-commit-id: 4d0c811adb6e18b6956fd10cabac25e1bdc9f451 --- .../Actions/{Action.h => AbstractAction.h} | 12 ++-- src/formula/Actions/MinMaxAction.h | 12 +++- src/formula/Actions/RangeAction.h | 4 +- src/parser/PrctlParser.cpp | 64 +++++++++---------- 4 files changed, 47 insertions(+), 45 deletions(-) rename src/formula/Actions/{Action.h => AbstractAction.h} (77%) diff --git a/src/formula/Actions/Action.h b/src/formula/Actions/AbstractAction.h similarity index 77% rename from src/formula/Actions/Action.h rename to src/formula/Actions/AbstractAction.h index dd7bd3502..d5a548046 100644 --- a/src/formula/Actions/Action.h +++ b/src/formula/Actions/AbstractAction.h @@ -1,12 +1,12 @@ /* - * Action.h + * AbstractAction.h * * Created on: Apr 26, 2014 * Author: Manuel Sascha Weiand */ -#ifndef STORM_FORMULA_ACTION_ACTION_H_ -#define STORM_FORMULA_ACTION_ACTION_H_ +#ifndef STORM_FORMULA_ACTION_ABSTRACTACTION_H_ +#define STORM_FORMULA_ACTION_ABSTRACTACTION_H_ #include <vector> #include "src/storage/BitVector.h" @@ -16,7 +16,7 @@ namespace property { namespace action { template <class T> -class Action { +class AbstractAction { public: @@ -24,7 +24,7 @@ public: * Virtual destructor * To ensure that the right destructor is called */ - virtual ~Action() { + virtual ~AbstractAction() { //Intentionally left empty } @@ -58,4 +58,4 @@ public: } //namespace storm -#endif /* STORM_FORMULA_ACTION_ACTION_H_ */ +#endif /* STORM_FORMULA_ACTION_ABSTRACTACTION_H_ */ diff --git a/src/formula/Actions/MinMaxAction.h b/src/formula/Actions/MinMaxAction.h index 2c32bd964..f23dd3195 100644 --- a/src/formula/Actions/MinMaxAction.h +++ b/src/formula/Actions/MinMaxAction.h @@ -8,14 +8,14 @@ #ifndef STORM_FORMULA_ACTION_MINMAXACTION_H_ #define STORM_FORMULA_ACTION_MINMAXACTION_H_ -#include "src/formula/Actions/Action.h" +#include "src/formula/Actions/AbstractAction.h" namespace storm { namespace property { namespace action { template <class T> -class MinMaxAction : Action<T> { +class MinMaxAction : AbstractAction<T> { public: @@ -27,6 +27,14 @@ public: //Intentionally left empty. } + /*! + * Virtual destructor + * To ensure that the right destructor is called + */ + virtual ~MinMaxAction() { + //Intentionally left empty + } + /*! * */ diff --git a/src/formula/Actions/RangeAction.h b/src/formula/Actions/RangeAction.h index 58a44aa0e..5ea2bd6ee 100644 --- a/src/formula/Actions/RangeAction.h +++ b/src/formula/Actions/RangeAction.h @@ -8,14 +8,14 @@ #ifndef STORM_FORMULA_ACTION_RANGEACTION_H_ #define STORM_FORMULA_ACTION_RANGEACTION_H_ -#include "src/formula/Actions/Action.h" +#include "src/formula/Actions/AbstractAction.h" namespace storm { namespace property { namespace action { template <class T> -class RangeAction : Action<T> { +class RangeAction : AbstractAction<T> { public: diff --git a/src/parser/PrctlParser.cpp b/src/parser/PrctlParser.cpp index fb58d7ee9..e5d6d47fa 100644 --- a/src/parser/PrctlParser.cpp +++ b/src/parser/PrctlParser.cpp @@ -2,6 +2,11 @@ #include "src/utility/OsDetection.h" #include "src/utility/constants.h" +// The action class header. +#include "src/formula/Actions/AbstractAction.h" +#include "src/formula/Actions/MinMaxAction.h" +#include "src/formula/Actions/RangeAction.h" + // If the parser fails due to ill-formed data, this exception is thrown. #include "src/exceptions/WrongFormatException.h" @@ -33,7 +38,7 @@ namespace storm { namespace parser { template<typename Iterator, typename Skipper> -struct PrctlParser::PrctlGrammar : qi::grammar<Iterator, storm::property::prctl::AbstractPrctlFormula<double>*(), Skipper > { +struct PrctlParser::PrctlGrammar : qi::grammar<Iterator, storm::property::prctl::PrctlFilter<double>*(), Skipper > { PrctlGrammar() : PrctlGrammar::base_type(start) { //This block contains helper rules that may be used several times freeIdentifierName = qi::lexeme[qi::alpha >> *(qi::alnum | qi::char_('_'))]; @@ -85,30 +90,6 @@ struct PrctlParser::PrctlGrammar : qi::grammar<Iterator, storm::property::prctl: ); rewardBoundOperator.name("state formula"); - //This block defines rules for parsing formulas with noBoundOperators - noBoundOperator = (probabilisticNoBoundOperator | rewardNoBoundOperator); - noBoundOperator.name("no bound operator"); - probabilisticNoBoundOperator = ( - (qi::lit("P") >> qi::lit("min") >> qi::lit("=") >> qi::lit("?") >> qi::lit("[") >> pathFormula >> qi::lit("]"))[qi::_val = - phoenix::new_<storm::property::prctl::ProbabilisticNoBoundOperator<double> >(qi::_1, true)] | - (qi::lit("P") >> qi::lit("max") >> qi::lit("=") >> qi::lit("?") >> qi::lit("[") >> pathFormula >> qi::lit("]"))[qi::_val = - phoenix::new_<storm::property::prctl::ProbabilisticNoBoundOperator<double> >(qi::_1, false)] | - (qi::lit("P") >> qi::lit("=") >> qi::lit("?") > qi::lit("[") > pathFormula > qi::lit("]"))[qi::_val = - phoenix::new_<storm::property::prctl::ProbabilisticNoBoundOperator<double> >(qi::_1)] - ); - probabilisticNoBoundOperator.name("no bound operator"); - - rewardNoBoundOperator = ( - (qi::lit("R") >> qi::lit("min") >> qi::lit("=") >> qi::lit("?") >> qi::lit("[") >> rewardPathFormula >> qi::lit("]"))[qi::_val = - phoenix::new_<storm::property::prctl::RewardNoBoundOperator<double> >(qi::_1, true)] | - (qi::lit("R") >> qi::lit("max") >> qi::lit("=") >> qi::lit("?") >> qi::lit("[") >> rewardPathFormula >> qi::lit("]"))[qi::_val = - phoenix::new_<storm::property::prctl::RewardNoBoundOperator<double> >(qi::_1, false)] | - (qi::lit("R") >> qi::lit("=") >> qi::lit("?") >> qi::lit("[") >> rewardPathFormula >> qi::lit("]"))[qi::_val = - phoenix::new_<storm::property::prctl::RewardNoBoundOperator<double> >(qi::_1)] - - ); - rewardNoBoundOperator.name("no bound operator"); - //This block defines rules for parsing probabilistic path formulas pathFormula = (boundedEventually | eventually | next | globally | boundedUntil | until); pathFormula.name("path formula"); @@ -145,16 +126,33 @@ struct PrctlParser::PrctlGrammar : qi::grammar<Iterator, storm::property::prctl: instantaneousReward.name("path formula (for reward operator)"); steadyStateReward = (qi::lit("S"))[qi::_val = phoenix::new_<storm::property::prctl::SteadyStateReward<double>>()]; - formula = (noBoundOperator | stateFormula); + formula = (pathFormula | stateFormula); formula.name("PRCTL formula"); - start = (((formula) > (comment | qi::eps))[qi::_val = qi::_1] | - comment - ) > qi::eoi; - start.name("PRCTL formula"); + minMaxAction = qi::lit("minmax") >> qi::lit(",") >> (qi::lit("min")[qi::_val = phoenix::new_<storm::property::action::MinMaxAction<double>>(true)] | qi::lit("min")[qi::_val = storm::property::action::MinMaxAction<double>(false)]); + minMaxAction.name("minmax action for the formula filter"); + + rangeAction = (qi::lit("range") >> qi::lit(",") >> qi::uint_ >> qi::lit(",") >> qi::uint_)[qi::_val = phoenix::new_<storm::property::action::RangeAction<double>>(qi::_1, qi::_2)]; + rangeAction.name("range action for the formula filter"); + + abstractAction = (rangeAction | minMaxAction) >> (qi::eps | qi::lit(",")); + abstractAction.name("filter action"); + + filter = ((qi::eps | qi::lit("filter") >> qi::lit("[") >> +abstractAction >> qi::lit("]")) >> (formula | (qi::lit("(") >> formula >> qi::lit(")")))) + [qi::_val = phoenix::new_<storm::property::prctl::PrctlFilter<double>>(qi::_2, qi::_1)]; + filter.name("PRCTL formula filter"); + + start = (((filter) > (comment | qi::eps))[qi::_val = qi::_1] | comment) > qi::eoi; + start.name("PRCTL formula filter"); } - qi::rule<Iterator, storm::property::prctl::AbstractPrctlFormula<double>*(), Skipper> start; + qi::rule<Iterator, storm::property::prctl::PrctlFilter<double>*(), Skipper> start; + qi::rule<Iterator, storm::property::prctl::PrctlFilter<double>*(), Skipper> filter; + + qi::rule<Iterator, storm::property::action::AbstractAction<double>*(), Skipper> abstractAction; + qi::rule<Iterator, storm::property::action::RangeAction<double>*(), Skipper> rangeAction; + qi::rule<Iterator, storm::property::action::MinMaxAction<double>*(), Skipper> minMaxAction; + qi::rule<Iterator, storm::property::prctl::AbstractPrctlFormula<double>*(), Skipper> formula; qi::rule<Iterator, storm::property::prctl::AbstractPrctlFormula<double>*(), Skipper> comment; @@ -168,10 +166,6 @@ struct PrctlParser::PrctlGrammar : qi::grammar<Iterator, storm::property::prctl: qi::rule<Iterator, storm::property::prctl::ProbabilisticBoundOperator<double>*(), Skipper> probabilisticBoundOperator; qi::rule<Iterator, storm::property::prctl::RewardBoundOperator<double>*(), Skipper> rewardBoundOperator; - qi::rule<Iterator, storm::property::prctl::AbstractNoBoundOperator<double>*(), Skipper> noBoundOperator; - qi::rule<Iterator, storm::property::prctl::AbstractNoBoundOperator<double>*(), Skipper> probabilisticNoBoundOperator; - qi::rule<Iterator, storm::property::prctl::AbstractNoBoundOperator<double>*(), Skipper> rewardNoBoundOperator; - qi::rule<Iterator, storm::property::prctl::AbstractPathFormula<double>*(), Skipper> pathFormula; qi::rule<Iterator, storm::property::prctl::BoundedEventually<double>*(), Skipper> boundedEventually; qi::rule<Iterator, storm::property::prctl::Eventually<double>*(), Skipper> eventually; From cf6623c68ce8c29e28071e608198ee7c3deef148 Mon Sep 17 00:00:00 2001 From: masawei <manuel.sascha.weiand@rwth-aachen.de> Date: Thu, 15 May 2014 22:54:57 +0200 Subject: [PATCH 08/30] Intruduced legacy support. - Every PRCTL formula that worked before works now and behaves in the same way. One exception: |- Formulas of the type Pmin<0.5[Phi] and Rmin<0.5[Psi] result in a parsing error, as the comparison operator already implies the scheduler to be used. | Also, the modelchecker now actually uses the comparison operator in order to choose the correct scheduler for MDPs. Former-commit-id: d942d18e7e472dcbdfe5c1bc83d7802d1af26cd8 --- src/formula/AbstractFilter.h | 12 +-- src/formula/Actions/AbstractAction.h | 2 +- src/formula/Actions/MinMaxAction.h | 2 +- src/formula/Actions/RangeAction.h | 31 ++++++-- src/formula/Prctl/PrctlFilter.h | 56 +++++++------ src/modelchecker/prctl/AbstractModelChecker.h | 4 +- .../prctl/SparseMdpPrctlModelChecker.h | 74 +++++++++++++++++ src/parser/PrctlFileParser.cpp | 4 +- src/parser/PrctlFileParser.h | 3 +- src/parser/PrctlParser.cpp | 79 +++++++++++++------ src/parser/PrctlParser.h | 6 +- 11 files changed, 201 insertions(+), 72 deletions(-) diff --git a/src/formula/AbstractFilter.h b/src/formula/AbstractFilter.h index 6e73913c8..4031125d5 100644 --- a/src/formula/AbstractFilter.h +++ b/src/formula/AbstractFilter.h @@ -10,7 +10,7 @@ #include <vector> #include "src/formula/AbstractFormula.h" -#include "src/formula/Actions/Action.h" +#include "src/formula/Actions/AbstractAction.h" namespace storm { namespace property { @@ -24,11 +24,11 @@ public: // Intentionally left empty. } - AbstractFilter(action::Action<T>* action) { + AbstractFilter(action::AbstractAction<T>* action) { actions.push_back(action); } - AbstractFilter(std::vector<action::Action<T>*> actions) : actions(actions) { + AbstractFilter(std::vector<action::AbstractAction<T>*> actions) : actions(actions) { // Intentionally left empty. } @@ -50,7 +50,7 @@ public: return desc; } - void addAction(action::Action<T>* action) { + void addAction(action::AbstractAction<T>* action) { actions.push_back(action); } @@ -58,7 +58,7 @@ public: actions.pop_back(); } - action::Action<T>* getAction(uint_fast64_t pos) const { + action::AbstractAction<T>* getAction(uint_fast64_t pos) const { return actions[pos]; } @@ -68,7 +68,7 @@ public: protected: - std::vector<action::Action<T>*> actions; + std::vector<action::AbstractAction<T>*> actions; }; } //namespace property diff --git a/src/formula/Actions/AbstractAction.h b/src/formula/Actions/AbstractAction.h index d5a548046..c58ad6be0 100644 --- a/src/formula/Actions/AbstractAction.h +++ b/src/formula/Actions/AbstractAction.h @@ -38,7 +38,7 @@ public: /*! * */ - virtual storm::storage::BitVector<T> evaluate(storm::storage::BitVector<T> input) const { + virtual storm::storage::BitVector evaluate(storm::storage::BitVector input) const { return input; } diff --git a/src/formula/Actions/MinMaxAction.h b/src/formula/Actions/MinMaxAction.h index f23dd3195..c775700e7 100644 --- a/src/formula/Actions/MinMaxAction.h +++ b/src/formula/Actions/MinMaxAction.h @@ -15,7 +15,7 @@ namespace property { namespace action { template <class T> -class MinMaxAction : AbstractAction<T> { +class MinMaxAction : public AbstractAction<T> { public: diff --git a/src/formula/Actions/RangeAction.h b/src/formula/Actions/RangeAction.h index 5ea2bd6ee..3952419ae 100644 --- a/src/formula/Actions/RangeAction.h +++ b/src/formula/Actions/RangeAction.h @@ -10,12 +10,14 @@ #include "src/formula/Actions/AbstractAction.h" +#include <string> + namespace storm { namespace property { namespace action { template <class T> -class RangeAction : AbstractAction<T> { +class RangeAction : public AbstractAction<T> { public: @@ -49,8 +51,19 @@ public: /*! * */ - virtual storm::storage::BitVector<T> evaluate(storm::storage::BitVector<T> input) const override { - storm::storage::BitVector<T> out(to - from + 1, input.begin() + from, input.begin() + to); + virtual storm::storage::BitVector evaluate(storm::storage::BitVector input) const override { + //Initialize the output vector. + storm::storage::BitVector out(to - from + 1); + + storm::storage::BitVector::const_iterator it = input.begin(); + + //Proceed the set index iterator to the first set bit within the range. + for(; *it < from; ++it); + + //Fill the output vector. + for(; *it <= to; ++it) { + out.set(*it-from); + } return out; } @@ -58,14 +71,22 @@ public: * */ virtual std::string toString() const override { - return "range, " + from + ", " + to; + std::string out = "range, "; + out += std::to_string(from); + out += ", "; + out += std::to_string(to); + return out; } /*! * */ virtual std::string toFormulaString() const override { - return "\"range\", " + from + ", " + to; + std::string out = "\"range\", "; + out += std::to_string(from); + out += ", "; + out += std::to_string(to); + return out; } private: diff --git a/src/formula/Prctl/PrctlFilter.h b/src/formula/Prctl/PrctlFilter.h index 9af9dc39a..f766a5942 100644 --- a/src/formula/Prctl/PrctlFilter.h +++ b/src/formula/Prctl/PrctlFilter.h @@ -12,13 +12,15 @@ #include "src/formula/Prctl/AbstractPrctlFormula.h" #include "src/formula/Prctl/AbstractPathFormula.h" #include "src/formula/Prctl/AbstractStateFormula.h" +#include "src/modelchecker/prctl/AbstractModelChecker.h" +#include "src/formula/Actions/MinMaxAction.h" namespace storm { namespace property { namespace prctl { template <class T> -class PrctlFilter : storm::property::AbstractFilter<T> { +class PrctlFilter : public storm::property::AbstractFilter<T> { public: @@ -26,24 +28,28 @@ public: // Intentionally left empty. } - PrctlFilter(AbstractPrctlFormula* child) : child(child) { + PrctlFilter(AbstractPrctlFormula<T>* child) : child(child) { // Intentionally left empty. } - PrctlFilter(AbstractPrctlFormula* child, action::Action<T>* action) : child(child) { - actions.push_back(action); + PrctlFilter(AbstractPrctlFormula<T>* child, bool minimize) : child(child) { + this->actions.push_back(new storm::property::action::MinMaxAction<T>(minimize)); } - PrctlFilter(AbstractPrctlFormula* child, std::vector<action::Action<T>*> actions) : child(child), actions(actions) { + PrctlFilter(AbstractPrctlFormula<T>* child, action::AbstractAction<T>* action) : child(child) { + this->actions.push_back(action); + } + + PrctlFilter(AbstractPrctlFormula<T>* child, std::vector<action::AbstractAction<T>*> actions) : AbstractFilter<T>(actions), child(child) { // Intentionally left empty. } virtual ~PrctlFilter() { - actions.clear(); + this->actions.clear(); delete child; } - void check(AbstractModelChecker const & modelchecker) const { + void check(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelchecker) const { // Write out the formula to be checked. std::cout << std::endl; @@ -68,13 +74,13 @@ public: // Now write out the result. - if(actions.empty()) { + if(this->actions.empty()) { // There is no filter action given. So provide legacy support: // Return the results for all states labeled with "init". LOG4CPLUS_INFO(logger, "Result for initial states:"); std::cout << "Result for initial states:" << std::endl; - for (auto initialState : modelchecker.getModel<storm::models::AbstractModel<T>>().getInitialStates()) { + for (auto initialState : modelchecker.getModel().getInitialStates()) { LOG4CPLUS_INFO(logger, "\t" << initialState << ": " << (result.get(initialState) ? "satisfied" : "not satisfied")); std::cout << "\t" << initialState << ": " << result.get(initialState) << std::endl; } @@ -100,13 +106,13 @@ public: // Now write out the result. - if(actions.empty()) { + if(this->actions.empty()) { // There is no filter action given. So provide legacy support: // Return the results for all states labeled with "init". LOG4CPLUS_INFO(logger, "Result for initial states:"); std::cout << "Result for initial states:" << std::endl; - for (auto initialState : modelchecker.getModel<storm::models::AbstractModel<T>>().getInitialStates()) { + for (auto initialState : modelchecker.getModel().getInitialStates()) { LOG4CPLUS_INFO(logger, "\t" << initialState << ": " << result[initialState]); std::cout << "\t" << initialState << ": " << result[initialState] << std::endl; } @@ -147,61 +153,61 @@ public: std::string toString() const { std::string desc = "Filter: "; desc += "\nActions:"; - for(auto action : actions) { - desc += "\n\t" + action.toString(); + for(auto action : this->actions) { + desc += "\n\t" + action->toString(); } desc += "\nFormula:\n\t" + child->toString(); return desc; } - void setChild(AbstractPrctlFormula* child) { + void setChild(AbstractPrctlFormula<T>* child) { this->child = child; } - AbstractFormula* getChild() const { + AbstractPrctlFormula<T>* getChild() const { return child; } private: - BitVector evaluate(AbstractModelChecker const & modelchecker, AbstractStateFormula<T>* formula) const { + storm::storage::BitVector evaluate(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelchecker, AbstractStateFormula<T>* formula) const { // First, get the model checking result. - BitVector result = modelchecker.checkMinMaxOperator(formula); + storm::storage::BitVector result; - if(getActionCount() != 0 && dynamic_cast<MinMaxAction<T>*>(getAction(0)) != nullptr) { + if(this->getActionCount() != 0 && dynamic_cast<storm::property::action::MinMaxAction<T>*>(this->getAction(0)) != nullptr) { // If there is an action specifying that min/max probabilities should be computed, call the appropriate method of the model checker. - result = modelchecker.checkMinMaxOperator(formula, static_cast<MinMaxAction<T>*>(getAction(0))->getMinimize()); + result = modelchecker.checkMinMaxOperator(formula, static_cast<storm::property::action::MinMaxAction<T>*>(this->getAction(0))->getMinimize()); } else { result = formula->check(modelchecker); } // Now apply all filter actions and return the result. - for(auto action : actions) { + for(auto action : this->actions) { result = action->evaluate(result); } return result; } - std::vector<T> evaluate(AbstractModelChecker const & modelchecker, AbstractPathFormula<T>* formula) const { + std::vector<T> evaluate(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelchecker, AbstractPathFormula<T>* formula) const { // First, get the model checking result. std::vector<T> result; - if(getActionCount() != 0 && dynamic_cast<MinMaxAction<T>*>(getAction(0)) != nullptr) { + if(this->getActionCount() != 0 && dynamic_cast<storm::property::action::MinMaxAction<T>*>(this->getAction(0)) != nullptr) { // If there is an action specifying that min/max probabilities should be computed, call the appropriate method of the model checker. - result = modelchecker.checkMinMaxOperator(formula, static_cast<MinMaxAction<T>*>(getAction(0))->getMinimize()); + result = modelchecker.checkMinMaxOperator(formula, static_cast<storm::property::action::MinMaxAction<T>*>(this->getAction(0))->getMinimize()); } else { result = formula->check(modelchecker, false); } // Now apply all filter actions and return the result. - for(auto action : actions) { + for(auto action : this->actions) { result = action->evaluate(result); } return result; } - AbstractPrctlFormula* child; + AbstractPrctlFormula<T>* child; }; } //namespace prctl diff --git a/src/modelchecker/prctl/AbstractModelChecker.h b/src/modelchecker/prctl/AbstractModelChecker.h index 5eaa14f80..ed79fdace 100644 --- a/src/modelchecker/prctl/AbstractModelChecker.h +++ b/src/modelchecker/prctl/AbstractModelChecker.h @@ -187,7 +187,7 @@ public: * @param formula The formula to check. * @return The set of states satisfying the formula represented by a bit vector. */ - storm::storage::BitVector checkProbabilisticBoundOperator(storm::property::prctl::ProbabilisticBoundOperator<Type> const& formula) const { + virtual storm::storage::BitVector checkProbabilisticBoundOperator(storm::property::prctl::ProbabilisticBoundOperator<Type> const& formula) const { // First, we need to compute the probability for satisfying the path formula for each state. std::vector<Type> quantitativeResult = formula.getPathFormula().check(*this, false); @@ -211,7 +211,7 @@ public: * @param formula The formula to check. * @return The set of states satisfying the formula represented by a bit vector. */ - storm::storage::BitVector checkRewardBoundOperator(const storm::property::prctl::RewardBoundOperator<Type>& formula) const { + virtual storm::storage::BitVector checkRewardBoundOperator(const storm::property::prctl::RewardBoundOperator<Type>& formula) const { // First, we need to compute the probability for satisfying the path formula for each state. std::vector<Type> quantitativeResult = formula.getPathFormula().check(*this, false); diff --git a/src/modelchecker/prctl/SparseMdpPrctlModelChecker.h b/src/modelchecker/prctl/SparseMdpPrctlModelChecker.h index 7a9c7c29c..c68c1057f 100644 --- a/src/modelchecker/prctl/SparseMdpPrctlModelChecker.h +++ b/src/modelchecker/prctl/SparseMdpPrctlModelChecker.h @@ -69,6 +69,80 @@ namespace storm { return AbstractModelChecker<Type>::template getModel<storm::models::Mdp<Type>>(); } + /*! + * Checks the given formula that is a P operator over a path formula featuring a value bound. + * + * @param formula The formula to check. + * @return The set of states satisfying the formula represented by a bit vector. + */ + virtual storm::storage::BitVector checkProbabilisticBoundOperator(storm::property::prctl::ProbabilisticBoundOperator<Type> const& formula) const override { + + // For P< and P<= the MDP satisfies the formula iff the probability maximizing scheduler is used. + // For P> and P>= " iff the probability minimizing " . + if(formula.getComparisonOperator() == storm::property::LESS || formula.getComparisonOperator() == storm::property::LESS_EQUAL) { + this->minimumOperatorStack.push(false); + } + else { + this->minimumOperatorStack.push(true); + } + + // First, we need to compute the probability for satisfying the path formula for each state. + std::vector<Type> quantitativeResult = formula.getPathFormula().check(*this, false); + + //Remove the minimizing operator entry from the stack. + this->minimumOperatorStack.pop(); + + // Create resulting bit vector that will hold the yes/no-answer for every state. + storm::storage::BitVector result(quantitativeResult.size()); + + // Now, we can compute which states meet the bound specified in this operator and set the + // corresponding bits to true in the resulting vector. + for (uint_fast64_t i = 0; i < quantitativeResult.size(); ++i) { + if (formula.meetsBound(quantitativeResult[i])) { + result.set(i, true); + } + } + + return result; + } + + /*! + * Checks the given formula that is an R operator over a reward formula featuring a value bound. + * + * @param formula The formula to check. + * @return The set of states satisfying the formula represented by a bit vector. + */ + virtual storm::storage::BitVector checkRewardBoundOperator(const storm::property::prctl::RewardBoundOperator<Type>& formula) const override { + + // For R< and R<= the MDP satisfies the formula iff the reward maximizing scheduler is used. + // For R> and R>= " iff the reward minimizing " . + if(formula.getComparisonOperator() == storm::property::LESS || formula.getComparisonOperator() == storm::property::LESS_EQUAL) { + this->minimumOperatorStack.push(false); + } + else { + this->minimumOperatorStack.push(true); + } + + // First, we need to compute the probability for satisfying the path formula for each state. + std::vector<Type> quantitativeResult = formula.getPathFormula().check(*this, false); + + //Remove the minimizing operator entry from the stack. + this->minimumOperatorStack.pop(); + + // Create resulting bit vector that will hold the yes/no-answer for every state. + storm::storage::BitVector result(quantitativeResult.size()); + + // Now, we can compute which states meet the bound specified in this operator and set the + // corresponding bits to true in the resulting vector. + for (uint_fast64_t i = 0; i < quantitativeResult.size(); ++i) { + if (formula.meetsBound(quantitativeResult[i])) { + result.set(i, true); + } + } + + return result; + } + /*! * Computes the probability to satisfy phi until psi within a limited number of steps for each state. * diff --git a/src/parser/PrctlFileParser.cpp b/src/parser/PrctlFileParser.cpp index b4f2b3f2e..9fadfbf2f 100644 --- a/src/parser/PrctlFileParser.cpp +++ b/src/parser/PrctlFileParser.cpp @@ -14,7 +14,7 @@ namespace storm { namespace parser { -std::list<storm::property::prctl::AbstractPrctlFormula<double>*> PrctlFileParser(std::string filename) { +std::list<storm::property::prctl::PrctlFilter<double>*> PrctlFileParser(std::string filename) { // Open file std::ifstream inputFileStream; inputFileStream.open(filename, std::ios::in); @@ -24,7 +24,7 @@ std::list<storm::property::prctl::AbstractPrctlFormula<double>*> PrctlFileParser throw storm::exceptions::FileIoException() << message << filename; } - std::list<storm::property::prctl::AbstractPrctlFormula<double>*> result; + std::list<storm::property::prctl::PrctlFilter<double>*> result; std::string line; //The while loop reads the input file line by line diff --git a/src/parser/PrctlFileParser.h b/src/parser/PrctlFileParser.h index b2a4335a2..15fc6b382 100644 --- a/src/parser/PrctlFileParser.h +++ b/src/parser/PrctlFileParser.h @@ -9,6 +9,7 @@ #define STORM_PARSER_PRCTLFILEPARSER_H_ #include "formula/Prctl.h" +#include "src/formula/Prctl/PrctlFilter.h" #include <list> @@ -21,7 +22,7 @@ namespace parser { * @param filename * @return The list of parsed formulas */ -std::list<storm::property::prctl::AbstractPrctlFormula<double>*> PrctlFileParser(std::string filename); +std::list<storm::property::prctl::PrctlFilter<double>*> PrctlFileParser(std::string filename); } /* namespace parser */ } /* namespace storm */ diff --git a/src/parser/PrctlParser.cpp b/src/parser/PrctlParser.cpp index e5d6d47fa..4be6ad1a3 100644 --- a/src/parser/PrctlParser.cpp +++ b/src/parser/PrctlParser.cpp @@ -2,7 +2,7 @@ #include "src/utility/OsDetection.h" #include "src/utility/constants.h" -// The action class header. +// The action class headers. #include "src/formula/Actions/AbstractAction.h" #include "src/formula/Actions/MinMaxAction.h" #include "src/formula/Actions/RangeAction.h" @@ -70,24 +70,12 @@ struct PrctlParser::PrctlGrammar : qi::grammar<Iterator, storm::property::prctl: atomicProposition = (freeIdentifierName)[qi::_val = phoenix::new_<storm::property::prctl::Ap<double>>(qi::_1)]; atomicProposition.name("state formula"); - probabilisticBoundOperator = ( - (qi::lit("P") >> qi::lit("min") > comparisonType > qi::double_ > qi::lit("[") > pathFormula > qi::lit("]"))[qi::_val = - phoenix::new_<storm::property::prctl::ProbabilisticBoundOperator<double> >(qi::_1, qi::_2, qi::_3, true)] | - (qi::lit("P") >> qi::lit("max") > comparisonType > qi::double_ > qi::lit("[") > pathFormula > qi::lit("]"))[qi::_val = - phoenix::new_<storm::property::prctl::ProbabilisticBoundOperator<double> >(qi::_1, qi::_2, qi::_3, false)] | - (qi::lit("P") >> comparisonType > qi::double_ > qi::lit("[") > pathFormula > qi::lit("]"))[qi::_val = - phoenix::new_<storm::property::prctl::ProbabilisticBoundOperator<double> >(qi::_1, qi::_2, qi::_3)] - ); + probabilisticBoundOperator = ((qi::lit("P") >> comparisonType > qi::double_ > qi::lit("[") > pathFormula > qi::lit("]"))[qi::_val = + phoenix::new_<storm::property::prctl::ProbabilisticBoundOperator<double> >(qi::_1, qi::_2, qi::_3)]); probabilisticBoundOperator.name("state formula"); - rewardBoundOperator = ( - (qi::lit("R") >> qi::lit("min") > comparisonType > qi::double_ > qi::lit("[") > rewardPathFormula > qi::lit("]"))[qi::_val = - phoenix::new_<storm::property::prctl::RewardBoundOperator<double> >(qi::_1, qi::_2, qi::_3, true)] | - (qi::lit("R") >> qi::lit("max") > comparisonType > qi::double_ > qi::lit("[") > rewardPathFormula > qi::lit("]"))[qi::_val = - phoenix::new_<storm::property::prctl::RewardBoundOperator<double> >(qi::_1, qi::_2, qi::_3, false)] | - (qi::lit("R") >> comparisonType > qi::double_ > qi::lit("[") > rewardPathFormula > qi::lit("]"))[qi::_val = - phoenix::new_<storm::property::prctl::RewardBoundOperator<double> >(qi::_1, qi::_2, qi::_3)] - ); + rewardBoundOperator = ((qi::lit("R") >> comparisonType > qi::double_ > qi::lit("[") > rewardPathFormula > qi::lit("]"))[qi::_val = + phoenix::new_<storm::property::prctl::RewardBoundOperator<double> >(qi::_1, qi::_2, qi::_3)]); rewardBoundOperator.name("state formula"); //This block defines rules for parsing probabilistic path formulas @@ -115,31 +103,66 @@ struct PrctlParser::PrctlGrammar : qi::grammar<Iterator, storm::property::prctl: //This block defines rules for parsing reward path formulas rewardPathFormula = (cumulativeReward | reachabilityReward | instantaneousReward | steadyStateReward); rewardPathFormula.name("path formula (for reward operator)"); - cumulativeReward = (qi::lit("C") > qi::lit("<=") > qi::double_) - [qi::_val = phoenix::new_<storm::property::prctl::CumulativeReward<double>>(qi::_1)]; + cumulativeReward = (qi::lit("C") > qi::lit("<=") > qi::double_)[qi::_val = + phoenix::new_<storm::property::prctl::CumulativeReward<double>>(qi::_1)]; cumulativeReward.name("path formula (for reward operator)"); reachabilityReward = (qi::lit("F") > stateFormula)[qi::_val = phoenix::new_<storm::property::prctl::ReachabilityReward<double>>(qi::_1)]; reachabilityReward.name("path formula (for reward operator)"); - instantaneousReward = (qi::lit("I") > qi::lit("=") > qi::double_) - [qi::_val = phoenix::new_<storm::property::prctl::InstantaneousReward<double>>(qi::_1)]; + instantaneousReward = (qi::lit("I") > qi::lit("=") > qi::double_)[qi::_val = + phoenix::new_<storm::property::prctl::InstantaneousReward<double>>(qi::_1)]; instantaneousReward.name("path formula (for reward operator)"); steadyStateReward = (qi::lit("S"))[qi::_val = phoenix::new_<storm::property::prctl::SteadyStateReward<double>>()]; formula = (pathFormula | stateFormula); formula.name("PRCTL formula"); - minMaxAction = qi::lit("minmax") >> qi::lit(",") >> (qi::lit("min")[qi::_val = phoenix::new_<storm::property::action::MinMaxAction<double>>(true)] | qi::lit("min")[qi::_val = storm::property::action::MinMaxAction<double>(false)]); + //This block defines rules for parsing formulas with noBoundOperators + //Note that this is purely for legacy support. + //NoBoundOperators are no longer part of the formula tree and are therefore deprecated. + noBoundOperator = (probabilisticNoBoundOperator | rewardNoBoundOperator); + noBoundOperator.name("no bound operator"); + probabilisticNoBoundOperator = ( + (qi::lit("P") >> qi::lit("min") >> qi::lit("=") >> qi::lit("?") >> qi::lit("[") >> pathFormula >> qi::lit("]"))[qi::_val = + phoenix::new_<storm::property::prctl::PrctlFilter<double> >(qi::_1, true)] | + (qi::lit("P") >> qi::lit("max") >> qi::lit("=") >> qi::lit("?") >> qi::lit("[") >> pathFormula >> qi::lit("]"))[qi::_val = + phoenix::new_<storm::property::prctl::PrctlFilter<double> >(qi::_1, false)] | + (qi::lit("P") >> qi::lit("=") >> qi::lit("?") > qi::lit("[") > pathFormula > qi::lit("]"))[qi::_val = + phoenix::new_<storm::property::prctl::PrctlFilter<double> >(qi::_1)] + ); + probabilisticNoBoundOperator.name("no bound operator"); + + rewardNoBoundOperator = ( + (qi::lit("R") >> qi::lit("min") >> qi::lit("=") >> qi::lit("?") >> qi::lit("[") >> rewardPathFormula >> qi::lit("]"))[qi::_val = + phoenix::new_<storm::property::prctl::PrctlFilter<double> >(qi::_1, true)] | + (qi::lit("R") >> qi::lit("max") >> qi::lit("=") >> qi::lit("?") >> qi::lit("[") >> rewardPathFormula >> qi::lit("]"))[qi::_val = + phoenix::new_<storm::property::prctl::PrctlFilter<double> >(qi::_1, false)] | + (qi::lit("R") >> qi::lit("=") >> qi::lit("?") >> qi::lit("[") >> rewardPathFormula >> qi::lit("]"))[qi::_val = + phoenix::new_<storm::property::prctl::PrctlFilter<double> >(qi::_1)] + + ); + rewardNoBoundOperator.name("no bound operator"); + + minMaxAction = qi::lit("minmax") >> qi::lit(",") >> ( + qi::lit("min")[qi::_val = + phoenix::new_<storm::property::action::MinMaxAction<double>>(true)] | + qi::lit("min")[qi::_val = + phoenix::new_<storm::property::action::MinMaxAction<double>>(false)]); minMaxAction.name("minmax action for the formula filter"); - rangeAction = (qi::lit("range") >> qi::lit(",") >> qi::uint_ >> qi::lit(",") >> qi::uint_)[qi::_val = phoenix::new_<storm::property::action::RangeAction<double>>(qi::_1, qi::_2)]; + rangeAction = (qi::lit("range") >> qi::lit(",") >> qi::uint_ >> qi::lit(",") >> qi::uint_)[qi::_val = + phoenix::new_<storm::property::action::RangeAction<double>>(qi::_1, qi::_2)]; rangeAction.name("range action for the formula filter"); abstractAction = (rangeAction | minMaxAction) >> (qi::eps | qi::lit(",")); abstractAction.name("filter action"); - filter = ((qi::eps | qi::lit("filter") >> qi::lit("[") >> +abstractAction >> qi::lit("]")) >> (formula | (qi::lit("(") >> formula >> qi::lit(")")))) - [qi::_val = phoenix::new_<storm::property::prctl::PrctlFilter<double>>(qi::_2, qi::_1)]; + filter = (qi::lit("filter") >> qi::lit("[") >> +abstractAction >> qi::lit("]") >> qi::lit("(") >> formula >> qi::lit(")"))[qi::_val = + phoenix::new_<storm::property::prctl::PrctlFilter<double>>(qi::_2, qi::_1)] | + (formula)[qi::_val = + phoenix::new_<storm::property::prctl::PrctlFilter<double>>(qi::_1)] | + (noBoundOperator)[qi::_val = + qi::_1]; filter.name("PRCTL formula filter"); start = (((filter) > (comment | qi::eps))[qi::_val = qi::_1] | comment) > qi::eoi; @@ -149,6 +172,10 @@ struct PrctlParser::PrctlGrammar : qi::grammar<Iterator, storm::property::prctl: qi::rule<Iterator, storm::property::prctl::PrctlFilter<double>*(), Skipper> start; qi::rule<Iterator, storm::property::prctl::PrctlFilter<double>*(), Skipper> filter; + qi::rule<Iterator, storm::property::prctl::PrctlFilter<double>*(), Skipper> noBoundOperator; + qi::rule<Iterator, storm::property::prctl::PrctlFilter<double>*(), Skipper> probabilisticNoBoundOperator; + qi::rule<Iterator, storm::property::prctl::PrctlFilter<double>*(), Skipper> rewardNoBoundOperator; + qi::rule<Iterator, storm::property::action::AbstractAction<double>*(), Skipper> abstractAction; qi::rule<Iterator, storm::property::action::RangeAction<double>*(), Skipper> rangeAction; qi::rule<Iterator, storm::property::action::MinMaxAction<double>*(), Skipper> minMaxAction; @@ -198,7 +225,7 @@ storm::parser::PrctlParser::PrctlParser(std::string formulaString) { // Prepare resulting intermediate representation of input. - storm::property::prctl::AbstractPrctlFormula<double>* result_pointer = nullptr; + storm::property::prctl::PrctlFilter<double>* result_pointer = nullptr; PrctlGrammar<PositionIteratorType, BOOST_TYPEOF(boost::spirit::ascii::space)> grammar; diff --git a/src/parser/PrctlParser.h b/src/parser/PrctlParser.h index 3ba8f1998..52a403afd 100644 --- a/src/parser/PrctlParser.h +++ b/src/parser/PrctlParser.h @@ -2,7 +2,7 @@ #define STORM_PARSER_PRCTLPARSER_H_ #include "src/formula/Prctl.h" -//#include <memory> +#include "src/formula/Prctl/PrctlFilter.h" namespace storm { namespace parser { @@ -32,7 +32,7 @@ class PrctlParser { /*! * @return a pointer to the parsed formula object */ - storm::property::prctl::AbstractPrctlFormula<double>* getFormula() { + storm::property::prctl::PrctlFilter<double>* getFormula() { return this->formula; } @@ -47,7 +47,7 @@ class PrctlParser { } private: - storm::property::prctl::AbstractPrctlFormula<double>* formula; + storm::property::prctl::PrctlFilter<double>* formula; /*! * Struct for the Prctl grammar, that Boost::Spirit uses to parse the formulas. From b45b52a097adb64ecad37526a93c385110655aee Mon Sep 17 00:00:00 2001 From: masawei <manuel.sascha.weiand@rwth-aachen.de> Date: Thu, 15 May 2014 23:54:16 +0200 Subject: [PATCH 09/30] Added the class AbstractRewardPathFormula to the PRCTL formula tree. - This change splits the path formulas into probabilistic path formulas like Next or Until and reward path formulas like InstantaneousReward or SteadyStateReward. |- That way it is assured at compile time that no reward path formula can ever be subformula of any probabilistic bound operator and vise versa. Next up: Adopt changes in the Csl formula tree to the Csl parser. Former-commit-id: d74c88bbf8f73f58c0bf01f14384f845be0cf285 --- src/formula/Prctl.h | 1 + src/formula/Prctl/AbstractPathFormula.h | 7 ++- src/formula/Prctl/AbstractRewardPathFormula.h | 62 +++++++++++++++++++ src/formula/Prctl/CumulativeReward.h | 7 +-- src/formula/Prctl/InstantaneousReward.h | 7 +-- src/formula/Prctl/PrctlFilter.h | 50 +++++++++++++++ src/formula/Prctl/ReachabilityReward.h | 6 +- src/formula/Prctl/RewardBoundOperator.h | 10 +-- src/formula/Prctl/SteadyStateReward.h | 7 +-- src/modelchecker/prctl/AbstractModelChecker.h | 20 +++++- src/parser/PrctlParser.cpp | 2 +- 11 files changed, 152 insertions(+), 27 deletions(-) create mode 100644 src/formula/Prctl/AbstractRewardPathFormula.h diff --git a/src/formula/Prctl.h b/src/formula/Prctl.h index 5f12911ea..e174d445e 100644 --- a/src/formula/Prctl.h +++ b/src/formula/Prctl.h @@ -33,6 +33,7 @@ #include "Prctl/AbstractPrctlFormula.h" #include "Prctl/AbstractStateFormula.h" #include "Prctl/AbstractPathFormula.h" +#include "Prctl/AbstractRewardPathFormula.h" #include "modelchecker/prctl/AbstractModelChecker.h" diff --git a/src/formula/Prctl/AbstractPathFormula.h b/src/formula/Prctl/AbstractPathFormula.h index 1c0be2dd6..62bb1f7f4 100644 --- a/src/formula/Prctl/AbstractPathFormula.h +++ b/src/formula/Prctl/AbstractPathFormula.h @@ -25,10 +25,11 @@ namespace prctl { * * @attention This class is abstract. * @note Formula classes do not have copy constructors. The parameters of the constructors are usually the subtrees, so - * the syntax conflicts with copy constructors for unary operators. To produce an identical object, use the method - * clone(). + * the syntax conflicts with copy constructors for unary operators. To produce an identical object, use the method + * clone(). * - * @note This class is intentionally not derived from AbstractPrctlFormula, as path formulas are not complete PRCTL formulas. + * @note Differing from the formal definitions of PRCTL a path formula may be the root of a PRCTL formula. + * The result of a modelchecking process on such a formula is a vector representing the satisfaction probabilities for each state of the model. */ template <class T> class AbstractPathFormula : public virtual storm::property::prctl::AbstractPrctlFormula<T> { diff --git a/src/formula/Prctl/AbstractRewardPathFormula.h b/src/formula/Prctl/AbstractRewardPathFormula.h new file mode 100644 index 000000000..844adb25b --- /dev/null +++ b/src/formula/Prctl/AbstractRewardPathFormula.h @@ -0,0 +1,62 @@ +/* + * AbstractRewardPathFormula.h + * + * Created on: May 15, 2014 + * Author: Manuel S. Weiand + */ + +#ifndef STORM_FORMULA_PRCTL_ABSTRACTREWARDPATHFORMULA_H_ +#define STORM_FORMULA_PRCTL_ABSTRACTREWARDPATHFORMULA_H_ + +namespace storm { +namespace property { +namespace prctl { + +/*! Base class for reward path formulas. + * + * Reward path formulas are subformulas of reward bound operators. + * They may not be subformulas of a probabilitic bound operator. + * + */ +template <class T> +class AbstractRewardPathFormula : public virtual storm::property::prctl::AbstractPrctlFormula<T> { + +public: + /*! + * Empty virtual destructor. + */ + virtual ~AbstractRewardPathFormula() { + // Intentionally left empty + } + + /*! + * Clones the called object. + * + * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones + * + * @note This function is not implemented in this class. + * @returns a new AND-object that is identical the called object. + */ + virtual AbstractRewardPathFormula<T>* clone() const = 0; + + /*! + * Calls the model checker to check this formula. + * Needed to infer the correct type of formula class. + * + * @note This function should only be called in a generic check function of a model checker class. For other uses, + * the methods of the model checker should be used. + * + * @note This function is not implemented in this class. + * + * @returns A vector indicating the probability that the formula holds for each state. + */ + virtual std::vector<T> check(const storm::modelchecker::prctl::AbstractModelChecker<T>& modelChecker, bool qualitative) const = 0; +}; + +} //namespace prctl +} //namespace property +} //namespace storm + + + +#endif /* STORM_FORMULA_PRCTL_ABSTRACTREWARDPATHFORMULA_H_ */ diff --git a/src/formula/Prctl/CumulativeReward.h b/src/formula/Prctl/CumulativeReward.h index a31f75a5d..baffaecd1 100644 --- a/src/formula/Prctl/CumulativeReward.h +++ b/src/formula/Prctl/CumulativeReward.h @@ -8,8 +8,7 @@ #ifndef STORM_FORMULA_PRCTL_CUMULATIVEREWARD_H_ #define STORM_FORMULA_PRCTL_CUMULATIVEREWARD_H_ -#include "AbstractPathFormula.h" -#include "AbstractStateFormula.h" +#include "AbstractRewardPathFormula.h" #include "src/formula/AbstractFormulaChecker.h" #include <string> @@ -48,7 +47,7 @@ class ICumulativeRewardModelChecker { * @see AbstractPrctlFormula */ template <class T> -class CumulativeReward : public AbstractPathFormula<T> { +class CumulativeReward : public AbstractRewardPathFormula<T> { public: /*! @@ -81,7 +80,7 @@ public: * * @returns a new CumulativeReward-object that is identical the called object. */ - virtual AbstractPathFormula<T>* clone() const override { + virtual AbstractRewardPathFormula<T>* clone() const override { return new CumulativeReward(this->getBound()); } diff --git a/src/formula/Prctl/InstantaneousReward.h b/src/formula/Prctl/InstantaneousReward.h index 774d07e5e..cec958780 100644 --- a/src/formula/Prctl/InstantaneousReward.h +++ b/src/formula/Prctl/InstantaneousReward.h @@ -8,8 +8,7 @@ #ifndef STORM_FORMULA_PRCTL_INSTANTANEOUSREWARD_H_ #define STORM_FORMULA_PRCTL_INSTANTANEOUSREWARD_H_ -#include "AbstractPathFormula.h" -#include "AbstractStateFormula.h" +#include "AbstractRewardPathFormula.h" #include "src/formula/AbstractFormulaChecker.h" #include <cstdint> #include <string> @@ -49,7 +48,7 @@ class IInstantaneousRewardModelChecker { * @see AbstractPrctlFormula */ template <class T> -class InstantaneousReward : public AbstractPathFormula<T> { +class InstantaneousReward : public AbstractRewardPathFormula<T> { public: @@ -83,7 +82,7 @@ public: * * @returns a new InstantaneousReward-object that is identical the called object. */ - virtual AbstractPathFormula<T>* clone() const override { + virtual AbstractRewardPathFormula<T>* clone() const override { return new InstantaneousReward(this->getBound()); } diff --git a/src/formula/Prctl/PrctlFilter.h b/src/formula/Prctl/PrctlFilter.h index f766a5942..d5559246b 100644 --- a/src/formula/Prctl/PrctlFilter.h +++ b/src/formula/Prctl/PrctlFilter.h @@ -120,6 +120,38 @@ public: std::cout << std::endl << "-------------------------------------------" << std::endl; + } + else if (dynamic_cast<AbstractRewardPathFormula<T>*>(child) != nullptr) { + + // Check the formula and apply the filter actions. + std::vector<T> result; + + try { + result = evaluate(modelchecker, static_cast<AbstractRewardPathFormula<T>*>(child)); + } catch (std::exception& e) { + std::cout << "Error during computation: " << e.what() << "Skipping property." << std::endl; + LOG4CPLUS_ERROR(logger, "Error during computation: " << e.what() << "Skipping property."); + std::cout << std::endl << "-------------------------------------------" << std::endl; + + return; + } + + // Now write out the result. + + if(this->actions.empty()) { + + // There is no filter action given. So provide legacy support: + // Return the results for all states labeled with "init". + LOG4CPLUS_INFO(logger, "Result for initial states:"); + std::cout << "Result for initial states:" << std::endl; + for (auto initialState : modelchecker.getModel().getInitialStates()) { + LOG4CPLUS_INFO(logger, "\t" << initialState << ": " << result[initialState]); + std::cout << "\t" << initialState << ": " << result[initialState] << std::endl; + } + } + + std::cout << std::endl << "-------------------------------------------" << std::endl; + } else { // This branch should be unreachable. If you ended up here, something strange has happened. @@ -207,6 +239,24 @@ private: return result; } + std::vector<T> evaluate(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelchecker, AbstractRewardPathFormula<T>* formula) const { + // First, get the model checking result. + std::vector<T> result; + + if(this->getActionCount() != 0 && dynamic_cast<storm::property::action::MinMaxAction<T>*>(this->getAction(0)) != nullptr) { + // If there is an action specifying that min/max probabilities should be computed, call the appropriate method of the model checker. + result = modelchecker.checkMinMaxOperator(formula, static_cast<storm::property::action::MinMaxAction<T>*>(this->getAction(0))->getMinimize()); + } else { + result = formula->check(modelchecker, false); + } + + // Now apply all filter actions and return the result. + for(auto action : this->actions) { + result = action->evaluate(result); + } + return result; + } + AbstractPrctlFormula<T>* child; }; diff --git a/src/formula/Prctl/ReachabilityReward.h b/src/formula/Prctl/ReachabilityReward.h index 0368b4ba9..5f88343da 100644 --- a/src/formula/Prctl/ReachabilityReward.h +++ b/src/formula/Prctl/ReachabilityReward.h @@ -8,7 +8,7 @@ #ifndef STORM_FORMULA_PRCTL_REACHABILITYREWARD_H_ #define STORM_FORMULA_PRCTL_REACHABILITYREWARD_H_ -#include "AbstractPathFormula.h" +#include "AbstractRewardPathFormula.h" #include "AbstractStateFormula.h" #include "src/formula/AbstractFormulaChecker.h" @@ -49,7 +49,7 @@ class IReachabilityRewardModelChecker { * @see AbstractPrctlFormula */ template <class T> -class ReachabilityReward : public AbstractPathFormula<T> { +class ReachabilityReward : public AbstractRewardPathFormula<T> { public: /*! @@ -87,7 +87,7 @@ public: * * @returns a new ReachabilityReward-object that is identical the called object. */ - virtual AbstractPathFormula<T>* clone() const override { + virtual AbstractRewardPathFormula<T>* clone() const override { ReachabilityReward<T>* result = new ReachabilityReward<T>(); if (this->childIsSet()) { result->setChild(this->getChild().clone()); diff --git a/src/formula/Prctl/RewardBoundOperator.h b/src/formula/Prctl/RewardBoundOperator.h index 73dea7ab3..bf12d471d 100644 --- a/src/formula/Prctl/RewardBoundOperator.h +++ b/src/formula/Prctl/RewardBoundOperator.h @@ -8,7 +8,7 @@ #ifndef STORM_FORMULA_PRCTL_REWARDBOUNDOPERATOR_H_ #define STORM_FORMULA_PRCTL_REWARDBOUNDOPERATOR_H_ -#include "AbstractPathFormula.h" +#include "AbstractRewardPathFormula.h" #include "AbstractStateFormula.h" #include "utility/constants.h" #include "src/formula/ComparisonType.h" @@ -69,7 +69,7 @@ public: * @param bound The bound for the probability * @param pathFormula The child node */ - RewardBoundOperator(storm::property::ComparisonType comparisonOperator, T bound, AbstractPathFormula<T>* pathFormula) + RewardBoundOperator(storm::property::ComparisonType comparisonOperator, T bound, AbstractRewardPathFormula<T>* pathFormula) : comparisonOperator(comparisonOperator), bound(bound), pathFormula(pathFormula) { // Intentionally left empty } @@ -146,7 +146,7 @@ public: /*! * @returns the child node (representation of a formula) */ - const AbstractPathFormula<T>& getPathFormula () const { + const AbstractRewardPathFormula<T>& getPathFormula () const { return *pathFormula; } @@ -155,7 +155,7 @@ public: * * @param pathFormula the path formula that becomes the new child node */ - void setPathFormula(AbstractPathFormula<T>* pathFormula) { + void setPathFormula(AbstractRewardPathFormula<T>* pathFormula) { this->pathFormula = pathFormula; } @@ -207,7 +207,7 @@ public: private: storm::property::ComparisonType comparisonOperator; T bound; - AbstractPathFormula<T>* pathFormula; + AbstractRewardPathFormula<T>* pathFormula; }; } //namespace prctl diff --git a/src/formula/Prctl/SteadyStateReward.h b/src/formula/Prctl/SteadyStateReward.h index f850988fa..86624d876 100644 --- a/src/formula/Prctl/SteadyStateReward.h +++ b/src/formula/Prctl/SteadyStateReward.h @@ -8,8 +8,7 @@ #ifndef STORM_FORMULA_PRCTL_STEADYSTATEREWARD_H_ #define STORM_FORMULA_PRCTL_STEADYSTATEREWARD_H_ -#include "AbstractPathFormula.h" -#include "AbstractStateFormula.h" +#include "AbstractRewardPathFormula.h" #include "src/formula/AbstractFormulaChecker.h" #include <string> @@ -45,7 +44,7 @@ class ISteadyStateRewardModelChecker { * @see AbstractPrctlFormula */ template <class T> -class SteadyStateReward: public AbstractPathFormula<T> { +class SteadyStateReward: public AbstractRewardPathFormula<T> { public: /*! * Empty constructor @@ -65,7 +64,7 @@ public: * * @returns a new SteadyState-object that is identical the called object. */ - virtual AbstractPathFormula<T>* clone() const override { + virtual AbstractRewardPathFormula<T>* clone() const override { return new SteadyStateReward<T>(); } diff --git a/src/modelchecker/prctl/AbstractModelChecker.h b/src/modelchecker/prctl/AbstractModelChecker.h index ed79fdace..fcaf0c2a9 100644 --- a/src/modelchecker/prctl/AbstractModelChecker.h +++ b/src/modelchecker/prctl/AbstractModelChecker.h @@ -230,11 +230,11 @@ public: } /*! - * Checks the given formula and determines whether minimum or maximum probabilities or rewards are to be computed for the formula. + * Checks the given formula and determines whether minimum or maximum probabilities are to be computed for the formula. * * @param formula The formula to check. - * @param minimumOperator True iff minimum probabilities/rewards are to be computed. - * @returns The probabilities to satisfy the formula or the rewards accumulated by it, represented by a vector. + * @param minimumOperator True iff minimum probabilities are to be computed. + * @returns The probabilities to satisfy the formula, represented by a vector. */ virtual std::vector<Type> checkMinMaxOperator(storm::property::prctl::AbstractPathFormula<Type> const & formula, bool minimumOperator) const { minimumOperatorStack.push(minimumOperator); @@ -243,6 +243,20 @@ public: return result; } + /*! + * Checks the given formula and determines whether minimum or maximum rewards are to be computed for the formula. + * + * @param formula The formula to check. + * @param minimumOperator True iff minimum rewards are to be computed. + * @returns The the rewards accumulated by the formula, represented by a vector. + */ + virtual std::vector<Type> checkMinMaxOperator(storm::property::prctl::AbstractRewardPathFormula<Type> const & formula, bool minimumOperator) const { + minimumOperatorStack.push(minimumOperator); + std::vector<Type> result = formula.check(*this, false); + minimumOperatorStack.pop(); + return result; + } + /*! * Checks the given formula and determines whether minimum or maximum probabilities or rewards are to be computed for the formula. * diff --git a/src/parser/PrctlParser.cpp b/src/parser/PrctlParser.cpp index 4be6ad1a3..82d0a3550 100644 --- a/src/parser/PrctlParser.cpp +++ b/src/parser/PrctlParser.cpp @@ -201,7 +201,7 @@ struct PrctlParser::PrctlGrammar : qi::grammar<Iterator, storm::property::prctl: qi::rule<Iterator, storm::property::prctl::BoundedUntil<double>*(), qi::locals< std::shared_ptr<storm::property::prctl::AbstractStateFormula<double>>>, Skipper> boundedUntil; qi::rule<Iterator, storm::property::prctl::Until<double>*(), qi::locals< std::shared_ptr<storm::property::prctl::AbstractStateFormula<double>>>, Skipper> until; - qi::rule<Iterator, storm::property::prctl::AbstractPathFormula<double>*(), Skipper> rewardPathFormula; + qi::rule<Iterator, storm::property::prctl::AbstractRewardPathFormula<double>*(), Skipper> rewardPathFormula; qi::rule<Iterator, storm::property::prctl::CumulativeReward<double>*(), Skipper> cumulativeReward; qi::rule<Iterator, storm::property::prctl::ReachabilityReward<double>*(), Skipper> reachabilityReward; qi::rule<Iterator, storm::property::prctl::InstantaneousReward<double>*(), Skipper> instantaneousReward; From 185c2197cb5d593055d40b85b5dd33f2ddfcade6 Mon Sep 17 00:00:00 2001 From: masawei <manuel.sascha.weiand@rwth-aachen.de> Date: Fri, 16 May 2014 22:09:28 +0200 Subject: [PATCH 10/30] Fixed up the CslParser. Next Up: Making the parsers static classes. Former-commit-id: 247a1050782f1b85a6cc24c33908c417b494480d --- src/formula/Csl/CslFilter.h | 54 +- src/formula/Ltl/LtlFilter.h | 27 +- src/modelchecker/csl/AbstractModelChecker.h | 2 +- .../SparseMarkovAutomatonCslModelChecker.h | 1184 +++++++++-------- src/parser/CslParser.cpp | 82 +- src/parser/CslParser.h | 3 +- 6 files changed, 721 insertions(+), 631 deletions(-) diff --git a/src/formula/Csl/CslFilter.h b/src/formula/Csl/CslFilter.h index db59a59a7..1507d1c2b 100644 --- a/src/formula/Csl/CslFilter.h +++ b/src/formula/Csl/CslFilter.h @@ -12,13 +12,15 @@ #include "src/formula/Csl/AbstractCslFormula.h" #include "src/formula/Csl/AbstractPathFormula.h" #include "src/formula/Csl/AbstractStateFormula.h" +#include "src/modelchecker/csl/AbstractModelChecker.h" +#include "src/formula/Actions/MinMaxAction.h" namespace storm { namespace property { namespace csl { template <class T> -class CslFilter : storm::property::AbstractFilter<T> { +class CslFilter : public storm::property::AbstractFilter<T> { public: @@ -26,24 +28,28 @@ public: // Intentionally left empty. } - CslFilter(AbstractCslFormula* child) : child(child) { + CslFilter(AbstractCslFormula<T>* child) : child(child) { // Intentionally left empty. } - CslFilter(AbstractCslFormula* child, action::Action<T>* action) : child(child) { - actions.push_back(action); + CslFilter(AbstractCslFormula<T>* child, bool minimize) : child(child) { + this->actions.push_back(new storm::property::action::MinMaxAction<T>(minimize)); } - CslFilter(AbstractCslFormula* child, std::vector<action::Action<T>*> actions) : child(child), actions(actions) { + CslFilter(AbstractCslFormula<T>* child, action::AbstractAction<T>* action) : child(child) { + this->actions.push_back(action); + } + + CslFilter(AbstractCslFormula<T>* child, std::vector<action::AbstractAction<T>*> actions) : AbstractFilter<T>(actions), child(child) { // Intentionally left empty. } virtual ~CslFilter() { - actions.clear(); + this->actions.clear(); delete child; } - void check(AbstractModelChecker const & modelchecker) const { + void check(storm::modelchecker::csl::AbstractModelChecker<T> const & modelchecker) const { // Write out the formula to be checked. std::cout << std::endl; @@ -68,13 +74,13 @@ public: // Now write out the result. - if(actions.empty()) { + if(this->actions.empty()) { // There is no filter action given. So provide legacy support: // Return the results for all states labeled with "init". LOG4CPLUS_INFO(logger, "Result for initial states:"); std::cout << "Result for initial states:" << std::endl; - for (auto initialState : modelchecker.getModel<storm::models::AbstractModel<T>>().getInitialStates()) { + for (auto initialState : modelchecker.getModel().getInitialStates()) { LOG4CPLUS_INFO(logger, "\t" << initialState << ": " << (result.get(initialState) ? "satisfied" : "not satisfied")); std::cout << "\t" << initialState << ": " << result.get(initialState) << std::endl; } @@ -100,13 +106,13 @@ public: // Now write out the result. - if(actions.empty()) { + if(this->actions.empty()) { // There is no filter action given. So provide legacy support: // Return the results for all states labeled with "init". LOG4CPLUS_INFO(logger, "Result for initial states:"); std::cout << "Result for initial states:" << std::endl; - for (auto initialState : modelchecker.getModel<storm::models::AbstractModel<T>>().getInitialStates()) { + for (auto initialState : modelchecker.getModel().getInitialStates()) { LOG4CPLUS_INFO(logger, "\t" << initialState << ": " << result[initialState]); std::cout << "\t" << initialState << ": " << result[initialState] << std::endl; } @@ -147,61 +153,61 @@ public: std::string toString() const { std::string desc = "Filter: "; desc += "\nActions:"; - for(auto action : actions) { + for(auto action : this->actions) { desc += "\n\t" + action.toString(); } desc += "\nFormula:\n\t" + child->toString(); return desc; } - void setChild(AbstractCslFormula* child) { + void setChild(AbstractCslFormula<T>* child) { this->child = child; } - AbstractFormula* getChild() const { + AbstractCslFormula<T>* getChild() const { return child; } private: - BitVector evaluate(AbstractModelChecker const & modelchecker, AbstractStateFormula<T>* formula) const { + storm::storage::BitVector evaluate(storm::modelchecker::csl::AbstractModelChecker<T> const & modelchecker, AbstractStateFormula<T>* formula) const { // First, get the model checking result. - BitVector result = modelchecker.checkMinMaxOperator(formula); + storm::storage::BitVector result = modelchecker.checkMinMaxOperator(formula); - if(getActionCount() != 0 && dynamic_cast<MinMaxAction<T>*>(getAction(0)) != nullptr) { + if(this->getActionCount() != 0 && dynamic_cast<storm::property::action::MinMaxAction<T>*>(this->getAction(0)) != nullptr) { // If there is an action specifying that min/max probabilities should be computed, call the appropriate method of the model checker. - result = modelchecker.checkMinMaxOperator(formula, static_cast<MinMaxAction<T>*>(getAction(0))->getMinimize()); + result = modelchecker.checkMinMaxOperator(formula, static_cast<storm::property::action::MinMaxAction<T>*>(this->getAction(0))->getMinimize()); } else { result = formula->check(modelchecker); } // Now apply all filter actions and return the result. - for(auto action : actions) { + for(auto action : this->actions) { result = action->evaluate(result); } return result; } - std::vector<T> evaluate(AbstractModelChecker const & modelchecker, AbstractPathFormula<T>* formula) const { + std::vector<T> evaluate(storm::modelchecker::csl::AbstractModelChecker<T> const & modelchecker, AbstractPathFormula<T>* formula) const { // First, get the model checking result. std::vector<T> result; - if(getActionCount() != 0 && dynamic_cast<MinMaxAction<T>*>(getAction(0)) != nullptr) { + if(this->getActionCount() != 0 && dynamic_cast<storm::property::action::MinMaxAction<T>*>(this->getAction(0)) != nullptr) { // If there is an action specifying that min/max probabilities should be computed, call the appropriate method of the model checker. - result = modelchecker.checkMinMaxOperator(formula, static_cast<MinMaxAction<T>*>(getAction(0))->getMinimize()); + result = modelchecker.checkMinMaxOperator(formula, static_cast<storm::property::action::MinMaxAction<T>*>(this->getAction(0))->getMinimize()); } else { result = formula->check(modelchecker, false); } // Now apply all filter actions and return the result. - for(auto action : actions) { + for(auto action : this->actions) { result = action->evaluate(result); } return result; } - AbstractCslFormula* child; + AbstractCslFormula<T>* child; }; } //namespace csl diff --git a/src/formula/Ltl/LtlFilter.h b/src/formula/Ltl/LtlFilter.h index 6fbb6398e..cbc31f71b 100644 --- a/src/formula/Ltl/LtlFilter.h +++ b/src/formula/Ltl/LtlFilter.h @@ -8,12 +8,15 @@ #ifndef STORM_FORMULA_LTL_LTLFILTER_H_ #define STORM_FORMULA_LTL_LTLFILTER_H_ +#include "src/formula/AbstractFilter.h" +#include "src/modelchecker/ltl/AbstractModelChecker.h" + namespace storm { namespace property { namespace ltl { template <class T> -class LtlFilter : storm::property::AbstractFilter<T> { +class LtlFilter : public storm::property::AbstractFilter<T> { public: @@ -26,15 +29,15 @@ public: } LtlFilter(AbstractLtlFormula* child, action::Action<T>* action) : child(child) { - actions.push_back(action); + this->actions.push_back(action); } - LtlFilter(AbstractLtlFormula* child, std::vector<action::Action<T>*> actions) : child(child), actions(actions) { + LtlFilter(AbstractLtlFormula* child, std::vector<action::Action<T>*> actions) : AbstractFilter<T>(actions), child(child) { // Intentionally left empty. } virtual ~LtlFilter() { - actions.clear(); + this->actions.clear(); delete child; } @@ -45,7 +48,7 @@ public: * * @param stateFormula The formula to be checked. */ - void check(AbstractModelChecker const & modelchecker) const { + void check(storm::modelchecker::ltl::AbstractModelChecker<T> const & modelchecker) const { // Write out the formula to be checked. std::cout << std::endl; @@ -68,7 +71,7 @@ public: // Now write out the result. - if(actions.empty()) { + if(this->actions.empty()) { // There is no filter action given. So provide legacy support: // Return the results for all states labeled with "init". @@ -99,35 +102,35 @@ public: std::string toString() const { std::string desc = "Filter: "; desc += "\nActions:"; - for(auto action : actions) { + for(auto action : this->actions) { desc += "\n\t" + action.toString(); } desc += "\nFormula:\n\t" + child->toString(); return desc; } - void setChild(AbstractLtlFormula* child) { + void setChild(AbstractLtlFormula<T>* child) { this->child = child; } - AbstractFormula* getChild() const { + AbstractLtlFormula<T>* getChild() const { return child; } private: - storm::storage::BitVector evaluate(AbstractModelChecker const & modelchecker, AbstractLtlFormula<T>* formula) const { + storm::storage::BitVector evaluate(storm::modelchecker::ltl::AbstractModelChecker<T> const & modelchecker, AbstractLtlFormula<T>* formula) const { // First, get the model checking result. storm::storage::BitVector result = formula->check(modelchecker); // Now apply all filter actions and return the result. - for(auto action : actions) { + for(auto action : this->actions) { result = action->evaluate(result); } return result; } - AbstractLtlFormula* child; + AbstractLtlFormula<T>* child; }; diff --git a/src/modelchecker/csl/AbstractModelChecker.h b/src/modelchecker/csl/AbstractModelChecker.h index a80b39445..3e6fcf546 100644 --- a/src/modelchecker/csl/AbstractModelChecker.h +++ b/src/modelchecker/csl/AbstractModelChecker.h @@ -172,7 +172,7 @@ public: * @param formula The formula to check. * @returns The set of states satisfying the formula represented by a bit vector. */ - storm::storage::BitVector checkProbabilisticBoundOperator(storm::property::csl::ProbabilisticBoundOperator<Type> const& formula) const { + virtual storm::storage::BitVector checkProbabilisticBoundOperator(storm::property::csl::ProbabilisticBoundOperator<Type> const& formula) const { // First, we need to compute the probability for satisfying the path formula for each state. std::vector<Type> quantitativeResult = formula.getPathFormula().check(*this, false); diff --git a/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h b/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h index 629e809af..e5aa4d075 100644 --- a/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h +++ b/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h @@ -15,583 +15,627 @@ #include "src/exceptions/NotImplementedException.h" namespace storm { - namespace modelchecker { - namespace csl { - - template<typename ValueType> - class SparseMarkovAutomatonCslModelChecker : public AbstractModelChecker<ValueType> { - public: - explicit SparseMarkovAutomatonCslModelChecker(storm::models::MarkovAutomaton<ValueType> const& model, std::shared_ptr<storm::solver::NondeterministicLinearEquationSolver<ValueType>> nondeterministicLinearEquationSolver) : AbstractModelChecker<ValueType>(model), nondeterministicLinearEquationSolver(nondeterministicLinearEquationSolver) { - // Intentionally left empty. - } - - /* - This Second constructor is NEEDED and a workaround for a common Bug in C++ with nested templates - See: http://stackoverflow.com/questions/14401308/visual-c-cannot-deduce-given-template-arguments-for-function-used-as-defaul - */ - explicit SparseMarkovAutomatonCslModelChecker(storm::models::MarkovAutomaton<ValueType> const& model) : AbstractModelChecker<ValueType>(model), nondeterministicLinearEquationSolver(storm::utility::solver::getNondeterministicLinearEquationSolver<ValueType>()) { - // Intentionally left empty. +namespace modelchecker { +namespace csl { + +template<typename ValueType> +class SparseMarkovAutomatonCslModelChecker : public AbstractModelChecker<ValueType> { +public: + explicit SparseMarkovAutomatonCslModelChecker(storm::models::MarkovAutomaton<ValueType> const& model, std::shared_ptr<storm::solver::NondeterministicLinearEquationSolver<ValueType>> nondeterministicLinearEquationSolver) : AbstractModelChecker<ValueType>(model), nondeterministicLinearEquationSolver(nondeterministicLinearEquationSolver) { + // Intentionally left empty. + } + + /* + This Second constructor is NEEDED and a workaround for a common Bug in C++ with nested templates + See: http://stackoverflow.com/questions/14401308/visual-c-cannot-deduce-given-template-arguments-for-function-used-as-defaul + */ + explicit SparseMarkovAutomatonCslModelChecker(storm::models::MarkovAutomaton<ValueType> const& model) : AbstractModelChecker<ValueType>(model), nondeterministicLinearEquationSolver(storm::utility::solver::getNondeterministicLinearEquationSolver<ValueType>()) { + // Intentionally left empty. + } + + /*! + * Virtual destructor. Needs to be virtual, because this class has virtual methods. + */ + virtual ~SparseMarkovAutomatonCslModelChecker() { + // Intentionally left empty. + } + + /*! + * Returns a constant reference to the MDP associated with this model checker. + * @returns A constant reference to the MDP associated with this model checker. + */ + storm::models::MarkovAutomaton<ValueType> const& getModel() const { + return AbstractModelChecker<ValueType>::template getModel<storm::models::MarkovAutomaton<ValueType>>(); + } + + /*! + * Checks the given formula that is a P operator over a path formula featuring a value bound. + * + * @param formula The formula to check. + * @returns The set of states satisfying the formula represented by a bit vector. + */ + virtual storm::storage::BitVector checkProbabilisticBoundOperator(storm::property::csl::ProbabilisticBoundOperator<ValueType> const& formula) const override{ + // For P< and P<= the MA satisfies the formula iff the probability maximizing scheduler is used. + // For P> and P>= " iff the probability minimizing " . + if(formula.getComparisonOperator() == storm::property::LESS || formula.getComparisonOperator() == storm::property::LESS_EQUAL) { + this->minimumOperatorStack.push(false); + } + else { + this->minimumOperatorStack.push(true); + } + + // First, we need to compute the probability for satisfying the path formula for each state. + std::vector<ValueType> quantitativeResult = formula.getPathFormula().check(*this, false); + + //Remove the minimizing operator entry from the stack. + this->minimumOperatorStack.pop(); + + // Create resulting bit vector that will hold the yes/no-answer for every state. + storm::storage::BitVector result(quantitativeResult.size()); + + // Now, we can compute which states meet the bound specified in this operator and set the + // corresponding bits to true in the resulting vector. + for (uint_fast64_t i = 0; i < quantitativeResult.size(); ++i) { + if (formula.meetsBound(quantitativeResult[i])) { + result.set(i, true); + } + } + + return result; + } + + std::vector<ValueType> checkUntil(storm::property::csl::Until<ValueType> const& formula, bool qualitative) const { + // Test whether it is specified if the minimum or maximum probabilities are to be computed. + if(this->minimumOperatorStack.empty()) { + LOG4CPLUS_ERROR(logger, "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."); + throw storm::exceptions::InvalidArgumentException() << "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."; + } + + storm::storage::BitVector leftStates = formula.getLeft().check(*this); + storm::storage::BitVector rightStates = formula.getRight().check(*this); + return computeUnboundedUntilProbabilities(this->minimumOperatorStack.top(), leftStates, rightStates, qualitative).first; + } + + std::pair<std::vector<ValueType>, storm::storage::TotalScheduler> computeUnboundedUntilProbabilities(bool min, storm::storage::BitVector const& leftStates, storm::storage::BitVector const& rightStates, bool qualitative) const { + return storm::modelchecker::prctl::SparseMdpPrctlModelChecker<ValueType>::computeUnboundedUntilProbabilities(min, this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), this->getModel().getInitialStates(), leftStates, rightStates, nondeterministicLinearEquationSolver, qualitative); + } + + std::vector<ValueType> checkTimeBoundedUntil(storm::property::csl::TimeBoundedUntil<ValueType> const& formula, bool qualitative) const { + throw storm::exceptions::NotImplementedException() << "Model checking Until formulas on Markov automata is not yet implemented."; + } + + std::vector<ValueType> checkTimeBoundedEventually(storm::property::csl::TimeBoundedEventually<ValueType> const& formula, bool qualitative) const { + // Test whether it is specified if the minimum or maximum probabilities are to be computed. + if(this->minimumOperatorStack.empty()) { + LOG4CPLUS_ERROR(logger, "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."); + throw storm::exceptions::InvalidArgumentException() << "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."; + } + + storm::storage::BitVector goalStates = formula.getChild().check(*this); + return this->checkTimeBoundedEventually(this->minimumOperatorStack.top(), goalStates, formula.getLowerBound(), formula.getUpperBound()); + } + + std::vector<ValueType> checkGlobally(storm::property::csl::Globally<ValueType> const& formula, bool qualitative) const { + throw storm::exceptions::NotImplementedException() << "Model checking Globally formulas on Markov automata is not yet implemented."; + } + + std::vector<ValueType> checkEventually(storm::property::csl::Eventually<ValueType> const& formula, bool qualitative) const { + // Test whether it is specified if the minimum or maximum probabilities are to be computed. + if(this->minimumOperatorStack.empty()) { + LOG4CPLUS_ERROR(logger, "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."); + throw storm::exceptions::InvalidArgumentException() << "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."; + } + + storm::storage::BitVector subFormulaStates = formula.getChild().check(*this); + return computeUnboundedUntilProbabilities(this->minimumOperatorStack.top(), storm::storage::BitVector(this->getModel().getNumberOfStates(), true), subFormulaStates, qualitative).first; + } + + std::vector<ValueType> checkNext(storm::property::csl::Next<ValueType> const& formula, bool qualitative) const { + throw storm::exceptions::NotImplementedException() << "Model checking Next formulas on Markov automata is not yet implemented."; + } + + static void computeBoundedReachabilityProbabilities(bool min, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRates, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& goalStates, storm::storage::BitVector const& markovianNonGoalStates, storm::storage::BitVector const& probabilisticNonGoalStates, std::vector<ValueType>& markovianNonGoalValues, std::vector<ValueType>& probabilisticNonGoalValues, ValueType delta, uint_fast64_t numberOfSteps) { + // Start by computing four sparse matrices: + // * a matrix aMarkovian with all (discretized) transitions from Markovian non-goal states to all Markovian non-goal states. + // * a matrix aMarkovianToProbabilistic with all (discretized) transitions from Markovian non-goal states to all probabilistic non-goal states. + // * a matrix aProbabilistic with all (non-discretized) transitions from probabilistic non-goal states to other probabilistic non-goal states. + // * a matrix aProbabilisticToMarkovian with all (non-discretized) transitions from probabilistic non-goal states to all Markovian non-goal states. + typename storm::storage::SparseMatrix<ValueType> aMarkovian = transitionMatrix.getSubmatrix(true, markovianNonGoalStates, markovianNonGoalStates, true); + typename storm::storage::SparseMatrix<ValueType> aMarkovianToProbabilistic = transitionMatrix.getSubmatrix(true, markovianNonGoalStates, probabilisticNonGoalStates); + typename storm::storage::SparseMatrix<ValueType> aProbabilistic = transitionMatrix.getSubmatrix(true, probabilisticNonGoalStates, probabilisticNonGoalStates); + typename storm::storage::SparseMatrix<ValueType> aProbabilisticToMarkovian = transitionMatrix.getSubmatrix(true, probabilisticNonGoalStates, markovianNonGoalStates); + + // The matrices with transitions from Markovian states need to be digitized. + // Digitize aMarkovian. Based on whether the transition is a self-loop or not, we apply the two digitization rules. + uint_fast64_t rowIndex = 0; + for (auto state : markovianNonGoalStates) { + for (auto& element : aMarkovian.getRow(rowIndex)) { + ValueType eTerm = std::exp(-exitRates[state] * delta); + if (element.first == rowIndex) { + element.second = (storm::utility::constantOne<ValueType>() - eTerm) * element.second + eTerm; + } else { + element.second = (storm::utility::constantOne<ValueType>() - eTerm) * element.second; } + } + ++rowIndex; + } + + // Digitize aMarkovianToProbabilistic. As there are no self-loops in this case, we only need to apply the digitization formula for regular successors. + rowIndex = 0; + for (auto state : markovianNonGoalStates) { + for (auto& element : aMarkovianToProbabilistic.getRow(rowIndex)) { + element.second = (1 - std::exp(-exitRates[state] * delta)) * element.second; + } + ++rowIndex; + } + + // Initialize the two vectors that hold the variable one-step probabilities to all target states for probabilistic and Markovian (non-goal) states. + std::vector<ValueType> bProbabilistic(aProbabilistic.getRowCount()); + std::vector<ValueType> bMarkovian(markovianNonGoalStates.getNumberOfSetBits()); + + // Compute the two fixed right-hand side vectors, one for Markovian states and one for the probabilistic ones. + std::vector<ValueType> bProbabilisticFixed = transitionMatrix.getConstrainedRowSumVector(probabilisticNonGoalStates, goalStates); + std::vector<ValueType> bMarkovianFixed; + bMarkovianFixed.reserve(markovianNonGoalStates.getNumberOfSetBits()); + for (auto state : markovianNonGoalStates) { + bMarkovianFixed.push_back(storm::utility::constantZero<ValueType>()); + + for (auto& element : transitionMatrix.getRowGroup(state)) { + if (goalStates.get(element.first)) { + bMarkovianFixed.back() += (1 - std::exp(-exitRates[state] * delta)) * element.second; + } + } + } + + std::shared_ptr<storm::solver::NondeterministicLinearEquationSolver<ValueType>> nondeterministiclinearEquationSolver = storm::utility::solver::getNondeterministicLinearEquationSolver<ValueType>(); + + // Perform the actual value iteration + // * loop until the step bound has been reached + // * in the loop: + // * perform value iteration using A_PSwG, v_PS and the vector b where b = (A * 1_G)|PS + A_PStoMS * v_MS + // and 1_G being the characteristic vector for all goal states. + // * perform one timed-step using v_MS := A_MSwG * v_MS + A_MStoPS * v_PS + (A * 1_G)|MS + std::vector<ValueType> markovianNonGoalValuesSwap(markovianNonGoalValues); + std::vector<ValueType> multiplicationResultScratchMemory(aProbabilistic.getRowCount()); + std::vector<ValueType> aProbabilisticScratchMemory(probabilisticNonGoalValues.size()); + for (uint_fast64_t currentStep = 0; currentStep < numberOfSteps; ++currentStep) { + // Start by (re-)computing bProbabilistic = bProbabilisticFixed + aProbabilisticToMarkovian * vMarkovian. + aProbabilisticToMarkovian.multiplyWithVector(markovianNonGoalValues, bProbabilistic); + storm::utility::vector::addVectorsInPlace(bProbabilistic, bProbabilisticFixed); + + // Now perform the inner value iteration for probabilistic states. + nondeterministiclinearEquationSolver->solveEquationSystem(min, aProbabilistic, probabilisticNonGoalValues, bProbabilistic, &multiplicationResultScratchMemory, &aProbabilisticScratchMemory); + + // (Re-)compute bMarkovian = bMarkovianFixed + aMarkovianToProbabilistic * vProbabilistic. + aMarkovianToProbabilistic.multiplyWithVector(probabilisticNonGoalValues, bMarkovian); + storm::utility::vector::addVectorsInPlace(bMarkovian, bMarkovianFixed); + aMarkovian.multiplyWithVector(markovianNonGoalValues, markovianNonGoalValuesSwap); + std::swap(markovianNonGoalValues, markovianNonGoalValuesSwap); + storm::utility::vector::addVectorsInPlace(markovianNonGoalValues, bMarkovian); + } + + // After the loop, perform one more step of the value iteration for PS states. + aProbabilisticToMarkovian.multiplyWithVector(markovianNonGoalValues, bProbabilistic); + storm::utility::vector::addVectorsInPlace(bProbabilistic, bProbabilisticFixed); + nondeterministiclinearEquationSolver->solveEquationSystem(min, aProbabilistic, probabilisticNonGoalValues, bProbabilistic, &multiplicationResultScratchMemory, &aProbabilisticScratchMemory); + } + + std::vector<ValueType> checkTimeBoundedEventually(bool min, storm::storage::BitVector const& goalStates, ValueType lowerBound, ValueType upperBound) const { + // Check whether the automaton is closed. + if (!this->getModel().isClosed()) { + throw storm::exceptions::InvalidArgumentException() << "Unable to compute time-bounded reachability on non-closed Markov automaton."; + } + + // Check whether the given bounds were valid. + if (lowerBound < storm::utility::constantZero<ValueType>() || upperBound < storm::utility::constantZero<ValueType>() || upperBound < lowerBound) { + throw storm::exceptions::InvalidArgumentException() << "Illegal interval ["; + } + + // Get some data fields for convenient access. + typename storm::storage::SparseMatrix<ValueType> const& transitionMatrix = this->getModel().getTransitionMatrix(); + std::vector<ValueType> const& exitRates = this->getModel().getExitRates(); + storm::storage::BitVector const& markovianStates = this->getModel().getMarkovianStates(); + + // (1) Compute the accuracy we need to achieve the required error bound. + ValueType maxExitRate = this->getModel().getMaximalExitRate(); + ValueType delta = (2 * storm::settings::Settings::getInstance()->getOptionByLongName("digiprecision").getArgument(0).getValueAsDouble()) / (upperBound * maxExitRate * maxExitRate); + + // (2) Compute the number of steps we need to make for the interval. + uint_fast64_t numberOfSteps = static_cast<uint_fast64_t>(std::ceil((upperBound - lowerBound) / delta)); + std::cout << "Performing " << numberOfSteps << " iterations (delta=" << delta << ") for interval [" << lowerBound << ", " << upperBound << "]." << std::endl; + + // (3) Compute the non-goal states and initialize two vectors + // * vProbabilistic holds the probability values of probabilistic non-goal states. + // * vMarkovian holds the probability values of Markovian non-goal states. + storm::storage::BitVector const& markovianNonGoalStates = markovianStates & ~goalStates; + storm::storage::BitVector const& probabilisticNonGoalStates = ~markovianStates & ~goalStates; + std::vector<ValueType> vProbabilistic(probabilisticNonGoalStates.getNumberOfSetBits()); + std::vector<ValueType> vMarkovian(markovianNonGoalStates.getNumberOfSetBits()); + + computeBoundedReachabilityProbabilities(min, transitionMatrix, exitRates, markovianStates, goalStates, markovianNonGoalStates, probabilisticNonGoalStates, vMarkovian, vProbabilistic, delta, numberOfSteps); + + // (4) If the lower bound of interval was non-zero, we need to take the current values as the starting values for a subsequent value iteration. + if (lowerBound != storm::utility::constantZero<ValueType>()) { + std::vector<ValueType> vAllProbabilistic((~markovianStates).getNumberOfSetBits()); + std::vector<ValueType> vAllMarkovian(markovianStates.getNumberOfSetBits()); + + // Create the starting value vectors for the next value iteration based on the results of the previous one. + storm::utility::vector::setVectorValues<ValueType>(vAllProbabilistic, goalStates % ~markovianStates, storm::utility::constantOne<ValueType>()); + storm::utility::vector::setVectorValues<ValueType>(vAllProbabilistic, ~goalStates % ~markovianStates, vProbabilistic); + storm::utility::vector::setVectorValues<ValueType>(vAllMarkovian, goalStates % markovianStates, storm::utility::constantOne<ValueType>()); + storm::utility::vector::setVectorValues<ValueType>(vAllMarkovian, ~goalStates % markovianStates, vMarkovian); + + // Compute the number of steps to reach the target interval. + numberOfSteps = static_cast<uint_fast64_t>(std::ceil(lowerBound / delta)); + std::cout << "Performing " << numberOfSteps << " iterations (delta=" << delta << ") for interval [0, " << lowerBound << "]." << std::endl; + + // Compute the bounded reachability for interval [0, b-a]. + computeBoundedReachabilityProbabilities(min, transitionMatrix, exitRates, markovianStates, storm::storage::BitVector(this->getModel().getNumberOfStates()), markovianStates, ~markovianStates, vAllMarkovian, vAllProbabilistic, delta, numberOfSteps); + + // Create the result vector out of vAllProbabilistic and vAllMarkovian and return it. + std::vector<ValueType> result(this->getModel().getNumberOfStates()); + storm::utility::vector::setVectorValues(result, ~markovianStates, vAllProbabilistic); + storm::utility::vector::setVectorValues(result, markovianStates, vAllMarkovian); + + return result; + } else { + // Create the result vector out of 1_G, vProbabilistic and vMarkovian and return it. + std::vector<ValueType> result(this->getModel().getNumberOfStates()); + storm::utility::vector::setVectorValues<ValueType>(result, goalStates, storm::utility::constantOne<ValueType>()); + storm::utility::vector::setVectorValues(result, probabilisticNonGoalStates, vProbabilistic); + storm::utility::vector::setVectorValues(result, markovianNonGoalStates, vMarkovian); + return result; + } + } + + std::vector<ValueType> checkLongRunAverage(bool min, storm::storage::BitVector const& goalStates) const { + // Check whether the automaton is closed. + if (!this->getModel().isClosed()) { + throw storm::exceptions::InvalidArgumentException() << "Unable to compute long-run average on non-closed Markov automaton."; + } + + // If there are no goal states, we avoid the computation and directly return zero. + if (goalStates.empty()) { + return std::vector<ValueType>(this->getModel().getNumberOfStates(), storm::utility::constantZero<ValueType>()); + } + + // Likewise, if all bits are set, we can avoid the computation and set. + if ((~goalStates).empty()) { + return std::vector<ValueType>(this->getModel().getNumberOfStates(), storm::utility::constantOne<ValueType>()); + } + + // Start by decomposing the Markov automaton into its MECs. + storm::storage::MaximalEndComponentDecomposition<double> mecDecomposition(this->getModel()); + + // Get some data members for convenience. + typename storm::storage::SparseMatrix<ValueType> const& transitionMatrix = this->getModel().getTransitionMatrix(); + std::vector<uint_fast64_t> const& nondeterministicChoiceIndices = this->getModel().getNondeterministicChoiceIndices(); + + // Now start with compute the long-run average for all end components in isolation. + std::vector<ValueType> lraValuesForEndComponents; + + // While doing so, we already gather some information for the following steps. + std::vector<uint_fast64_t> stateToMecIndexMap(this->getModel().getNumberOfStates()); + storm::storage::BitVector statesInMecs(this->getModel().getNumberOfStates()); + + for (uint_fast64_t currentMecIndex = 0; currentMecIndex < mecDecomposition.size(); ++currentMecIndex) { + storm::storage::MaximalEndComponent const& mec = mecDecomposition[currentMecIndex]; + + // Gather information for later use. + for (auto const& stateChoicesPair : mec) { + uint_fast64_t state = stateChoicesPair.first; + + statesInMecs.set(state); + stateToMecIndexMap[state] = currentMecIndex; + } + + // Compute the LRA value for the current MEC. + lraValuesForEndComponents.push_back(this->computeLraForMaximalEndComponent(min, transitionMatrix, nondeterministicChoiceIndices, this->getModel().getMarkovianStates(), this->getModel().getExitRates(), goalStates, mec, currentMecIndex)); + } - /*! - * Returns a constant reference to the MDP associated with this model checker. - * @returns A constant reference to the MDP associated with this model checker. - */ - storm::models::MarkovAutomaton<ValueType> const& getModel() const { - return AbstractModelChecker<ValueType>::template getModel<storm::models::MarkovAutomaton<ValueType>>(); - } - - std::vector<ValueType> checkUntil(storm::property::csl::Until<ValueType> const& formula, bool qualitative) const { - // Test whether it is specified if the minimum or maximum probabilities are to be computed. - if(this->minimumOperatorStack.empty()) { - LOG4CPLUS_ERROR(logger, "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."); - throw storm::exceptions::InvalidArgumentException() << "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."; + // For fast transition rewriting, we build some auxiliary data structures. + storm::storage::BitVector statesNotContainedInAnyMec = ~statesInMecs; + uint_fast64_t firstAuxiliaryStateIndex = statesNotContainedInAnyMec.getNumberOfSetBits(); + uint_fast64_t lastStateNotInMecs = 0; + uint_fast64_t numberOfStatesNotInMecs = 0; + std::vector<uint_fast64_t> statesNotInMecsBeforeIndex; + statesNotInMecsBeforeIndex.reserve(this->getModel().getNumberOfStates()); + for (auto state : statesNotContainedInAnyMec) { + while (lastStateNotInMecs <= state) { + statesNotInMecsBeforeIndex.push_back(numberOfStatesNotInMecs); + ++lastStateNotInMecs; + } + ++numberOfStatesNotInMecs; + } + + // Finally, we are ready to create the SSP matrix and right-hand side of the SSP. + std::vector<ValueType> b; + typename storm::storage::SparseMatrixBuilder<ValueType> sspMatrixBuilder(0, 0, 0, true, numberOfStatesNotInMecs + mecDecomposition.size() + 1); + + // If the source state is not contained in any MEC, we copy its choices (and perform the necessary modifications). + uint_fast64_t currentChoice = 0; + for (auto state : statesNotContainedInAnyMec) { + sspMatrixBuilder.newRowGroup(currentChoice); + + for (uint_fast64_t choice = nondeterministicChoiceIndices[state]; choice < nondeterministicChoiceIndices[state + 1]; ++choice, ++currentChoice) { + std::vector<ValueType> auxiliaryStateToProbabilityMap(mecDecomposition.size()); + b.push_back(storm::utility::constantZero<ValueType>()); + + for (auto element : transitionMatrix.getRow(choice)) { + if (statesNotContainedInAnyMec.get(element.first)) { + // If the target state is not contained in an MEC, we can copy over the entry. + sspMatrixBuilder.addNextValue(currentChoice, statesNotInMecsBeforeIndex[element.first], element.second); + } else { + // If the target state is contained in MEC i, we need to add the probability to the corresponding field in the vector + // so that we are able to write the cumulative probability to the MEC into the matrix. + auxiliaryStateToProbabilityMap[stateToMecIndexMap[element.first]] += element.second; } + } - storm::storage::BitVector leftStates = formula.getLeft().check(*this); - storm::storage::BitVector rightStates = formula.getRight().check(*this); - return computeUnboundedUntilProbabilities(this->minimumOperatorStack.top(), leftStates, rightStates, qualitative).first; - } - - std::pair<std::vector<ValueType>, storm::storage::TotalScheduler> computeUnboundedUntilProbabilities(bool min, storm::storage::BitVector const& leftStates, storm::storage::BitVector const& rightStates, bool qualitative) const { - return storm::modelchecker::prctl::SparseMdpPrctlModelChecker<ValueType>::computeUnboundedUntilProbabilities(min, this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), this->getModel().getInitialStates(), leftStates, rightStates, nondeterministicLinearEquationSolver, qualitative); - } - - std::vector<ValueType> checkTimeBoundedUntil(storm::property::csl::TimeBoundedUntil<ValueType> const& formula, bool qualitative) const { - throw storm::exceptions::NotImplementedException() << "Model checking Until formulas on Markov automata is not yet implemented."; - } - - std::vector<ValueType> checkTimeBoundedEventually(storm::property::csl::TimeBoundedEventually<ValueType> const& formula, bool qualitative) const { - // Test whether it is specified if the minimum or maximum probabilities are to be computed. - if(this->minimumOperatorStack.empty()) { - LOG4CPLUS_ERROR(logger, "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."); - throw storm::exceptions::InvalidArgumentException() << "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."; + // Now insert all (cumulative) probability values that target an MEC. + for (uint_fast64_t mecIndex = 0; mecIndex < auxiliaryStateToProbabilityMap.size(); ++mecIndex) { + if (auxiliaryStateToProbabilityMap[mecIndex] != 0) { + sspMatrixBuilder.addNextValue(currentChoice, firstAuxiliaryStateIndex + mecIndex, auxiliaryStateToProbabilityMap[mecIndex]); } + } + } + } + + // Now we are ready to construct the choices for the auxiliary states. + for (uint_fast64_t mecIndex = 0; mecIndex < mecDecomposition.size(); ++mecIndex) { + storm::storage::MaximalEndComponent const& mec = mecDecomposition[mecIndex]; + sspMatrixBuilder.newRowGroup(currentChoice); - storm::storage::BitVector goalStates = formula.getChild().check(*this); - return this->checkTimeBoundedEventually(this->minimumOperatorStack.top(), goalStates, formula.getLowerBound(), formula.getUpperBound()); - } - - std::vector<ValueType> checkGlobally(storm::property::csl::Globally<ValueType> const& formula, bool qualitative) const { - throw storm::exceptions::NotImplementedException() << "Model checking Globally formulas on Markov automata is not yet implemented."; - } - - std::vector<ValueType> checkEventually(storm::property::csl::Eventually<ValueType> const& formula, bool qualitative) const { - // Test whether it is specified if the minimum or maximum probabilities are to be computed. - if(this->minimumOperatorStack.empty()) { - LOG4CPLUS_ERROR(logger, "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."); - throw storm::exceptions::InvalidArgumentException() << "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."; + for (auto const& stateChoicesPair : mec) { + uint_fast64_t state = stateChoicesPair.first; + boost::container::flat_set<uint_fast64_t> const& choicesInMec = stateChoicesPair.second; + + for (uint_fast64_t choice = nondeterministicChoiceIndices[state]; choice < nondeterministicChoiceIndices[state + 1]; ++choice) { + std::vector<ValueType> auxiliaryStateToProbabilityMap(mecDecomposition.size()); + + // If the choice is not contained in the MEC itself, we have to add a similar distribution to the auxiliary state. + if (choicesInMec.find(choice) == choicesInMec.end()) { + b.push_back(storm::utility::constantZero<ValueType>()); + + for (auto element : transitionMatrix.getRow(choice)) { + if (statesNotContainedInAnyMec.get(element.first)) { + // If the target state is not contained in an MEC, we can copy over the entry. + sspMatrixBuilder.addNextValue(currentChoice, statesNotInMecsBeforeIndex[element.first], element.second); + } else { + // If the target state is contained in MEC i, we need to add the probability to the corresponding field in the vector + // so that we are able to write the cumulative probability to the MEC into the matrix. + auxiliaryStateToProbabilityMap[stateToMecIndexMap[element.first]] += element.second; + } + } + + // Now insert all (cumulative) probability values that target an MEC. + for (uint_fast64_t targetMecIndex = 0; targetMecIndex < auxiliaryStateToProbabilityMap.size(); ++targetMecIndex) { + if (auxiliaryStateToProbabilityMap[targetMecIndex] != 0) { + // If the target MEC is the same as the current one, instead of adding a transition, we need to add the weighted reward + // to the right-hand side vector of the SSP. + if (mecIndex == targetMecIndex) { + b.back() += auxiliaryStateToProbabilityMap[mecIndex] * lraValuesForEndComponents[mecIndex]; + } else { + // Otherwise, we add a transition to the auxiliary state that is associated with the target MEC. + sspMatrixBuilder.addNextValue(currentChoice, firstAuxiliaryStateIndex + targetMecIndex, auxiliaryStateToProbabilityMap[targetMecIndex]); + } + } + } + + ++currentChoice; } + } + } + + // For each auxiliary state, there is the option to achieve the reward value of the LRA associated with the MEC. + ++currentChoice; + b.push_back(lraValuesForEndComponents[mecIndex]); + } + + // Finalize the matrix and solve the corresponding system of equations. + storm::storage::SparseMatrix<ValueType> sspMatrix = sspMatrixBuilder.build(currentChoice + 1); + + std::vector<ValueType> x(numberOfStatesNotInMecs + mecDecomposition.size()); + nondeterministicLinearEquationSolver->solveEquationSystem(min, sspMatrix, x, b); + + // Prepare result vector. + std::vector<ValueType> result(this->getModel().getNumberOfStates()); + + // Set the values for states not contained in MECs. + storm::utility::vector::setVectorValues(result, statesNotContainedInAnyMec, x); + + // Set the values for all states in MECs. + for (auto state : statesInMecs) { + result[state] = lraValuesForEndComponents[stateToMecIndexMap[state]]; + } + + return result; + } + + std::vector<ValueType> checkExpectedTime(bool min, storm::storage::BitVector const& goalStates) const { + // Reduce the problem of computing the expected time to computing expected rewards where the rewards + // for all probabilistic states are zero and the reward values of Markovian states is 1. + std::vector<ValueType> rewardValues(this->getModel().getNumberOfStates(), storm::utility::constantZero<ValueType>()); + storm::utility::vector::setVectorValues(rewardValues, this->getModel().getMarkovianStates(), storm::utility::constantOne<ValueType>()); + return this->computeExpectedRewards(min, goalStates, rewardValues); + } + +protected: + /*! + * Computes the long-run average value for the given maximal end component of a Markov automaton. + * + * @param min Sets whether the long-run average is to be minimized or maximized. + * @param transitionMatrix The transition matrix of the underlying Markov automaton. + * @param nondeterministicChoiceIndices A vector indicating at which row the choice of a given state begins. + * @param markovianStates A bit vector storing all markovian states. + * @param exitRates A vector with exit rates for all states. Exit rates of probabilistic states are assumed to be zero. + * @param goalStates A bit vector indicating which states are to be considered as goal states. + * @param mec The maximal end component to consider for computing the long-run average. + * @param mecIndex The index of the MEC. + * @return The long-run average of being in a goal state for the given MEC. + */ + static ValueType computeLraForMaximalEndComponent(bool min, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, storm::storage::BitVector const& markovianStates, std::vector<ValueType> const& exitRates, storm::storage::BitVector const& goalStates, storm::storage::MaximalEndComponent const& mec, uint_fast64_t mecIndex = 0) { + std::shared_ptr<storm::solver::LpSolver> solver = storm::utility::solver::getLpSolver("LRA for MEC"); + solver->setModelSense(min ? storm::solver::LpSolver::MAXIMIZE : storm::solver::LpSolver::MINIMIZE); + + // First, we need to create the variables for the problem. + std::map<uint_fast64_t, uint_fast64_t> stateToVariableIndexMap; + for (auto const& stateChoicesPair : mec) { + stateToVariableIndexMap[stateChoicesPair.first] = solver->createContinuousVariable("x" + std::to_string(stateChoicesPair.first), storm::solver::LpSolver::UNBOUNDED, 0, 0, 0); + } + uint_fast64_t lraValueVariableIndex = solver->createContinuousVariable("k", storm::solver::LpSolver::UNBOUNDED, 0, 0, 1); + solver->update(); + + // Now we encode the problem as constraints. + std::vector<uint_fast64_t> variables; + std::vector<double> coefficients; + for (auto const& stateChoicesPair : mec) { + uint_fast64_t state = stateChoicesPair.first; + + // Now, based on the type of the state, create a suitable constraint. + if (markovianStates.get(state)) { + variables.clear(); + coefficients.clear(); + + variables.push_back(stateToVariableIndexMap.at(state)); + coefficients.push_back(1); + + for (auto element : transitionMatrix.getRow(nondeterministicChoiceIndices[state])) { + variables.push_back(stateToVariableIndexMap.at(element.first)); + coefficients.push_back(-element.second); + } + + variables.push_back(lraValueVariableIndex); + coefficients.push_back(storm::utility::constantOne<ValueType>() / exitRates[state]); + + solver->addConstraint("state" + std::to_string(state), variables, coefficients, min ? storm::solver::LpSolver::LESS_EQUAL : storm::solver::LpSolver::GREATER_EQUAL, goalStates.get(state) ? storm::utility::constantOne<ValueType>() / exitRates[state] : storm::utility::constantZero<ValueType>()); + } else { + // For probabilistic states, we want to add the constraint x_s <= sum P(s, a, s') * x_s' where a is the current action + // and the sum ranges over all states s'. + for (auto choice : stateChoicesPair.second) { + variables.clear(); + coefficients.clear(); + + variables.push_back(stateToVariableIndexMap.at(state)); + coefficients.push_back(1); + + for (auto element : transitionMatrix.getRow(choice)) { + variables.push_back(stateToVariableIndexMap.at(element.first)); + coefficients.push_back(-element.second); + } + + solver->addConstraint("state" + std::to_string(state), variables, coefficients, min ? storm::solver::LpSolver::LESS_EQUAL : storm::solver::LpSolver::GREATER_EQUAL, storm::utility::constantZero<ValueType>()); + } + } + } + + solver->optimize(); + return solver->getContinuousValue(lraValueVariableIndex); + } + + /*! + * Computes the expected reward that is gained from each state before entering any of the goal states. + * + * @param min Indicates whether minimal or maximal rewards are to be computed. + * @param goalStates The goal states that define until which point rewards are gained. + * @param stateRewards A vector that defines the reward gained in each state. For probabilistic states, this is an instantaneous reward + * that is fully gained and for Markovian states the actually gained reward is dependent on the expected time to stay in the + * state, i.e. it is gouverned by the exit rate of the state. + * @return A vector that contains the expected reward for each state of the model. + */ + std::vector<ValueType> computeExpectedRewards(bool min, storm::storage::BitVector const& goalStates, std::vector<ValueType> const& stateRewards) const { + // Check whether the automaton is closed. + if (!this->getModel().isClosed()) { + throw storm::exceptions::InvalidArgumentException() << "Unable to compute expected time on non-closed Markov automaton."; + } + + // First, we need to check which states have infinite expected time (by definition). + storm::storage::BitVector infinityStates; + if (min) { + // If we need to compute the minimum expected times, we have to set the values of those states to infinity that, under all schedulers, + // reach a bottom SCC without a goal state. + + // So we start by computing all bottom SCCs without goal states. + storm::storage::StronglyConnectedComponentDecomposition<double> sccDecomposition(this->getModel(), ~goalStates, true, true); + + // Now form the union of all these SCCs. + storm::storage::BitVector unionOfNonGoalBSccs(this->getModel().getNumberOfStates()); + for (auto const& scc : sccDecomposition) { + for (auto state : scc) { + unionOfNonGoalBSccs.set(state); + } + } + + // Finally, if this union is non-empty, compute the states such that all schedulers reach some state of the union. + if (!unionOfNonGoalBSccs.empty()) { + infinityStates = storm::utility::graph::performProbGreater0A(this->getModel().getTransitionMatrix(), this->getModel().getNondeterministicChoiceIndices(), this->getModel().getBackwardTransitions(), storm::storage::BitVector(this->getModel().getNumberOfStates(), true), unionOfNonGoalBSccs); + } else { + // Otherwise, we have no infinity states. + infinityStates = storm::storage::BitVector(this->getModel().getNumberOfStates()); + } + } else { + // If we maximize the property, the expected time of a state is infinite, if an end-component without any goal state is reachable. + + // So we start by computing all MECs that have no goal state. + storm::storage::MaximalEndComponentDecomposition<double> mecDecomposition(this->getModel(), ~goalStates); + + // Now we form the union of all states in these end components. + storm::storage::BitVector unionOfNonGoalMaximalEndComponents(this->getModel().getNumberOfStates()); + for (auto const& mec : mecDecomposition) { + for (auto const& stateActionPair : mec) { + unionOfNonGoalMaximalEndComponents.set(stateActionPair.first); + } + } + + if (!unionOfNonGoalMaximalEndComponents.empty()) { + // Now we need to check for which states there exists a scheduler that reaches one of the previously computed states. + infinityStates = storm::utility::graph::performProbGreater0E(this->getModel().getTransitionMatrix(), this->getModel().getNondeterministicChoiceIndices(), this->getModel().getBackwardTransitions(), storm::storage::BitVector(this->getModel().getNumberOfStates(), true), unionOfNonGoalMaximalEndComponents); + } else { + // Otherwise, we have no infinity states. + infinityStates = storm::storage::BitVector(this->getModel().getNumberOfStates()); + } + } + + // Now we identify the states for which values need to be computed. + storm::storage::BitVector maybeStates = ~(goalStates | infinityStates); + + // Then, we can eliminate the rows and columns for all states whose values are already known to be 0. + std::vector<ValueType> x(maybeStates.getNumberOfSetBits()); + storm::storage::SparseMatrix<ValueType> submatrix = this->getModel().getTransitionMatrix().getSubmatrix(true, maybeStates, maybeStates); + + // Now prepare the expected reward values for all states so they can be used as the right-hand side of the equation system. + std::vector<ValueType> rewardValues(stateRewards); + for (auto state : this->getModel().getMarkovianStates()) { + rewardValues[state] = rewardValues[state] / this->getModel().getExitRates()[state]; + } + + // Finally, prepare the actual right-hand side. + std::vector<ValueType> b(submatrix.getRowCount()); + storm::utility::vector::selectVectorValuesRepeatedly(b, maybeStates, this->getModel().getNondeterministicChoiceIndices(), rewardValues); + + // Solve the corresponding system of equations. + std::shared_ptr<storm::solver::NondeterministicLinearEquationSolver<ValueType>> nondeterministiclinearEquationSolver = storm::utility::solver::getNondeterministicLinearEquationSolver<ValueType>(); + nondeterministiclinearEquationSolver->solveEquationSystem(min, submatrix, x, b); + + // Create resulting vector. + std::vector<ValueType> result(this->getModel().getNumberOfStates()); + + // Set values of resulting vector according to previous result and return the result. + storm::utility::vector::setVectorValues<ValueType>(result, maybeStates, x); + storm::utility::vector::setVectorValues(result, goalStates, storm::utility::constantZero<ValueType>()); + storm::utility::vector::setVectorValues(result, infinityStates, storm::utility::constantInfinity<ValueType>()); + + return result; + } + + /*! + * A solver that is used for solving systems of linear equations that are the result of nondeterministic choices. + */ + std::shared_ptr<storm::solver::NondeterministicLinearEquationSolver<ValueType>> nondeterministicLinearEquationSolver; +}; - storm::storage::BitVector subFormulaStates = formula.getChild().check(*this); - return computeUnboundedUntilProbabilities(this->minimumOperatorStack.top(), storm::storage::BitVector(this->getModel().getNumberOfStates(), true), subFormulaStates, qualitative).first; - } - - std::vector<ValueType> checkNext(storm::property::csl::Next<ValueType> const& formula, bool qualitative) const { - throw storm::exceptions::NotImplementedException() << "Model checking Next formulas on Markov automata is not yet implemented."; - } - - static void computeBoundedReachabilityProbabilities(bool min, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRates, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& goalStates, storm::storage::BitVector const& markovianNonGoalStates, storm::storage::BitVector const& probabilisticNonGoalStates, std::vector<ValueType>& markovianNonGoalValues, std::vector<ValueType>& probabilisticNonGoalValues, ValueType delta, uint_fast64_t numberOfSteps) { - // Start by computing four sparse matrices: - // * a matrix aMarkovian with all (discretized) transitions from Markovian non-goal states to all Markovian non-goal states. - // * a matrix aMarkovianToProbabilistic with all (discretized) transitions from Markovian non-goal states to all probabilistic non-goal states. - // * a matrix aProbabilistic with all (non-discretized) transitions from probabilistic non-goal states to other probabilistic non-goal states. - // * a matrix aProbabilisticToMarkovian with all (non-discretized) transitions from probabilistic non-goal states to all Markovian non-goal states. - typename storm::storage::SparseMatrix<ValueType> aMarkovian = transitionMatrix.getSubmatrix(true, markovianNonGoalStates, markovianNonGoalStates, true); - typename storm::storage::SparseMatrix<ValueType> aMarkovianToProbabilistic = transitionMatrix.getSubmatrix(true, markovianNonGoalStates, probabilisticNonGoalStates); - typename storm::storage::SparseMatrix<ValueType> aProbabilistic = transitionMatrix.getSubmatrix(true, probabilisticNonGoalStates, probabilisticNonGoalStates); - typename storm::storage::SparseMatrix<ValueType> aProbabilisticToMarkovian = transitionMatrix.getSubmatrix(true, probabilisticNonGoalStates, markovianNonGoalStates); - - // The matrices with transitions from Markovian states need to be digitized. - // Digitize aMarkovian. Based on whether the transition is a self-loop or not, we apply the two digitization rules. - uint_fast64_t rowIndex = 0; - for (auto state : markovianNonGoalStates) { - for (auto& element : aMarkovian.getRow(rowIndex)) { - ValueType eTerm = std::exp(-exitRates[state] * delta); - if (element.first == rowIndex) { - element.second = (storm::utility::constantOne<ValueType>() - eTerm) * element.second + eTerm; - } else { - element.second = (storm::utility::constantOne<ValueType>() - eTerm) * element.second; - } - } - ++rowIndex; - } - - // Digitize aMarkovianToProbabilistic. As there are no self-loops in this case, we only need to apply the digitization formula for regular successors. - rowIndex = 0; - for (auto state : markovianNonGoalStates) { - for (auto& element : aMarkovianToProbabilistic.getRow(rowIndex)) { - element.second = (1 - std::exp(-exitRates[state] * delta)) * element.second; - } - ++rowIndex; - } - - // Initialize the two vectors that hold the variable one-step probabilities to all target states for probabilistic and Markovian (non-goal) states. - std::vector<ValueType> bProbabilistic(aProbabilistic.getRowCount()); - std::vector<ValueType> bMarkovian(markovianNonGoalStates.getNumberOfSetBits()); - - // Compute the two fixed right-hand side vectors, one for Markovian states and one for the probabilistic ones. - std::vector<ValueType> bProbabilisticFixed = transitionMatrix.getConstrainedRowSumVector(probabilisticNonGoalStates, goalStates); - std::vector<ValueType> bMarkovianFixed; - bMarkovianFixed.reserve(markovianNonGoalStates.getNumberOfSetBits()); - for (auto state : markovianNonGoalStates) { - bMarkovianFixed.push_back(storm::utility::constantZero<ValueType>()); - - for (auto& element : transitionMatrix.getRowGroup(state)) { - if (goalStates.get(element.first)) { - bMarkovianFixed.back() += (1 - std::exp(-exitRates[state] * delta)) * element.second; - } - } - } - - std::shared_ptr<storm::solver::NondeterministicLinearEquationSolver<ValueType>> nondeterministiclinearEquationSolver = storm::utility::solver::getNondeterministicLinearEquationSolver<ValueType>(); - - // Perform the actual value iteration - // * loop until the step bound has been reached - // * in the loop: - // * perform value iteration using A_PSwG, v_PS and the vector b where b = (A * 1_G)|PS + A_PStoMS * v_MS - // and 1_G being the characteristic vector for all goal states. - // * perform one timed-step using v_MS := A_MSwG * v_MS + A_MStoPS * v_PS + (A * 1_G)|MS - std::vector<ValueType> markovianNonGoalValuesSwap(markovianNonGoalValues); - std::vector<ValueType> multiplicationResultScratchMemory(aProbabilistic.getRowCount()); - std::vector<ValueType> aProbabilisticScratchMemory(probabilisticNonGoalValues.size()); - for (uint_fast64_t currentStep = 0; currentStep < numberOfSteps; ++currentStep) { - // Start by (re-)computing bProbabilistic = bProbabilisticFixed + aProbabilisticToMarkovian * vMarkovian. - aProbabilisticToMarkovian.multiplyWithVector(markovianNonGoalValues, bProbabilistic); - storm::utility::vector::addVectorsInPlace(bProbabilistic, bProbabilisticFixed); - - // Now perform the inner value iteration for probabilistic states. - nondeterministiclinearEquationSolver->solveEquationSystem(min, aProbabilistic, probabilisticNonGoalValues, bProbabilistic, &multiplicationResultScratchMemory, &aProbabilisticScratchMemory); - - // (Re-)compute bMarkovian = bMarkovianFixed + aMarkovianToProbabilistic * vProbabilistic. - aMarkovianToProbabilistic.multiplyWithVector(probabilisticNonGoalValues, bMarkovian); - storm::utility::vector::addVectorsInPlace(bMarkovian, bMarkovianFixed); - aMarkovian.multiplyWithVector(markovianNonGoalValues, markovianNonGoalValuesSwap); - std::swap(markovianNonGoalValues, markovianNonGoalValuesSwap); - storm::utility::vector::addVectorsInPlace(markovianNonGoalValues, bMarkovian); - } - - // After the loop, perform one more step of the value iteration for PS states. - aProbabilisticToMarkovian.multiplyWithVector(markovianNonGoalValues, bProbabilistic); - storm::utility::vector::addVectorsInPlace(bProbabilistic, bProbabilisticFixed); - nondeterministiclinearEquationSolver->solveEquationSystem(min, aProbabilistic, probabilisticNonGoalValues, bProbabilistic, &multiplicationResultScratchMemory, &aProbabilisticScratchMemory); - } - - std::vector<ValueType> checkTimeBoundedEventually(bool min, storm::storage::BitVector const& goalStates, ValueType lowerBound, ValueType upperBound) const { - // Check whether the automaton is closed. - if (!this->getModel().isClosed()) { - throw storm::exceptions::InvalidArgumentException() << "Unable to compute time-bounded reachability on non-closed Markov automaton."; - } - - // Check whether the given bounds were valid. - if (lowerBound < storm::utility::constantZero<ValueType>() || upperBound < storm::utility::constantZero<ValueType>() || upperBound < lowerBound) { - throw storm::exceptions::InvalidArgumentException() << "Illegal interval ["; - } - - // Get some data fields for convenient access. - typename storm::storage::SparseMatrix<ValueType> const& transitionMatrix = this->getModel().getTransitionMatrix(); - std::vector<ValueType> const& exitRates = this->getModel().getExitRates(); - storm::storage::BitVector const& markovianStates = this->getModel().getMarkovianStates(); - - // (1) Compute the accuracy we need to achieve the required error bound. - ValueType maxExitRate = this->getModel().getMaximalExitRate(); - ValueType delta = (2 * storm::settings::Settings::getInstance()->getOptionByLongName("digiprecision").getArgument(0).getValueAsDouble()) / (upperBound * maxExitRate * maxExitRate); - - // (2) Compute the number of steps we need to make for the interval. - uint_fast64_t numberOfSteps = static_cast<uint_fast64_t>(std::ceil((upperBound - lowerBound) / delta)); - std::cout << "Performing " << numberOfSteps << " iterations (delta=" << delta << ") for interval [" << lowerBound << ", " << upperBound << "]." << std::endl; - - // (3) Compute the non-goal states and initialize two vectors - // * vProbabilistic holds the probability values of probabilistic non-goal states. - // * vMarkovian holds the probability values of Markovian non-goal states. - storm::storage::BitVector const& markovianNonGoalStates = markovianStates & ~goalStates; - storm::storage::BitVector const& probabilisticNonGoalStates = ~markovianStates & ~goalStates; - std::vector<ValueType> vProbabilistic(probabilisticNonGoalStates.getNumberOfSetBits()); - std::vector<ValueType> vMarkovian(markovianNonGoalStates.getNumberOfSetBits()); - - computeBoundedReachabilityProbabilities(min, transitionMatrix, exitRates, markovianStates, goalStates, markovianNonGoalStates, probabilisticNonGoalStates, vMarkovian, vProbabilistic, delta, numberOfSteps); - - // (4) If the lower bound of interval was non-zero, we need to take the current values as the starting values for a subsequent value iteration. - if (lowerBound != storm::utility::constantZero<ValueType>()) { - std::vector<ValueType> vAllProbabilistic((~markovianStates).getNumberOfSetBits()); - std::vector<ValueType> vAllMarkovian(markovianStates.getNumberOfSetBits()); - - // Create the starting value vectors for the next value iteration based on the results of the previous one. - storm::utility::vector::setVectorValues<ValueType>(vAllProbabilistic, goalStates % ~markovianStates, storm::utility::constantOne<ValueType>()); - storm::utility::vector::setVectorValues<ValueType>(vAllProbabilistic, ~goalStates % ~markovianStates, vProbabilistic); - storm::utility::vector::setVectorValues<ValueType>(vAllMarkovian, goalStates % markovianStates, storm::utility::constantOne<ValueType>()); - storm::utility::vector::setVectorValues<ValueType>(vAllMarkovian, ~goalStates % markovianStates, vMarkovian); - - // Compute the number of steps to reach the target interval. - numberOfSteps = static_cast<uint_fast64_t>(std::ceil(lowerBound / delta)); - std::cout << "Performing " << numberOfSteps << " iterations (delta=" << delta << ") for interval [0, " << lowerBound << "]." << std::endl; - - // Compute the bounded reachability for interval [0, b-a]. - computeBoundedReachabilityProbabilities(min, transitionMatrix, exitRates, markovianStates, storm::storage::BitVector(this->getModel().getNumberOfStates()), markovianStates, ~markovianStates, vAllMarkovian, vAllProbabilistic, delta, numberOfSteps); - - // Create the result vector out of vAllProbabilistic and vAllMarkovian and return it. - std::vector<ValueType> result(this->getModel().getNumberOfStates()); - storm::utility::vector::setVectorValues(result, ~markovianStates, vAllProbabilistic); - storm::utility::vector::setVectorValues(result, markovianStates, vAllMarkovian); - - return result; - } else { - // Create the result vector out of 1_G, vProbabilistic and vMarkovian and return it. - std::vector<ValueType> result(this->getModel().getNumberOfStates()); - storm::utility::vector::setVectorValues<ValueType>(result, goalStates, storm::utility::constantOne<ValueType>()); - storm::utility::vector::setVectorValues(result, probabilisticNonGoalStates, vProbabilistic); - storm::utility::vector::setVectorValues(result, markovianNonGoalStates, vMarkovian); - return result; - } - } - - std::vector<ValueType> checkLongRunAverage(bool min, storm::storage::BitVector const& goalStates) const { - // Check whether the automaton is closed. - if (!this->getModel().isClosed()) { - throw storm::exceptions::InvalidArgumentException() << "Unable to compute long-run average on non-closed Markov automaton."; - } - - // If there are no goal states, we avoid the computation and directly return zero. - if (goalStates.empty()) { - return std::vector<ValueType>(this->getModel().getNumberOfStates(), storm::utility::constantZero<ValueType>()); - } - - // Likewise, if all bits are set, we can avoid the computation and set. - if ((~goalStates).empty()) { - return std::vector<ValueType>(this->getModel().getNumberOfStates(), storm::utility::constantOne<ValueType>()); - } - - // Start by decomposing the Markov automaton into its MECs. - storm::storage::MaximalEndComponentDecomposition<double> mecDecomposition(this->getModel()); - - // Get some data members for convenience. - typename storm::storage::SparseMatrix<ValueType> const& transitionMatrix = this->getModel().getTransitionMatrix(); - std::vector<uint_fast64_t> const& nondeterministicChoiceIndices = this->getModel().getNondeterministicChoiceIndices(); - - // Now start with compute the long-run average for all end components in isolation. - std::vector<ValueType> lraValuesForEndComponents; - - // While doing so, we already gather some information for the following steps. - std::vector<uint_fast64_t> stateToMecIndexMap(this->getModel().getNumberOfStates()); - storm::storage::BitVector statesInMecs(this->getModel().getNumberOfStates()); - - for (uint_fast64_t currentMecIndex = 0; currentMecIndex < mecDecomposition.size(); ++currentMecIndex) { - storm::storage::MaximalEndComponent const& mec = mecDecomposition[currentMecIndex]; - - // Gather information for later use. - for (auto const& stateChoicesPair : mec) { - uint_fast64_t state = stateChoicesPair.first; - - statesInMecs.set(state); - stateToMecIndexMap[state] = currentMecIndex; - } - - // Compute the LRA value for the current MEC. - lraValuesForEndComponents.push_back(this->computeLraForMaximalEndComponent(min, transitionMatrix, nondeterministicChoiceIndices, this->getModel().getMarkovianStates(), this->getModel().getExitRates(), goalStates, mec, currentMecIndex)); - } - - // For fast transition rewriting, we build some auxiliary data structures. - storm::storage::BitVector statesNotContainedInAnyMec = ~statesInMecs; - uint_fast64_t firstAuxiliaryStateIndex = statesNotContainedInAnyMec.getNumberOfSetBits(); - uint_fast64_t lastStateNotInMecs = 0; - uint_fast64_t numberOfStatesNotInMecs = 0; - std::vector<uint_fast64_t> statesNotInMecsBeforeIndex; - statesNotInMecsBeforeIndex.reserve(this->getModel().getNumberOfStates()); - for (auto state : statesNotContainedInAnyMec) { - while (lastStateNotInMecs <= state) { - statesNotInMecsBeforeIndex.push_back(numberOfStatesNotInMecs); - ++lastStateNotInMecs; - } - ++numberOfStatesNotInMecs; - } - - // Finally, we are ready to create the SSP matrix and right-hand side of the SSP. - std::vector<ValueType> b; - typename storm::storage::SparseMatrixBuilder<ValueType> sspMatrixBuilder(0, 0, 0, true, numberOfStatesNotInMecs + mecDecomposition.size() + 1); - - // If the source state is not contained in any MEC, we copy its choices (and perform the necessary modifications). - uint_fast64_t currentChoice = 0; - for (auto state : statesNotContainedInAnyMec) { - sspMatrixBuilder.newRowGroup(currentChoice); - - for (uint_fast64_t choice = nondeterministicChoiceIndices[state]; choice < nondeterministicChoiceIndices[state + 1]; ++choice, ++currentChoice) { - std::vector<ValueType> auxiliaryStateToProbabilityMap(mecDecomposition.size()); - b.push_back(storm::utility::constantZero<ValueType>()); - - for (auto element : transitionMatrix.getRow(choice)) { - if (statesNotContainedInAnyMec.get(element.first)) { - // If the target state is not contained in an MEC, we can copy over the entry. - sspMatrixBuilder.addNextValue(currentChoice, statesNotInMecsBeforeIndex[element.first], element.second); - } else { - // If the target state is contained in MEC i, we need to add the probability to the corresponding field in the vector - // so that we are able to write the cumulative probability to the MEC into the matrix. - auxiliaryStateToProbabilityMap[stateToMecIndexMap[element.first]] += element.second; - } - } - - // Now insert all (cumulative) probability values that target an MEC. - for (uint_fast64_t mecIndex = 0; mecIndex < auxiliaryStateToProbabilityMap.size(); ++mecIndex) { - if (auxiliaryStateToProbabilityMap[mecIndex] != 0) { - sspMatrixBuilder.addNextValue(currentChoice, firstAuxiliaryStateIndex + mecIndex, auxiliaryStateToProbabilityMap[mecIndex]); - } - } - } - } - - // Now we are ready to construct the choices for the auxiliary states. - for (uint_fast64_t mecIndex = 0; mecIndex < mecDecomposition.size(); ++mecIndex) { - storm::storage::MaximalEndComponent const& mec = mecDecomposition[mecIndex]; - sspMatrixBuilder.newRowGroup(currentChoice); - - for (auto const& stateChoicesPair : mec) { - uint_fast64_t state = stateChoicesPair.first; - boost::container::flat_set<uint_fast64_t> const& choicesInMec = stateChoicesPair.second; - - for (uint_fast64_t choice = nondeterministicChoiceIndices[state]; choice < nondeterministicChoiceIndices[state + 1]; ++choice) { - std::vector<ValueType> auxiliaryStateToProbabilityMap(mecDecomposition.size()); - - // If the choice is not contained in the MEC itself, we have to add a similar distribution to the auxiliary state. - if (choicesInMec.find(choice) == choicesInMec.end()) { - b.push_back(storm::utility::constantZero<ValueType>()); - - for (auto element : transitionMatrix.getRow(choice)) { - if (statesNotContainedInAnyMec.get(element.first)) { - // If the target state is not contained in an MEC, we can copy over the entry. - sspMatrixBuilder.addNextValue(currentChoice, statesNotInMecsBeforeIndex[element.first], element.second); - } else { - // If the target state is contained in MEC i, we need to add the probability to the corresponding field in the vector - // so that we are able to write the cumulative probability to the MEC into the matrix. - auxiliaryStateToProbabilityMap[stateToMecIndexMap[element.first]] += element.second; - } - } - - // Now insert all (cumulative) probability values that target an MEC. - for (uint_fast64_t targetMecIndex = 0; targetMecIndex < auxiliaryStateToProbabilityMap.size(); ++targetMecIndex) { - if (auxiliaryStateToProbabilityMap[targetMecIndex] != 0) { - // If the target MEC is the same as the current one, instead of adding a transition, we need to add the weighted reward - // to the right-hand side vector of the SSP. - if (mecIndex == targetMecIndex) { - b.back() += auxiliaryStateToProbabilityMap[mecIndex] * lraValuesForEndComponents[mecIndex]; - } else { - // Otherwise, we add a transition to the auxiliary state that is associated with the target MEC. - sspMatrixBuilder.addNextValue(currentChoice, firstAuxiliaryStateIndex + targetMecIndex, auxiliaryStateToProbabilityMap[targetMecIndex]); - } - } - } - - ++currentChoice; - } - } - } - - // For each auxiliary state, there is the option to achieve the reward value of the LRA associated with the MEC. - ++currentChoice; - b.push_back(lraValuesForEndComponents[mecIndex]); - } - - // Finalize the matrix and solve the corresponding system of equations. - storm::storage::SparseMatrix<ValueType> sspMatrix = sspMatrixBuilder.build(currentChoice + 1); - - std::vector<ValueType> x(numberOfStatesNotInMecs + mecDecomposition.size()); - nondeterministicLinearEquationSolver->solveEquationSystem(min, sspMatrix, x, b); - - // Prepare result vector. - std::vector<ValueType> result(this->getModel().getNumberOfStates()); - - // Set the values for states not contained in MECs. - storm::utility::vector::setVectorValues(result, statesNotContainedInAnyMec, x); - - // Set the values for all states in MECs. - for (auto state : statesInMecs) { - result[state] = lraValuesForEndComponents[stateToMecIndexMap[state]]; - } - - return result; - } - - std::vector<ValueType> checkExpectedTime(bool min, storm::storage::BitVector const& goalStates) const { - // Reduce the problem of computing the expected time to computing expected rewards where the rewards - // for all probabilistic states are zero and the reward values of Markovian states is 1. - std::vector<ValueType> rewardValues(this->getModel().getNumberOfStates(), storm::utility::constantZero<ValueType>()); - storm::utility::vector::setVectorValues(rewardValues, this->getModel().getMarkovianStates(), storm::utility::constantOne<ValueType>()); - return this->computeExpectedRewards(min, goalStates, rewardValues); - } - - protected: - /*! - * Computes the long-run average value for the given maximal end component of a Markov automaton. - * - * @param min Sets whether the long-run average is to be minimized or maximized. - * @param transitionMatrix The transition matrix of the underlying Markov automaton. - * @param nondeterministicChoiceIndices A vector indicating at which row the choice of a given state begins. - * @param markovianStates A bit vector storing all markovian states. - * @param exitRates A vector with exit rates for all states. Exit rates of probabilistic states are assumed to be zero. - * @param goalStates A bit vector indicating which states are to be considered as goal states. - * @param mec The maximal end component to consider for computing the long-run average. - * @param mecIndex The index of the MEC. - * @return The long-run average of being in a goal state for the given MEC. - */ - static ValueType computeLraForMaximalEndComponent(bool min, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, storm::storage::BitVector const& markovianStates, std::vector<ValueType> const& exitRates, storm::storage::BitVector const& goalStates, storm::storage::MaximalEndComponent const& mec, uint_fast64_t mecIndex = 0) { - std::shared_ptr<storm::solver::LpSolver> solver = storm::utility::solver::getLpSolver("LRA for MEC"); - solver->setModelSense(min ? storm::solver::LpSolver::MAXIMIZE : storm::solver::LpSolver::MINIMIZE); - - // First, we need to create the variables for the problem. - std::map<uint_fast64_t, uint_fast64_t> stateToVariableIndexMap; - for (auto const& stateChoicesPair : mec) { - stateToVariableIndexMap[stateChoicesPair.first] = solver->createContinuousVariable("x" + std::to_string(stateChoicesPair.first), storm::solver::LpSolver::UNBOUNDED, 0, 0, 0); - } - uint_fast64_t lraValueVariableIndex = solver->createContinuousVariable("k", storm::solver::LpSolver::UNBOUNDED, 0, 0, 1); - solver->update(); - - // Now we encode the problem as constraints. - std::vector<uint_fast64_t> variables; - std::vector<double> coefficients; - for (auto const& stateChoicesPair : mec) { - uint_fast64_t state = stateChoicesPair.first; - - // Now, based on the type of the state, create a suitable constraint. - if (markovianStates.get(state)) { - variables.clear(); - coefficients.clear(); - - variables.push_back(stateToVariableIndexMap.at(state)); - coefficients.push_back(1); - - for (auto element : transitionMatrix.getRow(nondeterministicChoiceIndices[state])) { - variables.push_back(stateToVariableIndexMap.at(element.first)); - coefficients.push_back(-element.second); - } - - variables.push_back(lraValueVariableIndex); - coefficients.push_back(storm::utility::constantOne<ValueType>() / exitRates[state]); - - solver->addConstraint("state" + std::to_string(state), variables, coefficients, min ? storm::solver::LpSolver::LESS_EQUAL : storm::solver::LpSolver::GREATER_EQUAL, goalStates.get(state) ? storm::utility::constantOne<ValueType>() / exitRates[state] : storm::utility::constantZero<ValueType>()); - } else { - // For probabilistic states, we want to add the constraint x_s <= sum P(s, a, s') * x_s' where a is the current action - // and the sum ranges over all states s'. - for (auto choice : stateChoicesPair.second) { - variables.clear(); - coefficients.clear(); - - variables.push_back(stateToVariableIndexMap.at(state)); - coefficients.push_back(1); - - for (auto element : transitionMatrix.getRow(choice)) { - variables.push_back(stateToVariableIndexMap.at(element.first)); - coefficients.push_back(-element.second); - } - - solver->addConstraint("state" + std::to_string(state), variables, coefficients, min ? storm::solver::LpSolver::LESS_EQUAL : storm::solver::LpSolver::GREATER_EQUAL, storm::utility::constantZero<ValueType>()); - } - } - } - - solver->optimize(); - return solver->getContinuousValue(lraValueVariableIndex); - } - - /*! - * Computes the expected reward that is gained from each state before entering any of the goal states. - * - * @param min Indicates whether minimal or maximal rewards are to be computed. - * @param goalStates The goal states that define until which point rewards are gained. - * @param stateRewards A vector that defines the reward gained in each state. For probabilistic states, this is an instantaneous reward - * that is fully gained and for Markovian states the actually gained reward is dependent on the expected time to stay in the - * state, i.e. it is gouverned by the exit rate of the state. - * @return A vector that contains the expected reward for each state of the model. - */ - std::vector<ValueType> computeExpectedRewards(bool min, storm::storage::BitVector const& goalStates, std::vector<ValueType> const& stateRewards) const { - // Check whether the automaton is closed. - if (!this->getModel().isClosed()) { - throw storm::exceptions::InvalidArgumentException() << "Unable to compute expected time on non-closed Markov automaton."; - } - - // First, we need to check which states have infinite expected time (by definition). - storm::storage::BitVector infinityStates; - if (min) { - // If we need to compute the minimum expected times, we have to set the values of those states to infinity that, under all schedulers, - // reach a bottom SCC without a goal state. - - // So we start by computing all bottom SCCs without goal states. - storm::storage::StronglyConnectedComponentDecomposition<double> sccDecomposition(this->getModel(), ~goalStates, true, true); - - // Now form the union of all these SCCs. - storm::storage::BitVector unionOfNonGoalBSccs(this->getModel().getNumberOfStates()); - for (auto const& scc : sccDecomposition) { - for (auto state : scc) { - unionOfNonGoalBSccs.set(state); - } - } - - // Finally, if this union is non-empty, compute the states such that all schedulers reach some state of the union. - if (!unionOfNonGoalBSccs.empty()) { - infinityStates = storm::utility::graph::performProbGreater0A(this->getModel().getTransitionMatrix(), this->getModel().getNondeterministicChoiceIndices(), this->getModel().getBackwardTransitions(), storm::storage::BitVector(this->getModel().getNumberOfStates(), true), unionOfNonGoalBSccs); - } else { - // Otherwise, we have no infinity states. - infinityStates = storm::storage::BitVector(this->getModel().getNumberOfStates()); - } - } else { - // If we maximize the property, the expected time of a state is infinite, if an end-component without any goal state is reachable. - - // So we start by computing all MECs that have no goal state. - storm::storage::MaximalEndComponentDecomposition<double> mecDecomposition(this->getModel(), ~goalStates); - - // Now we form the union of all states in these end components. - storm::storage::BitVector unionOfNonGoalMaximalEndComponents(this->getModel().getNumberOfStates()); - for (auto const& mec : mecDecomposition) { - for (auto const& stateActionPair : mec) { - unionOfNonGoalMaximalEndComponents.set(stateActionPair.first); - } - } - - if (!unionOfNonGoalMaximalEndComponents.empty()) { - // Now we need to check for which states there exists a scheduler that reaches one of the previously computed states. - infinityStates = storm::utility::graph::performProbGreater0E(this->getModel().getTransitionMatrix(), this->getModel().getNondeterministicChoiceIndices(), this->getModel().getBackwardTransitions(), storm::storage::BitVector(this->getModel().getNumberOfStates(), true), unionOfNonGoalMaximalEndComponents); - } else { - // Otherwise, we have no infinity states. - infinityStates = storm::storage::BitVector(this->getModel().getNumberOfStates()); - } - } - - // Now we identify the states for which values need to be computed. - storm::storage::BitVector maybeStates = ~(goalStates | infinityStates); - - // Then, we can eliminate the rows and columns for all states whose values are already known to be 0. - std::vector<ValueType> x(maybeStates.getNumberOfSetBits()); - storm::storage::SparseMatrix<ValueType> submatrix = this->getModel().getTransitionMatrix().getSubmatrix(true, maybeStates, maybeStates); - - // Now prepare the expected reward values for all states so they can be used as the right-hand side of the equation system. - std::vector<ValueType> rewardValues(stateRewards); - for (auto state : this->getModel().getMarkovianStates()) { - rewardValues[state] = rewardValues[state] / this->getModel().getExitRates()[state]; - } - - // Finally, prepare the actual right-hand side. - std::vector<ValueType> b(submatrix.getRowCount()); - storm::utility::vector::selectVectorValuesRepeatedly(b, maybeStates, this->getModel().getNondeterministicChoiceIndices(), rewardValues); - - // Solve the corresponding system of equations. - std::shared_ptr<storm::solver::NondeterministicLinearEquationSolver<ValueType>> nondeterministiclinearEquationSolver = storm::utility::solver::getNondeterministicLinearEquationSolver<ValueType>(); - nondeterministiclinearEquationSolver->solveEquationSystem(min, submatrix, x, b); - - // Create resulting vector. - std::vector<ValueType> result(this->getModel().getNumberOfStates()); - - // Set values of resulting vector according to previous result and return the result. - storm::utility::vector::setVectorValues<ValueType>(result, maybeStates, x); - storm::utility::vector::setVectorValues(result, goalStates, storm::utility::constantZero<ValueType>()); - storm::utility::vector::setVectorValues(result, infinityStates, storm::utility::constantInfinity<ValueType>()); - - return result; - } - - /*! - * A solver that is used for solving systems of linear equations that are the result of nondeterministic choices. - */ - std::shared_ptr<storm::solver::NondeterministicLinearEquationSolver<ValueType>> nondeterministicLinearEquationSolver; - }; - } - } -} +} // namespace csl +} // namespace modelchecker +} // namespace storm #endif /* STORM_MODELCHECKER_CSL_SPARSEMARKOVAUTOMATONCSLMODELCHECKER_H_ */ diff --git a/src/parser/CslParser.cpp b/src/parser/CslParser.cpp index efca04e02..52c4012aa 100644 --- a/src/parser/CslParser.cpp +++ b/src/parser/CslParser.cpp @@ -9,6 +9,11 @@ #include "src/utility/OsDetection.h" #include "src/utility/constants.h" +// The action class headers. +#include "src/formula/Actions/AbstractAction.h" +#include "src/formula/Actions/MinMaxAction.h" +#include "src/formula/Actions/RangeAction.h" + // If the parser fails due to ill-formed data, this exception is thrown. #include "src/exceptions/WrongFormatException.h" @@ -38,7 +43,7 @@ namespace storm { namespace parser { template<typename Iterator, typename Skipper> -struct CslGrammar : qi::grammar<Iterator, storm::property::csl::AbstractCslFormula<double>*(), Skipper > { +struct CslGrammar : qi::grammar<Iterator, storm::property::csl::CslFilter<double>*(), Skipper > { CslGrammar() : CslGrammar::base_type(start) { //This block contains helper rules that may be used several times freeIdentifierName = qi::lexeme[qi::alpha >> *(qi::alnum | qi::char_('_'))]; @@ -81,16 +86,6 @@ struct CslGrammar : qi::grammar<Iterator, storm::property::csl::AbstractCslFormu ); steadyStateBoundOperator.name("state formula"); - //This block defines rules for parsing formulas with noBoundOperators - noBoundOperator = (probabilisticNoBoundOperator | steadyStateNoBoundOperator); - noBoundOperator.name("no bound operator"); - probabilisticNoBoundOperator = (qi::lit("P") >> qi::lit("=") >> qi::lit("?") >> qi::lit("[") >> pathFormula >> qi::lit("]"))[qi::_val = - phoenix::new_<storm::property::csl::ProbabilisticNoBoundOperator<double> >(qi::_1)]; - probabilisticNoBoundOperator.name("no bound operator"); - steadyStateNoBoundOperator = (qi::lit("S") >> qi::lit("=") >> qi::lit("?") >> qi::lit("[") >> stateFormula >> qi::lit("]"))[qi::_val = - phoenix::new_<storm::property::csl::SteadyStateNoBoundOperator<double> >(qi::_1)]; - steadyStateNoBoundOperator.name("no bound operator"); - //This block defines rules for parsing probabilistic path formulas pathFormula = (timeBoundedEventually | eventually | globally | next | timeBoundedUntil | until); pathFormula.name("path formula"); @@ -125,16 +120,61 @@ struct CslGrammar : qi::grammar<Iterator, storm::property::csl::AbstractCslFormu phoenix::new_<storm::property::csl::Until<double>>(phoenix::bind(&storm::property::csl::AbstractStateFormula<double>::clone, phoenix::bind(&std::shared_ptr<storm::property::csl::AbstractStateFormula<double>>::get, qi::_a)), qi::_2)]; until.name("path formula (for probabilistic operator)"); - formula = (noBoundOperator | stateFormula); + formula = (pathFormula | stateFormula); formula.name("CSL formula"); - start = (((formula) > (comment | qi::eps))[qi::_val = qi::_1] | - comment - ) > qi::eoi; - start.name("CSL formula"); + //This block defines rules for parsing formulas with noBoundOperators + noBoundOperator = (probabilisticNoBoundOperator | steadyStateNoBoundOperator); + noBoundOperator.name("no bound operator"); + probabilisticNoBoundOperator = + (qi::lit("P") >> qi::lit("min") >> qi::lit("=") >> qi::lit("?") >> qi::lit("[") >> pathFormula >> qi::lit("]"))[qi::_val = + phoenix::new_<storm::property::csl::CslFilter<double>>(qi::_1, true)]; + (qi::lit("P") >> qi::lit("max") >> qi::lit("=") >> qi::lit("?") >> qi::lit("[") >> pathFormula >> qi::lit("]"))[qi::_val = + phoenix::new_<storm::property::csl::CslFilter<double>>(qi::_1, false)]; + (qi::lit("P") >> qi::lit("=") >> qi::lit("?") >> qi::lit("[") >> pathFormula >> qi::lit("]"))[qi::_val = + phoenix::new_<storm::property::csl::CslFilter<double>>(qi::_1)]; + probabilisticNoBoundOperator.name("no bound operator"); + steadyStateNoBoundOperator = (qi::lit("S") >> qi::lit("=") >> qi::lit("?") >> qi::lit("[") >> stateFormula >> qi::lit("]"))[qi::_val = + phoenix::new_<storm::property::csl::CslFilter<double>>(qi::_1)]; + steadyStateNoBoundOperator.name("no bound operator"); + + minMaxAction = qi::lit("minmax") >> qi::lit(",") >> ( + qi::lit("min")[qi::_val = + phoenix::new_<storm::property::action::MinMaxAction<double>>(true)] | + qi::lit("min")[qi::_val = + phoenix::new_<storm::property::action::MinMaxAction<double>>(false)]); + minMaxAction.name("minmax action for the formula filter"); + + rangeAction = (qi::lit("range") >> qi::lit(",") >> qi::uint_ >> qi::lit(",") >> qi::uint_)[qi::_val = + phoenix::new_<storm::property::action::RangeAction<double>>(qi::_1, qi::_2)]; + rangeAction.name("range action for the formula filter"); + + abstractAction = (rangeAction | minMaxAction) >> (qi::eps | qi::lit(",")); + abstractAction.name("filter action"); + + filter = (qi::lit("filter") >> qi::lit("[") >> +abstractAction >> qi::lit("]") >> qi::lit("(") >> formula >> qi::lit(")"))[qi::_val = + phoenix::new_<storm::property::csl::CslFilter<double>>(qi::_2, qi::_1)] | + (formula)[qi::_val = + phoenix::new_<storm::property::csl::CslFilter<double>>(qi::_1)] | + (noBoundOperator)[qi::_val = + qi::_1]; + filter.name("PRCTL formula filter"); + + start = (((filter) > (comment | qi::eps))[qi::_val = qi::_1] | comment ) > qi::eoi; + start.name("CSL formula filter"); } - qi::rule<Iterator, storm::property::csl::AbstractCslFormula<double>*(), Skipper> start; + qi::rule<Iterator, storm::property::csl::CslFilter<double>*(), Skipper> start; + qi::rule<Iterator, storm::property::csl::CslFilter<double>*(), Skipper> filter; + + qi::rule<Iterator, storm::property::csl::CslFilter<double>*(), Skipper> noBoundOperator; + qi::rule<Iterator, storm::property::csl::CslFilter<double>*(), Skipper> probabilisticNoBoundOperator; + qi::rule<Iterator, storm::property::csl::CslFilter<double>*(), Skipper> steadyStateNoBoundOperator; + + qi::rule<Iterator, storm::property::action::AbstractAction<double>*(), Skipper> abstractAction; + qi::rule<Iterator, storm::property::action::RangeAction<double>*(), Skipper> rangeAction; + qi::rule<Iterator, storm::property::action::MinMaxAction<double>*(), Skipper> minMaxAction; + qi::rule<Iterator, storm::property::csl::AbstractCslFormula<double>*(), Skipper> formula; qi::rule<Iterator, storm::property::csl::AbstractCslFormula<double>*(), Skipper> comment; @@ -148,10 +188,6 @@ struct CslGrammar : qi::grammar<Iterator, storm::property::csl::AbstractCslFormu qi::rule<Iterator, storm::property::csl::ProbabilisticBoundOperator<double>*(), Skipper> probabilisticBoundOperator; qi::rule<Iterator, storm::property::csl::SteadyStateBoundOperator<double>*(), Skipper> steadyStateBoundOperator; - qi::rule<Iterator, storm::property::csl::AbstractNoBoundOperator<double>*(), Skipper> noBoundOperator; - qi::rule<Iterator, storm::property::csl::AbstractNoBoundOperator<double>*(), Skipper> probabilisticNoBoundOperator; - qi::rule<Iterator, storm::property::csl::AbstractNoBoundOperator<double>*(), Skipper> steadyStateNoBoundOperator; - qi::rule<Iterator, storm::property::csl::AbstractPathFormula<double>*(), Skipper> pathFormula; qi::rule<Iterator, storm::property::csl::TimeBoundedEventually<double>*(), Skipper> timeBoundedEventually; qi::rule<Iterator, storm::property::csl::Eventually<double>*(), Skipper> eventually; @@ -166,7 +202,7 @@ struct CslGrammar : qi::grammar<Iterator, storm::property::csl::AbstractCslFormu }; -storm::property::csl::AbstractCslFormula<double>* CslParser(std::string formulaString) { +storm::property::csl::CslFilter<double>* CslParser(std::string formulaString) { // Prepare iterators to input. BaseIteratorType stringIteratorBegin = formulaString.begin(); BaseIteratorType stringIteratorEnd = formulaString.end(); @@ -175,7 +211,7 @@ storm::property::csl::AbstractCslFormula<double>* CslParser(std::string formulaS // Prepare resulting intermediate representation of input. - storm::property::csl::AbstractCslFormula<double>* result_pointer = nullptr; + storm::property::csl::CslFilter<double>* result_pointer = nullptr; CslGrammar<PositionIteratorType, BOOST_TYPEOF(boost::spirit::ascii::space)> grammar; diff --git a/src/parser/CslParser.h b/src/parser/CslParser.h index 2ef4c64e3..179cde297 100644 --- a/src/parser/CslParser.h +++ b/src/parser/CslParser.h @@ -9,6 +9,7 @@ #define STORM_PARSER_CSLPARSER_H_ #include "src/formula/Csl.h" +#include "src/formula/Csl/CslFilter.h" #include <functional> namespace storm { @@ -23,7 +24,7 @@ namespace parser { * @param formulaString The string representation of the formula * @throw wrongFormatException If the input could not be parsed successfully */ -storm::property::csl::AbstractCslFormula<double>* CslParser(std::string formulaString); +storm::property::csl::CslFilter<double>* CslParser(std::string formulaString); /*! * Struct for the CSL grammar, that Boost::Spirit uses to parse the formulas. From 4bf029927957af3d487485b9e128ff2d0f2a16d4 Mon Sep 17 00:00:00 2001 From: masawei <manuel.sascha.weiand@rwth-aachen.de> Date: Sun, 18 May 2014 21:48:22 +0200 Subject: [PATCH 11/30] Changed the Prctl/Csl formula parsers to be static classes. - Also fixed up control flow and some tests for new interfaces. |-> It now compiles again. Next up: More functionallity in the filter. Former-commit-id: 21d43e75c471be3209d1c58f5ae6e8e054fa2cef --- src/formula/Csl/CslFilter.h | 2 +- src/formula/Prctl/PrctlFilter.h | 18 +- src/parser/CslParser.cpp | 4 +- src/parser/CslParser.h | 37 +++-- src/parser/PrctlFileParser.cpp | 10 +- src/parser/PrctlFileParser.h | 19 ++- src/parser/PrctlParser.cpp | 7 +- src/parser/PrctlParser.h | 58 +++---- src/storm.cpp | 18 +- .../GmmxxDtmcPrctlModelCheckerTest.cpp | 58 +++---- .../SparseMdpPrctlModelCheckerTest.cpp | 155 ++++++------------ test/functional/parser/CslParserTest.cpp | 129 +++++++++------ test/functional/parser/PrctlParserTest.cpp | 131 ++++++++------- .../GmmxxDtmcPrctModelCheckerTest.cpp | 39 ++--- .../SparseMdpPrctlModelCheckerTest.cpp | 103 +++++------- 15 files changed, 359 insertions(+), 429 deletions(-) diff --git a/src/formula/Csl/CslFilter.h b/src/formula/Csl/CslFilter.h index 1507d1c2b..dbbd22368 100644 --- a/src/formula/Csl/CslFilter.h +++ b/src/formula/Csl/CslFilter.h @@ -154,7 +154,7 @@ public: std::string desc = "Filter: "; desc += "\nActions:"; for(auto action : this->actions) { - desc += "\n\t" + action.toString(); + desc += "\n\t" + action->toString(); } desc += "\nFormula:\n\t" + child->toString(); return desc; diff --git a/src/formula/Prctl/PrctlFilter.h b/src/formula/Prctl/PrctlFilter.h index d5559246b..7302148a3 100644 --- a/src/formula/Prctl/PrctlFilter.h +++ b/src/formula/Prctl/PrctlFilter.h @@ -63,7 +63,7 @@ public: storm::storage::BitVector result; try { - result = evaluate(modelchecker, static_cast<AbstractStateFormula<T>*>(child)); + result = evaluate(modelchecker, dynamic_cast<AbstractStateFormula<T>*>(child)); } catch (std::exception& e) { std::cout << "Error during computation: " << e.what() << "Skipping property." << std::endl; LOG4CPLUS_ERROR(logger, "Error during computation: " << e.what() << "Skipping property."); @@ -80,7 +80,7 @@ public: // Return the results for all states labeled with "init". LOG4CPLUS_INFO(logger, "Result for initial states:"); std::cout << "Result for initial states:" << std::endl; - for (auto initialState : modelchecker.getModel().getInitialStates()) { + for (auto initialState : modelchecker.template getModel<storm::models::AbstractModel<T>>().getInitialStates()) { LOG4CPLUS_INFO(logger, "\t" << initialState << ": " << (result.get(initialState) ? "satisfied" : "not satisfied")); std::cout << "\t" << initialState << ": " << result.get(initialState) << std::endl; } @@ -95,7 +95,7 @@ public: std::vector<T> result; try { - result = evaluate(modelchecker, static_cast<AbstractPathFormula<T>*>(child)); + result = evaluate(modelchecker, dynamic_cast<AbstractPathFormula<T>*>(child)); } catch (std::exception& e) { std::cout << "Error during computation: " << e.what() << "Skipping property." << std::endl; LOG4CPLUS_ERROR(logger, "Error during computation: " << e.what() << "Skipping property."); @@ -112,7 +112,7 @@ public: // Return the results for all states labeled with "init". LOG4CPLUS_INFO(logger, "Result for initial states:"); std::cout << "Result for initial states:" << std::endl; - for (auto initialState : modelchecker.getModel().getInitialStates()) { + for (auto initialState : modelchecker.template getModel<storm::models::AbstractModel<T>>().getInitialStates()) { LOG4CPLUS_INFO(logger, "\t" << initialState << ": " << result[initialState]); std::cout << "\t" << initialState << ": " << result[initialState] << std::endl; } @@ -127,7 +127,7 @@ public: std::vector<T> result; try { - result = evaluate(modelchecker, static_cast<AbstractRewardPathFormula<T>*>(child)); + result = evaluate(modelchecker, dynamic_cast<AbstractRewardPathFormula<T>*>(child)); } catch (std::exception& e) { std::cout << "Error during computation: " << e.what() << "Skipping property." << std::endl; LOG4CPLUS_ERROR(logger, "Error during computation: " << e.what() << "Skipping property."); @@ -144,7 +144,7 @@ public: // Return the results for all states labeled with "init". LOG4CPLUS_INFO(logger, "Result for initial states:"); std::cout << "Result for initial states:" << std::endl; - for (auto initialState : modelchecker.getModel().getInitialStates()) { + for (auto initialState : modelchecker.template getModel<storm::models::AbstractModel<T>>().getInitialStates()) { LOG4CPLUS_INFO(logger, "\t" << initialState << ": " << result[initialState]); std::cout << "\t" << initialState << ": " << result[initialState] << std::endl; } @@ -208,7 +208,7 @@ private: if(this->getActionCount() != 0 && dynamic_cast<storm::property::action::MinMaxAction<T>*>(this->getAction(0)) != nullptr) { // If there is an action specifying that min/max probabilities should be computed, call the appropriate method of the model checker. - result = modelchecker.checkMinMaxOperator(formula, static_cast<storm::property::action::MinMaxAction<T>*>(this->getAction(0))->getMinimize()); + result = modelchecker.checkMinMaxOperator(*formula, static_cast<storm::property::action::MinMaxAction<T>*>(this->getAction(0))->getMinimize()); } else { result = formula->check(modelchecker); } @@ -227,7 +227,7 @@ private: if(this->getActionCount() != 0 && dynamic_cast<storm::property::action::MinMaxAction<T>*>(this->getAction(0)) != nullptr) { // If there is an action specifying that min/max probabilities should be computed, call the appropriate method of the model checker. - result = modelchecker.checkMinMaxOperator(formula, static_cast<storm::property::action::MinMaxAction<T>*>(this->getAction(0))->getMinimize()); + result = modelchecker.checkMinMaxOperator(*formula, dynamic_cast<storm::property::action::MinMaxAction<T>*>(this->getAction(0))->getMinimize()); } else { result = formula->check(modelchecker, false); } @@ -245,7 +245,7 @@ private: if(this->getActionCount() != 0 && dynamic_cast<storm::property::action::MinMaxAction<T>*>(this->getAction(0)) != nullptr) { // If there is an action specifying that min/max probabilities should be computed, call the appropriate method of the model checker. - result = modelchecker.checkMinMaxOperator(formula, static_cast<storm::property::action::MinMaxAction<T>*>(this->getAction(0))->getMinimize()); + result = modelchecker.checkMinMaxOperator(*formula, dynamic_cast<storm::property::action::MinMaxAction<T>*>(this->getAction(0))->getMinimize()); } else { result = formula->check(modelchecker, false); } diff --git a/src/parser/CslParser.cpp b/src/parser/CslParser.cpp index 52c4012aa..5ae34df1c 100644 --- a/src/parser/CslParser.cpp +++ b/src/parser/CslParser.cpp @@ -43,7 +43,7 @@ namespace storm { namespace parser { template<typename Iterator, typename Skipper> -struct CslGrammar : qi::grammar<Iterator, storm::property::csl::CslFilter<double>*(), Skipper > { +struct CslParser::CslGrammar : qi::grammar<Iterator, storm::property::csl::CslFilter<double>*(), Skipper > { CslGrammar() : CslGrammar::base_type(start) { //This block contains helper rules that may be used several times freeIdentifierName = qi::lexeme[qi::alpha >> *(qi::alnum | qi::char_('_'))]; @@ -202,7 +202,7 @@ struct CslGrammar : qi::grammar<Iterator, storm::property::csl::CslFilter<double }; -storm::property::csl::CslFilter<double>* CslParser(std::string formulaString) { +storm::property::csl::CslFilter<double>* CslParser::parseCslFormula(std::string formulaString) { // Prepare iterators to input. BaseIteratorType stringIteratorBegin = formulaString.begin(); BaseIteratorType stringIteratorEnd = formulaString.end(); diff --git a/src/parser/CslParser.h b/src/parser/CslParser.h index 179cde297..ddc767438 100644 --- a/src/parser/CslParser.h +++ b/src/parser/CslParser.h @@ -15,22 +15,29 @@ namespace storm { namespace parser { -/*! - * Reads a CSL formula from its string representation and parses it into a formula tree, consisting of - * classes in the namespace storm::property. - * - * If the string could not be parsed successfully, it will throw a wrongFormatException. - * - * @param formulaString The string representation of the formula - * @throw wrongFormatException If the input could not be parsed successfully - */ -storm::property::csl::CslFilter<double>* CslParser(std::string formulaString); +class CslParser { +public: -/*! - * Struct for the CSL grammar, that Boost::Spirit uses to parse the formulas. - */ -template<typename Iterator, typename Skipper> -struct CslGrammar; + /*! + * Reads a CSL formula from its string representation and parses it into a formula tree, consisting of + * classes in the namespace storm::property. + * + * If the string could not be parsed successfully, it will throw a wrongFormatException. + * + * @param formulaString The string representation of the formula + * @throw wrongFormatException If the input could not be parsed successfully + */ + static storm::property::csl::CslFilter<double>* parseCslFormula(std::string formulaString); + +private: + + /*! + * Struct for the CSL grammar, that Boost::Spirit uses to parse the formulas. + */ + template<typename Iterator, typename Skipper> + struct CslGrammar; + +}; } /* namespace parser */ } /* namespace storm */ diff --git a/src/parser/PrctlFileParser.cpp b/src/parser/PrctlFileParser.cpp index 9fadfbf2f..ca5905e4e 100644 --- a/src/parser/PrctlFileParser.cpp +++ b/src/parser/PrctlFileParser.cpp @@ -14,7 +14,7 @@ namespace storm { namespace parser { -std::list<storm::property::prctl::PrctlFilter<double>*> PrctlFileParser(std::string filename) { +std::list<storm::property::prctl::PrctlFilter<double>*> PrctlFileParser::parsePrctlFile(std::string filename) { // Open file std::ifstream inputFileStream; inputFileStream.open(filename, std::ios::in); @@ -29,11 +29,11 @@ std::list<storm::property::prctl::PrctlFilter<double>*> PrctlFileParser(std::str std::string line; //The while loop reads the input file line by line while (std::getline(inputFileStream, line)) { - PrctlParser parser(line); - if (!parser.parsedComment()) { + storm::property::prctl::PrctlFilter<double>* formula = PrctlParser::parsePrctlFormula(line); + if (formula != nullptr) { //lines containing comments will be skipped. - LOG4CPLUS_INFO(logger, "Parsed formula \"" + line + "\" into \"" + parser.getFormula()->toString() + "\""); - result.push_back(parser.getFormula()); + LOG4CPLUS_INFO(logger, "Parsed formula \"" + line + "\" into \"" + formula->toString() + "\""); + result.push_back(formula); } } diff --git a/src/parser/PrctlFileParser.h b/src/parser/PrctlFileParser.h index 15fc6b382..4d914d8cc 100644 --- a/src/parser/PrctlFileParser.h +++ b/src/parser/PrctlFileParser.h @@ -16,13 +16,18 @@ namespace storm { namespace parser { -/*! - * Parses each line of a given file as prctl formula and returns a list containing the results of the parsing. - * - * @param filename - * @return The list of parsed formulas - */ -std::list<storm::property::prctl::PrctlFilter<double>*> PrctlFileParser(std::string filename); +class PrctlFileParser { +public: + + /*! + * Parses each line of a given file as prctl formula and returns a list containing the results of the parsing. + * + * @param filename + * @return The list of parsed formulas + */ + static std::list<storm::property::prctl::PrctlFilter<double>*> parsePrctlFile(std::string filename); + +}; } /* namespace parser */ } /* namespace storm */ diff --git a/src/parser/PrctlParser.cpp b/src/parser/PrctlParser.cpp index 82d0a3550..d92cd6178 100644 --- a/src/parser/PrctlParser.cpp +++ b/src/parser/PrctlParser.cpp @@ -32,7 +32,6 @@ namespace qi = boost::spirit::qi; namespace phoenix = boost::phoenix; - namespace storm { namespace parser { @@ -165,7 +164,7 @@ struct PrctlParser::PrctlGrammar : qi::grammar<Iterator, storm::property::prctl: qi::_1]; filter.name("PRCTL formula filter"); - start = (((filter) > (comment | qi::eps))[qi::_val = qi::_1] | comment) > qi::eoi; + start = (((filter) > (comment | qi::eps))[qi::_val = qi::_1] | comment[qi::_val = nullptr]) > qi::eoi; start.name("PRCTL formula filter"); } @@ -216,7 +215,7 @@ struct PrctlParser::PrctlGrammar : qi::grammar<Iterator, storm::property::prctl: } //namespace storm } //namespace parser -storm::parser::PrctlParser::PrctlParser(std::string formulaString) { +storm::property::prctl::PrctlFilter<double>* storm::parser::PrctlParser::parsePrctlFormula(std::string formulaString) { // Prepare iterators to input. BaseIteratorType stringIteratorBegin = formulaString.begin(); BaseIteratorType stringIteratorEnd = formulaString.end(); @@ -259,5 +258,5 @@ storm::parser::PrctlParser::PrctlParser(std::string formulaString) { throw storm::exceptions::WrongFormatException() << msg.str(); } - formula = result_pointer; + return result_pointer; } diff --git a/src/parser/PrctlParser.h b/src/parser/PrctlParser.h index 52a403afd..6e1a55c34 100644 --- a/src/parser/PrctlParser.h +++ b/src/parser/PrctlParser.h @@ -17,43 +17,27 @@ namespace parser { * class PrctlParser). However, it will not delete this object. */ class PrctlParser { - public: - /*! - * Reads a PRCTL formula from its string representation and parses it into a formula tree, consisting of - * classes in the namespace storm::property. - * - * If the string could not be parsed successfully, it will throw a wrongFormatException. - * - * @param formulaString The string representation of the formula - * @throw wrongFormatException If the input could not be parsed successfully - */ - PrctlParser(std::string formulaString); - - /*! - * @return a pointer to the parsed formula object - */ - storm::property::prctl::PrctlFilter<double>* getFormula() { - return this->formula; - } - - /*! - * Checks whether the line which was parsed was a comment line; also returns true if the line was empty (as the semantics are - * the same) - * - * @return True if the parsed line consisted completely of a (valid) comment, false otherwise. - */ - bool parsedComment() { - return (formula == nullptr); - } - - private: - storm::property::prctl::PrctlFilter<double>* formula; - - /*! - * Struct for the Prctl grammar, that Boost::Spirit uses to parse the formulas. - */ - template<typename Iterator, typename Skipper> - struct PrctlGrammar; +public: + + /*! + * Reads a PRCTL formula from its string representation and parses it into a formula tree, consisting of + * classes in the namespace storm::property. + * + * If the string could not be parsed successfully, it will throw a wrongFormatException. + * + * @param formulaString The string representation of the formula + * @throw wrongFormatException If the input could not be parsed successfully + * @return A pointer to the parsed Prctl formula. If the line just contained a comment a nullptr will be returned instead. + */ + static storm::property::prctl::PrctlFilter<double>* parsePrctlFormula(std::string formulaString); + +private: + + /*! + * Struct for the Prctl grammar, that Boost::Spirit uses to parse the formulas. + */ + template<typename Iterator, typename Skipper> + struct PrctlGrammar; }; diff --git a/src/storm.cpp b/src/storm.cpp index a13bf8e23..5b4e06309 100644 --- a/src/storm.cpp +++ b/src/storm.cpp @@ -285,10 +285,10 @@ void checkPrctlFormulae(storm::modelchecker::prctl::AbstractModelChecker<double> if (s->isSet("prctl")) { std::string const chosenPrctlFile = s->getOptionByLongName("prctl").getArgument(0).getValueAsString(); LOG4CPLUS_INFO(logger, "Parsing prctl file: " << chosenPrctlFile << "."); - std::list<storm::property::prctl::AbstractPrctlFormula<double>*> formulaList = storm::parser::PrctlFileParser(chosenPrctlFile); + std::list<storm::property::prctl::PrctlFilter<double>*> formulaList = storm::parser::PrctlFileParser::parsePrctlFile(chosenPrctlFile); for (auto formula : formulaList) { - modelchecker.check(*formula); + formula->check(modelchecker); delete formula; } } @@ -339,7 +339,7 @@ void checkPrctlFormulae(storm::modelchecker::prctl::AbstractModelChecker<double> std::string const chosenPrctlFile = s->getOptionByLongName("prctl").getArgument(0).getValueAsString(); LOG4CPLUS_INFO(logger, "Parsing prctl file: " << chosenPrctlFile << "."); - std::list<storm::property::prctl::AbstractPrctlFormula<double>*> formulaList = storm::parser::PrctlFileParser(chosenPrctlFile); + std::list<storm::property::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) { @@ -369,13 +369,13 @@ void checkPrctlFormulae(storm::modelchecker::prctl::AbstractModelChecker<double> for (auto formula : formulaList) { // First check if it is a formula type for which a counterexample can be generated. - if (dynamic_cast<storm::property::prctl::AbstractStateFormula<double> const*>(formula) == nullptr) { + if (dynamic_cast<storm::property::prctl::AbstractStateFormula<double> const*>(formula->getChild()) == nullptr) { LOG4CPLUS_ERROR(logger, "Unexpected kind of formula. Expected a state formula."); delete formula; continue; } - storm::property::prctl::AbstractStateFormula<double> const& stateForm = static_cast<storm::property::prctl::AbstractStateFormula<double> const&>(*formula); + storm::property::prctl::AbstractStateFormula<double> const& stateForm = static_cast<storm::property::prctl::AbstractStateFormula<double> const&>(*(formula->getChild())); // Do some output std::cout << "Generating counterexample for formula " << fIndex << ":" << std::endl; @@ -552,14 +552,14 @@ int main(const int argc, const char* argv[]) { // Now parse the property file and receive the list of parsed formulas. std::string const& propertyFile = s->getOptionByLongName("mincmd").getArgumentByName("propertyFile").getValueAsString(); - std::list<storm::property::prctl::AbstractPrctlFormula<double>*> formulaList = storm::parser::PrctlFileParser(propertyFile); + std::list<storm::property::prctl::PrctlFilter<double>*> formulaList = storm::parser::PrctlFileParser::parsePrctlFile(propertyFile); // Now generate the counterexamples for each formula. - for (storm::property::prctl::AbstractPrctlFormula<double>* formulaPtr : formulaList) { + for (storm::property::prctl::PrctlFilter<double>* formulaPtr : formulaList) { if (useMILP) { - storm::counterexamples::MILPMinimalLabelSetGenerator<double>::computeCounterexample(program, *mdp, formulaPtr); + storm::counterexamples::MILPMinimalLabelSetGenerator<double>::computeCounterexample(program, *mdp, formulaPtr->getChild()); } else { - storm::counterexamples::SMTMinimalCommandSetGenerator<double>::computeCounterexample(program, constants, *mdp, formulaPtr); + storm::counterexamples::SMTMinimalCommandSetGenerator<double>::computeCounterexample(program, constants, *mdp, formulaPtr->getChild()); } // Once we are done with the formula, delete it. diff --git a/test/functional/modelchecker/GmmxxDtmcPrctlModelCheckerTest.cpp b/test/functional/modelchecker/GmmxxDtmcPrctlModelCheckerTest.cpp index fdff14a66..ac90211b5 100644 --- a/test/functional/modelchecker/GmmxxDtmcPrctlModelCheckerTest.cpp +++ b/test/functional/modelchecker/GmmxxDtmcPrctlModelCheckerTest.cpp @@ -24,43 +24,39 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, Die) { storm::property::prctl::Ap<double>* apFormula = new storm::property::prctl::Ap<double>("one"); storm::property::prctl::Eventually<double>* eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); - storm::property::prctl::ProbabilisticNoBoundOperator<double>* probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula); - std::vector<double> result = probFormula->check(mc); + std::vector<double> result = eventuallyFormula->check(mc, false); ASSERT_LT(std::abs(result[0] - ((double)1.0/6.0)), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; + delete eventuallyFormula; apFormula = new storm::property::prctl::Ap<double>("two"); eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); - probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula); - result = probFormula->check(mc); + result = eventuallyFormula->check(mc, false); ASSERT_LT(std::abs(result[0] - ((double)1.0/6.0)), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; + delete eventuallyFormula; apFormula = new storm::property::prctl::Ap<double>("three"); eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); - probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula); - result = probFormula->check(mc); + result = eventuallyFormula->check(mc, false); ASSERT_LT(std::abs(result[0] - ((double)1.0/6.0)), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; + delete eventuallyFormula; storm::property::prctl::Ap<double>* done = new storm::property::prctl::Ap<double>("done"); storm::property::prctl::ReachabilityReward<double>* reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward<double>(done); - storm::property::prctl::RewardNoBoundOperator<double>* rewardFormula = new storm::property::prctl::RewardNoBoundOperator<double>(reachabilityRewardFormula); - result = rewardFormula->check(mc); + result = reachabilityRewardFormula->check(mc, false); ASSERT_LT(std::abs(result[0] - ((double)11/3)), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete rewardFormula; + delete reachabilityRewardFormula; } TEST(GmmxxDtmcPrctlModelCheckerTest, Crowds) { @@ -73,40 +69,37 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, Crowds) { std::shared_ptr<storm::models::Dtmc<double>> dtmc = abstractModel->as<storm::models::Dtmc<double>>(); - ASSERT_EQ(dtmc->getNumberOfStates(), 8607ull); - ASSERT_EQ(dtmc->getNumberOfTransitions(), 22460ull); + ASSERT_EQ(8607ull, dtmc->getNumberOfStates()); + ASSERT_EQ(22460ull, dtmc->getNumberOfTransitions()); storm::modelchecker::prctl::SparseDtmcPrctlModelChecker<double> mc(*dtmc, new storm::solver::GmmxxLinearEquationSolver<double>()); storm::property::prctl::Ap<double>* apFormula = new storm::property::prctl::Ap<double>("observe0Greater1"); storm::property::prctl::Eventually<double>* eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); - storm::property::prctl::ProbabilisticNoBoundOperator<double>* probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula); - std::vector<double> result = probFormula->check(mc); + std::vector<double> result = eventuallyFormula->check(mc, false); ASSERT_LT(std::abs(result[0] - 0.3328800375801578281), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; + delete eventuallyFormula; apFormula = new storm::property::prctl::Ap<double>("observeIGreater1"); eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); - probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula); - result = probFormula->check(mc); + result = eventuallyFormula->check(mc, false); ASSERT_LT(std::abs(result[0] - 0.1522194965), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; + delete eventuallyFormula; apFormula = new storm::property::prctl::Ap<double>("observeOnlyTrueSender"); eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); - probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula); - result = probFormula->check(mc); + result = eventuallyFormula->check(mc, false); ASSERT_LT(std::abs(result[0] - 0.32153724292835045), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; + delete eventuallyFormula; } TEST(GmmxxDtmcPrctlModelCheckerTest, SynchronousLeader) { @@ -118,38 +111,35 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, SynchronousLeader) { ASSERT_EQ(abstractModel->getType(), storm::models::DTMC); std::shared_ptr<storm::models::Dtmc<double>> dtmc = abstractModel->as<storm::models::Dtmc<double>>(); - ASSERT_EQ(dtmc->getNumberOfStates(), 12400ull); - ASSERT_EQ(dtmc->getNumberOfTransitions(), 28894ull); + ASSERT_EQ(12400ull, dtmc->getNumberOfStates()); + ASSERT_EQ(28894ull, dtmc->getNumberOfTransitions()); storm::modelchecker::prctl::SparseDtmcPrctlModelChecker<double> mc(*dtmc, new storm::solver::GmmxxLinearEquationSolver<double>()); storm::property::prctl::Ap<double>* apFormula = new storm::property::prctl::Ap<double>("elected"); storm::property::prctl::Eventually<double>* eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); - storm::property::prctl::ProbabilisticNoBoundOperator<double>* probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula); - std::vector<double> result = probFormula->check(mc); + std::vector<double> result = eventuallyFormula->check(mc, false); ASSERT_LT(std::abs(result[0] - 1.0), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; + delete eventuallyFormula; apFormula = new storm::property::prctl::Ap<double>("elected"); storm::property::prctl::BoundedUntil<double>* boundedUntilFormula = new storm::property::prctl::BoundedUntil<double>(new storm::property::prctl::Ap<double>("true"), apFormula, 20); - probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(boundedUntilFormula); - result = probFormula->check(mc); + result = boundedUntilFormula->check(mc, false); ASSERT_LT(std::abs(result[0] - 0.9999965911265462636), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; + delete boundedUntilFormula; apFormula = new storm::property::prctl::Ap<double>("elected"); storm::property::prctl::ReachabilityReward<double>* reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward<double>(apFormula); - storm::property::prctl::RewardNoBoundOperator<double>* rewardFormula = new storm::property::prctl::RewardNoBoundOperator<double>(reachabilityRewardFormula); - result = rewardFormula->check(mc); + result = reachabilityRewardFormula->check(mc, false); ASSERT_LT(std::abs(result[0] - 1.044879046), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete rewardFormula; + delete reachabilityRewardFormula; } diff --git a/test/functional/modelchecker/SparseMdpPrctlModelCheckerTest.cpp b/test/functional/modelchecker/SparseMdpPrctlModelCheckerTest.cpp index 67fe2d63a..2fd8e148e 100644 --- a/test/functional/modelchecker/SparseMdpPrctlModelCheckerTest.cpp +++ b/test/functional/modelchecker/SparseMdpPrctlModelCheckerTest.cpp @@ -21,81 +21,55 @@ TEST(SparseMdpPrctlModelCheckerTest, Dice) { storm::property::prctl::Ap<double>* apFormula = new storm::property::prctl::Ap<double>("two"); storm::property::prctl::Eventually<double>* eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); - storm::property::prctl::ProbabilisticNoBoundOperator<double>* probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula, true); - std::vector<double> result = mc.checkNoBoundOperator(*probFormula); + std::vector<double> result = mc.checkMinMaxOperator(*eventuallyFormula, true); ASSERT_LT(std::abs(result[0] - 0.0277777612209320068), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; - - apFormula = new storm::property::prctl::Ap<double>("two"); - eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); - probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula, false); - - result = mc.checkNoBoundOperator(*probFormula); - + result = mc.checkMinMaxOperator(*eventuallyFormula, false); + ASSERT_LT(std::abs(result[0] - 0.0277777612209320068), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - - delete probFormula; + + delete eventuallyFormula; apFormula = new storm::property::prctl::Ap<double>("three"); eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); - probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula, true); - result = mc.checkNoBoundOperator(*probFormula); + result = mc.checkMinMaxOperator(*eventuallyFormula, true); ASSERT_LT(std::abs(result[0] - 0.0555555224418640136), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; - - apFormula = new storm::property::prctl::Ap<double>("three"); - eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); - probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula, false); - - result = mc.checkNoBoundOperator(*probFormula); - + result = mc.checkMinMaxOperator(*eventuallyFormula, false); + ASSERT_LT(std::abs(result[0] - 0.0555555224418640136), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - - delete probFormula; + + delete eventuallyFormula; apFormula = new storm::property::prctl::Ap<double>("four"); eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); - probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula, true); - result = mc.checkNoBoundOperator(*probFormula); + result = mc.checkMinMaxOperator(*eventuallyFormula, true); ASSERT_LT(std::abs(result[0] - 0.083333283662796020508), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - - delete probFormula; - - apFormula = new storm::property::prctl::Ap<double>("four"); - eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); - probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula, false); - - result = mc.checkNoBoundOperator(*probFormula); + + result = mc.checkMinMaxOperator(*eventuallyFormula, false); ASSERT_LT(std::abs(result[0] - 0.083333283662796020508), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - - delete probFormula; - + + delete eventuallyFormula; + apFormula = new storm::property::prctl::Ap<double>("done"); storm::property::prctl::ReachabilityReward<double>* reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward<double>(apFormula); - storm::property::prctl::RewardNoBoundOperator<double>* rewardFormula = new storm::property::prctl::RewardNoBoundOperator<double>(reachabilityRewardFormula, true); - - result = mc.checkNoBoundOperator(*rewardFormula); - + + result = mc.checkMinMaxOperator(*reachabilityRewardFormula, true); + ASSERT_LT(std::abs(result[0] - 7.333329499), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete rewardFormula; - - apFormula = new storm::property::prctl::Ap<double>("done"); - reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward<double>(apFormula); - rewardFormula = new storm::property::prctl::RewardNoBoundOperator<double>(reachabilityRewardFormula, false); - - result = mc.checkNoBoundOperator(*rewardFormula);; - + + result = mc.checkMinMaxOperator(*reachabilityRewardFormula, false); + ASSERT_LT(std::abs(result[0] - 7.333329499), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete rewardFormula; + + delete reachabilityRewardFormula; abstractModel = storm::parser::AutoParser::parseModel(STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.tra", STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.lab", STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.flip.state.rew", ""); @@ -107,21 +81,16 @@ TEST(SparseMdpPrctlModelCheckerTest, Dice) { apFormula = new storm::property::prctl::Ap<double>("done"); reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward<double>(apFormula); - rewardFormula = new storm::property::prctl::RewardNoBoundOperator<double>(reachabilityRewardFormula, true); - - result = stateRewardModelChecker.checkNoBoundOperator(*rewardFormula); + + result = mc.checkMinMaxOperator(*reachabilityRewardFormula, true); ASSERT_LT(std::abs(result[0] - 7.333329499), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete rewardFormula; - - apFormula = new storm::property::prctl::Ap<double>("done"); - reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward<double>(apFormula); - rewardFormula = new storm::property::prctl::RewardNoBoundOperator<double>(reachabilityRewardFormula, false); - - result = stateRewardModelChecker.checkNoBoundOperator(*rewardFormula); - + + result = mc.checkMinMaxOperator(*reachabilityRewardFormula, false); + ASSERT_LT(std::abs(result[0] - 7.333329499), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete rewardFormula; + + delete reachabilityRewardFormula; abstractModel = storm::parser::AutoParser::parseModel(STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.tra", STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.lab", STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.flip.state.rew", STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.flip.trans.rew"); @@ -133,91 +102,67 @@ TEST(SparseMdpPrctlModelCheckerTest, Dice) { apFormula = new storm::property::prctl::Ap<double>("done"); reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward<double>(apFormula); - rewardFormula = new storm::property::prctl::RewardNoBoundOperator<double>(reachabilityRewardFormula, true); - result = stateAndTransitionRewardModelChecker.checkNoBoundOperator(*rewardFormula); + result = mc.checkMinMaxOperator(*reachabilityRewardFormula, true); ASSERT_LT(std::abs(result[0] - 14.666658998), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete rewardFormula; - - apFormula = new storm::property::prctl::Ap<double>("done"); - reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward<double>(apFormula); - rewardFormula = new storm::property::prctl::RewardNoBoundOperator<double>(reachabilityRewardFormula, false); - - result = stateAndTransitionRewardModelChecker.checkNoBoundOperator(*rewardFormula); - + + result = mc.checkMinMaxOperator(*reachabilityRewardFormula, false); + ASSERT_LT(std::abs(result[0] - 14.666658998), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete rewardFormula; + + delete reachabilityRewardFormula; } TEST(SparseMdpPrctlModelCheckerTest, AsynchronousLeader) { storm::settings::Settings* s = storm::settings::Settings::getInstance(); std::shared_ptr<storm::models::AbstractModel<double>> abstractModel = storm::parser::AutoParser::parseModel(STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader4.tra", STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader4.lab", "", STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader4.trans.rew"); - ASSERT_EQ(abstractModel->getType(), storm::models::MDP); + ASSERT_EQ(storm::models::MDP, abstractModel->getType()); std::shared_ptr<storm::models::Mdp<double>> mdp = abstractModel->as<storm::models::Mdp<double>>(); - ASSERT_EQ(mdp->getNumberOfStates(), 3172ull); - ASSERT_EQ(mdp->getNumberOfTransitions(), 7144ull); + ASSERT_EQ(3172ull, mdp->getNumberOfStates()); + ASSERT_EQ(7144ull, mdp->getNumberOfTransitions()); storm::modelchecker::prctl::SparseMdpPrctlModelChecker<double> mc(*mdp, std::shared_ptr<storm::solver::NativeNondeterministicLinearEquationSolver<double>>(new storm::solver::NativeNondeterministicLinearEquationSolver<double>())); storm::property::prctl::Ap<double>* apFormula = new storm::property::prctl::Ap<double>("elected"); storm::property::prctl::Eventually<double>* eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); - storm::property::prctl::ProbabilisticNoBoundOperator<double>* probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula, true); - std::vector<double> result = mc.checkNoBoundOperator(*probFormula); + std::vector<double> result = mc.checkMinMaxOperator(*eventuallyFormula, true); ASSERT_LT(std::abs(result[0] - 1), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; - - apFormula = new storm::property::prctl::Ap<double>("elected"); - eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); - probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula, false); - - result = mc.checkNoBoundOperator(*probFormula); + result = mc.checkMinMaxOperator(*eventuallyFormula, false); ASSERT_LT(std::abs(result[0] - 1), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; + delete eventuallyFormula; apFormula = new storm::property::prctl::Ap<double>("elected"); storm::property::prctl::BoundedEventually<double>* boundedEventuallyFormula = new storm::property::prctl::BoundedEventually<double>(apFormula, 25); - probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(boundedEventuallyFormula, false); - result = mc.checkNoBoundOperator(*probFormula); + result = mc.checkMinMaxOperator(*boundedEventuallyFormula, true); ASSERT_LT(std::abs(result[0] - 0.0625), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; - - apFormula = new storm::property::prctl::Ap<double>("elected"); - boundedEventuallyFormula = new storm::property::prctl::BoundedEventually<double>(apFormula, 25); - probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(boundedEventuallyFormula, true); - - result = mc.checkNoBoundOperator(*probFormula); + result = mc.checkMinMaxOperator(*boundedEventuallyFormula, false); ASSERT_LT(std::abs(result[0] - 0.0625), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; + delete boundedEventuallyFormula; apFormula = new storm::property::prctl::Ap<double>("elected"); storm::property::prctl::ReachabilityReward<double>* reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward<double>(apFormula); - storm::property::prctl::RewardNoBoundOperator<double>* rewardFormula = new storm::property::prctl::RewardNoBoundOperator<double>(reachabilityRewardFormula, true); - result = mc.checkNoBoundOperator(*rewardFormula);; + result = mc.checkMinMaxOperator(*reachabilityRewardFormula, true); ASSERT_LT(std::abs(result[0] - 4.285689611), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete rewardFormula; - apFormula = new storm::property::prctl::Ap<double>("elected"); - reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward<double>(apFormula); - rewardFormula = new storm::property::prctl::RewardNoBoundOperator<double>(reachabilityRewardFormula, false); - - result = mc.checkNoBoundOperator(*rewardFormula);; + result = mc.checkMinMaxOperator(*reachabilityRewardFormula, false); ASSERT_LT(std::abs(result[0] - 4.285689611), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete rewardFormula; + + delete reachabilityRewardFormula; } diff --git a/test/functional/parser/CslParserTest.cpp b/test/functional/parser/CslParserTest.cpp index 4e4a67af9..9b8ad7ea9 100644 --- a/test/functional/parser/CslParserTest.cpp +++ b/test/functional/parser/CslParserTest.cpp @@ -11,130 +11,153 @@ #include "src/exceptions/WrongFormatException.h" TEST(CslParserTest, parseApOnlyTest) { - std::string formula = "ap"; - storm::property::csl::AbstractCslFormula<double>* cslFormula = nullptr; + std::string input = "ap"; + storm::property::csl::CslFilter<double>* formula = nullptr; ASSERT_NO_THROW( - cslFormula = storm::parser::CslParser(formula); + formula = storm::parser::CslParser::parseCslFormula(input); ); - ASSERT_NE(cslFormula, nullptr); - ASSERT_EQ(cslFormula->toString(), formula); + // The parser did not falsely recognize the input as a comment. + ASSERT_NE(formula, nullptr); - delete cslFormula; + // The input was parsed correctly. + ASSERT_EQ(input, formula->toString()); + + delete formula; } TEST(CslParserTest, parsePropositionalFormulaTest) { - std::string formula = "!(a & b) | a & ! c"; - storm::property::csl::AbstractCslFormula<double>* cslFormula = nullptr; + std::string input = "!(a & b) | a & ! c"; + storm::property::csl::CslFilter<double>* formula = nullptr; ASSERT_NO_THROW( - cslFormula = storm::parser::CslParser(formula); + formula = storm::parser::CslParser::parseCslFormula(input); ); - ASSERT_NE(cslFormula, nullptr); - ASSERT_EQ(cslFormula->toString(), "(!(a & b) | (a & !c))"); + // The parser did not falsely recognize the input as a comment. + ASSERT_NE(formula, nullptr); + + // The input was parsed correctly. + ASSERT_EQ("(!(a & b) | (a & !c))", formula->toString()); - delete cslFormula; + delete formula; } TEST(CslParserTest, parseProbabilisticFormulaTest) { - std::string formula = "P > 0.5 [ F a ]"; - storm::property::csl::AbstractCslFormula<double>* cslFormula = nullptr; + std::string input = "P > 0.5 [ F a ]"; + storm::property::csl::CslFilter<double>* formula = nullptr; ASSERT_NO_THROW( - cslFormula = storm::parser::CslParser(formula); + formula = storm::parser::CslParser::parseCslFormula(input); ); - ASSERT_NE(cslFormula, nullptr); + // The parser did not falsely recognize the input as a comment. + ASSERT_NE(formula, nullptr); - storm::property::csl::ProbabilisticBoundOperator<double>* op = static_cast<storm::property::csl::ProbabilisticBoundOperator<double>*>(cslFormula); + ASSERT_NE(dynamic_cast<storm::property::csl::ProbabilisticBoundOperator<double>*>(formula->getChild()), nullptr); + storm::property::csl::ProbabilisticBoundOperator<double>* op = static_cast<storm::property::csl::ProbabilisticBoundOperator<double>*>(formula->getChild()); ASSERT_EQ(storm::property::GREATER, op->getComparisonOperator()); ASSERT_EQ(0.5, op->getBound()); - ASSERT_EQ(cslFormula->toString(), "P > 0.500000 [F a]"); + // Test the string representation for the parsed formula. + ASSERT_EQ("P > 0.500000 [F a]", formula->toString()); - delete cslFormula; + delete formula; } TEST(CslParserTest, parseSteadyStateBoundFormulaTest) { - std::string formula = "S >= 15 [ P < 0.2 [ a U<=3 b ] ]"; - storm::property::csl::AbstractCslFormula<double>* cslFormula = nullptr; + std::string input = "S >= 15 [ P < 0.2 [ a U<=3 b ] ]"; + storm::property::csl::CslFilter<double>* formula = nullptr; ASSERT_NO_THROW( - cslFormula = storm::parser::CslParser(formula); + formula = storm::parser::CslParser::parseCslFormula(input); ); - ASSERT_NE(cslFormula, nullptr); + // The parser did not falsely recognize the input as a comment. + ASSERT_NE(formula, nullptr); - storm::property::csl::SteadyStateBoundOperator<double>* op = static_cast<storm::property::csl::SteadyStateBoundOperator<double>*>(cslFormula); + storm::property::csl::SteadyStateBoundOperator<double>* op = static_cast<storm::property::csl::SteadyStateBoundOperator<double>*>(formula->getChild()); ASSERT_EQ(storm::property::GREATER_EQUAL, op->getComparisonOperator()); ASSERT_EQ(15.0, op->getBound()); - ASSERT_EQ(cslFormula->toString(), "S >= 15.000000 [P < 0.200000 [a U[0.000000,3.000000] b]]"); + // Test the string representation for the parsed formula. + ASSERT_EQ("S >= 15.000000 [P < 0.200000 [a U[0.000000,3.000000] b]]", formula->toString()); - delete cslFormula; + delete formula; } TEST(CslParserTest, parseSteadyStateNoBoundFormulaTest) { - std::string formula = "S = ? [ P <= 0.5 [ F<=3 a ] ]"; - storm::property::csl::AbstractCslFormula<double>* cslFormula = nullptr; + std::string input = "S = ? [ P <= 0.5 [ F<=3 a ] ]"; + storm::property::csl::CslFilter<double>* formula = nullptr; ASSERT_NO_THROW( - cslFormula = storm::parser::CslParser(formula); + formula = storm::parser::CslParser::parseCslFormula(input); ); - ASSERT_NE(cslFormula, nullptr); - ASSERT_EQ(cslFormula->toString(), "S = ? [P <= 0.500000 [F[0.000000,3.000000] a]]"); + // The parser did not falsely recognize the input as a comment. + ASSERT_NE(formula, nullptr); + + // The input was parsed correctly. + ASSERT_EQ("S = ? [P <= 0.500000 [F[0.000000,3.000000] a]]", formula->toString()); - delete cslFormula; + delete formula; } TEST(CslParserTest, parseProbabilisticNoBoundFormulaTest) { - std::string formula = "P = ? [ a U [3,4] b & (!c) ]"; - storm::property::csl::AbstractCslFormula<double>* cslFormula = nullptr; + std::string input = "P = ? [ a U [3,4] b & (!c) ]"; + storm::property::csl::CslFilter<double>* formula = nullptr; ASSERT_NO_THROW( - cslFormula = storm::parser::CslParser(formula); + formula = storm::parser::CslParser::parseCslFormula(input); ); - ASSERT_NE(cslFormula, nullptr); - ASSERT_EQ(cslFormula->toString(), "P = ? [a U[3.000000,4.000000] (b & !c)]"); + // The parser did not falsely recognize the input as a comment. + ASSERT_NE(formula, nullptr); - delete cslFormula; + // The input was parsed correctly. + ASSERT_EQ("P = ? [a U[3.000000,4.000000] (b & !c)]", formula->toString()); + + delete formula; } TEST(CslParserTest, parseComplexFormulaTest) { - std::string formula = "S<=0.5 [ P <= 0.5 [ a U c ] ] & (P > 0.5 [ G b] | !P < 0.4 [ G P>0.9 [F >=7 a & b] ]) //and a comment"; - storm::property::csl::AbstractCslFormula<double>* cslFormula = nullptr; + std::string input = "S<=0.5 [ P <= 0.5 [ a U c ] ] & (P > 0.5 [ G b] | !P < 0.4 [ G P>0.9 [F >=7 a & b] ]) //and a comment"; + storm::property::csl::CslFilter<double>* formula = nullptr; ASSERT_NO_THROW( - cslFormula = storm::parser::CslParser(formula); + formula = storm::parser::CslParser::parseCslFormula(input); ); - ASSERT_NE(cslFormula, nullptr); - ASSERT_EQ(cslFormula->toString(), "(S <= 0.500000 [P <= 0.500000 [a U c]] & (P > 0.500000 [G b] | !P < 0.400000 [G P > 0.900000 [F>=7.000000 (a & b)]]))"); + // The parser did not falsely recognize the input as a comment. + ASSERT_NE(formula, nullptr); + + // The input was parsed correctly. + ASSERT_EQ("(S <= 0.500000 [P <= 0.500000 [a U c]] & (P > 0.500000 [G b] | !P < 0.400000 [G P > 0.900000 [F>=7.000000 (a & b)]]))", formula->toString()); - delete cslFormula; + delete formula; } TEST(CslParserTest, wrongProbabilisticFormulaTest) { - std::string formula = "P > 0.5 [ a ]"; - storm::property::csl::AbstractCslFormula<double>* cslFormula = nullptr; + std::string input = "P > 0.5 [ a ]"; + storm::property::csl::CslFilter<double>* formula = nullptr; ASSERT_THROW( - cslFormula = storm::parser::CslParser(formula), + formula = storm::parser::CslParser::parseCslFormula(input), storm::exceptions::WrongFormatException ); + delete formula; } TEST(CslParserTest, wrongFormulaTest) { - std::string formula = "(a | b) & +"; - storm::property::csl::AbstractCslFormula<double>* cslFormula = nullptr; + std::string input = "(a | b) & +"; + storm::property::csl::CslFilter<double>* formula = nullptr; ASSERT_THROW( - cslFormula = storm::parser::CslParser(formula), + formula = storm::parser::CslParser::parseCslFormula(input), storm::exceptions::WrongFormatException ); + delete formula; } TEST(CslParserTest, wrongFormulaTest2) { - std::string formula = "P>0 [ F & a ]"; - storm::property::csl::AbstractCslFormula<double>* cslFormula = nullptr; + std::string input = "P>0 [ F & a ]"; + storm::property::csl::CslFilter<double>* formula = nullptr; ASSERT_THROW( - cslFormula = storm::parser::CslParser(formula), + formula = storm::parser::CslParser::parseCslFormula(input), storm::exceptions::WrongFormatException ); + delete formula; } diff --git a/test/functional/parser/PrctlParserTest.cpp b/test/functional/parser/PrctlParserTest.cpp index c51cf3164..5db06c465 100644 --- a/test/functional/parser/PrctlParserTest.cpp +++ b/test/functional/parser/PrctlParserTest.cpp @@ -12,149 +12,158 @@ #include "src/exceptions/WrongFormatException.h" TEST(PrctlParserTest, parseApOnlyTest) { - std::string ap = "ap"; - storm::parser::PrctlParser* prctlParser = nullptr; + std::string input = "ap"; + storm::property::prctl::PrctlFilter<double>* formula = nullptr; ASSERT_NO_THROW( - prctlParser = new storm::parser::PrctlParser(ap); + formula = storm::parser::PrctlParser::parsePrctlFormula(input) ); - ASSERT_NE(prctlParser->getFormula(), nullptr); + // The parser did not falsely recognize the input as a comment. + ASSERT_NE(formula, nullptr); + // The input was parsed correctly. + ASSERT_EQ(input, formula->toString()); - ASSERT_EQ(ap, prctlParser->getFormula()->toString()); - - delete prctlParser->getFormula(); - delete prctlParser; + delete formula; } TEST(PrctlParserTest, parsePropositionalFormulaTest) { - storm::parser::PrctlParser* prctlParser = nullptr; + std::string input = "!(a & b) | a & ! c"; + storm::property::prctl::PrctlFilter<double>* formula = nullptr; ASSERT_NO_THROW( - prctlParser = new storm::parser::PrctlParser("!(a & b) | a & ! c") + formula = storm::parser::PrctlParser::parsePrctlFormula(input) ); - ASSERT_NE(prctlParser->getFormula(), nullptr); - + // The parser did not falsely recognize the input as a comment. + ASSERT_NE(formula, nullptr); - ASSERT_EQ(prctlParser->getFormula()->toString(), "(!(a & b) | (a & !c))"); + // The input was parsed correctly. + ASSERT_EQ("(!(a & b) | (a & !c))", formula->toString()); - delete prctlParser->getFormula(); - delete prctlParser; + delete formula; } TEST(PrctlParserTest, parseProbabilisticFormulaTest) { - storm::parser::PrctlParser* prctlParser = nullptr; + std::string input = "P > 0.5 [ F a ]"; + storm::property::prctl::PrctlFilter<double>* formula = nullptr; ASSERT_NO_THROW( - prctlParser = new storm::parser::PrctlParser("P > 0.5 [ F a ]") + formula = storm::parser::PrctlParser::parsePrctlFormula(input) ); - ASSERT_NE(prctlParser->getFormula(), nullptr); + // The parser did not falsely recognize the input as a comment. + ASSERT_NE(formula, nullptr); - storm::property::prctl::ProbabilisticBoundOperator<double>* op = static_cast<storm::property::prctl::ProbabilisticBoundOperator<double>*>(prctlParser->getFormula()); + + ASSERT_NE(dynamic_cast<storm::property::prctl::ProbabilisticBoundOperator<double>*>(formula->getChild()), nullptr); + storm::property::prctl::ProbabilisticBoundOperator<double>* op = static_cast<storm::property::prctl::ProbabilisticBoundOperator<double>*>(formula->getChild()); ASSERT_EQ(storm::property::GREATER, op->getComparisonOperator()); ASSERT_EQ(0.5, op->getBound()); - ASSERT_EQ(prctlParser->getFormula()->toString(), "P > 0.500000 [F a]"); + // Test the string representation for the parsed formula. + ASSERT_EQ("P > 0.500000 [F a]", formula->toString()); - delete prctlParser->getFormula(); - delete prctlParser; + delete formula; } TEST(PrctlParserTest, parseRewardFormulaTest) { - storm::parser::PrctlParser* prctlParser = nullptr; + std::string input = "R >= 15 [ I=5 ]"; + storm::property::prctl::PrctlFilter<double>* formula = nullptr; ASSERT_NO_THROW( - prctlParser = new storm::parser::PrctlParser("R >= 15 [ I=5 ]") + formula = storm::parser::PrctlParser::parsePrctlFormula(input); ); - ASSERT_NE(prctlParser->getFormula(), nullptr); + // The parser did not falsely recognize the input as a comment. + ASSERT_NE(formula, nullptr); - storm::property::prctl::RewardBoundOperator<double>* op = static_cast<storm::property::prctl::RewardBoundOperator<double>*>(prctlParser->getFormula()); + ASSERT_NE(dynamic_cast<storm::property::prctl::RewardBoundOperator<double>*>(formula->getChild()), nullptr); + storm::property::prctl::RewardBoundOperator<double>* op = static_cast<storm::property::prctl::RewardBoundOperator<double>*>(formula->getChild()); ASSERT_EQ(storm::property::GREATER_EQUAL, op->getComparisonOperator()); ASSERT_EQ(15.0, op->getBound()); - ASSERT_EQ("R >= 15.000000 [I=5]", prctlParser->getFormula()->toString()); + // Test the string representation for the parsed formula. + ASSERT_EQ("R >= 15.000000 [I=5]", formula->toString()); - delete prctlParser->getFormula(); - delete prctlParser; + delete formula; } TEST(PrctlParserTest, parseRewardNoBoundFormulaTest) { - storm::parser::PrctlParser* prctlParser = nullptr; + std::string input = "R = ? [ F a ]"; + storm::property::prctl::PrctlFilter<double>* formula = nullptr; ASSERT_NO_THROW( - prctlParser = new storm::parser::PrctlParser("R = ? [ F a ]") + formula = storm::parser::PrctlParser::parsePrctlFormula(input) ); - ASSERT_NE(prctlParser->getFormula(), nullptr); - + // The parser did not falsely recognize the input as a comment. + ASSERT_NE(formula, nullptr); - ASSERT_EQ(prctlParser->getFormula()->toString(), "R = ? [F a]"); - - delete prctlParser->getFormula(); - delete prctlParser; + // The input was parsed correctly. + ASSERT_EQ("R = ? [F a]", formula->toString()); + delete formula; } TEST(PrctlParserTest, parseProbabilisticNoBoundFormulaTest) { - storm::parser::PrctlParser* prctlParser = nullptr; + std::string input = "P = ? [ a U <= 4 b & (!c) ]"; + storm::property::prctl::PrctlFilter<double>* formula = nullptr; ASSERT_NO_THROW( - prctlParser = new storm::parser::PrctlParser("P = ? [ a U <= 4 b & (!c) ]") + formula = storm::parser::PrctlParser::parsePrctlFormula(input) ); - ASSERT_NE(prctlParser->getFormula(), nullptr); - + // The parser did not falsely recognize the input as a comment. + ASSERT_NE(formula, nullptr); - ASSERT_EQ(prctlParser->getFormula()->toString(), "P = ? [a U<=4 (b & !c)]"); - - delete prctlParser->getFormula(); - delete prctlParser; + // The input was parsed correctly. + ASSERT_EQ("P = ? [a U<=4 (b & !c)]", formula->toString()); + delete formula; } TEST(PrctlParserTest, parseComplexFormulaTest) { - storm::parser::PrctlParser* prctlParser = nullptr; + std::string input = "R<=0.5 [ S ] & (R > 15 [ C<=0.5 ] | !P < 0.4 [ G P>0.9 [F<=7 a & b] ])"; + storm::property::prctl::PrctlFilter<double>* formula = nullptr; ASSERT_NO_THROW( - prctlParser = new storm::parser::PrctlParser("R<=0.5 [ S ] & (R > 15 [ C<=0.5 ] | !P < 0.4 [ G P>0.9 [F<=7 a & b] ])") + formula = storm::parser::PrctlParser::parsePrctlFormula(input) ); - ASSERT_NE(prctlParser->getFormula(), nullptr); - + // The parser did not falsely recognize the input as a comment. + ASSERT_NE(formula, nullptr); - ASSERT_EQ("(R <= 0.500000 [S] & (R > 15.000000 [C <= 0.500000] | !P < 0.400000 [G P > 0.900000 [F<=7 (a & b)]]))", prctlParser->getFormula()->toString()); - delete prctlParser->getFormula(); - delete prctlParser; + // The input was parsed correctly. + ASSERT_EQ("(R <= 0.500000 [S] & (R > 15.000000 [C <= 0.500000] | !P < 0.400000 [G P > 0.900000 [F<=7 (a & b)]]))", formula->toString()); + delete formula; } TEST(PrctlParserTest, wrongProbabilisticFormulaTest) { - storm::parser::PrctlParser* prctlParser = nullptr; + storm::property::prctl::PrctlFilter<double>* formula = nullptr; ASSERT_THROW( - prctlParser = new storm::parser::PrctlParser("P > 0.5 [ a ]"), + formula = storm::parser::PrctlParser::parsePrctlFormula("P > 0.5 [ a ]"), storm::exceptions::WrongFormatException ); - delete prctlParser; + delete formula; } TEST(PrctlParserTest, wrongFormulaTest) { - storm::parser::PrctlParser* prctlParser = nullptr; + storm::property::prctl::PrctlFilter<double>* formula = nullptr; ASSERT_THROW( - prctlParser = new storm::parser::PrctlParser("(a | b) & +"), + formula = storm::parser::PrctlParser::parsePrctlFormula("(a | b) & +"), storm::exceptions::WrongFormatException ); - delete prctlParser; + delete formula; } TEST(PrctlParserTest, wrongFormulaTest2) { - storm::parser::PrctlParser* prctlParser = nullptr; + storm::property::prctl::PrctlFilter<double>* formula = nullptr; ASSERT_THROW( - prctlParser = new storm::parser::PrctlParser("P>0 [ F & a ]"), + formula = storm::parser::PrctlParser::parsePrctlFormula("P>0 [ F & a ]"), storm::exceptions::WrongFormatException ); - delete prctlParser; + delete formula; } diff --git a/test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp b/test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp index 809f602fb..3e2b3c347 100644 --- a/test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp +++ b/test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp @@ -16,46 +16,43 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, Crowds) { std::shared_ptr<storm::models::Dtmc<double>> dtmc = abstractModel->as<storm::models::Dtmc<double>>(); - ASSERT_EQ(dtmc->getNumberOfStates(), 2036647ull); - ASSERT_EQ(dtmc->getNumberOfTransitions(), 8973900ull); + ASSERT_EQ(2036647ull, dtmc->getNumberOfStates()); + ASSERT_EQ(8973900ull, dtmc->getNumberOfTransitions()); storm::modelchecker::prctl::SparseDtmcPrctlModelChecker<double> mc(*dtmc, new storm::solver::GmmxxLinearEquationSolver<double>()); storm::property::prctl::Ap<double>* apFormula = new storm::property::prctl::Ap<double>("observe0Greater1"); storm::property::prctl::Eventually<double>* eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); - storm::property::prctl::ProbabilisticNoBoundOperator<double>* probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula); LOG4CPLUS_WARN(logger, "Model Checking P=? [F observe0Greater1] on crowds/crowds20_5..."); - std::vector<double> result = probFormula->check(mc); + std::vector<double> result = eventuallyFormula->check(mc, false); LOG4CPLUS_WARN(logger, "Done."); ASSERT_LT(std::abs(result[0] - 0.2296800237), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; + delete eventuallyFormula; apFormula = new storm::property::prctl::Ap<double>("observeIGreater1"); eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); - probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula); LOG4CPLUS_WARN(logger, "Model Checking P=? [F observeIGreater1] on crowds/crowds20_5..."); - result = probFormula->check(mc); + result = eventuallyFormula->check(mc, false); LOG4CPLUS_WARN(logger, "Done."); ASSERT_LT(std::abs(result[0] - 0.05073232193), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; + delete eventuallyFormula; apFormula = new storm::property::prctl::Ap<double>("observeOnlyTrueSender"); eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); - probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula); LOG4CPLUS_WARN(logger, "Model Checking P=? [F observeOnlyTrueSender] on crowds/crowds20_5..."); - result = probFormula->check(mc); + result = eventuallyFormula->check(mc, false); LOG4CPLUS_WARN(logger, "Done."); ASSERT_LT(std::abs(result[0] - 0.22742171078), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; + delete eventuallyFormula; } @@ -67,47 +64,43 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, SynchronousLeader) { ASSERT_EQ(abstractModel->getType(), storm::models::DTMC); - std::shared_ptr<storm::models::Dtmc<double>> dtmc = abstractModel->as<storm::models::Dtmc<double>>(); - ASSERT_EQ(dtmc->getNumberOfStates(), 1312334ull); - ASSERT_EQ(dtmc->getNumberOfTransitions(), 2886810ull); + ASSERT_EQ(1312334ull, dtmc->getNumberOfStates()); + ASSERT_EQ(2886810ull, dtmc->getNumberOfTransitions()); storm::modelchecker::prctl::SparseDtmcPrctlModelChecker<double> mc(*dtmc, new storm::solver::GmmxxLinearEquationSolver<double>()); storm::property::prctl::Ap<double>* apFormula = new storm::property::prctl::Ap<double>("elected"); storm::property::prctl::Eventually<double>* eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); - storm::property::prctl::ProbabilisticNoBoundOperator<double>* probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula); LOG4CPLUS_WARN(logger, "Model Checking P=? [F elected] on synchronous_leader/leader6_8..."); - std::vector<double> result = probFormula->check(mc); + std::vector<double> result = eventuallyFormula->check(mc, false); LOG4CPLUS_WARN(logger, "Done."); ASSERT_LT(std::abs(result[0] - 1.0), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; + delete eventuallyFormula; apFormula = new storm::property::prctl::Ap<double>("elected"); storm::property::prctl::BoundedUntil<double>* boundedUntilFormula = new storm::property::prctl::BoundedUntil<double>(new storm::property::prctl::Ap<double>("true"), apFormula, 20); - probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(boundedUntilFormula); LOG4CPLUS_WARN(logger, "Model Checking P=? [F<=20 elected] on synchronous_leader/leader6_8..."); - result = probFormula->check(mc); + result = boundedUntilFormula->check(mc, false); LOG4CPLUS_WARN(logger, "Done."); ASSERT_LT(std::abs(result[0] - 0.9993949793), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; + delete boundedUntilFormula; apFormula = new storm::property::prctl::Ap<double>("elected"); storm::property::prctl::ReachabilityReward<double>* reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward<double>(apFormula); - storm::property::prctl::RewardNoBoundOperator<double>* rewardFormula = new storm::property::prctl::RewardNoBoundOperator<double>(reachabilityRewardFormula); LOG4CPLUS_WARN(logger, "Model Checking R=? [F elected] on synchronous_leader/leader6_8..."); - result = rewardFormula->check(mc); + result = reachabilityRewardFormula->check(mc, false); LOG4CPLUS_WARN(logger, "Done."); ASSERT_LT(std::abs(result[0] - 1.025106273), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete rewardFormula; + delete reachabilityRewardFormula; } diff --git a/test/performance/modelchecker/SparseMdpPrctlModelCheckerTest.cpp b/test/performance/modelchecker/SparseMdpPrctlModelCheckerTest.cpp index 8f083f89f..98db638df 100644 --- a/test/performance/modelchecker/SparseMdpPrctlModelCheckerTest.cpp +++ b/test/performance/modelchecker/SparseMdpPrctlModelCheckerTest.cpp @@ -14,64 +14,49 @@ TEST(SparseMdpPrctlModelCheckerTest, AsynchronousLeader) { std::shared_ptr<storm::models::Mdp<double>> mdp = abstractModel->as<storm::models::Mdp<double>>(); - ASSERT_EQ(mdp->getNumberOfStates(), 2095783ull); - ASSERT_EQ(mdp->getNumberOfTransitions(), 7714385ull); + ASSERT_EQ(2095783ull, mdp->getNumberOfStates()); + ASSERT_EQ(7714385ull, mdp->getNumberOfTransitions()); storm::modelchecker::prctl::SparseMdpPrctlModelChecker<double> mc(*mdp, std::shared_ptr<storm::solver::NativeNondeterministicLinearEquationSolver<double>>(new storm::solver::NativeNondeterministicLinearEquationSolver<double>())); storm::property::prctl::Ap<double>* apFormula = new storm::property::prctl::Ap<double>("elected"); storm::property::prctl::Eventually<double>* eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); - storm::property::prctl::ProbabilisticNoBoundOperator<double>* probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula, true); - std::vector<double> result = mc.checkNoBoundOperator(*probFormula); + std::vector<double> result = mc.checkMinMaxOperator(*eventuallyFormula, true); ASSERT_LT(std::abs(result[0] - 1.0), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; - apFormula = new storm::property::prctl::Ap<double>("elected"); - eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); - probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula, false); - - result = mc.checkNoBoundOperator(*probFormula); + result = mc.checkMinMaxOperator(*eventuallyFormula, false); ASSERT_LT(std::abs(result[0] - 1.0), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; + + delete eventuallyFormula; apFormula = new storm::property::prctl::Ap<double>("elected"); storm::property::prctl::BoundedEventually<double>* boundedEventuallyFormula = new storm::property::prctl::BoundedEventually<double>(apFormula, 25); - probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(boundedEventuallyFormula, true); - result = mc.checkNoBoundOperator(*probFormula); + result = mc.checkMinMaxOperator(*boundedEventuallyFormula, true); ASSERT_LT(std::abs(result[0] - 0.0), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; - apFormula = new storm::property::prctl::Ap<double>("elected"); - boundedEventuallyFormula = new storm::property::prctl::BoundedEventually<double>(apFormula, 25); - probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(boundedEventuallyFormula, false); - - result = mc.checkNoBoundOperator(*probFormula); + result = mc.checkMinMaxOperator(*boundedEventuallyFormula, false); ASSERT_LT(std::abs(result[0] - 0.0), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; + + delete boundedEventuallyFormula; apFormula = new storm::property::prctl::Ap<double>("elected"); storm::property::prctl::ReachabilityReward<double>* reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward<double>(apFormula); - storm::property::prctl::RewardNoBoundOperator<double>* rewardFormula = new storm::property::prctl::RewardNoBoundOperator<double>(reachabilityRewardFormula, true); - result = mc.checkNoBoundOperator(*rewardFormula); + result = mc.checkMinMaxOperator(*reachabilityRewardFormula, true); ASSERT_LT(std::abs(result[0] - 6.172433512), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete rewardFormula; - apFormula = new storm::property::prctl::Ap<double>("elected"); - reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward<double>(apFormula); - rewardFormula = new storm::property::prctl::RewardNoBoundOperator<double>(reachabilityRewardFormula, false); - - result = mc.checkNoBoundOperator(*rewardFormula); + result = mc.checkMinMaxOperator(*reachabilityRewardFormula, false); ASSERT_LT(std::abs(result[0] - 6.1724344), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete rewardFormula; + + delete reachabilityRewardFormula; } TEST(SparseMdpPrctlModelCheckerTest, Consensus) { @@ -85,87 +70,77 @@ TEST(SparseMdpPrctlModelCheckerTest, Consensus) { std::shared_ptr<storm::models::Mdp<double>> mdp = abstractModel->as<storm::models::Mdp<double>>(); - ASSERT_EQ(mdp->getNumberOfStates(), 63616ull); - ASSERT_EQ(mdp->getNumberOfTransitions(), 213472ull); + ASSERT_EQ(63616ull, mdp->getNumberOfStates()); + ASSERT_EQ(213472ull, mdp->getNumberOfTransitions()); storm::modelchecker::prctl::SparseMdpPrctlModelChecker<double> mc(*mdp, std::shared_ptr<storm::solver::NativeNondeterministicLinearEquationSolver<double>>(new storm::solver::NativeNondeterministicLinearEquationSolver<double>())); storm::property::prctl::Ap<double>* apFormula = new storm::property::prctl::Ap<double>("finished"); storm::property::prctl::Eventually<double>* eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); - storm::property::prctl::ProbabilisticNoBoundOperator<double>* probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula, true); - std::vector<double> result = mc.checkNoBoundOperator(*probFormula); + std::vector<double> result = mc.checkMinMaxOperator(*eventuallyFormula, true); ASSERT_LT(std::abs(result[31168] - 1.0), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; + delete eventuallyFormula; + apFormula = new storm::property::prctl::Ap<double>("finished"); storm::property::prctl::Ap<double>* apFormula2 = new storm::property::prctl::Ap<double>("all_coins_equal_0"); storm::property::prctl::And<double>* andFormula = new storm::property::prctl::And<double>(apFormula, apFormula2); eventuallyFormula = new storm::property::prctl::Eventually<double>(andFormula); - probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula, true); - result = mc.checkNoBoundOperator(*probFormula); + result = mc.checkMinMaxOperator(*eventuallyFormula, true); ASSERT_LT(std::abs(result[31168] - 0.4374282832), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; + + delete eventuallyFormula; apFormula = new storm::property::prctl::Ap<double>("finished"); apFormula2 = new storm::property::prctl::Ap<double>("all_coins_equal_1"); andFormula = new storm::property::prctl::And<double>(apFormula, apFormula2); eventuallyFormula = new storm::property::prctl::Eventually<double>(andFormula); - probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula, false); - result = mc.checkNoBoundOperator(*probFormula); + result = mc.checkMinMaxOperator(*eventuallyFormula, false); ASSERT_LT(std::abs(result[31168] - 0.5293286369), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; + delete eventuallyFormula; + apFormula = new storm::property::prctl::Ap<double>("finished"); apFormula2 = new storm::property::prctl::Ap<double>("agree"); storm::property::prctl::Not<double>* notFormula = new storm::property::prctl::Not<double>(apFormula2); andFormula = new storm::property::prctl::And<double>(apFormula, notFormula); eventuallyFormula = new storm::property::prctl::Eventually<double>(andFormula); - probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula, false); - result = mc.checkNoBoundOperator(*probFormula); + result = mc.checkMinMaxOperator(*eventuallyFormula, false); ASSERT_LT(std::abs(result[31168] - 0.10414097), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; + delete eventuallyFormula; + apFormula = new storm::property::prctl::Ap<double>("finished"); storm::property::prctl::BoundedEventually<double>* boundedEventuallyFormula = new storm::property::prctl::BoundedEventually<double>(apFormula, 50ull); - probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(boundedEventuallyFormula, true); - result = mc.checkNoBoundOperator(*probFormula); + result = mc.checkMinMaxOperator(*boundedEventuallyFormula, true); ASSERT_LT(std::abs(result[31168] - 0.0), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; - - apFormula = new storm::property::prctl::Ap<double>("finished"); - boundedEventuallyFormula = new storm::property::prctl::BoundedEventually<double>(apFormula, 50ull); - probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(boundedEventuallyFormula, false); - - result = mc.checkNoBoundOperator(*probFormula); + result = mc.checkMinMaxOperator(*boundedEventuallyFormula, false); + ASSERT_LT(std::abs(result[31168] - 0.0), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; + + delete boundedEventuallyFormula; apFormula = new storm::property::prctl::Ap<double>("finished"); storm::property::prctl::ReachabilityReward<double>* reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward<double>(apFormula); - storm::property::prctl::RewardNoBoundOperator<double>* rewardFormula = new storm::property::prctl::RewardNoBoundOperator<double>(reachabilityRewardFormula, true); - result = mc.checkNoBoundOperator(*rewardFormula); + result = mc.checkMinMaxOperator(*reachabilityRewardFormula, true); ASSERT_LT(std::abs(result[31168] - 1725.593313), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete rewardFormula; - - apFormula = new storm::property::prctl::Ap<double>("finished"); - reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward<double>(apFormula); - rewardFormula = new storm::property::prctl::RewardNoBoundOperator<double>(reachabilityRewardFormula, false); - - result = mc.checkNoBoundOperator(*rewardFormula); - + + result = mc.checkMinMaxOperator(*reachabilityRewardFormula, false); + ASSERT_LT(std::abs(result[31168] - 2183.142422), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete rewardFormula; + + delete reachabilityRewardFormula; } From 9a28e5b580da618d581a37e042611776bc5375a0 Mon Sep 17 00:00:00 2001 From: masawei <manuel.sascha.weiand@rwth-aachen.de> Date: Fri, 30 May 2014 23:06:22 +0200 Subject: [PATCH 12/30] Added proper formula string method to filters. - Lots of debugging - Changed the way the filter keeps information about the scheduler to use for probability/reward queries. | This was done by keeping a special action at the first position of the action list. | Which was not exactly consistent with the idea behind the filter actions. | Now the filter keeps this information as an enum value in a member variable. - All but one tests are green. So we almost reestablished full functionality. |- The last test that still fails is SparseMdpPrctlModelCheckerTest.Dice where the second to last model check returns the wrong result. Next up: Debug. Then introduce the full range of filter actions. Former-commit-id: fd311966cc55c005b4b331bc127933b56f156a8e --- src/formula/AbstractFilter.h | 41 +++++- src/formula/Actions/MinMaxAction.h | 68 ---------- src/formula/Csl/CslFilter.h | 113 +++++++++++++--- src/formula/Csl/ProbabilisticBoundOperator.h | 4 +- src/formula/Csl/SteadyStateBoundOperator.h | 4 +- src/formula/Csl/TimeBoundedEventually.h | 6 +- src/formula/Csl/TimeBoundedUntil.h | 4 +- src/formula/Prctl/BoundedNaryUntil.h | 2 +- src/formula/Prctl/PrctlFilter.h | 125 ++++++++++++++---- .../Prctl/ProbabilisticBoundOperator.h | 4 +- src/formula/Prctl/RewardBoundOperator.h | 4 +- src/modelchecker/prctl/AbstractModelChecker.h | 18 +-- .../prctl/SparseDtmcPrctlModelChecker.h | 8 +- src/parser/CslParser.cpp | 60 ++++----- src/parser/PrctlParser.cpp | 60 ++++----- .../SparseMdpPrctlModelCheckerTest.cpp | 36 ++--- test/functional/parser/CslParserTest.cpp | 10 +- test/functional/parser/PrctlParserTest.cpp | 10 +- .../SparseMdpPrctlModelCheckerTest.cpp | 28 ++-- 19 files changed, 353 insertions(+), 252 deletions(-) delete mode 100644 src/formula/Actions/MinMaxAction.h diff --git a/src/formula/AbstractFilter.h b/src/formula/AbstractFilter.h index 4031125d5..fe9798fca 100644 --- a/src/formula/AbstractFilter.h +++ b/src/formula/AbstractFilter.h @@ -15,20 +15,25 @@ namespace storm { namespace property { +/*! + * + */ +enum OptimizingOperator {MINIMIZE, MAXIMIZE, UNDEFINED}; + template <class T> class AbstractFilter { public: - AbstractFilter() { + AbstractFilter(OptimizingOperator opt = UNDEFINED) : opt(opt) { // Intentionally left empty. } - AbstractFilter(action::AbstractAction<T>* action) { + AbstractFilter(action::AbstractAction<T>* action, OptimizingOperator opt = UNDEFINED) : opt(opt) { actions.push_back(action); } - AbstractFilter(std::vector<action::AbstractAction<T>*> actions) : actions(actions) { + AbstractFilter(std::vector<action::AbstractAction<T>*> actions, OptimizingOperator opt = UNDEFINED) : actions(actions), opt(opt) { // Intentionally left empty. } @@ -36,16 +41,30 @@ public: actions.clear(); } - std::string toFormulaString() const { + virtual std::string toString() const { std::string desc = "filter("; + + for(auto action : actions) { + desc += action->toString(); + desc += ", "; + } + + // Remove the last ", ". + if(!actions.empty()) { + desc.pop_back(); + desc.pop_back(); + } + + desc += ")"; + return desc; } - std::string toString() const { + virtual std::string toPrettyString() const { std::string desc = "Filter: "; desc += "\nActions:"; for(auto action : actions) { - desc += "\n\t" + action.toString(); + desc += "\n\t" + action->toString(); } return desc; } @@ -66,9 +85,19 @@ public: return actions.size(); } + void setOptimizingOperator(OptimizingOperator opt) { + this->opt = opt; + } + + OptimizingOperator getOptimizingOperator() const { + return opt; + } + protected: std::vector<action::AbstractAction<T>*> actions; + + OptimizingOperator opt; }; } //namespace property diff --git a/src/formula/Actions/MinMaxAction.h b/src/formula/Actions/MinMaxAction.h deleted file mode 100644 index c775700e7..000000000 --- a/src/formula/Actions/MinMaxAction.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * MinMaxAction.h - * - * Created on: Apr 30, 2014 - * Author: Manuel Sascha Weiand - */ - -#ifndef STORM_FORMULA_ACTION_MINMAXACTION_H_ -#define STORM_FORMULA_ACTION_MINMAXACTION_H_ - -#include "src/formula/Actions/AbstractAction.h" - -namespace storm { -namespace property { -namespace action { - -template <class T> -class MinMaxAction : public AbstractAction<T> { - -public: - - MinMaxAction() : minimize(true) { - //Intentionally left empty. - } - - explicit MinMaxAction(bool minimize) : minimize(minimize) { - //Intentionally left empty. - } - - /*! - * Virtual destructor - * To ensure that the right destructor is called - */ - virtual ~MinMaxAction() { - //Intentionally left empty - } - - /*! - * - */ - virtual std::string toString() const override { - return minimize ? "min" : "max"; - } - - /*! - * - */ - virtual std::string toFormulaString() const override { - return minimize ? "min" : "max"; - } - - /*! - * - */ - bool getMinimize() { - return minimize; - } - -private: - bool minimize; - -}; - -} //namespace action -} //namespace property -} //namespace storm - -#endif /* STORM_FORMULA_ACTION_MINMAXACTION_H_ */ diff --git a/src/formula/Csl/CslFilter.h b/src/formula/Csl/CslFilter.h index dbbd22368..14c578be7 100644 --- a/src/formula/Csl/CslFilter.h +++ b/src/formula/Csl/CslFilter.h @@ -13,7 +13,6 @@ #include "src/formula/Csl/AbstractPathFormula.h" #include "src/formula/Csl/AbstractStateFormula.h" #include "src/modelchecker/csl/AbstractModelChecker.h" -#include "src/formula/Actions/MinMaxAction.h" namespace storm { namespace property { @@ -24,23 +23,19 @@ class CslFilter : public storm::property::AbstractFilter<T> { public: - CslFilter() : child(nullptr) { + CslFilter() : AbstractFilter<T>(UNDEFINED), child(nullptr), steadyStateQuery(false) { // Intentionally left empty. } - CslFilter(AbstractCslFormula<T>* child) : child(child) { + CslFilter(AbstractCslFormula<T>* child, OptimizingOperator opt = UNDEFINED, bool steadyStateQuery = false) : AbstractFilter<T>(opt), child(child), steadyStateQuery(steadyStateQuery) { // Intentionally left empty. } - CslFilter(AbstractCslFormula<T>* child, bool minimize) : child(child) { - this->actions.push_back(new storm::property::action::MinMaxAction<T>(minimize)); + CslFilter(AbstractCslFormula<T>* child, action::AbstractAction<T>* action, OptimizingOperator opt = UNDEFINED, bool steadyStateQuery = false) : AbstractFilter<T>(action, opt), child(child), steadyStateQuery(steadyStateQuery) { + // Intentionally left empty } - CslFilter(AbstractCslFormula<T>* child, action::AbstractAction<T>* action) : child(child) { - this->actions.push_back(action); - } - - CslFilter(AbstractCslFormula<T>* child, std::vector<action::AbstractAction<T>*> actions) : AbstractFilter<T>(actions), child(child) { + CslFilter(AbstractCslFormula<T>* child, std::vector<action::AbstractAction<T>*> actions, OptimizingOperator opt = UNDEFINED, bool steadyStateQuery = false) : AbstractFilter<T>(actions, opt), child(child), steadyStateQuery(steadyStateQuery) { // Intentionally left empty. } @@ -145,12 +140,94 @@ public: return true; } - std::string toFormulaString() const { - std::string desc = "filter("; + virtual std::string toString() const override { + std::string desc = ""; + + if(dynamic_cast<AbstractStateFormula<T>*>(child) == nullptr) { + + // The formula is not a state formula so we have a probability query. + if(this->actions.empty()){ + + // Since there are no actions given we do legacy support. + + desc += "P "; + switch(this->opt) { + case MINIMIZE: + desc += "min "; + break; + case MAXIMIZE: + desc += "max "; + break; + default: + break; + } + desc += "= ? "; + + } else { + desc = "filter["; + + switch(this->opt) { + case MINIMIZE: + desc += "min, "; + break; + case MAXIMIZE: + desc += "max, "; + break; + default: + break; + } + + for(auto action : this->actions) { + desc += action->toString(); + desc += ", "; + } + + // Remove the last ", ". + desc.pop_back(); + desc.pop_back(); + + desc += "]"; + } + + } else { + + if(this->actions.empty()) { + + if(steadyStateQuery) { + + // Legacy support for the steady state query. + desc += "S = ? "; + + } else { + + // There are no filter actions but only the raw state formula. So just print that. + return child->toString(); + } + } else { + + desc = "filter["; + + for(auto action : this->actions) { + desc += action->toString(); + desc += ", "; + } + + // Remove the last ", ". + desc.pop_back(); + desc.pop_back(); + + desc += "]"; + } + } + + desc += "("; + desc += child->toString(); + desc += ")"; + return desc; } - std::string toString() const { + virtual std::string toPrettyString() const override{ std::string desc = "Filter: "; desc += "\nActions:"; for(auto action : this->actions) { @@ -174,9 +251,9 @@ private: // First, get the model checking result. storm::storage::BitVector result = modelchecker.checkMinMaxOperator(formula); - if(this->getActionCount() != 0 && dynamic_cast<storm::property::action::MinMaxAction<T>*>(this->getAction(0)) != nullptr) { + if(this->opt != UNDEFINED) { // If there is an action specifying that min/max probabilities should be computed, call the appropriate method of the model checker. - result = modelchecker.checkMinMaxOperator(formula, static_cast<storm::property::action::MinMaxAction<T>*>(this->getAction(0))->getMinimize()); + result = modelchecker.checkMinMaxOperator(formula, this->opt == MINIMIZE ? true : false); } else { result = formula->check(modelchecker); } @@ -193,9 +270,9 @@ private: // First, get the model checking result. std::vector<T> result; - if(this->getActionCount() != 0 && dynamic_cast<storm::property::action::MinMaxAction<T>*>(this->getAction(0)) != nullptr) { + if(this->opt != UNDEFINED) { // If there is an action specifying that min/max probabilities should be computed, call the appropriate method of the model checker. - result = modelchecker.checkMinMaxOperator(formula, static_cast<storm::property::action::MinMaxAction<T>*>(this->getAction(0))->getMinimize()); + result = modelchecker.checkMinMaxOperator(formula, this->opt == MINIMIZE ? true : false); } else { result = formula->check(modelchecker, false); } @@ -208,6 +285,8 @@ private: } AbstractCslFormula<T>* child; + + bool steadyStateQuery; }; } //namespace csl diff --git a/src/formula/Csl/ProbabilisticBoundOperator.h b/src/formula/Csl/ProbabilisticBoundOperator.h index 4b4e5d937..d40bb90e2 100644 --- a/src/formula/Csl/ProbabilisticBoundOperator.h +++ b/src/formula/Csl/ProbabilisticBoundOperator.h @@ -139,9 +139,9 @@ public: } result += " "; result += std::to_string(bound); - result += " ["; + result += " ("; result += pathFormula->toString(); - result += "]"; + result += ")"; return result; } diff --git a/src/formula/Csl/SteadyStateBoundOperator.h b/src/formula/Csl/SteadyStateBoundOperator.h index c8d9e8de4..ecaad5ad4 100644 --- a/src/formula/Csl/SteadyStateBoundOperator.h +++ b/src/formula/Csl/SteadyStateBoundOperator.h @@ -135,9 +135,9 @@ public: case GREATER_EQUAL: result += ">= "; break; } result += std::to_string(bound); - result += " ["; + result += " ("; result += stateFormula->toString(); - result += "]"; + result += ")"; return result; } diff --git a/src/formula/Csl/TimeBoundedEventually.h b/src/formula/Csl/TimeBoundedEventually.h index ac601b7d8..c80eecb4b 100644 --- a/src/formula/Csl/TimeBoundedEventually.h +++ b/src/formula/Csl/TimeBoundedEventually.h @@ -50,7 +50,7 @@ public: setInterval(lowerBound, upperBound); } - TimeBoundedEventually(T lowerBound, T upperBound, AbstractStateFormula<T>* child) : child(nullptr) { + TimeBoundedEventually(T lowerBound, T upperBound, AbstractStateFormula<T>* child) : child(child) { setInterval(lowerBound, upperBound); } @@ -104,9 +104,9 @@ public: virtual std::string toString() const override { std::string result = "F"; if (upperBound == std::numeric_limits<double>::infinity()) { - result = ">=" + std::to_string(lowerBound); + result += ">=" + std::to_string(lowerBound); } else { - result = "["; + result += "["; result += std::to_string(lowerBound); result += ","; result += std::to_string(upperBound); diff --git a/src/formula/Csl/TimeBoundedUntil.h b/src/formula/Csl/TimeBoundedUntil.h index 560bb8df8..3da7fa968 100644 --- a/src/formula/Csl/TimeBoundedUntil.h +++ b/src/formula/Csl/TimeBoundedUntil.h @@ -123,9 +123,9 @@ public: std::string result = left->toString(); result += " U"; if (upperBound == std::numeric_limits<double>::infinity()) { - result = ">=" + std::to_string(lowerBound); + result += ">=" + std::to_string(lowerBound); } else { - result = "["; + result += "["; result += std::to_string(lowerBound); result += ","; result += std::to_string(upperBound); diff --git a/src/formula/Prctl/BoundedNaryUntil.h b/src/formula/Prctl/BoundedNaryUntil.h index f59431447..9c27158ba 100644 --- a/src/formula/Prctl/BoundedNaryUntil.h +++ b/src/formula/Prctl/BoundedNaryUntil.h @@ -143,7 +143,7 @@ public: std::stringstream result; result << "( " << left->toString(); for (auto it = this->right->begin(); it != this->right->end(); ++it) { - result << " U[" << std::get<1>(*it) << "," << std::get<2>(*it) << "] " << std::get<0>(*it)->toString(); + result << " U(" << std::get<1>(*it) << "," << std::get<2>(*it) << ") " << std::get<0>(*it)->toString(); } result << ")"; return result.str(); diff --git a/src/formula/Prctl/PrctlFilter.h b/src/formula/Prctl/PrctlFilter.h index 7302148a3..407b4f6c3 100644 --- a/src/formula/Prctl/PrctlFilter.h +++ b/src/formula/Prctl/PrctlFilter.h @@ -13,7 +13,6 @@ #include "src/formula/Prctl/AbstractPathFormula.h" #include "src/formula/Prctl/AbstractStateFormula.h" #include "src/modelchecker/prctl/AbstractModelChecker.h" -#include "src/formula/Actions/MinMaxAction.h" namespace storm { namespace property { @@ -24,23 +23,19 @@ class PrctlFilter : public storm::property::AbstractFilter<T> { public: - PrctlFilter() : child(nullptr) { + PrctlFilter() : AbstractFilter<T>(UNDEFINED), child(nullptr) { // Intentionally left empty. } - PrctlFilter(AbstractPrctlFormula<T>* child) : child(child) { + PrctlFilter(AbstractPrctlFormula<T>* child, OptimizingOperator opt = UNDEFINED) : AbstractFilter<T>(opt), child(child) { // Intentionally left empty. } - PrctlFilter(AbstractPrctlFormula<T>* child, bool minimize) : child(child) { - this->actions.push_back(new storm::property::action::MinMaxAction<T>(minimize)); - } - - PrctlFilter(AbstractPrctlFormula<T>* child, action::AbstractAction<T>* action) : child(child) { - this->actions.push_back(action); + PrctlFilter(AbstractPrctlFormula<T>* child, action::AbstractAction<T>* action, OptimizingOperator opt = UNDEFINED) : AbstractFilter<T>(action, opt), child(child) { + // Intentionally left empty. } - PrctlFilter(AbstractPrctlFormula<T>* child, std::vector<action::AbstractAction<T>*> actions) : AbstractFilter<T>(actions), child(child) { + PrctlFilter(AbstractPrctlFormula<T>* child, std::vector<action::AbstractAction<T>*> actions, OptimizingOperator opt = UNDEFINED) : AbstractFilter<T>(actions, opt), child(child) { // Intentionally left empty. } @@ -53,8 +48,8 @@ public: // Write out the formula to be checked. std::cout << std::endl; - LOG4CPLUS_INFO(logger, "Model checking formula\t" << this->toFormulaString()); - std::cout << "Model checking formula:\t" << this->toFormulaString() << std::endl; + LOG4CPLUS_INFO(logger, "Model checking formula\t" << this->toString()); + std::cout << "Model checking formula:\t" << this->toString() << std::endl; // Do a dynamic cast to test for the actual formula type and call the correct evaluation function. if(dynamic_cast<AbstractStateFormula<T>*>(child) != nullptr) { @@ -177,12 +172,94 @@ public: return true; } - std::string toFormulaString() const { - std::string desc = "filter("; + virtual std::string toString() const override { + std::string desc = ""; + + if(dynamic_cast<AbstractStateFormula<T>*>(child) == nullptr) { + + // The formula is not a state formula so we either have a probability query or a reward query. + if(this->actions.empty()){ + + // There is exactly one action in the list, the minmax action. Again, we do legacy support- + + if(dynamic_cast<AbstractPathFormula<T>*>(child) != nullptr) { + // It is a probability query. + desc += "P "; + + } else { + // It is a reward query. + desc += "R "; + } + + switch(this->opt) { + case MINIMIZE: + desc += "min "; + break; + case MAXIMIZE: + desc += "max "; + break; + default: + break; + } + + desc += "= ? "; + + } else { + desc = "filter["; + + switch(this->opt) { + case MINIMIZE: + desc += " min, "; + break; + case MAXIMIZE: + desc += " max, "; + break; + default: + break; + } + + for(auto action : this->actions) { + desc += action->toString(); + desc += ", "; + } + + // Remove the last ", ". + desc.pop_back(); + desc.pop_back(); + + desc += "]"; + } + + } else { + + if(this->actions.empty()) { + + // There are no filter actions but only the raw state formula. So just print that. + return child->toString(); + } + + desc = "filter["; + + for(auto action : this->actions) { + desc += action->toString(); + desc += ", "; + } + + // Remove the last ", ". + desc.pop_back(); + desc.pop_back(); + + desc += "]"; + } + + desc += "("; + desc += child->toString(); + desc += ")"; + return desc; } - std::string toString() const { + virtual std::string toPrettyString() const override{ std::string desc = "Filter: "; desc += "\nActions:"; for(auto action : this->actions) { @@ -206,9 +283,9 @@ private: // First, get the model checking result. storm::storage::BitVector result; - if(this->getActionCount() != 0 && dynamic_cast<storm::property::action::MinMaxAction<T>*>(this->getAction(0)) != nullptr) { - // If there is an action specifying that min/max probabilities should be computed, call the appropriate method of the model checker. - result = modelchecker.checkMinMaxOperator(*formula, static_cast<storm::property::action::MinMaxAction<T>*>(this->getAction(0))->getMinimize()); + if(this->opt != UNDEFINED) { + // If it is specified that min/max probabilities/rewards should be computed, call the appropriate method of the model checker. + result = modelchecker.checkOptimizingOperator(*formula, this->opt == storm::property::MINIMIZE ? true : false); } else { result = formula->check(modelchecker); } @@ -225,9 +302,9 @@ private: // First, get the model checking result. std::vector<T> result; - if(this->getActionCount() != 0 && dynamic_cast<storm::property::action::MinMaxAction<T>*>(this->getAction(0)) != nullptr) { - // If there is an action specifying that min/max probabilities should be computed, call the appropriate method of the model checker. - result = modelchecker.checkMinMaxOperator(*formula, dynamic_cast<storm::property::action::MinMaxAction<T>*>(this->getAction(0))->getMinimize()); + if(this->opt != UNDEFINED) { + // If it is specified that min/max probabilities/rewards should be computed, call the appropriate method of the model checker. + result = modelchecker.checkOptimizingOperator(*formula, this->opt == storm::property::MINIMIZE ? true : false); } else { result = formula->check(modelchecker, false); } @@ -243,9 +320,9 @@ private: // First, get the model checking result. std::vector<T> result; - if(this->getActionCount() != 0 && dynamic_cast<storm::property::action::MinMaxAction<T>*>(this->getAction(0)) != nullptr) { - // If there is an action specifying that min/max probabilities should be computed, call the appropriate method of the model checker. - result = modelchecker.checkMinMaxOperator(*formula, dynamic_cast<storm::property::action::MinMaxAction<T>*>(this->getAction(0))->getMinimize()); + if(this->opt != UNDEFINED) { + // If it is specified that min/max probabilities/rewards should be computed, call the appropriate method of the model checker. + result = modelchecker.checkOptimizingOperator(*formula, this->opt == storm::property::MINIMIZE ? true : false); } else { result = formula->check(modelchecker, false); } diff --git a/src/formula/Prctl/ProbabilisticBoundOperator.h b/src/formula/Prctl/ProbabilisticBoundOperator.h index 9cbcee34c..e1c325ef2 100644 --- a/src/formula/Prctl/ProbabilisticBoundOperator.h +++ b/src/formula/Prctl/ProbabilisticBoundOperator.h @@ -139,9 +139,9 @@ public: } result += " "; result += std::to_string(bound); - result += " ["; + result += " ("; result += pathFormula->toString(); - result += "]"; + result += ")"; return result; } diff --git a/src/formula/Prctl/RewardBoundOperator.h b/src/formula/Prctl/RewardBoundOperator.h index bf12d471d..ac9b721cc 100644 --- a/src/formula/Prctl/RewardBoundOperator.h +++ b/src/formula/Prctl/RewardBoundOperator.h @@ -137,9 +137,9 @@ public: } result += " "; result += std::to_string(bound); - result += " ["; + result += " ("; result += pathFormula->toString(); - result += "]"; + result += ")"; return result; } diff --git a/src/modelchecker/prctl/AbstractModelChecker.h b/src/modelchecker/prctl/AbstractModelChecker.h index fcaf0c2a9..e877cc672 100644 --- a/src/modelchecker/prctl/AbstractModelChecker.h +++ b/src/modelchecker/prctl/AbstractModelChecker.h @@ -233,11 +233,11 @@ public: * Checks the given formula and determines whether minimum or maximum probabilities are to be computed for the formula. * * @param formula The formula to check. - * @param minimumOperator True iff minimum probabilities are to be computed. + * @param optOperator True iff minimum probabilities are to be computed. * @returns The probabilities to satisfy the formula, represented by a vector. */ - virtual std::vector<Type> checkMinMaxOperator(storm::property::prctl::AbstractPathFormula<Type> const & formula, bool minimumOperator) const { - minimumOperatorStack.push(minimumOperator); + virtual std::vector<Type> checkOptimizingOperator(storm::property::prctl::AbstractPathFormula<Type> const & formula, bool optOperator) const { + minimumOperatorStack.push(optOperator); std::vector<Type> result = formula.check(*this, false); minimumOperatorStack.pop(); return result; @@ -247,11 +247,11 @@ public: * Checks the given formula and determines whether minimum or maximum rewards are to be computed for the formula. * * @param formula The formula to check. - * @param minimumOperator True iff minimum rewards are to be computed. + * @param optOperator True iff minimum rewards are to be computed. * @returns The the rewards accumulated by the formula, represented by a vector. */ - virtual std::vector<Type> checkMinMaxOperator(storm::property::prctl::AbstractRewardPathFormula<Type> const & formula, bool minimumOperator) const { - minimumOperatorStack.push(minimumOperator); + virtual std::vector<Type> checkOptimizingOperator(storm::property::prctl::AbstractRewardPathFormula<Type> const & formula, bool optOperator) const { + minimumOperatorStack.push(optOperator); std::vector<Type> result = formula.check(*this, false); minimumOperatorStack.pop(); return result; @@ -261,11 +261,11 @@ public: * Checks the given formula and determines whether minimum or maximum probabilities or rewards are to be computed for the formula. * * @param formula The formula to check. - * @param minimumOperator True iff minimum probabilities/rewards are to be computed. + * @param optOperator True iff minimum probabilities/rewards are to be computed. * @returns The set of states satisfying the formula represented by a bit vector. */ - virtual storm::storage::BitVector checkMinMaxOperator(storm::property::prctl::AbstractStateFormula<Type> const & formula, bool minimumOperator) const { - minimumOperatorStack.push(minimumOperator); + virtual storm::storage::BitVector checkOptimizingOperator(storm::property::prctl::AbstractStateFormula<Type> const & formula, bool optOperator) const { + minimumOperatorStack.push(optOperator); storm::storage::BitVector result = formula.check(*this); minimumOperatorStack.pop(); return result; diff --git a/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h b/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h index ba61201c7..acdb6945c 100644 --- a/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h +++ b/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h @@ -488,10 +488,10 @@ public: * should be computed for the formula makes no sense in the context of a deterministic model. * * @param formula The formula to check. - * @param minimumOperator True iff minimum probabilities/rewards are to be computed. + * @param optOperator True iff minimum probabilities/rewards are to be computed. * @returns The probabilities to satisfy the formula or the rewards accumulated by it, represented by a vector. */ - virtual std::vector<Type> checkMinMaxOperator(storm::property::prctl::AbstractPathFormula<Type> const & formula, bool minimumOperator) const override { + virtual std::vector<Type> checkOptimizingOperator(storm::property::prctl::AbstractPathFormula<Type> const & formula, bool optOperator) const override { LOG4CPLUS_WARN(logger, "Formula contains min/max operator, which is not meaningful over deterministic models."); @@ -506,10 +506,10 @@ public: * should be computed for the formula makes no sense in the context of a deterministic model. * * @param formula The formula to check. - * @param minimumOperator True iff minimum probabilities/rewards are to be computed. + * @param optOperator True iff minimum probabilities/rewards are to be computed. * @returns The set of states satisfying the formula represented by a bit vector. */ - virtual storm::storage::BitVector checkMinMaxOperator(storm::property::prctl::AbstractStateFormula<Type> const & formula, bool minimumOperator) const override { + virtual storm::storage::BitVector checkOptimizingOperator(storm::property::prctl::AbstractStateFormula<Type> const & formula, bool optOperator) const override { LOG4CPLUS_WARN(logger, "Formula contains min/max operator, which is not meaningful over deterministic models."); diff --git a/src/parser/CslParser.cpp b/src/parser/CslParser.cpp index 5ae34df1c..296deecc0 100644 --- a/src/parser/CslParser.cpp +++ b/src/parser/CslParser.cpp @@ -11,7 +11,6 @@ // The action class headers. #include "src/formula/Actions/AbstractAction.h" -#include "src/formula/Actions/MinMaxAction.h" #include "src/formula/Actions/RangeAction.h" // If the parser fails due to ill-formed data, this exception is thrown. @@ -38,7 +37,6 @@ typedef boost::spirit::classic::position_iterator2<BaseIteratorType> PositionIte namespace qi = boost::spirit::qi; namespace phoenix = boost::phoenix; - namespace storm { namespace parser { @@ -60,31 +58,31 @@ struct CslParser::CslGrammar : qi::grammar<Iterator, storm::property::csl::CslFi stateFormula.name("state formula"); orFormula = andFormula[qi::_val = qi::_1] > *(qi::lit("|") > andFormula)[qi::_val = phoenix::new_<storm::property::csl::Or<double>>(qi::_val, qi::_1)]; - orFormula.name("state formula"); + orFormula.name("or formula"); andFormula = notFormula[qi::_val = qi::_1] > *(qi::lit("&") > notFormula)[qi::_val = phoenix::new_<storm::property::csl::And<double>>(qi::_val, qi::_1)]; - andFormula.name("state formula"); + andFormula.name("and formula"); notFormula = atomicStateFormula[qi::_val = qi::_1] | (qi::lit("!") > atomicStateFormula)[qi::_val = phoenix::new_<storm::property::csl::Not<double>>(qi::_1)]; - notFormula.name("state formula"); + notFormula.name("not formula"); //This block defines rules for "atomic" state formulas //(Propositions, probabilistic/reward formulas, and state formulas in brackets) atomicStateFormula %= probabilisticBoundOperator | steadyStateBoundOperator | atomicProposition | qi::lit("(") >> stateFormula >> qi::lit(")"); - atomicStateFormula.name("state formula"); + atomicStateFormula.name("atomic state formula"); atomicProposition = (freeIdentifierName)[qi::_val = phoenix::new_<storm::property::csl::Ap<double>>(qi::_1)]; - atomicProposition.name("state formula"); + atomicProposition.name("atomic proposition"); probabilisticBoundOperator = ( (qi::lit("P") >> comparisonType > qi::double_ > qi::lit("[") > pathFormula > qi::lit("]"))[qi::_val = phoenix::new_<storm::property::csl::ProbabilisticBoundOperator<double> >(qi::_1, qi::_2, qi::_3)] ); - probabilisticBoundOperator.name("state formula"); + probabilisticBoundOperator.name("probabilistic bound operator"); steadyStateBoundOperator = ( (qi::lit("S") >> comparisonType > qi::double_ > qi::lit("[") > stateFormula > qi::lit("]"))[qi::_val = phoenix::new_<storm::property::csl::SteadyStateBoundOperator<double> >(qi::_1, qi::_2, qi::_3)] ); - steadyStateBoundOperator.name("state formula"); + steadyStateBoundOperator.name("steady state bound operator"); //This block defines rules for parsing probabilistic path formulas pathFormula = (timeBoundedEventually | eventually | globally | next | timeBoundedUntil | until); @@ -97,16 +95,16 @@ struct CslParser::CslGrammar : qi::grammar<Iterator, storm::property::csl::CslFi (qi::lit("F") >> (qi::lit(">=") | qi::lit(">")) > qi::double_ > stateFormula)[qi::_val = phoenix::new_<storm::property::csl::TimeBoundedEventually<double>>(qi::_1, std::numeric_limits<double>::infinity(), qi::_2)] ); - timeBoundedEventually.name("path formula (for probabilistic operator)"); + timeBoundedEventually.name("time bounded eventually"); eventually = (qi::lit("F") > stateFormula)[qi::_val = phoenix::new_<storm::property::csl::Eventually<double> >(qi::_1)]; - eventually.name("path formula (for probabilistic operator)"); + eventually.name("eventually"); next = (qi::lit("X") > stateFormula)[qi::_val = phoenix::new_<storm::property::csl::Next<double> >(qi::_1)]; - next.name("path formula (for probabilistic operator)"); + next.name("next"); globally = (qi::lit("G") > stateFormula)[qi::_val = phoenix::new_<storm::property::csl::Globally<double> >(qi::_1)]; - globally.name("path formula (for probabilistic operator)"); + globally.name("globally"); timeBoundedUntil = ( (stateFormula[qi::_a = phoenix::construct<std::shared_ptr<storm::property::csl::AbstractStateFormula<double>>>(qi::_1)] >> qi::lit("U") >> qi::lit("[") > qi::double_ > qi::lit(",") > qi::double_ > qi::lit("]") > stateFormula) [qi::_val = phoenix::new_<storm::property::csl::TimeBoundedUntil<double>>(qi::_2, qi::_3, phoenix::bind(&storm::property::csl::AbstractStateFormula<double>::clone, phoenix::bind(&std::shared_ptr<storm::property::csl::AbstractStateFormula<double>>::get, qi::_a)), qi::_4)] | @@ -115,10 +113,10 @@ struct CslParser::CslGrammar : qi::grammar<Iterator, storm::property::csl::CslFi (stateFormula[qi::_a = phoenix::construct<std::shared_ptr<storm::property::csl::AbstractStateFormula<double>>>(qi::_1)] >> qi::lit("U") >> (qi::lit(">=") | qi::lit(">")) > qi::double_ > stateFormula) [qi::_val = phoenix::new_<storm::property::csl::TimeBoundedUntil<double>>(qi::_2, std::numeric_limits<double>::infinity(), phoenix::bind(&storm::property::csl::AbstractStateFormula<double>::clone, phoenix::bind(&std::shared_ptr<storm::property::csl::AbstractStateFormula<double>>::get, qi::_a)), qi::_3)] ); - timeBoundedUntil.name("path formula (for probabilistic operator)"); + timeBoundedUntil.name("time bounded until"); until = (stateFormula[qi::_a = phoenix::construct<std::shared_ptr<storm::property::csl::AbstractStateFormula<double>>>(qi::_1)] >> qi::lit("U") > stateFormula)[qi::_val = phoenix::new_<storm::property::csl::Until<double>>(phoenix::bind(&storm::property::csl::AbstractStateFormula<double>::clone, phoenix::bind(&std::shared_ptr<storm::property::csl::AbstractStateFormula<double>>::get, qi::_a)), qi::_2)]; - until.name("path formula (for probabilistic operator)"); + until.name("until formula"); formula = (pathFormula | stateFormula); formula.name("CSL formula"); @@ -128,40 +126,35 @@ struct CslParser::CslGrammar : qi::grammar<Iterator, storm::property::csl::CslFi noBoundOperator.name("no bound operator"); probabilisticNoBoundOperator = (qi::lit("P") >> qi::lit("min") >> qi::lit("=") >> qi::lit("?") >> qi::lit("[") >> pathFormula >> qi::lit("]"))[qi::_val = - phoenix::new_<storm::property::csl::CslFilter<double>>(qi::_1, true)]; + phoenix::new_<storm::property::csl::CslFilter<double>>(qi::_1, storm::property::MINIMIZE)] | (qi::lit("P") >> qi::lit("max") >> qi::lit("=") >> qi::lit("?") >> qi::lit("[") >> pathFormula >> qi::lit("]"))[qi::_val = - phoenix::new_<storm::property::csl::CslFilter<double>>(qi::_1, false)]; + phoenix::new_<storm::property::csl::CslFilter<double>>(qi::_1, storm::property::MAXIMIZE)] | (qi::lit("P") >> qi::lit("=") >> qi::lit("?") >> qi::lit("[") >> pathFormula >> qi::lit("]"))[qi::_val = phoenix::new_<storm::property::csl::CslFilter<double>>(qi::_1)]; - probabilisticNoBoundOperator.name("no bound operator"); + probabilisticNoBoundOperator.name("probabilistic no bound operator"); steadyStateNoBoundOperator = (qi::lit("S") >> qi::lit("=") >> qi::lit("?") >> qi::lit("[") >> stateFormula >> qi::lit("]"))[qi::_val = - phoenix::new_<storm::property::csl::CslFilter<double>>(qi::_1)]; - steadyStateNoBoundOperator.name("no bound operator"); - - minMaxAction = qi::lit("minmax") >> qi::lit(",") >> ( - qi::lit("min")[qi::_val = - phoenix::new_<storm::property::action::MinMaxAction<double>>(true)] | - qi::lit("min")[qi::_val = - phoenix::new_<storm::property::action::MinMaxAction<double>>(false)]); - minMaxAction.name("minmax action for the formula filter"); + phoenix::new_<storm::property::csl::CslFilter<double>>(qi::_1, storm::property::UNDEFINED, true)]; + steadyStateNoBoundOperator.name("steady state no bound operator"); rangeAction = (qi::lit("range") >> qi::lit(",") >> qi::uint_ >> qi::lit(",") >> qi::uint_)[qi::_val = phoenix::new_<storm::property::action::RangeAction<double>>(qi::_1, qi::_2)]; rangeAction.name("range action for the formula filter"); - abstractAction = (rangeAction | minMaxAction) >> (qi::eps | qi::lit(",")); + abstractAction = (rangeAction) >> (qi::eps | qi::lit(",")); abstractAction.name("filter action"); filter = (qi::lit("filter") >> qi::lit("[") >> +abstractAction >> qi::lit("]") >> qi::lit("(") >> formula >> qi::lit(")"))[qi::_val = phoenix::new_<storm::property::csl::CslFilter<double>>(qi::_2, qi::_1)] | - (formula)[qi::_val = - phoenix::new_<storm::property::csl::CslFilter<double>>(qi::_1)] | (noBoundOperator)[qi::_val = - qi::_1]; - filter.name("PRCTL formula filter"); + qi::_1] | + (formula)[qi::_val = + phoenix::new_<storm::property::csl::CslFilter<double>>(qi::_1)]; + + filter.name("CSL formula filter"); start = (((filter) > (comment | qi::eps))[qi::_val = qi::_1] | comment ) > qi::eoi; - start.name("CSL formula filter"); + start.name("CSL formula filter start"); + } qi::rule<Iterator, storm::property::csl::CslFilter<double>*(), Skipper> start; @@ -173,7 +166,6 @@ struct CslParser::CslGrammar : qi::grammar<Iterator, storm::property::csl::CslFi qi::rule<Iterator, storm::property::action::AbstractAction<double>*(), Skipper> abstractAction; qi::rule<Iterator, storm::property::action::RangeAction<double>*(), Skipper> rangeAction; - qi::rule<Iterator, storm::property::action::MinMaxAction<double>*(), Skipper> minMaxAction; qi::rule<Iterator, storm::property::csl::AbstractCslFormula<double>*(), Skipper> formula; qi::rule<Iterator, storm::property::csl::AbstractCslFormula<double>*(), Skipper> comment; diff --git a/src/parser/PrctlParser.cpp b/src/parser/PrctlParser.cpp index d92cd6178..49bfe281b 100644 --- a/src/parser/PrctlParser.cpp +++ b/src/parser/PrctlParser.cpp @@ -4,7 +4,6 @@ // The action class headers. #include "src/formula/Actions/AbstractAction.h" -#include "src/formula/Actions/MinMaxAction.h" #include "src/formula/Actions/RangeAction.h" // If the parser fails due to ill-formed data, this exception is thrown. @@ -54,31 +53,31 @@ struct PrctlParser::PrctlGrammar : qi::grammar<Iterator, storm::property::prctl: stateFormula.name("state formula"); orFormula = andFormula[qi::_val = qi::_1] > *(qi::lit("|") > andFormula)[qi::_val = phoenix::new_<storm::property::prctl::Or<double>>(qi::_val, qi::_1)]; - orFormula.name("state formula"); + orFormula.name("or formula"); andFormula = notFormula[qi::_val = qi::_1] > *(qi::lit("&") > notFormula)[qi::_val = phoenix::new_<storm::property::prctl::And<double>>(qi::_val, qi::_1)]; - andFormula.name("state formula"); + andFormula.name("and formula"); notFormula = atomicStateFormula[qi::_val = qi::_1] | (qi::lit("!") > atomicStateFormula)[qi::_val = phoenix::new_<storm::property::prctl::Not<double>>(qi::_1)]; - notFormula.name("state formula"); + notFormula.name("not formula"); //This block defines rules for "atomic" state formulas //(Propositions, probabilistic/reward formulas, and state formulas in brackets) - atomicStateFormula %= probabilisticBoundOperator | rewardBoundOperator | atomicProposition | qi::lit("(") >> stateFormula >> qi::lit(")"); - atomicStateFormula.name("state formula"); + atomicStateFormula %= probabilisticBoundOperator | rewardBoundOperator | atomicProposition | qi::lit("(") >> stateFormula >> qi::lit(")") | qi::lit("[") >> stateFormula >> qi::lit("]"); + atomicStateFormula.name("atomic state formula"); atomicProposition = (freeIdentifierName)[qi::_val = phoenix::new_<storm::property::prctl::Ap<double>>(qi::_1)]; - atomicProposition.name("state formula"); + atomicProposition.name("atomic proposition"); probabilisticBoundOperator = ((qi::lit("P") >> comparisonType > qi::double_ > qi::lit("[") > pathFormula > qi::lit("]"))[qi::_val = phoenix::new_<storm::property::prctl::ProbabilisticBoundOperator<double> >(qi::_1, qi::_2, qi::_3)]); - probabilisticBoundOperator.name("state formula"); + probabilisticBoundOperator.name("probabilistic bound operator"); rewardBoundOperator = ((qi::lit("R") >> comparisonType > qi::double_ > qi::lit("[") > rewardPathFormula > qi::lit("]"))[qi::_val = phoenix::new_<storm::property::prctl::RewardBoundOperator<double> >(qi::_1, qi::_2, qi::_3)]); - rewardBoundOperator.name("state formula"); + rewardBoundOperator.name("reward bound operator"); //This block defines rules for parsing probabilistic path formulas - pathFormula = (boundedEventually | eventually | next | globally | boundedUntil | until); + pathFormula = (boundedEventually | eventually | next | globally | boundedUntil | until | qi::lit("(") >> pathFormula >> qi::lit(")") | qi::lit("[") >> pathFormula >> qi::lit("]")); pathFormula.name("path formula"); boundedEventually = (qi::lit("F") >> qi::lit("<=") > qi::int_ > stateFormula)[qi::_val = phoenix::new_<storm::property::prctl::BoundedEventually<double>>(qi::_2, qi::_1)]; @@ -100,7 +99,7 @@ struct PrctlParser::PrctlGrammar : qi::grammar<Iterator, storm::property::prctl: until.name("path formula (for probabilistic operator)"); //This block defines rules for parsing reward path formulas - rewardPathFormula = (cumulativeReward | reachabilityReward | instantaneousReward | steadyStateReward); + rewardPathFormula = (cumulativeReward | reachabilityReward | instantaneousReward | steadyStateReward | qi::lit("(") >> rewardPathFormula >> qi::lit(")") | qi::lit("[") >> rewardPathFormula >> qi::lit("]")); rewardPathFormula.name("path formula (for reward operator)"); cumulativeReward = (qi::lit("C") > qi::lit("<=") > qi::double_)[qi::_val = phoenix::new_<storm::property::prctl::CumulativeReward<double>>(qi::_1)]; @@ -122,50 +121,44 @@ struct PrctlParser::PrctlGrammar : qi::grammar<Iterator, storm::property::prctl: noBoundOperator = (probabilisticNoBoundOperator | rewardNoBoundOperator); noBoundOperator.name("no bound operator"); probabilisticNoBoundOperator = ( - (qi::lit("P") >> qi::lit("min") >> qi::lit("=") >> qi::lit("?") >> qi::lit("[") >> pathFormula >> qi::lit("]"))[qi::_val = - phoenix::new_<storm::property::prctl::PrctlFilter<double> >(qi::_1, true)] | - (qi::lit("P") >> qi::lit("max") >> qi::lit("=") >> qi::lit("?") >> qi::lit("[") >> pathFormula >> qi::lit("]"))[qi::_val = - phoenix::new_<storm::property::prctl::PrctlFilter<double> >(qi::_1, false)] | - (qi::lit("P") >> qi::lit("=") >> qi::lit("?") > qi::lit("[") > pathFormula > qi::lit("]"))[qi::_val = + (qi::lit("P") >> qi::lit("min") >> qi::lit("=") > qi::lit("?") >> pathFormula )[qi::_val = + phoenix::new_<storm::property::prctl::PrctlFilter<double> >(qi::_1, storm::property::MINIMIZE)] | + (qi::lit("P") >> qi::lit("max") >> qi::lit("=") > qi::lit("?") >> pathFormula )[qi::_val = + phoenix::new_<storm::property::prctl::PrctlFilter<double> >(qi::_1, storm::property::MAXIMIZE)] | + (qi::lit("P") >> qi::lit("=") > qi::lit("?") >> pathFormula )[qi::_val = phoenix::new_<storm::property::prctl::PrctlFilter<double> >(qi::_1)] ); probabilisticNoBoundOperator.name("no bound operator"); rewardNoBoundOperator = ( - (qi::lit("R") >> qi::lit("min") >> qi::lit("=") >> qi::lit("?") >> qi::lit("[") >> rewardPathFormula >> qi::lit("]"))[qi::_val = - phoenix::new_<storm::property::prctl::PrctlFilter<double> >(qi::_1, true)] | - (qi::lit("R") >> qi::lit("max") >> qi::lit("=") >> qi::lit("?") >> qi::lit("[") >> rewardPathFormula >> qi::lit("]"))[qi::_val = - phoenix::new_<storm::property::prctl::PrctlFilter<double> >(qi::_1, false)] | - (qi::lit("R") >> qi::lit("=") >> qi::lit("?") >> qi::lit("[") >> rewardPathFormula >> qi::lit("]"))[qi::_val = + (qi::lit("R") >> qi::lit("min") >> qi::lit("=") > qi::lit("?") >> rewardPathFormula )[qi::_val = + phoenix::new_<storm::property::prctl::PrctlFilter<double> >(qi::_1, storm::property::MINIMIZE)] | + (qi::lit("R") >> qi::lit("max") >> qi::lit("=") > qi::lit("?") >> rewardPathFormula )[qi::_val = + phoenix::new_<storm::property::prctl::PrctlFilter<double> >(qi::_1, storm::property::MAXIMIZE)] | + (qi::lit("R") >> qi::lit("=") >> qi::lit("?") >> rewardPathFormula )[qi::_val = phoenix::new_<storm::property::prctl::PrctlFilter<double> >(qi::_1)] ); rewardNoBoundOperator.name("no bound operator"); - minMaxAction = qi::lit("minmax") >> qi::lit(",") >> ( - qi::lit("min")[qi::_val = - phoenix::new_<storm::property::action::MinMaxAction<double>>(true)] | - qi::lit("min")[qi::_val = - phoenix::new_<storm::property::action::MinMaxAction<double>>(false)]); - minMaxAction.name("minmax action for the formula filter"); - rangeAction = (qi::lit("range") >> qi::lit(",") >> qi::uint_ >> qi::lit(",") >> qi::uint_)[qi::_val = phoenix::new_<storm::property::action::RangeAction<double>>(qi::_1, qi::_2)]; rangeAction.name("range action for the formula filter"); - abstractAction = (rangeAction | minMaxAction) >> (qi::eps | qi::lit(",")); + abstractAction = (rangeAction) >> (qi::eps | qi::lit(",")); abstractAction.name("filter action"); - filter = (qi::lit("filter") >> qi::lit("[") >> +abstractAction >> qi::lit("]") >> qi::lit("(") >> formula >> qi::lit(")"))[qi::_val = + filter = (qi::lit("filter") > qi::lit("[") >> +abstractAction >> qi::lit("]") >> qi::lit("(") >> formula >> qi::lit(")"))[qi::_val = phoenix::new_<storm::property::prctl::PrctlFilter<double>>(qi::_2, qi::_1)] | - (formula)[qi::_val = - phoenix::new_<storm::property::prctl::PrctlFilter<double>>(qi::_1)] | (noBoundOperator)[qi::_val = - qi::_1]; + qi::_1] | + (formula)[qi::_val = + phoenix::new_<storm::property::prctl::PrctlFilter<double>>(qi::_1)]; filter.name("PRCTL formula filter"); start = (((filter) > (comment | qi::eps))[qi::_val = qi::_1] | comment[qi::_val = nullptr]) > qi::eoi; start.name("PRCTL formula filter"); + } qi::rule<Iterator, storm::property::prctl::PrctlFilter<double>*(), Skipper> start; @@ -177,7 +170,6 @@ struct PrctlParser::PrctlGrammar : qi::grammar<Iterator, storm::property::prctl: qi::rule<Iterator, storm::property::action::AbstractAction<double>*(), Skipper> abstractAction; qi::rule<Iterator, storm::property::action::RangeAction<double>*(), Skipper> rangeAction; - qi::rule<Iterator, storm::property::action::MinMaxAction<double>*(), Skipper> minMaxAction; qi::rule<Iterator, storm::property::prctl::AbstractPrctlFormula<double>*(), Skipper> formula; qi::rule<Iterator, storm::property::prctl::AbstractPrctlFormula<double>*(), Skipper> comment; diff --git a/test/functional/modelchecker/SparseMdpPrctlModelCheckerTest.cpp b/test/functional/modelchecker/SparseMdpPrctlModelCheckerTest.cpp index 2fd8e148e..538bfc6f8 100644 --- a/test/functional/modelchecker/SparseMdpPrctlModelCheckerTest.cpp +++ b/test/functional/modelchecker/SparseMdpPrctlModelCheckerTest.cpp @@ -22,11 +22,11 @@ TEST(SparseMdpPrctlModelCheckerTest, Dice) { storm::property::prctl::Ap<double>* apFormula = new storm::property::prctl::Ap<double>("two"); storm::property::prctl::Eventually<double>* eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); - std::vector<double> result = mc.checkMinMaxOperator(*eventuallyFormula, true); + std::vector<double> result = mc.checkOptimizingOperator(*eventuallyFormula, true); ASSERT_LT(std::abs(result[0] - 0.0277777612209320068), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - result = mc.checkMinMaxOperator(*eventuallyFormula, false); + result = mc.checkOptimizingOperator(*eventuallyFormula, false); ASSERT_LT(std::abs(result[0] - 0.0277777612209320068), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); @@ -35,11 +35,11 @@ TEST(SparseMdpPrctlModelCheckerTest, Dice) { apFormula = new storm::property::prctl::Ap<double>("three"); eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); - result = mc.checkMinMaxOperator(*eventuallyFormula, true); + result = mc.checkOptimizingOperator(*eventuallyFormula, true); ASSERT_LT(std::abs(result[0] - 0.0555555224418640136), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - result = mc.checkMinMaxOperator(*eventuallyFormula, false); + result = mc.checkOptimizingOperator(*eventuallyFormula, false); ASSERT_LT(std::abs(result[0] - 0.0555555224418640136), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); @@ -48,11 +48,11 @@ TEST(SparseMdpPrctlModelCheckerTest, Dice) { apFormula = new storm::property::prctl::Ap<double>("four"); eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); - result = mc.checkMinMaxOperator(*eventuallyFormula, true); + result = mc.checkOptimizingOperator(*eventuallyFormula, true); ASSERT_LT(std::abs(result[0] - 0.083333283662796020508), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - result = mc.checkMinMaxOperator(*eventuallyFormula, false); + result = mc.checkOptimizingOperator(*eventuallyFormula, false); ASSERT_LT(std::abs(result[0] - 0.083333283662796020508), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); @@ -61,11 +61,11 @@ TEST(SparseMdpPrctlModelCheckerTest, Dice) { apFormula = new storm::property::prctl::Ap<double>("done"); storm::property::prctl::ReachabilityReward<double>* reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward<double>(apFormula); - result = mc.checkMinMaxOperator(*reachabilityRewardFormula, true); + result = mc.checkOptimizingOperator(*reachabilityRewardFormula, true); ASSERT_LT(std::abs(result[0] - 7.333329499), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - result = mc.checkMinMaxOperator(*reachabilityRewardFormula, false); + result = mc.checkOptimizingOperator(*reachabilityRewardFormula, false); ASSERT_LT(std::abs(result[0] - 7.333329499), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); @@ -82,11 +82,11 @@ TEST(SparseMdpPrctlModelCheckerTest, Dice) { apFormula = new storm::property::prctl::Ap<double>("done"); reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward<double>(apFormula); - result = mc.checkMinMaxOperator(*reachabilityRewardFormula, true); + result = mc.checkOptimizingOperator(*reachabilityRewardFormula, true); ASSERT_LT(std::abs(result[0] - 7.333329499), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - result = mc.checkMinMaxOperator(*reachabilityRewardFormula, false); + result = mc.checkOptimizingOperator(*reachabilityRewardFormula, false); ASSERT_LT(std::abs(result[0] - 7.333329499), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); @@ -103,11 +103,11 @@ TEST(SparseMdpPrctlModelCheckerTest, Dice) { apFormula = new storm::property::prctl::Ap<double>("done"); reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward<double>(apFormula); - result = mc.checkMinMaxOperator(*reachabilityRewardFormula, true); + result = mc.checkOptimizingOperator(*reachabilityRewardFormula, true); ASSERT_LT(std::abs(result[0] - 14.666658998), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - result = mc.checkMinMaxOperator(*reachabilityRewardFormula, false); + result = mc.checkOptimizingOperator(*reachabilityRewardFormula, false); ASSERT_LT(std::abs(result[0] - 14.666658998), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); @@ -130,11 +130,11 @@ TEST(SparseMdpPrctlModelCheckerTest, AsynchronousLeader) { storm::property::prctl::Ap<double>* apFormula = new storm::property::prctl::Ap<double>("elected"); storm::property::prctl::Eventually<double>* eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); - std::vector<double> result = mc.checkMinMaxOperator(*eventuallyFormula, true); + std::vector<double> result = mc.checkOptimizingOperator(*eventuallyFormula, true); ASSERT_LT(std::abs(result[0] - 1), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - result = mc.checkMinMaxOperator(*eventuallyFormula, false); + result = mc.checkOptimizingOperator(*eventuallyFormula, false); ASSERT_LT(std::abs(result[0] - 1), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); @@ -143,11 +143,11 @@ TEST(SparseMdpPrctlModelCheckerTest, AsynchronousLeader) { apFormula = new storm::property::prctl::Ap<double>("elected"); storm::property::prctl::BoundedEventually<double>* boundedEventuallyFormula = new storm::property::prctl::BoundedEventually<double>(apFormula, 25); - result = mc.checkMinMaxOperator(*boundedEventuallyFormula, true); + result = mc.checkOptimizingOperator(*boundedEventuallyFormula, true); ASSERT_LT(std::abs(result[0] - 0.0625), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - result = mc.checkMinMaxOperator(*boundedEventuallyFormula, false); + result = mc.checkOptimizingOperator(*boundedEventuallyFormula, false); ASSERT_LT(std::abs(result[0] - 0.0625), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); @@ -156,11 +156,11 @@ TEST(SparseMdpPrctlModelCheckerTest, AsynchronousLeader) { apFormula = new storm::property::prctl::Ap<double>("elected"); storm::property::prctl::ReachabilityReward<double>* reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward<double>(apFormula); - result = mc.checkMinMaxOperator(*reachabilityRewardFormula, true); + result = mc.checkOptimizingOperator(*reachabilityRewardFormula, true); ASSERT_LT(std::abs(result[0] - 4.285689611), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - result = mc.checkMinMaxOperator(*reachabilityRewardFormula, false); + result = mc.checkOptimizingOperator(*reachabilityRewardFormula, false); ASSERT_LT(std::abs(result[0] - 4.285689611), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); diff --git a/test/functional/parser/CslParserTest.cpp b/test/functional/parser/CslParserTest.cpp index 9b8ad7ea9..929d72c71 100644 --- a/test/functional/parser/CslParserTest.cpp +++ b/test/functional/parser/CslParserTest.cpp @@ -58,7 +58,7 @@ TEST(CslParserTest, parseProbabilisticFormulaTest) { ASSERT_EQ(0.5, op->getBound()); // Test the string representation for the parsed formula. - ASSERT_EQ("P > 0.500000 [F a]", formula->toString()); + ASSERT_EQ("P > 0.500000 (F a)", formula->toString()); delete formula; } @@ -78,7 +78,7 @@ TEST(CslParserTest, parseSteadyStateBoundFormulaTest) { ASSERT_EQ(15.0, op->getBound()); // Test the string representation for the parsed formula. - ASSERT_EQ("S >= 15.000000 [P < 0.200000 [a U[0.000000,3.000000] b]]", formula->toString()); + ASSERT_EQ("S >= 15.000000 (P < 0.200000 (a U[0.000000,3.000000] b))", formula->toString()); delete formula; } @@ -94,7 +94,7 @@ TEST(CslParserTest, parseSteadyStateNoBoundFormulaTest) { ASSERT_NE(formula, nullptr); // The input was parsed correctly. - ASSERT_EQ("S = ? [P <= 0.500000 [F[0.000000,3.000000] a]]", formula->toString()); + ASSERT_EQ("S = ? (P <= 0.500000 (F[0.000000,3.000000] a))", formula->toString()); delete formula; } @@ -110,7 +110,7 @@ TEST(CslParserTest, parseProbabilisticNoBoundFormulaTest) { ASSERT_NE(formula, nullptr); // The input was parsed correctly. - ASSERT_EQ("P = ? [a U[3.000000,4.000000] (b & !c)]", formula->toString()); + ASSERT_EQ("P = ? (a U[3.000000,4.000000] (b & !c))", formula->toString()); delete formula; } @@ -127,7 +127,7 @@ TEST(CslParserTest, parseComplexFormulaTest) { ASSERT_NE(formula, nullptr); // The input was parsed correctly. - ASSERT_EQ("(S <= 0.500000 [P <= 0.500000 [a U c]] & (P > 0.500000 [G b] | !P < 0.400000 [G P > 0.900000 [F>=7.000000 (a & b)]]))", formula->toString()); + ASSERT_EQ("(S <= 0.500000 (P <= 0.500000 (a U c)) & (P > 0.500000 (G b) | !P < 0.400000 (G P > 0.900000 (F>=7.000000 (a & b)))))", formula->toString()); delete formula; } diff --git a/test/functional/parser/PrctlParserTest.cpp b/test/functional/parser/PrctlParserTest.cpp index 5db06c465..49b618ee7 100644 --- a/test/functional/parser/PrctlParserTest.cpp +++ b/test/functional/parser/PrctlParserTest.cpp @@ -63,7 +63,7 @@ TEST(PrctlParserTest, parseProbabilisticFormulaTest) { ASSERT_EQ(0.5, op->getBound()); // Test the string representation for the parsed formula. - ASSERT_EQ("P > 0.500000 [F a]", formula->toString()); + ASSERT_EQ("P > 0.500000 (F a)", formula->toString()); delete formula; @@ -86,7 +86,7 @@ TEST(PrctlParserTest, parseRewardFormulaTest) { ASSERT_EQ(15.0, op->getBound()); // Test the string representation for the parsed formula. - ASSERT_EQ("R >= 15.000000 [I=5]", formula->toString()); + ASSERT_EQ("R >= 15.000000 (I=5)", formula->toString()); delete formula; } @@ -102,7 +102,7 @@ TEST(PrctlParserTest, parseRewardNoBoundFormulaTest) { ASSERT_NE(formula, nullptr); // The input was parsed correctly. - ASSERT_EQ("R = ? [F a]", formula->toString()); + ASSERT_EQ("R = ? (F a)", formula->toString()); delete formula; } @@ -118,7 +118,7 @@ TEST(PrctlParserTest, parseProbabilisticNoBoundFormulaTest) { ASSERT_NE(formula, nullptr); // The input was parsed correctly. - ASSERT_EQ("P = ? [a U<=4 (b & !c)]", formula->toString()); + ASSERT_EQ("P = ? (a U<=4 (b & !c))", formula->toString()); delete formula; } @@ -134,7 +134,7 @@ TEST(PrctlParserTest, parseComplexFormulaTest) { ASSERT_NE(formula, nullptr); // The input was parsed correctly. - ASSERT_EQ("(R <= 0.500000 [S] & (R > 15.000000 [C <= 0.500000] | !P < 0.400000 [G P > 0.900000 [F<=7 (a & b)]]))", formula->toString()); + ASSERT_EQ("(R <= 0.500000 (S) & (R > 15.000000 (C <= 0.500000) | !P < 0.400000 (G P > 0.900000 (F<=7 (a & b)))))", formula->toString()); delete formula; } diff --git a/test/performance/modelchecker/SparseMdpPrctlModelCheckerTest.cpp b/test/performance/modelchecker/SparseMdpPrctlModelCheckerTest.cpp index 98db638df..259fb6c73 100644 --- a/test/performance/modelchecker/SparseMdpPrctlModelCheckerTest.cpp +++ b/test/performance/modelchecker/SparseMdpPrctlModelCheckerTest.cpp @@ -22,11 +22,11 @@ TEST(SparseMdpPrctlModelCheckerTest, AsynchronousLeader) { storm::property::prctl::Ap<double>* apFormula = new storm::property::prctl::Ap<double>("elected"); storm::property::prctl::Eventually<double>* eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); - std::vector<double> result = mc.checkMinMaxOperator(*eventuallyFormula, true); + std::vector<double> result = mc.checkOptimizingOperator(*eventuallyFormula, true); ASSERT_LT(std::abs(result[0] - 1.0), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - result = mc.checkMinMaxOperator(*eventuallyFormula, false); + result = mc.checkOptimizingOperator(*eventuallyFormula, false); ASSERT_LT(std::abs(result[0] - 1.0), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); @@ -35,11 +35,11 @@ TEST(SparseMdpPrctlModelCheckerTest, AsynchronousLeader) { apFormula = new storm::property::prctl::Ap<double>("elected"); storm::property::prctl::BoundedEventually<double>* boundedEventuallyFormula = new storm::property::prctl::BoundedEventually<double>(apFormula, 25); - result = mc.checkMinMaxOperator(*boundedEventuallyFormula, true); + result = mc.checkOptimizingOperator(*boundedEventuallyFormula, true); ASSERT_LT(std::abs(result[0] - 0.0), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - result = mc.checkMinMaxOperator(*boundedEventuallyFormula, false); + result = mc.checkOptimizingOperator(*boundedEventuallyFormula, false); ASSERT_LT(std::abs(result[0] - 0.0), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); @@ -48,11 +48,11 @@ TEST(SparseMdpPrctlModelCheckerTest, AsynchronousLeader) { apFormula = new storm::property::prctl::Ap<double>("elected"); storm::property::prctl::ReachabilityReward<double>* reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward<double>(apFormula); - result = mc.checkMinMaxOperator(*reachabilityRewardFormula, true); + result = mc.checkOptimizingOperator(*reachabilityRewardFormula, true); ASSERT_LT(std::abs(result[0] - 6.172433512), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - result = mc.checkMinMaxOperator(*reachabilityRewardFormula, false); + result = mc.checkOptimizingOperator(*reachabilityRewardFormula, false); ASSERT_LT(std::abs(result[0] - 6.1724344), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); @@ -78,7 +78,7 @@ TEST(SparseMdpPrctlModelCheckerTest, Consensus) { storm::property::prctl::Ap<double>* apFormula = new storm::property::prctl::Ap<double>("finished"); storm::property::prctl::Eventually<double>* eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); - std::vector<double> result = mc.checkMinMaxOperator(*eventuallyFormula, true); + std::vector<double> result = mc.checkOptimizingOperator(*eventuallyFormula, true); ASSERT_LT(std::abs(result[31168] - 1.0), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); @@ -89,7 +89,7 @@ TEST(SparseMdpPrctlModelCheckerTest, Consensus) { storm::property::prctl::And<double>* andFormula = new storm::property::prctl::And<double>(apFormula, apFormula2); eventuallyFormula = new storm::property::prctl::Eventually<double>(andFormula); - result = mc.checkMinMaxOperator(*eventuallyFormula, true); + result = mc.checkOptimizingOperator(*eventuallyFormula, true); ASSERT_LT(std::abs(result[31168] - 0.4374282832), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); @@ -100,7 +100,7 @@ TEST(SparseMdpPrctlModelCheckerTest, Consensus) { andFormula = new storm::property::prctl::And<double>(apFormula, apFormula2); eventuallyFormula = new storm::property::prctl::Eventually<double>(andFormula); - result = mc.checkMinMaxOperator(*eventuallyFormula, false); + result = mc.checkOptimizingOperator(*eventuallyFormula, false); ASSERT_LT(std::abs(result[31168] - 0.5293286369), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); @@ -112,7 +112,7 @@ TEST(SparseMdpPrctlModelCheckerTest, Consensus) { andFormula = new storm::property::prctl::And<double>(apFormula, notFormula); eventuallyFormula = new storm::property::prctl::Eventually<double>(andFormula); - result = mc.checkMinMaxOperator(*eventuallyFormula, false); + result = mc.checkOptimizingOperator(*eventuallyFormula, false); ASSERT_LT(std::abs(result[31168] - 0.10414097), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); @@ -121,11 +121,11 @@ TEST(SparseMdpPrctlModelCheckerTest, Consensus) { apFormula = new storm::property::prctl::Ap<double>("finished"); storm::property::prctl::BoundedEventually<double>* boundedEventuallyFormula = new storm::property::prctl::BoundedEventually<double>(apFormula, 50ull); - result = mc.checkMinMaxOperator(*boundedEventuallyFormula, true); + result = mc.checkOptimizingOperator(*boundedEventuallyFormula, true); ASSERT_LT(std::abs(result[31168] - 0.0), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - result = mc.checkMinMaxOperator(*boundedEventuallyFormula, false); + result = mc.checkOptimizingOperator(*boundedEventuallyFormula, false); ASSERT_LT(std::abs(result[31168] - 0.0), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); @@ -134,11 +134,11 @@ TEST(SparseMdpPrctlModelCheckerTest, Consensus) { apFormula = new storm::property::prctl::Ap<double>("finished"); storm::property::prctl::ReachabilityReward<double>* reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward<double>(apFormula); - result = mc.checkMinMaxOperator(*reachabilityRewardFormula, true); + result = mc.checkOptimizingOperator(*reachabilityRewardFormula, true); ASSERT_LT(std::abs(result[31168] - 1725.593313), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - result = mc.checkMinMaxOperator(*reachabilityRewardFormula, false); + result = mc.checkOptimizingOperator(*reachabilityRewardFormula, false); ASSERT_LT(std::abs(result[31168] - 2183.142422), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); From 3271e73f01b9a317883f19284ac4a4cb236f3871 Mon Sep 17 00:00:00 2001 From: masawei <manuel.sascha.weiand@rwth-aachen.de> Date: Fri, 30 May 2014 23:49:14 +0200 Subject: [PATCH 13/30] Fixed the last test. All tests green now (well, except the ones that need gurobi, which I don't have). Former-commit-id: 7636a2a6ab1101720fe5ef68ecbc934358423a69 --- .../modelchecker/SparseMdpPrctlModelCheckerTest.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/functional/modelchecker/SparseMdpPrctlModelCheckerTest.cpp b/test/functional/modelchecker/SparseMdpPrctlModelCheckerTest.cpp index 538bfc6f8..f3d817c9f 100644 --- a/test/functional/modelchecker/SparseMdpPrctlModelCheckerTest.cpp +++ b/test/functional/modelchecker/SparseMdpPrctlModelCheckerTest.cpp @@ -82,11 +82,11 @@ TEST(SparseMdpPrctlModelCheckerTest, Dice) { apFormula = new storm::property::prctl::Ap<double>("done"); reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward<double>(apFormula); - result = mc.checkOptimizingOperator(*reachabilityRewardFormula, true); + result = stateRewardModelChecker.checkOptimizingOperator(*reachabilityRewardFormula, true); ASSERT_LT(std::abs(result[0] - 7.333329499), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - result = mc.checkOptimizingOperator(*reachabilityRewardFormula, false); + result = stateRewardModelChecker.checkOptimizingOperator(*reachabilityRewardFormula, false); ASSERT_LT(std::abs(result[0] - 7.333329499), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); @@ -103,11 +103,11 @@ TEST(SparseMdpPrctlModelCheckerTest, Dice) { apFormula = new storm::property::prctl::Ap<double>("done"); reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward<double>(apFormula); - result = mc.checkOptimizingOperator(*reachabilityRewardFormula, true); + result = stateAndTransitionRewardModelChecker.checkOptimizingOperator(*reachabilityRewardFormula, true); ASSERT_LT(std::abs(result[0] - 14.666658998), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - result = mc.checkOptimizingOperator(*reachabilityRewardFormula, false); + result = stateAndTransitionRewardModelChecker.checkOptimizingOperator(*reachabilityRewardFormula, false); ASSERT_LT(std::abs(result[0] - 14.666658998), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); From a5e28fcf04ab1b27edb5c9ad01793317ea56ef29 Mon Sep 17 00:00:00 2001 From: masawei <manuel.sascha.weiand@rwth-aachen.de> Date: Sun, 22 Jun 2014 22:26:47 +0200 Subject: [PATCH 14/30] Added some filter actions. - Also major cleanup of the filter. - Implementation clompleted for pctl. Next up: Wrap up the Csl and Ltl filter and then testing. Former-commit-id: 8189f8462c9ecbcf5b842090be350d180726ca90 --- src/formula/AbstractFilter.h | 1 + src/formula/Actions/AbstractAction.h | 61 ++++++- src/formula/Actions/BoundAction.h | 167 +++++++++++++++++ src/formula/Actions/InvertAction.h | 80 +++++++++ src/formula/Actions/RangeAction.h | 80 +++++---- src/formula/Actions/SortAction.h | 174 ++++++++++++++++++ src/formula/Csl/CslFilter.h | 18 -- src/formula/Prctl/PrctlFilter.h | 257 ++++++++++++--------------- src/parser/CslParser.cpp | 47 ++++- src/parser/PrctlParser.cpp | 74 ++++++-- 10 files changed, 742 insertions(+), 217 deletions(-) create mode 100644 src/formula/Actions/BoundAction.h create mode 100644 src/formula/Actions/InvertAction.h create mode 100644 src/formula/Actions/SortAction.h diff --git a/src/formula/AbstractFilter.h b/src/formula/AbstractFilter.h index fe9798fca..ba95d5524 100644 --- a/src/formula/AbstractFilter.h +++ b/src/formula/AbstractFilter.h @@ -9,6 +9,7 @@ #define STORM_FORMULA_ABSTRACTFILTER_H_ #include <vector> +#include <string> #include "src/formula/AbstractFormula.h" #include "src/formula/Actions/AbstractAction.h" diff --git a/src/formula/Actions/AbstractAction.h b/src/formula/Actions/AbstractAction.h index c58ad6be0..77d2089ea 100644 --- a/src/formula/Actions/AbstractAction.h +++ b/src/formula/Actions/AbstractAction.h @@ -9,7 +9,11 @@ #define STORM_FORMULA_ACTION_ABSTRACTACTION_H_ #include <vector> +#include <utility> #include "src/storage/BitVector.h" +#include "src/modelchecker/prctl/AbstractModelChecker.h" +#include "src/modelchecker/csl/AbstractModelChecker.h" +#include "src/modelchecker/ltl/AbstractModelChecker.h" namespace storm { namespace property { @@ -20,6 +24,42 @@ class AbstractAction { public: + struct Result { + + /*! + * + */ + Result() : selection(), stateMap(), pathResult(), stateResult(){ + // Intentionally left empty. + } + + /*! + * + */ + Result(Result const & other) : selection(other.selection), stateMap(other.stateMap), pathResult(other.pathResult), stateResult(other.stateResult) { + // Intentionally left empty. + } + + /*! + * + */ + Result(storm::storage::BitVector const & selection, std::vector<uint_fast64_t> const & stateMap, std::vector<T> const & pathResult, storm::storage::BitVector const & stateResult) : selection(selection), stateMap(stateMap), pathResult(pathResult), stateResult(stateResult) { + // Intentionally left empty. + } + + //! + storm::storage::BitVector selection; + + //! + std::vector<uint_fast64_t> stateMap; + + //! + std::vector<T> pathResult; + + //! + storm::storage::BitVector stateResult; + }; + /*! * Virtual destructor * To ensure that the right destructor is called @@ -28,29 +68,32 @@ public: //Intentionally left empty } - /*! + /* * */ - virtual std::vector<T> evaluate(std::vector<T> input) const { - return input; + virtual Result evaluate(Result const & filterResult, storm::modelchecker::prctl::AbstractModelChecker<T> const & mc) const { + return Result(); } - /*! + /* * */ - virtual storm::storage::BitVector evaluate(storm::storage::BitVector input) const { - return input; + virtual Result evaluate(Result const & filterResult, storm::modelchecker::csl::AbstractModelChecker<T> const & mc) const { + return Result(); } - /*! + /* * */ - virtual std::string toString() const = 0; + virtual Result evaluate(Result const & filterResult, storm::modelchecker::ltl::AbstractModelChecker<T> const & mc) const { + return Result(); + } /*! * */ - virtual std::string toFormulaString() const = 0; + virtual std::string toString() const = 0; + }; } //namespace action diff --git a/src/formula/Actions/BoundAction.h b/src/formula/Actions/BoundAction.h new file mode 100644 index 000000000..4b7f77cc0 --- /dev/null +++ b/src/formula/Actions/BoundAction.h @@ -0,0 +1,167 @@ +/* + * BoundAction.h + * + * Created on: Jun 22, 2014 + * Author: Manuel Sascha Weiand + */ + +#ifndef STORM_FORMULA_ACTION_BOUNDACTION_H_ +#define STORM_FORMULA_ACTION_BOUNDACTION_H_ + +#include "src/formula/Actions/AbstractAction.h" +#include "src/formula/ComparisonType.h" + +namespace storm { +namespace property { +namespace action { + +template <class T> +class BoundAction : public AbstractAction<T> { + + typedef typename AbstractAction<T>::Result Result; + +public: + + BoundAction() : comparisonOperator(storm::property::GREATER_EQUAL), bound(0) { + //Intentionally left empty. + } + + BoundAction(storm::property::ComparisonType comparisonOperator, T bound) : comparisonOperator(comparisonOperator), bound(bound) { + //Intentionally left empty. + } + + /*! + * Virtual destructor + * To ensure that the right destructor is called + */ + virtual ~BoundAction() { + //Intentionally left empty + } + + /*! + * + */ + virtual Result evaluate(Result const & result, storm::modelchecker::prctl::AbstractModelChecker<T> const & mc) const override { + return evaluate(result); + } + + /*! + * + */ + virtual Result evaluate(Result const & result, storm::modelchecker::csl::AbstractModelChecker<T> const & mc) const override { + return evaluate(result); + } + + /*! + * + */ + virtual Result evaluate(Result const & result, storm::modelchecker::ltl::AbstractModelChecker<T> const & mc) const override { + return evaluate(result); + } + + /*! + * + */ + virtual std::string toString() const override { + std::string out = "bound("; + switch (comparisonOperator) { + case LESS: + out += "<"; + break; + case LESS_EQUAL: + out += "<="; + break; + case GREATER: + out += ">"; + break; + case GREATER_EQUAL: + out += ">="; + break; + default: + LOG4CPLUS_INFO(logger, "Unknown comparison operator of value " << comparisonOperator << "."); + std::cout << "Unknown comparison operator of value " << comparisonOperator << "." << std::endl; + break; + } + out += ", "; + out += std::to_string(bound); + out += ")"; + return out; + } + +private: + + /*! + * + */ + virtual Result evaluate(Result const & result) const { + + //Initialize the new selection vector. + storm::storage::BitVector out(result.selection.size()); + + if(result.pathResult.size() != 0) { + + //Fill the selction by comapring the values for all previously selected states with theegiven bound using the comparison operator. + for(uint_fast64_t i = 0; i < result.stateMap.size(); i++) { + if(result.selection[result.stateMap[i]]) { + switch(comparisonOperator) { + case storm::property::GREATER_EQUAL: + out.set(result.pathResult[result.stateMap[i]] >= bound); + break; + case storm::property::GREATER: + out.set(result.pathResult[result.stateMap[i]] > bound); + break; + case storm::property::LESS_EQUAL: + out.set(result.pathResult[result.stateMap[i]] <= bound); + break; + case storm::property::LESS: + out.set(result.pathResult[result.stateMap[i]] < bound); + break; + default: + LOG4CPLUS_INFO(logger, "Unknown comparison operator of value " << comparisonOperator << "."); + std::cout << "Unknown comparison operator of value " << comparisonOperator << "." << std::endl; + break; + } + } + } + } else { + + //Fill the selction by comapring the values for all previously selected states with theegiven bound using the comparison operator. + for(uint_fast64_t i = 0; i < result.stateMap.size(); i++) { + if(result.selection[result.stateMap[i]]) { + switch(comparisonOperator) { + case storm::property::GREATER_EQUAL: + out.set(result.stateResult[result.stateMap[i]] >= bound); + break; + case storm::property::GREATER: + out.set(result.stateResult[result.stateMap[i]] > bound); + break; + case storm::property::LESS_EQUAL: + out.set(result.stateResult[result.stateMap[i]] <= bound); + break; + case storm::property::LESS: + out.set(result.stateResult[result.stateMap[i]] < bound); + break; + default: + LOG4CPLUS_INFO(logger, "Unknown comparison operator of value " << comparisonOperator << "."); + std::cout << "Unknown comparison operator of value " << comparisonOperator << "." << std::endl; + break; + } + } + } + } + + return Result(out, result.stateMap, result.pathResult, result.stateResult); + } + + storm::property::ComparisonType comparisonOperator; + T bound; + +}; + + +} +} +} + + +#endif /* STORM_FORMULA_ACTION_BOUNDACTION_H_ */ diff --git a/src/formula/Actions/InvertAction.h b/src/formula/Actions/InvertAction.h new file mode 100644 index 000000000..90192020c --- /dev/null +++ b/src/formula/Actions/InvertAction.h @@ -0,0 +1,80 @@ +/* + * InvertAction.h + * + * Created on: Jun 22, 2014 + * Author: Manuel Sascha Weiand + */ + +#ifndef STORM_FORMULA_ACTION_INVERTACTION_H_ +#define STORM_FORMULA_ACTION_INVERTACTION_H_ + +#include "src/formula/Actions/AbstractAction.h" + +namespace storm { +namespace property { +namespace action { + +template <class T> +class InvertAction : public AbstractAction<T> { + + typedef typename AbstractAction<T>::Result Result; + +public: + + InvertAction() { + //Intentionally left empty. + } + + /*! + * Virtual destructor + * To ensure that the right destructor is called + */ + virtual ~InvertAction() { + //Intentionally left empty + } + + /*! + * + */ + virtual Result evaluate(Result const & result, storm::modelchecker::prctl::AbstractModelChecker<T> const & mc) const override { + return evaluate(result); + } + + /*! + * + */ + virtual Result evaluate(Result const & result, storm::modelchecker::csl::AbstractModelChecker<T> const & mc) const override { + return evaluate(result); + } + + /*! + * + */ + virtual Result evaluate(Result const & result, storm::modelchecker::ltl::AbstractModelChecker<T> const & mc) const override { + return evaluate(result); + } + + /*! + * + */ + virtual std::string toString() const override { + return "invert"; + } + +private: + + /*! + * + */ + virtual Result evaluate(Result const & result) const { + storm::storage::BitVector out(result.selection); + return Result(~out, result.stateMap, result.pathResult, result.stateResult); + } +}; + +} //namespace action +} //namespace property +} //namespace storm + + +#endif /* STORM_FORMULA_ACTION_INVERTACTION_H_ */ diff --git a/src/formula/Actions/RangeAction.h b/src/formula/Actions/RangeAction.h index 3952419ae..ce8b0e2ae 100644 --- a/src/formula/Actions/RangeAction.h +++ b/src/formula/Actions/RangeAction.h @@ -10,8 +10,6 @@ #include "src/formula/Actions/AbstractAction.h" -#include <string> - namespace storm { namespace property { namespace action { @@ -19,14 +17,21 @@ namespace action { template <class T> class RangeAction : public AbstractAction<T> { + typedef typename AbstractAction<T>::Result Result; + public: RangeAction() : from(0), to(0) { //Intentionally left empty. } + /*! + * Excluding the state with position to. + */ RangeAction(uint_fast64_t from, uint_fast64_t to) : from(from), to(to) { - //Intentionally left empty. + if(from > to) { + throw storm::exceptions::IllegalArgumentException() << "The end of the range is lower than its beginning"; + } } /*! @@ -40,56 +45,71 @@ public: /*! * */ - virtual std::vector<T> evaluate(std::vector<T> input) const override { - // The range constructor is used here instead of manipulating the incoming vector. - // While deleting the element at the end of the vector is efficient, deleting elements at any position but the end is not. - // Also this leaves the incoming vector unchanged. - std::vector<T> out(input.begin() + from, input.begin() + to); - return out; + virtual Result evaluate(Result const & result, storm::modelchecker::prctl::AbstractModelChecker<T> const & mc) const override { + return evaluate(result); } /*! * */ - virtual storm::storage::BitVector evaluate(storm::storage::BitVector input) const override { - //Initialize the output vector. - storm::storage::BitVector out(to - from + 1); - - storm::storage::BitVector::const_iterator it = input.begin(); - - //Proceed the set index iterator to the first set bit within the range. - for(; *it < from; ++it); + virtual Result evaluate(Result const & result, storm::modelchecker::csl::AbstractModelChecker<T> const & mc) const override { + return evaluate(result); + } - //Fill the output vector. - for(; *it <= to; ++it) { - out.set(*it-from); - } - return out; + /*! + * + */ + virtual Result evaluate(Result const & result, storm::modelchecker::ltl::AbstractModelChecker<T> const & mc) const override { + return evaluate(result); } /*! * */ virtual std::string toString() const override { - std::string out = "range, "; + std::string out = "range("; out += std::to_string(from); out += ", "; out += std::to_string(to); + out += ")"; return out; } +private: + /*! * */ - virtual std::string toFormulaString() const override { - std::string out = "\"range\", "; - out += std::to_string(from); - out += ", "; - out += std::to_string(to); - return out; + virtual Result evaluate(Result const & result) const { + //Initialize the output vector. + storm::storage::BitVector out(result.selection.size()); + + uint_fast64_t end = to - from; + + // Safety check for access bounds. + if(from > result.stateMap.size()) { + LOG4CPLUS_WARN(logger, "Range begins behind the end of the states by " << to - result.stateMap.size() << ". No state was selected."); + std::cout << "Range begins behind the end of the states by " << to - result.stateMap.size() << ". No state was selected." << std::endl; + + return Result(out, result.stateMap, result.pathResult, result.stateResult); + } + + if(to > result.stateMap.size()) { + + end = result.selection.size() - from; + + LOG4CPLUS_WARN(logger, "Range ends behind the end of the states by " << to - result.stateMap.size() << ". The range has been cut at the last state."); + std::cout << "Range ends behind the end of the states by " << to - result.stateMap.size() << ". The range has been cut at the last state." << std::endl; + } + + //Fill the output vector. + for(uint_fast64_t i=0; i < end; i++) { + out.set(result.stateMap[from + i], result.selection[result.stateMap[from + i]]); + } + + return Result(out, result.stateMap, result.pathResult, result.stateResult); } -private: uint_fast64_t from; uint_fast64_t to; diff --git a/src/formula/Actions/SortAction.h b/src/formula/Actions/SortAction.h new file mode 100644 index 000000000..5a4c1c622 --- /dev/null +++ b/src/formula/Actions/SortAction.h @@ -0,0 +1,174 @@ +/* + * SortAction.h + * + * Created on: Jun 22, 2014 + * Author: Manuel Sascha Weiand + */ + +#ifndef STORM_FORMULA_ACTION_SORTACTION_H_ +#define STORM_FORMULA_ACTION_SORTACTION_H_ + +#include "src/formula/Actions/AbstractAction.h" +#include <cctype> + +namespace storm { +namespace property { +namespace action { + +template <class T> +class SortAction : public AbstractAction<T> { + + typedef typename AbstractAction<T>::Result Result; + +public: + + enum SortingCategory {INDEX, VALUE}; + + SortAction() : category(INDEX), ascending(true) { + //Intentionally left empty. + } + + SortAction(SortingCategory category, bool ascending = true) : category(category), ascending(ascending) { + //Intentionally left empty. + } + + /*! + * Virtual destructor + * To ensure that the right destructor is called + */ + virtual ~SortAction() { + //Intentionally left empty + } + + /*! + * + */ + virtual Result evaluate(Result const & result, storm::modelchecker::prctl::AbstractModelChecker<T> const & mc) const override { + return evaluate(result); + } + + /*! + * + */ + virtual Result evaluate(Result const & result, storm::modelchecker::csl::AbstractModelChecker<T> const & mc) const override { + return evaluate(result); + } + + /*! + * + */ + virtual Result evaluate(Result const & result, storm::modelchecker::ltl::AbstractModelChecker<T> const & mc) const override { + return evaluate(result); + } + + /*! + * + */ + virtual std::string toString() const override { + std::string out = "sort, "; + switch (category) { + case INDEX: + out += "index"; + break; + case VALUE: + out += "value"; + break; + default: + LOG4CPLUS_INFO(logger, "Unknown sorting category of value " << category << "."); + std::cout << "Unknown sorting category of value " << category << "." << std::endl; + break; + } + out += ", "; + out += ascending ? "ascending" : "descending"; + return out; + } + + +private: + + /*! + * + */ + Result evaluate(Result const & result) const { + + if(category == VALUE) { + //TODO + + if(result.pathResult.size() != 0) { + return Result(result.selection, sort(result.stateMap, result.pathResult), result.pathResult, result.stateResult); + } else { + return Result(result.selection, sort(result.stateMap, result.stateResult), result.pathResult, result.stateResult); + } + + } else { + return Result(result.selection, sort(result.stateMap.size()), result.pathResult, result.stateResult); + } + } + + /*! + * + */ + std::vector<uint_fast64_t> sort(uint_fast64_t length) const { + + // Project the vector down to its first component. + std::vector<uint_fast64_t> outMap(length); + + // Sort the combined vector. + if(ascending) { + for(uint_fast64_t i = 0; i < length; i++) { + outMap[i] = i; + } + } else { + for(uint_fast64_t i = 0; i < length; i++) { + outMap[i] = length - i - 1; + } + } + + return outMap; + } + + /*! + * + */ + std::vector<uint_fast64_t> sort(std::vector<uint_fast64_t> const & stateMap, std::vector<T> const & values) const { + + // Prepare the new state map. + std::vector<uint_fast64_t> outMap(stateMap); + + // Sort the state map. + if(ascending) { + std::sort(outMap.begin(), outMap.end(), [&] (uint_fast64_t a, uint_fast64_t b) -> bool { return values[a] <= values[b]; }); + } else { + std::sort(outMap.begin(), outMap.end(), [&] (uint_fast64_t a, uint_fast64_t b) -> bool { return values[a] >= values[b]; }); + } + + return outMap; + } + + /*! + * + */ + std::vector<uint_fast64_t> sort(std::vector<uint_fast64_t> const & stateMap, storm::storage::BitVector const & values) const { + + // Prepare the new state map. + std::vector<uint_fast64_t> outMap(stateMap); + + // Sort the state map. + if(ascending) { + std::sort(outMap.begin(), outMap.end(), [&] (uint_fast64_t a, uint_fast64_t b) -> bool { return values[a] <= values[b]; }); + } else { + std::sort(outMap.begin(), outMap.end(), [&] (uint_fast64_t a, uint_fast64_t b) -> bool { return values[a] >= values[b]; }); + } + + return outMap; + } + + SortingCategory category; + bool ascending; +}; + +} //namespace action +} //namespace property +} //namespace storm + +#endif /* STORM_FORMULA_ACTION_SORTACTION_H_ */ diff --git a/src/formula/Csl/CslFilter.h b/src/formula/Csl/CslFilter.h index 14c578be7..ae5c256d9 100644 --- a/src/formula/Csl/CslFilter.h +++ b/src/formula/Csl/CslFilter.h @@ -122,24 +122,6 @@ public: } } - bool validate() const { - // Test whether the stored filter actions are consistent in relation to themselves and to the ingoing modelchecking result. - - // Do a dynamic cast to test for the actual formula type. - if(dynamic_cast<AbstractStateFormula<T>*>(child) != nullptr) { - //TODO: Actual validation. - } - else if (dynamic_cast<AbstractPathFormula<T>*>(child) != nullptr) { - //TODO: Actual validation. - } - else { - // This branch should be unreachable. If you ended up here, something strange has happened. - //TODO: Error here. - } - - return true; - } - virtual std::string toString() const override { std::string desc = ""; diff --git a/src/formula/Prctl/PrctlFilter.h b/src/formula/Prctl/PrctlFilter.h index 407b4f6c3..77a8c35f7 100644 --- a/src/formula/Prctl/PrctlFilter.h +++ b/src/formula/Prctl/PrctlFilter.h @@ -13,6 +13,17 @@ #include "src/formula/Prctl/AbstractPathFormula.h" #include "src/formula/Prctl/AbstractStateFormula.h" #include "src/modelchecker/prctl/AbstractModelChecker.h" +#include "src/formula/Actions/AbstractAction.h" + +namespace storm { +namespace property { +namespace action { + template <typename T> class AbstractAction; +} +} +} + +#include <algorithm> namespace storm { namespace property { @@ -21,6 +32,8 @@ namespace prctl { template <class T> class PrctlFilter : public storm::property::AbstractFilter<T> { + typedef typename storm::property::action::AbstractAction<T>::Result Result; + public: PrctlFilter() : AbstractFilter<T>(UNDEFINED), child(nullptr) { @@ -51,125 +64,26 @@ public: LOG4CPLUS_INFO(logger, "Model checking formula\t" << this->toString()); std::cout << "Model checking formula:\t" << this->toString() << std::endl; - // Do a dynamic cast to test for the actual formula type and call the correct evaluation function. - if(dynamic_cast<AbstractStateFormula<T>*>(child) != nullptr) { - - // Check the formula and apply the filter actions. - storm::storage::BitVector result; - - try { - result = evaluate(modelchecker, dynamic_cast<AbstractStateFormula<T>*>(child)); - } catch (std::exception& e) { - std::cout << "Error during computation: " << e.what() << "Skipping property." << std::endl; - LOG4CPLUS_ERROR(logger, "Error during computation: " << e.what() << "Skipping property."); - std::cout << std::endl << "-------------------------------------------" << std::endl; + Result result; - return; - } - - // Now write out the result. - - if(this->actions.empty()) { - - // There is no filter action given. So provide legacy support: - // Return the results for all states labeled with "init". - LOG4CPLUS_INFO(logger, "Result for initial states:"); - std::cout << "Result for initial states:" << std::endl; - for (auto initialState : modelchecker.template getModel<storm::models::AbstractModel<T>>().getInitialStates()) { - LOG4CPLUS_INFO(logger, "\t" << initialState << ": " << (result.get(initialState) ? "satisfied" : "not satisfied")); - std::cout << "\t" << initialState << ": " << result.get(initialState) << std::endl; - } + try { + if(dynamic_cast<AbstractStateFormula<T> *>(child) != nullptr) { + result = evaluate(modelchecker, dynamic_cast<AbstractStateFormula<T> *>(child)); + } else if (dynamic_cast<AbstractPathFormula<T> *>(child) != nullptr) { + result = evaluate(modelchecker, dynamic_cast<AbstractPathFormula<T> *>(child)); + } else if (dynamic_cast<AbstractRewardPathFormula<T> *>(child) != nullptr) { + result = evaluate(modelchecker, dynamic_cast<AbstractRewardPathFormula<T> *>(child)); } - + } catch (std::exception& e) { + std::cout << "Error during computation: " << e.what() << "Skipping property." << std::endl; + LOG4CPLUS_ERROR(logger, "Error during computation: " << e.what() << "Skipping property."); std::cout << std::endl << "-------------------------------------------" << std::endl; + return; } - else if (dynamic_cast<AbstractPathFormula<T>*>(child) != nullptr) { - - // Check the formula and apply the filter actions. - std::vector<T> result; - - try { - result = evaluate(modelchecker, dynamic_cast<AbstractPathFormula<T>*>(child)); - } catch (std::exception& e) { - std::cout << "Error during computation: " << e.what() << "Skipping property." << std::endl; - LOG4CPLUS_ERROR(logger, "Error during computation: " << e.what() << "Skipping property."); - std::cout << std::endl << "-------------------------------------------" << std::endl; - return; - } - - // Now write out the result. - - if(this->actions.empty()) { + writeOut(result, modelchecker); - // There is no filter action given. So provide legacy support: - // Return the results for all states labeled with "init". - LOG4CPLUS_INFO(logger, "Result for initial states:"); - std::cout << "Result for initial states:" << std::endl; - for (auto initialState : modelchecker.template getModel<storm::models::AbstractModel<T>>().getInitialStates()) { - LOG4CPLUS_INFO(logger, "\t" << initialState << ": " << result[initialState]); - std::cout << "\t" << initialState << ": " << result[initialState] << std::endl; - } - } - - std::cout << std::endl << "-------------------------------------------" << std::endl; - - } - else if (dynamic_cast<AbstractRewardPathFormula<T>*>(child) != nullptr) { - - // Check the formula and apply the filter actions. - std::vector<T> result; - - try { - result = evaluate(modelchecker, dynamic_cast<AbstractRewardPathFormula<T>*>(child)); - } catch (std::exception& e) { - std::cout << "Error during computation: " << e.what() << "Skipping property." << std::endl; - LOG4CPLUS_ERROR(logger, "Error during computation: " << e.what() << "Skipping property."); - std::cout << std::endl << "-------------------------------------------" << std::endl; - - return; - } - - // Now write out the result. - - if(this->actions.empty()) { - - // There is no filter action given. So provide legacy support: - // Return the results for all states labeled with "init". - LOG4CPLUS_INFO(logger, "Result for initial states:"); - std::cout << "Result for initial states:" << std::endl; - for (auto initialState : modelchecker.template getModel<storm::models::AbstractModel<T>>().getInitialStates()) { - LOG4CPLUS_INFO(logger, "\t" << initialState << ": " << result[initialState]); - std::cout << "\t" << initialState << ": " << result[initialState] << std::endl; - } - } - - std::cout << std::endl << "-------------------------------------------" << std::endl; - - } - else { - // This branch should be unreachable. If you ended up here, something strange has happened. - //TODO: Error here. - } - } - - bool validate() const { - // Test whether the stored filter actions are consistent in relation to themselves and to the ingoing modelchecking result. - - // Do a dynamic cast to test for the actual formula type. - if(dynamic_cast<AbstractStateFormula<T>*>(child) != nullptr) { - //TODO: Actual validation. - } - else if (dynamic_cast<AbstractPathFormula<T>*>(child) != nullptr) { - //TODO: Actual validation. - } - else { - // This branch should be unreachable. If you ended up here, something strange has happened. - //TODO: Error here. - } - - return true; } virtual std::string toString() const override { @@ -220,10 +134,10 @@ public: for(auto action : this->actions) { desc += action->toString(); - desc += ", "; + desc += "; "; } - // Remove the last ", ". + // Remove the last "; ". desc.pop_back(); desc.pop_back(); @@ -242,10 +156,10 @@ public: for(auto action : this->actions) { desc += action->toString(); - desc += ", "; + desc += "; "; } - // Remove the last ", ". + // Remove the last "; ". desc.pop_back(); desc.pop_back(); @@ -259,7 +173,7 @@ public: return desc; } - virtual std::string toPrettyString() const override{ + virtual std::string toPrettyString() const override { std::string desc = "Filter: "; desc += "\nActions:"; for(auto action : this->actions) { @@ -279,61 +193,122 @@ public: private: - storm::storage::BitVector evaluate(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelchecker, AbstractStateFormula<T>* formula) const { + Result evaluate(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelchecker, AbstractStateFormula<T> * formula) const { // First, get the model checking result. - storm::storage::BitVector result; + Result result; if(this->opt != UNDEFINED) { // If it is specified that min/max probabilities/rewards should be computed, call the appropriate method of the model checker. - result = modelchecker.checkOptimizingOperator(*formula, this->opt == storm::property::MINIMIZE ? true : false); + result.stateResult = modelchecker.checkOptimizingOperator(*formula, this->opt == storm::property::MINIMIZE ? true : false); } else { - result = formula->check(modelchecker); + result.stateResult = formula->check(modelchecker); } - - // Now apply all filter actions and return the result. - for(auto action : this->actions) { - result = action->evaluate(result); - } - return result; + return evaluateActions(result, modelchecker); } - std::vector<T> evaluate(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelchecker, AbstractPathFormula<T>* formula) const { + Result evaluate(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelchecker, AbstractPathFormula<T> * formula) const { // First, get the model checking result. - std::vector<T> result; + Result result; if(this->opt != UNDEFINED) { // If it is specified that min/max probabilities/rewards should be computed, call the appropriate method of the model checker. - result = modelchecker.checkOptimizingOperator(*formula, this->opt == storm::property::MINIMIZE ? true : false); + result.pathResult = modelchecker.checkOptimizingOperator(*formula, this->opt == storm::property::MINIMIZE ? true : false); } else { - result = formula->check(modelchecker, false); + result.pathResult = formula->check(modelchecker, false); } - // Now apply all filter actions and return the result. - for(auto action : this->actions) { - result = action->evaluate(result); - } - return result; + return evaluateActions(result, modelchecker); } - std::vector<T> evaluate(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelchecker, AbstractRewardPathFormula<T>* formula) const { + Result evaluate(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelchecker, AbstractRewardPathFormula<T> * formula) const { // First, get the model checking result. - std::vector<T> result; + Result result; if(this->opt != UNDEFINED) { // If it is specified that min/max probabilities/rewards should be computed, call the appropriate method of the model checker. - result = modelchecker.checkOptimizingOperator(*formula, this->opt == storm::property::MINIMIZE ? true : false); + result.pathResult = modelchecker.checkOptimizingOperator(*formula, this->opt == storm::property::MINIMIZE ? true : false); } else { - result = formula->check(modelchecker, false); + result.pathResult = formula->check(modelchecker, false); + } + + return evaluateActions(result, modelchecker); + } + + Result evaluateActions(Result result, storm::modelchecker::prctl::AbstractModelChecker<T> const & modelchecker) const { + + // Init the state selection and state map vectors. + result.selection = storm::storage::BitVector(result.stateResult.size(), true); + result.stateMap = std::vector<uint_fast64_t>(result.selection.size()); + for(uint_fast64_t i = 0; i < result.selection.size(); i++) { + result.stateMap[i] = i; } // Now apply all filter actions and return the result. for(auto action : this->actions) { - result = action->evaluate(result); + result = action->evaluate(result, modelchecker); } return result; } + + void writeOut(Result const & result, storm::modelchecker::prctl::AbstractModelChecker<T> const & modelchecker) const { + + // Test for the kind of result. Values or states. + if(!result.pathResult.empty()) { + + // Write out the selected value results in the order given by the stateMap. + if(this->actions.empty()) { + + // There is no filter action given. So provide legacy support: + // Return the results for all states labeled with "init". + LOG4CPLUS_INFO(logger, "Result for initial states:"); + std::cout << "Result for initial states:" << std::endl; + for (auto initialState : modelchecker.template getModel<storm::models::AbstractModel<T>>().getInitialStates()) { + LOG4CPLUS_INFO(logger, "\t" << initialState << ": " << result.pathResult[initialState]); + std::cout << "\t" << initialState << ": " << result.pathResult[initialState] << std::endl; + } + } else { + LOG4CPLUS_INFO(logger, "Result for " << result.selection.getNumberOfSetBits() << " selected states:"); + std::cout << "Result for " << result.selection.getNumberOfSetBits() << " selected states:" << std::endl; + + for(uint_fast64_t i = 0; i < result.stateMap.size(); i++) { + if(result.selection.get(result.stateMap[i])) { + LOG4CPLUS_INFO(logger, "\t" << result.stateMap[i] << ": " << result.pathResult[result.stateMap[i]]); + std::cout << "\t" << result.stateMap[i] << ": " << result.pathResult[result.stateMap[i]] << std::endl; + } + } + } + + } else { + + // Write out the selected state results in the order given by the stateMap. + if(this->actions.empty()) { + + // There is no filter action given. So provide legacy support: + // Return the results for all states labeled with "init". + LOG4CPLUS_INFO(logger, "Result for initial states:"); + std::cout << "Result for initial states:" << std::endl; + for (auto initialState : modelchecker.template getModel<storm::models::AbstractModel<T>>().getInitialStates()) { + LOG4CPLUS_INFO(logger, "\t" << initialState << ": " << (result.stateResult[initialState] ? "satisfied" : "not satisfied")); + std::cout << "\t" << initialState << ": " << result.stateResult[initialState] << std::endl; + } + } else { + LOG4CPLUS_INFO(logger, "Result for " << result.selection.getNumberOfSetBits() << " selected states:"); + std::cout << "Result for " << result.selection.getNumberOfSetBits() << " selected states:" << std::endl; + + for(uint_fast64_t i = 0; i < result.stateMap.size(); i++) { + if(result.selection.get(result.stateMap[i])) { + LOG4CPLUS_INFO(logger, "\t" << result.stateMap[i] << ": " << (result.stateResult[result.stateMap[i]] ? "satisfied" : "not satisfied")); + std::cout << "\t" << result.stateMap[i] << ": " << (result.stateResult[result.stateMap[i]] ? "satisfied" : "not satisfied") << std::endl; + } + } + } + } + + std::cout << std::endl << "-------------------------------------------" << std::endl; + } + AbstractPrctlFormula<T>* child; }; diff --git a/src/parser/CslParser.cpp b/src/parser/CslParser.cpp index 296deecc0..9e38a9c59 100644 --- a/src/parser/CslParser.cpp +++ b/src/parser/CslParser.cpp @@ -11,7 +11,11 @@ // The action class headers. #include "src/formula/Actions/AbstractAction.h" +#include "src/formula/Actions/BoundAction.h" +#include "src/formula/Actions/InvertAction.h" +#include "src/formula/Actions/FormulaAction.h" #include "src/formula/Actions/RangeAction.h" +#include "src/formula/Actions/SortAction.h" // If the parser fails due to ill-formed data, this exception is thrown. #include "src/exceptions/WrongFormatException.h" @@ -50,6 +54,10 @@ struct CslParser::CslGrammar : qi::grammar<Iterator, storm::property::csl::CslFi (qi::lit(">"))[qi::_val = storm::property::GREATER] | (qi::lit("<="))[qi::_val = storm::property::LESS_EQUAL] | (qi::lit("<"))[qi::_val = storm::property::LESS]); + sortingCategory = ( + (qi::lit("index"))[qi::_val = storm::property::action::SortAction<double>::INDEX] | + (qi::lit("value"))[qi::_val = storm::property::action::SortAction<double>::VALUE] + ); //Comment: Empty line or line starting with "//" comment = (qi::lit("//") >> *(qi::char_))[qi::_val = nullptr]; @@ -136,11 +144,37 @@ struct CslParser::CslGrammar : qi::grammar<Iterator, storm::property::csl::CslFi phoenix::new_<storm::property::csl::CslFilter<double>>(qi::_1, storm::property::UNDEFINED, true)]; steadyStateNoBoundOperator.name("steady state no bound operator"); - rangeAction = (qi::lit("range") >> qi::lit(",") >> qi::uint_ >> qi::lit(",") >> qi::uint_)[qi::_val = - phoenix::new_<storm::property::action::RangeAction<double>>(qi::_1, qi::_2)]; - rangeAction.name("range action for the formula filter"); + // This block defines rules for parsing filter actions. + boundAction = (qi::lit("bound") > qi::lit("(") >> comparisonType >> qi::lit(",") >> qi::double_ >> qi::lit(")"))[qi::_val = + phoenix::new_<storm::property::action::BoundAction<double>>(qi::_1, qi::_2)]; + boundAction.name("bound action"); + + invertAction = qi::lit("invert")[qi::_val = phoenix::new_<storm::property::action::InvertAction<double>>()]; + invertAction.name("invert action"); + + formulaAction = (qi::lit("formula") > qi::lit("(") >> stateFormula >> qi::lit(")"))[qi::_val = + phoenix::new_<storm::property::action::FormulaAction<double>>(qi::_1)]; + formulaAction.name("formula action"); + + rangeAction = ( + (qi::lit("range") >> qi::lit("(") >> qi::uint_ >> qi::lit(",") > qi::uint_ >> qi::lit(")"))[qi::_val = + phoenix::new_<storm::property::action::RangeAction<double>>(qi::_1, qi::_2)] | + (qi::lit("range") >> qi::lit("(") >> qi::uint_ >> qi::lit(")"))[qi::_val = + phoenix::new_<storm::property::action::RangeAction<double>>(qi::_1, qi::_1 + 1)] + ); + rangeAction.name("range action"); + + sortAction = ( + (qi::lit("sort") > qi::lit("(") >> sortingCategory >> qi::lit(")"))[qi::_val = + phoenix::new_<storm::property::action::SortAction<double>>(qi::_1)] | + (qi::lit("sort") > qi::lit("(") >> sortingCategory >> qi::lit(", ") >> qi::lit("asc") > qi::lit(")"))[qi::_val = + phoenix::new_<storm::property::action::SortAction<double>>(qi::_1, true)] | + (qi::lit("sort") > qi::lit("(") >> sortingCategory >> qi::lit(", ") >> qi::lit("desc") > qi::lit(")"))[qi::_val = + phoenix::new_<storm::property::action::SortAction<double>>(qi::_1, false)] + ); + sortAction.name("sort action"); - abstractAction = (rangeAction) >> (qi::eps | qi::lit(",")); + abstractAction = (rangeAction) >> (qi::eps | qi::lit(";")); abstractAction.name("filter action"); filter = (qi::lit("filter") >> qi::lit("[") >> +abstractAction >> qi::lit("]") >> qi::lit("(") >> formula >> qi::lit(")"))[qi::_val = @@ -165,7 +199,11 @@ struct CslParser::CslGrammar : qi::grammar<Iterator, storm::property::csl::CslFi qi::rule<Iterator, storm::property::csl::CslFilter<double>*(), Skipper> steadyStateNoBoundOperator; qi::rule<Iterator, storm::property::action::AbstractAction<double>*(), Skipper> abstractAction; + qi::rule<Iterator, storm::property::action::BoundAction<double>*(), Skipper> boundAction; + qi::rule<Iterator, storm::property::action::InvertAction<double>*(), Skipper> invertAction; + qi::rule<Iterator, storm::property::action::FormulaAction<double>*(), Skipper> formulaAction; qi::rule<Iterator, storm::property::action::RangeAction<double>*(), Skipper> rangeAction; + qi::rule<Iterator, storm::property::action::SortAction<double>*(), Skipper> sortAction; qi::rule<Iterator, storm::property::csl::AbstractCslFormula<double>*(), Skipper> formula; qi::rule<Iterator, storm::property::csl::AbstractCslFormula<double>*(), Skipper> comment; @@ -191,6 +229,7 @@ struct CslParser::CslGrammar : qi::grammar<Iterator, storm::property::csl::CslFi qi::rule<Iterator, std::string(), Skipper> freeIdentifierName; qi::rule<Iterator, storm::property::ComparisonType(), Skipper> comparisonType; + qi::rule<Iterator, storm::property::action::SortAction<double>::SortingCategory(), Skipper> sortingCategory; }; diff --git a/src/parser/PrctlParser.cpp b/src/parser/PrctlParser.cpp index 49bfe281b..0fb8b538a 100644 --- a/src/parser/PrctlParser.cpp +++ b/src/parser/PrctlParser.cpp @@ -4,7 +4,11 @@ // The action class headers. #include "src/formula/Actions/AbstractAction.h" +#include "src/formula/Actions/BoundAction.h" +#include "src/formula/Actions/InvertAction.h" +#include "src/formula/Actions/FormulaAction.h" #include "src/formula/Actions/RangeAction.h" +#include "src/formula/Actions/SortAction.h" // If the parser fails due to ill-formed data, this exception is thrown. #include "src/exceptions/WrongFormatException.h" @@ -38,17 +42,21 @@ namespace parser { template<typename Iterator, typename Skipper> struct PrctlParser::PrctlGrammar : qi::grammar<Iterator, storm::property::prctl::PrctlFilter<double>*(), Skipper > { PrctlGrammar() : PrctlGrammar::base_type(start) { - //This block contains helper rules that may be used several times + // This block contains helper rules that may be used several times freeIdentifierName = qi::lexeme[qi::alpha >> *(qi::alnum | qi::char_('_'))]; comparisonType = ( (qi::lit(">="))[qi::_val = storm::property::GREATER_EQUAL] | (qi::lit(">"))[qi::_val = storm::property::GREATER] | (qi::lit("<="))[qi::_val = storm::property::LESS_EQUAL] | (qi::lit("<"))[qi::_val = storm::property::LESS]); - //Comment: Empty line or line starting with "//" + sortingCategory = ( + (qi::lit("index"))[qi::_val = storm::property::action::SortAction<double>::INDEX] | + (qi::lit("value"))[qi::_val = storm::property::action::SortAction<double>::VALUE] + ); + // Comment: Empty line or line starting with "//" comment = (qi::lit("//") >> *(qi::char_))[qi::_val = nullptr]; - //This block defines rules for parsing state formulas + // This block defines rules for parsing state formulas stateFormula %= orFormula; stateFormula.name("state formula"); orFormula = andFormula[qi::_val = qi::_1] > *(qi::lit("|") > andFormula)[qi::_val = @@ -61,8 +69,8 @@ struct PrctlParser::PrctlGrammar : qi::grammar<Iterator, storm::property::prctl: phoenix::new_<storm::property::prctl::Not<double>>(qi::_1)]; notFormula.name("not formula"); - //This block defines rules for "atomic" state formulas - //(Propositions, probabilistic/reward formulas, and state formulas in brackets) + // This block defines rules for "atomic" state formulas + // (Propositions, probabilistic/reward formulas, and state formulas in brackets) atomicStateFormula %= probabilisticBoundOperator | rewardBoundOperator | atomicProposition | qi::lit("(") >> stateFormula >> qi::lit(")") | qi::lit("[") >> stateFormula >> qi::lit("]"); atomicStateFormula.name("atomic state formula"); atomicProposition = (freeIdentifierName)[qi::_val = @@ -76,7 +84,7 @@ struct PrctlParser::PrctlGrammar : qi::grammar<Iterator, storm::property::prctl: phoenix::new_<storm::property::prctl::RewardBoundOperator<double> >(qi::_1, qi::_2, qi::_3)]); rewardBoundOperator.name("reward bound operator"); - //This block defines rules for parsing probabilistic path formulas + // This block defines rules for parsing probabilistic path formulas pathFormula = (boundedEventually | eventually | next | globally | boundedUntil | until | qi::lit("(") >> pathFormula >> qi::lit(")") | qi::lit("[") >> pathFormula >> qi::lit("]")); pathFormula.name("path formula"); boundedEventually = (qi::lit("F") >> qi::lit("<=") > qi::int_ > stateFormula)[qi::_val = @@ -98,7 +106,7 @@ struct PrctlParser::PrctlGrammar : qi::grammar<Iterator, storm::property::prctl: phoenix::new_<storm::property::prctl::Until<double>>(phoenix::bind(&storm::property::prctl::AbstractStateFormula<double>::clone, phoenix::bind(&std::shared_ptr<storm::property::prctl::AbstractStateFormula<double>>::get, qi::_a)), qi::_2)]; until.name("path formula (for probabilistic operator)"); - //This block defines rules for parsing reward path formulas + // This block defines rules for parsing reward path formulas. rewardPathFormula = (cumulativeReward | reachabilityReward | instantaneousReward | steadyStateReward | qi::lit("(") >> rewardPathFormula >> qi::lit(")") | qi::lit("[") >> rewardPathFormula >> qi::lit("]")); rewardPathFormula.name("path formula (for reward operator)"); cumulativeReward = (qi::lit("C") > qi::lit("<=") > qi::double_)[qi::_val = @@ -115,9 +123,9 @@ struct PrctlParser::PrctlGrammar : qi::grammar<Iterator, storm::property::prctl: formula = (pathFormula | stateFormula); formula.name("PRCTL formula"); - //This block defines rules for parsing formulas with noBoundOperators - //Note that this is purely for legacy support. - //NoBoundOperators are no longer part of the formula tree and are therefore deprecated. + // This block defines rules for parsing formulas with noBoundOperators. + // Note that this is purely for legacy support. + // NoBoundOperators are no longer part of the formula tree and are therefore deprecated. noBoundOperator = (probabilisticNoBoundOperator | rewardNoBoundOperator); noBoundOperator.name("no bound operator"); probabilisticNoBoundOperator = ( @@ -141,15 +149,46 @@ struct PrctlParser::PrctlGrammar : qi::grammar<Iterator, storm::property::prctl: ); rewardNoBoundOperator.name("no bound operator"); - rangeAction = (qi::lit("range") >> qi::lit(",") >> qi::uint_ >> qi::lit(",") >> qi::uint_)[qi::_val = - phoenix::new_<storm::property::action::RangeAction<double>>(qi::_1, qi::_2)]; - rangeAction.name("range action for the formula filter"); - abstractAction = (rangeAction) >> (qi::eps | qi::lit(",")); + // This block defines rules for parsing filter actions. + boundAction = (qi::lit("bound") > qi::lit("(") >> comparisonType >> qi::lit(",") >> qi::double_ >> qi::lit(")"))[qi::_val = + phoenix::new_<storm::property::action::BoundAction<double>>(qi::_1, qi::_2)]; + boundAction.name("bound action"); + + invertAction = qi::lit("invert")[qi::_val = phoenix::new_<storm::property::action::InvertAction<double>>()]; + invertAction.name("invert action"); + + formulaAction = (qi::lit("formula") > qi::lit("(") >> stateFormula >> qi::lit(")"))[qi::_val = + phoenix::new_<storm::property::action::FormulaAction<double>>(qi::_1)]; + formulaAction.name("formula action"); + + rangeAction = ( + (qi::lit("range") >> qi::lit("(") >> qi::uint_ >> qi::lit(",") > qi::uint_ >> qi::lit(")"))[qi::_val = + phoenix::new_<storm::property::action::RangeAction<double>>(qi::_1, qi::_2)] | + (qi::lit("range") >> qi::lit("(") >> qi::uint_ >> qi::lit(")"))[qi::_val = + phoenix::new_<storm::property::action::RangeAction<double>>(qi::_1, qi::_1 + 1)] + ); + rangeAction.name("range action"); + + sortAction = ( + (qi::lit("sort") > qi::lit("(") >> sortingCategory >> qi::lit(")"))[qi::_val = + phoenix::new_<storm::property::action::SortAction<double>>(qi::_1)] | + (qi::lit("sort") > qi::lit("(") >> sortingCategory >> qi::lit(", ") >> qi::lit("asc") > qi::lit(")"))[qi::_val = + phoenix::new_<storm::property::action::SortAction<double>>(qi::_1, true)] | + (qi::lit("sort") > qi::lit("(") >> sortingCategory >> qi::lit(", ") >> qi::lit("desc") > qi::lit(")"))[qi::_val = + phoenix::new_<storm::property::action::SortAction<double>>(qi::_1, false)] + ); + sortAction.name("sort action"); + + abstractAction = (rangeAction) >> (qi::eps | qi::lit(";")); abstractAction.name("filter action"); - filter = (qi::lit("filter") > qi::lit("[") >> +abstractAction >> qi::lit("]") >> qi::lit("(") >> formula >> qi::lit(")"))[qi::_val = + filter = (qi::lit("filter") >> qi::lit("[") >> +abstractAction >> qi::lit("]") > qi::lit("(") >> formula >> qi::lit(")"))[qi::_val = phoenix::new_<storm::property::prctl::PrctlFilter<double>>(qi::_2, qi::_1)] | + (qi::lit("filter") >> qi::lit("[") >> qi::lit("max") > +abstractAction >> qi::lit("]") >> qi::lit("(") >> formula >> qi::lit(")"))[qi::_val = + phoenix::new_<storm::property::prctl::PrctlFilter<double>>(qi::_2, qi::_1, storm::property::MAXIMIZE)] | + (qi::lit("filter") >> qi::lit("[") >> qi::lit("min") > +abstractAction >> qi::lit("]") >> qi::lit("(") >> formula >> qi::lit(")"))[qi::_val = + phoenix::new_<storm::property::prctl::PrctlFilter<double>>(qi::_2, qi::_1, storm::property::MINIMIZE)] | (noBoundOperator)[qi::_val = qi::_1] | (formula)[qi::_val = @@ -169,7 +208,11 @@ struct PrctlParser::PrctlGrammar : qi::grammar<Iterator, storm::property::prctl: qi::rule<Iterator, storm::property::prctl::PrctlFilter<double>*(), Skipper> rewardNoBoundOperator; qi::rule<Iterator, storm::property::action::AbstractAction<double>*(), Skipper> abstractAction; + qi::rule<Iterator, storm::property::action::BoundAction<double>*(), Skipper> boundAction; + qi::rule<Iterator, storm::property::action::InvertAction<double>*(), Skipper> invertAction; + qi::rule<Iterator, storm::property::action::FormulaAction<double>*(), Skipper> formulaAction; qi::rule<Iterator, storm::property::action::RangeAction<double>*(), Skipper> rangeAction; + qi::rule<Iterator, storm::property::action::SortAction<double>*(), Skipper> sortAction; qi::rule<Iterator, storm::property::prctl::AbstractPrctlFormula<double>*(), Skipper> formula; qi::rule<Iterator, storm::property::prctl::AbstractPrctlFormula<double>*(), Skipper> comment; @@ -201,6 +244,7 @@ struct PrctlParser::PrctlGrammar : qi::grammar<Iterator, storm::property::prctl: qi::rule<Iterator, std::string(), Skipper> freeIdentifierName; qi::rule<Iterator, storm::property::ComparisonType(), Skipper> comparisonType; + qi::rule<Iterator, storm::property::action::SortAction<double>::SortingCategory(), Skipper> sortingCategory; }; From df5bafc38bf8cc3d4637d98afb87a8d49190437f Mon Sep 17 00:00:00 2001 From: masawei <manuel.sascha.weiand@rwth-aachen.de> Date: Tue, 24 Jun 2014 00:55:04 +0200 Subject: [PATCH 15/30] Finished the implementation of the Cls and Ltl filters. -Mostly copy and paste from the prctl version with some individual changes. Next up: Testing. Former-commit-id: 19a4f902555d92bdce08a6bcaca35047fccc2929 --- src/formula/Actions/FormulaAction.h | 103 +++++++++++++++++ src/formula/Csl/CslFilter.h | 168 ++++++++++++++++------------ src/formula/Ltl/LtlFilter.h | 146 ++++++++++++++++++------ src/formula/Prctl/PrctlFilter.h | 4 + src/parser/CslParser.cpp | 4 +- src/parser/LtlFileParser.cpp | 4 +- src/parser/LtlFileParser.h | 3 +- src/parser/LtlParser.cpp | 98 ++++++++++++---- src/parser/LtlParser.h | 3 +- src/parser/PrctlParser.cpp | 2 +- 10 files changed, 404 insertions(+), 131 deletions(-) create mode 100644 src/formula/Actions/FormulaAction.h diff --git a/src/formula/Actions/FormulaAction.h b/src/formula/Actions/FormulaAction.h new file mode 100644 index 000000000..805bc1acb --- /dev/null +++ b/src/formula/Actions/FormulaAction.h @@ -0,0 +1,103 @@ +/* + * PrctlFormulaAction.h + * + * Created on: Jun 6, 2014 + * Author: Manuel Sascha Weiand + */ + +#ifndef STORM_FORMULA_ACTION_FORMULAACTION_H_ +#define STORM_FORMULA_ACTION_FORMULAACTION_H_ + +#include "src/formula/Actions/AbstractAction.h" +#include "src/formula/Prctl/AbstractStateFormula.h" + + +#include <string> + +namespace storm { +namespace property { +namespace action { + +template <class T> +class FormulaAction : public AbstractAction<T> { + + typedef typename AbstractAction<T>::Result Result; + +public: + + FormulaAction(storm::property::prctl::AbstractStateFormula<T>* prctlFormula) : prctlFormula(prctlFormula), cslFormula(nullptr) { + //Intentionally left empty. + } + + FormulaAction(storm::property::csl::AbstractStateFormula<T>* cslFormula) : prctlFormula(nullptr), cslFormula(cslFormula) { + //Intentionally left empty. + } + + /*! + * Virtual destructor + * To ensure that the right destructor is called + */ + virtual ~FormulaAction() { + if(prctlFormula != nullptr) { + delete prctlFormula; + } + if(cslFormula != nullptr) { + delete cslFormula; + } + } + + /*! + * + */ + virtual Result evaluate(Result const & result, storm::modelchecker::prctl::AbstractModelChecker<T> const & mc) const override { + + storm::storage::BitVector selection(result.selection); + + //Compute the modelchecking results of the actions state formula and deselect all states that do not satisfy it. + if(prctlFormula != nullptr) { + selection = selection & prctlFormula->check(mc); + } + + return Result(selection, result.stateMap, result.pathResult, result.stateResult); + } + + /*! + * + */ + virtual Result evaluate(Result const & result, storm::modelchecker::csl::AbstractModelChecker<T> const & mc) const override { + + storm::storage::BitVector selection(result.selection); + + //Compute the modelchecking results of the actions state formula and deselect all states that do not satisfy it. + if(cslFormula != nullptr) { + selection = selection & cslFormula->check(mc); + } + + return Result(selection, result.stateMap, result.pathResult, result.stateResult); + } + + /*! + * + */ + virtual std::string toString() const override { + std::string out = "states("; + if(prctlFormula != nullptr) { + out += prctlFormula->toString(); + } else if(cslFormula != nullptr) { + out += cslFormula->toString(); + } + out += ")"; + return out; + } + +private: + storm::property::prctl::AbstractStateFormula<T>* prctlFormula; + storm::property::csl::AbstractStateFormula<T>* cslFormula; + +}; + +} //namespace action +} //namespace property +} //namespace storm + +#endif /* STORM_FORMULA_ACTION_FORMULAACTION_H_ */ diff --git a/src/formula/Csl/CslFilter.h b/src/formula/Csl/CslFilter.h index ae5c256d9..928163fbd 100644 --- a/src/formula/Csl/CslFilter.h +++ b/src/formula/Csl/CslFilter.h @@ -14,6 +14,16 @@ #include "src/formula/Csl/AbstractStateFormula.h" #include "src/modelchecker/csl/AbstractModelChecker.h" +#include "src/formula/Actions/AbstractAction.h" + +namespace storm { +namespace property { +namespace action { + template <typename T> class AbstractAction; +} +} +} + namespace storm { namespace property { namespace csl { @@ -21,6 +31,8 @@ namespace csl { template <class T> class CslFilter : public storm::property::AbstractFilter<T> { + typedef typename storm::property::action::AbstractAction<T>::Result Result; + public: CslFilter() : AbstractFilter<T>(UNDEFINED), child(nullptr), steadyStateQuery(false) { @@ -44,82 +56,31 @@ public: delete child; } - void check(storm::modelchecker::csl::AbstractModelChecker<T> const & modelchecker) const { + void check(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelchecker) const { // Write out the formula to be checked. std::cout << std::endl; - LOG4CPLUS_INFO(logger, "Model checking formula\t" << this->toFormulaString()); - std::cout << "Model checking formula:\t" << this->toFormulaString() << std::endl; + LOG4CPLUS_INFO(logger, "Model checking formula\t" << this->toString()); + std::cout << "Model checking formula:\t" << this->toString() << std::endl; - // Do a dynamic cast to test for the actual formula type and call the correct evaluation function. - if(dynamic_cast<AbstractStateFormula<T>*>(child) != nullptr) { + Result result; - // Check the formula and apply the filter actions. - storm::storage::BitVector result; - - try { - result = evaluate(modelchecker, static_cast<AbstractStateFormula<T>*>(child)); - } catch (std::exception& e) { - std::cout << "Error during computation: " << e.what() << "Skipping property." << std::endl; - LOG4CPLUS_ERROR(logger, "Error during computation: " << e.what() << "Skipping property."); - std::cout << std::endl << "-------------------------------------------" << std::endl; - - return; + try { + if(dynamic_cast<AbstractStateFormula<T> *>(child) != nullptr) { + result = evaluate(modelchecker, dynamic_cast<AbstractStateFormula<T> *>(child)); + } else if (dynamic_cast<AbstractPathFormula<T> *>(child) != nullptr) { + result = evaluate(modelchecker, dynamic_cast<AbstractPathFormula<T> *>(child)); } - - // Now write out the result. - - if(this->actions.empty()) { - - // There is no filter action given. So provide legacy support: - // Return the results for all states labeled with "init". - LOG4CPLUS_INFO(logger, "Result for initial states:"); - std::cout << "Result for initial states:" << std::endl; - for (auto initialState : modelchecker.getModel().getInitialStates()) { - LOG4CPLUS_INFO(logger, "\t" << initialState << ": " << (result.get(initialState) ? "satisfied" : "not satisfied")); - std::cout << "\t" << initialState << ": " << result.get(initialState) << std::endl; - } - } - + } catch (std::exception& e) { + std::cout << "Error during computation: " << e.what() << "Skipping property." << std::endl; + LOG4CPLUS_ERROR(logger, "Error during computation: " << e.what() << "Skipping property."); std::cout << std::endl << "-------------------------------------------" << std::endl; + return; } - else if (dynamic_cast<AbstractPathFormula<T>*>(child) != nullptr) { - - // Check the formula and apply the filter actions. - std::vector<T> result; - try { - result = evaluate(modelchecker, static_cast<AbstractPathFormula<T>*>(child)); - } catch (std::exception& e) { - std::cout << "Error during computation: " << e.what() << "Skipping property." << std::endl; - LOG4CPLUS_ERROR(logger, "Error during computation: " << e.what() << "Skipping property."); - std::cout << std::endl << "-------------------------------------------" << std::endl; + writeOut(result, modelchecker); - return; - } - - // Now write out the result. - - if(this->actions.empty()) { - - // There is no filter action given. So provide legacy support: - // Return the results for all states labeled with "init". - LOG4CPLUS_INFO(logger, "Result for initial states:"); - std::cout << "Result for initial states:" << std::endl; - for (auto initialState : modelchecker.getModel().getInitialStates()) { - LOG4CPLUS_INFO(logger, "\t" << initialState << ": " << result[initialState]); - std::cout << "\t" << initialState << ": " << result[initialState] << std::endl; - } - } - - std::cout << std::endl << "-------------------------------------------" << std::endl; - - } - else { - // This branch should be unreachable. If you ended up here, something strange has happened. - //TODO: Error here. - } } virtual std::string toString() const override { @@ -242,10 +203,7 @@ private: // Now apply all filter actions and return the result. - for(auto action : this->actions) { - result = action->evaluate(result); - } - return result; + return evaluateActions(result, modelchecker); } std::vector<T> evaluate(storm::modelchecker::csl::AbstractModelChecker<T> const & modelchecker, AbstractPathFormula<T>* formula) const { @@ -259,13 +217,83 @@ private: result = formula->check(modelchecker, false); } + // Now apply all filter actions and return the result. + return evaluateActions(result, modelchecker); + } + + Result evaluateActions(Result result, storm::modelchecker::csl::AbstractModelChecker<T> const & modelchecker) const { + + // Init the state selection and state map vectors. + result.selection = storm::storage::BitVector(result.stateResult.size(), true); + result.stateMap = std::vector<uint_fast64_t>(result.selection.size()); + for(uint_fast64_t i = 0; i < result.selection.size(); i++) { + result.stateMap[i] = i; + } + // Now apply all filter actions and return the result. for(auto action : this->actions) { - result = action->evaluate(result); + result = action->evaluate(result, modelchecker); } return result; } + void writeOut(Result const & result, storm::modelchecker::prctl::AbstractModelChecker<T> const & modelchecker) const { + + // Test for the kind of result. Values or states. + if(!result.pathResult.empty()) { + + // Write out the selected value results in the order given by the stateMap. + if(this->actions.empty()) { + + // There is no filter action given. So provide legacy support: + // Return the results for all states labeled with "init". + LOG4CPLUS_INFO(logger, "Result for initial states:"); + std::cout << "Result for initial states:" << std::endl; + for (auto initialState : modelchecker.template getModel<storm::models::AbstractModel<T>>().getInitialStates()) { + LOG4CPLUS_INFO(logger, "\t" << initialState << ": " << result.pathResult[initialState]); + std::cout << "\t" << initialState << ": " << result.pathResult[initialState] << std::endl; + } + } else { + LOG4CPLUS_INFO(logger, "Result for " << result.selection.getNumberOfSetBits() << " selected states:"); + std::cout << "Result for " << result.selection.getNumberOfSetBits() << " selected states:" << std::endl; + + for(uint_fast64_t i = 0; i < result.stateMap.size(); i++) { + if(result.selection.get(result.stateMap[i])) { + LOG4CPLUS_INFO(logger, "\t" << result.stateMap[i] << ": " << result.pathResult[result.stateMap[i]]); + std::cout << "\t" << result.stateMap[i] << ": " << result.pathResult[result.stateMap[i]] << std::endl; + } + } + } + + } else { + + // Write out the selected state results in the order given by the stateMap. + if(this->actions.empty()) { + + // There is no filter action given. So provide legacy support: + // Return the results for all states labeled with "init". + LOG4CPLUS_INFO(logger, "Result for initial states:"); + std::cout << "Result for initial states:" << std::endl; + for (auto initialState : modelchecker.template getModel<storm::models::AbstractModel<T>>().getInitialStates()) { + LOG4CPLUS_INFO(logger, "\t" << initialState << ": " << (result.stateResult[initialState] ? "satisfied" : "not satisfied")); + std::cout << "\t" << initialState << ": " << result.stateResult[initialState] << std::endl; + } + } else { + LOG4CPLUS_INFO(logger, "Result for " << result.selection.getNumberOfSetBits() << " selected states:"); + std::cout << "Result for " << result.selection.getNumberOfSetBits() << " selected states:" << std::endl; + + for(uint_fast64_t i = 0; i < result.stateMap.size(); i++) { + if(result.selection.get(result.stateMap[i])) { + LOG4CPLUS_INFO(logger, "\t" << result.stateMap[i] << ": " << (result.stateResult[result.stateMap[i]] ? "satisfied" : "not satisfied")); + std::cout << "\t" << result.stateMap[i] << ": " << (result.stateResult[result.stateMap[i]] ? "satisfied" : "not satisfied") << std::endl; + } + } + } + } + + std::cout << std::endl << "-------------------------------------------" << std::endl; + } + AbstractCslFormula<T>* child; bool steadyStateQuery; diff --git a/src/formula/Ltl/LtlFilter.h b/src/formula/Ltl/LtlFilter.h index cbc31f71b..96fac586c 100644 --- a/src/formula/Ltl/LtlFilter.h +++ b/src/formula/Ltl/LtlFilter.h @@ -10,6 +10,17 @@ #include "src/formula/AbstractFilter.h" #include "src/modelchecker/ltl/AbstractModelChecker.h" +#include "src/formula/Ltl/AbstractLtlFormula.h" +#include "src/formula/Actions/AbstractAction.h" +#include "src/exceptions/NotImplementedException.h" + +namespace storm { +namespace property { +namespace action { + template <typename T> class AbstractAction; +} +} +} namespace storm { namespace property { @@ -18,21 +29,23 @@ namespace ltl { template <class T> class LtlFilter : public storm::property::AbstractFilter<T> { + typedef typename storm::property::action::AbstractAction<T>::Result Result; + public: - LtlFilter() : child(nullptr) { + LtlFilter() : AbstractFilter<T>(UNDEFINED), child(nullptr) { // Intentionally left empty. } - LtlFilter(AbstractLtlFormula* child) : child(child) { + LtlFilter(AbstractLtlFormula<T>* child, OptimizingOperator opt = UNDEFINED) : AbstractFilter<T>(opt), child(child) { // Intentionally left empty. } - LtlFilter(AbstractLtlFormula* child, action::Action<T>* action) : child(child) { + LtlFilter(AbstractLtlFormula<T>* child, action::AbstractAction<T>* action, OptimizingOperator opt = UNDEFINED) : AbstractFilter<T>(action, opt), child(child) { this->actions.push_back(action); } - LtlFilter(AbstractLtlFormula* child, std::vector<action::Action<T>*> actions) : AbstractFilter<T>(actions), child(child) { + LtlFilter(AbstractLtlFormula<T>* child, std::vector<action::AbstractAction<T>*> actions, OptimizingOperator opt = UNDEFINED) : AbstractFilter<T>(actions, opt), child(child) { // Intentionally left empty. } @@ -52,15 +65,13 @@ public: // Write out the formula to be checked. std::cout << std::endl; - LOG4CPLUS_INFO(logger, "Model checking formula\t" << this->toFormulaString()); - std::cout << "Model checking formula:\t" << this->toFormulaString() << std::endl; + LOG4CPLUS_INFO(logger, "Model checking formula\t" << this->toString()); + std::cout << "Model checking formula:\t" << this->toString() << std::endl; - - // Check the formula and apply the filter actions. - storm::storage::BitVector result; + Result result; try { - result = evaluate(modelchecker, child); + result = evaluate(modelchecker); } catch (std::exception& e) { std::cout << "Error during computation: " << e.what() << "Skipping property." << std::endl; LOG4CPLUS_ERROR(logger, "Error during computation: " << e.what() << "Skipping property."); @@ -69,41 +80,54 @@ public: return; } - // Now write out the result. + writeOut(result, modelchecker); - if(this->actions.empty()) { + } - // There is no filter action given. So provide legacy support: - // Return the results for all states labeled with "init". - LOG4CPLUS_INFO(logger, "Result for initial states:"); - std::cout << "Result for initial states:" << std::endl; - for (auto initialState : modelchecker.getModel<storm::models::AbstractModel<T>>().getInitialStates()) { - LOG4CPLUS_INFO(logger, "\t" << initialState << ": " << (result.get(initialState) ? "satisfied" : "not satisfied")); - std::cout << "\t" << initialState << ": " << result.get(initialState) << std::endl; - } + std::string toString() const override { + std::string desc = ""; + + if(this->actions.empty()){ + // There are no filter actions but only the raw state formula. So just print that. + return child->toString(); } - std::cout << std::endl << "-------------------------------------------" << std::endl; - } + desc = "filter["; + + switch(this->opt) { + case MINIMIZE: + desc += " min, "; + break; + case MAXIMIZE: + desc += " max, "; + break; + default: + break; + } - bool validate() const { - // Test whether the stored filter actions are consistent in relation to themselves and to the ingoing modelchecking result. + for(auto action : this->actions) { + desc += action->toString(); + desc += "; "; + } - //TODO: Actual validation. + // Remove the last "; ". + desc.pop_back(); + desc.pop_back(); - return true; - } + desc += "]"; + + desc += "("; + desc += child->toString(); + desc += ")"; - std::string toFormulaString() const { - std::string desc = "filter("; return desc; } - std::string toString() const { + virtual std::string toPrettyString() const override { std::string desc = "Filter: "; desc += "\nActions:"; for(auto action : this->actions) { - desc += "\n\t" + action.toString(); + desc += "\n\t" + action->toString(); } desc += "\nFormula:\n\t" + child->toString(); return desc; @@ -119,17 +143,71 @@ public: private: - storm::storage::BitVector evaluate(storm::modelchecker::ltl::AbstractModelChecker<T> const & modelchecker, AbstractLtlFormula<T>* formula) const { + Result evaluate(storm::modelchecker::ltl::AbstractModelChecker<T> const & modelchecker) const { // First, get the model checking result. - storm::storage::BitVector result = formula->check(modelchecker); + Result result; + + if(this->opt != UNDEFINED) { + // If it is specified that min/max probabilities/rewards should be computed, call the appropriate method of the model checker. + LOG4CPLUS_ERROR(logger, "Calculation of minimizing and maximizing schedulers for LTL-formula model checking is not yet implemented."); + throw storm::exceptions::NotImplementedException() << "Calculation of minimizing and maximizing schedulers for LTL-formula model checking is not yet implemented."; + } else { + result.stateResult = child->check(modelchecker); + } + + // Now apply all filter actions and return the result. + + // Init the state selection and state map vectors. + result.selection = storm::storage::BitVector(result.stateResult.size(), true); + result.stateMap = std::vector<uint_fast64_t>(result.selection.size()); + for(uint_fast64_t i = 0; i < result.selection.size(); i++) { + result.stateMap[i] = i; + } // Now apply all filter actions and return the result. for(auto action : this->actions) { - result = action->evaluate(result); + result = action->evaluate(result, modelchecker); } + return result; } + void writeOut(Result const & result, storm::modelchecker::ltl::AbstractModelChecker<T> const & modelchecker) const { + + // Test for the kind of result. Values or states. + if(!result.pathResult.empty()) { + + // Write out the selected value results in the order given by the stateMap. + if(this->actions.empty()) { + + // There is no filter action given. So provide legacy support: + // Return the results for all states labeled with "init". + LOG4CPLUS_INFO(logger, "Result for initial states:"); + std::cout << "Result for initial states:" << std::endl; + for (auto initialState : modelchecker.template getModel<storm::models::AbstractModel<T>>().getInitialStates()) { + LOG4CPLUS_INFO(logger, "\t" << initialState << ": " << result.pathResult[initialState]); + std::cout << "\t" << initialState << ": " << result.pathResult[initialState] << std::endl; + } + } else { + LOG4CPLUS_INFO(logger, "Result for " << result.selection.getNumberOfSetBits() << " selected states:"); + std::cout << "Result for " << result.selection.getNumberOfSetBits() << " selected states:" << std::endl; + + for(uint_fast64_t i = 0; i < result.stateMap.size(); i++) { + if(result.selection.get(result.stateMap[i])) { + LOG4CPLUS_INFO(logger, "\t" << result.stateMap[i] << ": " << result.pathResult[result.stateMap[i]]); + std::cout << "\t" << result.stateMap[i] << ": " << result.pathResult[result.stateMap[i]] << std::endl; + } + } + } + + } else { + LOG4CPLUS_WARN(logger, "No results could be computed."); + std::cout << "No results could be computed." << std::endl; + } + + std::cout << std::endl << "-------------------------------------------" << std::endl; + } + AbstractLtlFormula<T>* child; }; diff --git a/src/formula/Prctl/PrctlFilter.h b/src/formula/Prctl/PrctlFilter.h index 77a8c35f7..395337b9a 100644 --- a/src/formula/Prctl/PrctlFilter.h +++ b/src/formula/Prctl/PrctlFilter.h @@ -15,6 +15,7 @@ #include "src/modelchecker/prctl/AbstractModelChecker.h" #include "src/formula/Actions/AbstractAction.h" +// TODO: Test if this can be can be ommitted. namespace storm { namespace property { namespace action { @@ -204,6 +205,7 @@ private: result.stateResult = formula->check(modelchecker); } + // Now apply all filter actions and return the result. return evaluateActions(result, modelchecker); } @@ -218,6 +220,7 @@ private: result.pathResult = formula->check(modelchecker, false); } + // Now apply all filter actions and return the result. return evaluateActions(result, modelchecker); } @@ -232,6 +235,7 @@ private: result.pathResult = formula->check(modelchecker, false); } + // Now apply all filter actions and return the result. return evaluateActions(result, modelchecker); } diff --git a/src/parser/CslParser.cpp b/src/parser/CslParser.cpp index 9e38a9c59..f7b11dd14 100644 --- a/src/parser/CslParser.cpp +++ b/src/parser/CslParser.cpp @@ -174,7 +174,7 @@ struct CslParser::CslGrammar : qi::grammar<Iterator, storm::property::csl::CslFi ); sortAction.name("sort action"); - abstractAction = (rangeAction) >> (qi::eps | qi::lit(";")); + abstractAction = (boundAction | invertAction | formulaAction | rangeAction | sortAction) >> (qi::eps | qi::lit(";")); abstractAction.name("filter action"); filter = (qi::lit("filter") >> qi::lit("[") >> +abstractAction >> qi::lit("]") >> qi::lit("(") >> formula >> qi::lit(")"))[qi::_val = @@ -186,7 +186,7 @@ struct CslParser::CslGrammar : qi::grammar<Iterator, storm::property::csl::CslFi filter.name("CSL formula filter"); - start = (((filter) > (comment | qi::eps))[qi::_val = qi::_1] | comment ) > qi::eoi; + start = (((filter) > (comment | qi::eps))[qi::_val = qi::_1] | comment[qi::_val = nullptr] ) > qi::eoi; start.name("CSL formula filter start"); } diff --git a/src/parser/LtlFileParser.cpp b/src/parser/LtlFileParser.cpp index a53557b89..d3d9459ae 100644 --- a/src/parser/LtlFileParser.cpp +++ b/src/parser/LtlFileParser.cpp @@ -15,7 +15,7 @@ namespace storm { namespace parser { -std::list<storm::property::ltl::AbstractLtlFormula<double>*> LtlFileParser(std::string filename) { +std::list<storm::property::ltl::LtlFilter<double>*> LtlFileParser(std::string filename) { // Open file std::ifstream inputFileStream(filename, std::ios::in); @@ -24,7 +24,7 @@ std::list<storm::property::ltl::AbstractLtlFormula<double>*> LtlFileParser(std:: throw storm::exceptions::FileIoException() << message << filename; } - std::list<storm::property::ltl::AbstractLtlFormula<double>*> result; + std::list<storm::property::ltl::LtlFilter<double>*> result; while(!inputFileStream.eof()) { std::string line; diff --git a/src/parser/LtlFileParser.h b/src/parser/LtlFileParser.h index cb187a82f..7c30abc11 100644 --- a/src/parser/LtlFileParser.h +++ b/src/parser/LtlFileParser.h @@ -9,6 +9,7 @@ #define LTLFILEPARSER_H_ #include "formula/Ltl.h" +#include "src/formula/Ltl/LtlFilter.h" #include <list> @@ -21,7 +22,7 @@ namespace parser { * @param filename * @return The list of parsed formulas */ -std::list<storm::property::ltl::AbstractLtlFormula<double>*> LtlFileParser(std::string filename); +std::list<storm::property::ltl::LtlFilter<double>*> LtlFileParser(std::string filename); } //namespace parser } //namespace storm diff --git a/src/parser/LtlParser.cpp b/src/parser/LtlParser.cpp index 5083837b9..6c4787fee 100644 --- a/src/parser/LtlParser.cpp +++ b/src/parser/LtlParser.cpp @@ -10,6 +10,13 @@ #include "src/utility/OsDetection.h" #include "src/utility/constants.h" +// The action class headers. +#include "src/formula/Actions/AbstractAction.h" +#include "src/formula/Actions/BoundAction.h" +#include "src/formula/Actions/InvertAction.h" +#include "src/formula/Actions/RangeAction.h" +#include "src/formula/Actions/SortAction.h" + // If the parser fails due to ill-formed data, this exception is thrown. #include "src/exceptions/WrongFormatException.h" @@ -41,18 +48,27 @@ namespace storm { namespace parser { template<typename Iterator, typename Skipper> -struct LtlGrammar : qi::grammar<Iterator, storm::property::ltl::AbstractLtlFormula<double>*(), Skipper > { +struct LtlGrammar : qi::grammar<Iterator, storm::property::ltl::LtlFilter<double>*(), Skipper > { LtlGrammar() : LtlGrammar::base_type(start) { //This block contains helper rules that may be used several times freeIdentifierName = qi::lexeme[qi::alpha >> *(qi::alnum | qi::char_('_'))]; + comparisonType = ( + (qi::lit(">="))[qi::_val = storm::property::GREATER_EQUAL] | + (qi::lit(">"))[qi::_val = storm::property::GREATER] | + (qi::lit("<="))[qi::_val = storm::property::LESS_EQUAL] | + (qi::lit("<"))[qi::_val = storm::property::LESS]); + sortingCategory = ( + (qi::lit("index"))[qi::_val = storm::property::action::SortAction<double>::INDEX] | + (qi::lit("value"))[qi::_val = storm::property::action::SortAction<double>::VALUE] + ); //Comment: Empty line or line starting with "//" comment = (qi::lit("//") >> *(qi::char_))[qi::_val = nullptr]; freeIdentifierName = qi::lexeme[+(qi::alpha | qi::char_('_'))]; //This block defines rules for parsing state formulas - ltlFormula %= orFormula; - ltlFormula.name("LTL formula"); + formula %= orFormula; + formula.name("LTL formula"); orFormula = andFormula[qi::_val = qi::_1] > *(qi::lit("|") > andFormula)[qi::_val = phoenix::new_<storm::property::ltl::Or<double>>(qi::_val, qi::_1)]; orFormula.name("LTL formula"); @@ -68,7 +84,7 @@ struct LtlGrammar : qi::grammar<Iterator, storm::property::ltl::AbstractLtlFormu //This block defines rules for "atomic" state formulas //(Propositions, probabilistic/reward formulas, and state formulas in brackets) - atomicLtlFormula %= pathFormula | atomicProposition | qi::lit("(") >> ltlFormula >> qi::lit(")"); + atomicLtlFormula %= pathFormula | atomicProposition | qi::lit("(") >> formula >> qi::lit(")"); atomicLtlFormula.name("LTL formula"); atomicProposition = (freeIdentifierName)[qi::_val = phoenix::new_<storm::property::ltl::Ap<double>>(qi::_1)]; @@ -77,29 +93,73 @@ struct LtlGrammar : qi::grammar<Iterator, storm::property::ltl::AbstractLtlFormu //This block defines rules for parsing probabilistic path formulas pathFormula = (boundedEventually | eventually | globally | next); pathFormula.name("LTL formula"); - boundedEventually = (qi::lit("F") >> qi::lit("<=") > qi::int_ > ltlFormula)[qi::_val = + boundedEventually = (qi::lit("F") >> qi::lit("<=") > qi::int_ > formula)[qi::_val = phoenix::new_<storm::property::ltl::BoundedEventually<double>>(qi::_2, qi::_1)]; boundedEventually.name("LTL formula"); - eventually = (qi::lit("F") >> ltlFormula)[qi::_val = + eventually = (qi::lit("F") >> formula)[qi::_val = phoenix::new_<storm::property::ltl::Eventually<double> >(qi::_1)]; eventually.name("LTL formula"); - globally = (qi::lit("G") >> ltlFormula)[qi::_val = + globally = (qi::lit("G") >> formula)[qi::_val = phoenix::new_<storm::property::ltl::Globally<double> >(qi::_1)]; globally.name("LTL formula"); - next = (qi::lit("X") >> ltlFormula)[qi::_val = + next = (qi::lit("X") >> formula)[qi::_val = phoenix::new_<storm::property::ltl::Next<double> >(qi::_1)]; next.name("LTL formula"); - start = (((ltlFormula) > (comment | qi::eps))[qi::_val = qi::_1] | - comment - ) > qi::eoi; + // This block defines rules for parsing filter actions. + boundAction = (qi::lit("bound") > qi::lit("(") >> comparisonType >> qi::lit(",") >> qi::double_ >> qi::lit(")"))[qi::_val = + phoenix::new_<storm::property::action::BoundAction<double>>(qi::_1, qi::_2)]; + boundAction.name("bound action"); + + invertAction = qi::lit("invert")[qi::_val = phoenix::new_<storm::property::action::InvertAction<double>>()]; + invertAction.name("invert action"); + + rangeAction = ( + (qi::lit("range") >> qi::lit("(") >> qi::uint_ >> qi::lit(",") > qi::uint_ >> qi::lit(")"))[qi::_val = + phoenix::new_<storm::property::action::RangeAction<double>>(qi::_1, qi::_2)] | + (qi::lit("range") >> qi::lit("(") >> qi::uint_ >> qi::lit(")"))[qi::_val = + phoenix::new_<storm::property::action::RangeAction<double>>(qi::_1, qi::_1 + 1)] + ); + rangeAction.name("range action"); + + sortAction = ( + (qi::lit("sort") > qi::lit("(") >> sortingCategory >> qi::lit(")"))[qi::_val = + phoenix::new_<storm::property::action::SortAction<double>>(qi::_1)] | + (qi::lit("sort") > qi::lit("(") >> sortingCategory >> qi::lit(", ") >> qi::lit("asc") > qi::lit(")"))[qi::_val = + phoenix::new_<storm::property::action::SortAction<double>>(qi::_1, true)] | + (qi::lit("sort") > qi::lit("(") >> sortingCategory >> qi::lit(", ") >> qi::lit("desc") > qi::lit(")"))[qi::_val = + phoenix::new_<storm::property::action::SortAction<double>>(qi::_1, false)] + ); + sortAction.name("sort action"); + + abstractAction = (boundAction | invertAction | rangeAction | sortAction) >> (qi::eps | qi::lit(";")); + abstractAction.name("filter action"); + + filter = (qi::lit("filter") >> qi::lit("[") >> +abstractAction >> qi::lit("]") > qi::lit("(") >> formula >> qi::lit(")"))[qi::_val = + phoenix::new_<storm::property::ltl::LtlFilter<double>>(qi::_2, qi::_1)] | + (qi::lit("filter") >> qi::lit("[") >> qi::lit("max") > +abstractAction >> qi::lit("]") >> qi::lit("(") >> formula >> qi::lit(")"))[qi::_val = + phoenix::new_<storm::property::ltl::LtlFilter<double>>(qi::_2, qi::_1, storm::property::MAXIMIZE)] | + (qi::lit("filter") >> qi::lit("[") >> qi::lit("min") > +abstractAction >> qi::lit("]") >> qi::lit("(") >> formula >> qi::lit(")"))[qi::_val = + phoenix::new_<storm::property::ltl::LtlFilter<double>>(qi::_2, qi::_1, storm::property::MINIMIZE)] | + (formula)[qi::_val = + phoenix::new_<storm::property::ltl::LtlFilter<double>>(qi::_1)]; + filter.name("PRCTL formula filter"); + + start = (((filter) > (comment | qi::eps))[qi::_val = qi::_1] | comment[qi::_val = nullptr] ) > qi::eoi; start.name("LTL formula"); } - qi::rule<Iterator, storm::property::ltl::AbstractLtlFormula<double>*(), Skipper> start; - qi::rule<Iterator, storm::property::ltl::AbstractLtlFormula<double>*(), Skipper> comment; + qi::rule<Iterator, storm::property::ltl::LtlFilter<double>*(), Skipper> start; + qi::rule<Iterator, storm::property::ltl::LtlFilter<double>*(), Skipper> filter; + + qi::rule<Iterator, storm::property::action::AbstractAction<double>*(), Skipper> abstractAction; + qi::rule<Iterator, storm::property::action::BoundAction<double>*(), Skipper> boundAction; + qi::rule<Iterator, storm::property::action::InvertAction<double>*(), Skipper> invertAction; + qi::rule<Iterator, storm::property::action::RangeAction<double>*(), Skipper> rangeAction; + qi::rule<Iterator, storm::property::action::SortAction<double>*(), Skipper> sortAction; - qi::rule<Iterator, storm::property::ltl::AbstractLtlFormula<double>*(), Skipper> ltlFormula; + qi::rule<Iterator, storm::property::ltl::AbstractLtlFormula<double>*(), Skipper> comment; + qi::rule<Iterator, storm::property::ltl::AbstractLtlFormula<double>*(), Skipper> formula; qi::rule<Iterator, storm::property::ltl::AbstractLtlFormula<double>*(), Skipper> atomicLtlFormula; qi::rule<Iterator, storm::property::ltl::AbstractLtlFormula<double>*(), Skipper> andFormula; @@ -107,10 +167,6 @@ struct LtlGrammar : qi::grammar<Iterator, storm::property::ltl::AbstractLtlFormu qi::rule<Iterator, storm::property::ltl::AbstractLtlFormula<double>*(), Skipper> atomicProposition; qi::rule<Iterator, storm::property::ltl::AbstractLtlFormula<double>*(), Skipper> orFormula; qi::rule<Iterator, storm::property::ltl::AbstractLtlFormula<double>*(), Skipper> notFormula; - //qi::rule<Iterator, storm::property::ltl::ProbabilisticBoundOperator<double>*(), Skipper> probabilisticBoundOperator; - - //qi::rule<Iterator, storm::property::ltl::AbstractNoBoundOperator<double>*(), Skipper> noBoundOperator; - //qi::rule<Iterator, storm::property::ltl::AbstractNoBoundOperator<double>*(), Skipper> probabilisticNoBoundOperator; qi::rule<Iterator, storm::property::ltl::AbstractLtlFormula<double>*(), Skipper> pathFormula; qi::rule<Iterator, storm::property::ltl::BoundedEventually<double>*(), Skipper> boundedEventually; @@ -121,6 +177,8 @@ struct LtlGrammar : qi::grammar<Iterator, storm::property::ltl::AbstractLtlFormu qi::rule<Iterator, storm::property::ltl::AbstractLtlFormula<double>*(), qi::locals< std::shared_ptr<storm::property::ltl::AbstractLtlFormula<double>>>, Skipper> until; qi::rule<Iterator, std::string(), Skipper> freeIdentifierName; + qi::rule<Iterator, storm::property::ComparisonType(), Skipper> comparisonType; + qi::rule<Iterator, storm::property::action::SortAction<double>::SortingCategory(), Skipper> sortingCategory; }; @@ -128,7 +186,7 @@ struct LtlGrammar : qi::grammar<Iterator, storm::property::ltl::AbstractLtlFormu } //namespace parser -storm::property::ltl::AbstractLtlFormula<double>* storm::parser::LtlParser(std::string formulaString) { +storm::property::ltl::LtlFilter<double>* storm::parser::LtlParser(std::string formulaString) { // Prepare iterators to input. BaseIteratorType stringIteratorBegin = formulaString.begin(); BaseIteratorType stringIteratorEnd = formulaString.end(); @@ -137,7 +195,7 @@ storm::property::ltl::AbstractLtlFormula<double>* storm::parser::LtlParser(std:: // Prepare resulting intermediate representation of input. - storm::property::ltl::AbstractLtlFormula<double>* result_pointer = nullptr; + storm::property::ltl::LtlFilter<double>* result_pointer = nullptr; LtlGrammar<PositionIteratorType, BOOST_TYPEOF(boost::spirit::ascii::space)> grammar; diff --git a/src/parser/LtlParser.h b/src/parser/LtlParser.h index cefcd8f2c..bbf10d259 100644 --- a/src/parser/LtlParser.h +++ b/src/parser/LtlParser.h @@ -9,6 +9,7 @@ #define STORM_PARSER_LTLPARSER_H_ #include "src/formula/Ltl.h" +#include "src/formula/Ltl/LtlFilter.h" namespace storm { namespace parser { @@ -22,7 +23,7 @@ namespace parser { * @param formulaString The string representation of the formula * @throw wrongFormatException If the input could not be parsed successfully */ -storm::property::ltl::AbstractLtlFormula<double>* LtlParser(std::string formulaString); +storm::property::ltl::LtlFilter<double>* LtlParser(std::string formulaString); /*! * Struct for the Ltl grammar, that Boost::Spirit uses to parse the formulas. diff --git a/src/parser/PrctlParser.cpp b/src/parser/PrctlParser.cpp index 0fb8b538a..7675f1cd3 100644 --- a/src/parser/PrctlParser.cpp +++ b/src/parser/PrctlParser.cpp @@ -180,7 +180,7 @@ struct PrctlParser::PrctlGrammar : qi::grammar<Iterator, storm::property::prctl: ); sortAction.name("sort action"); - abstractAction = (rangeAction) >> (qi::eps | qi::lit(";")); + abstractAction = (boundAction | invertAction | formulaAction | rangeAction | sortAction) >> (qi::eps | qi::lit(";")); abstractAction.name("filter action"); filter = (qi::lit("filter") >> qi::lit("[") >> +abstractAction >> qi::lit("]") > qi::lit("(") >> formula >> qi::lit(")"))[qi::_val = From 9fe246a98b5e38cfce0107902e5c8bc823825a5b Mon Sep 17 00:00:00 2001 From: masawei <manuel.sascha.weiand@rwth-aachen.de> Date: Sat, 28 Jun 2014 23:25:33 +0200 Subject: [PATCH 16/30] Renamed the folders containing the formulas to lowercase to adhere to the naming conventions and Started with testing. -Tests for BoundAction done Former-commit-id: d5698d3d53e682c8e5ca7a3adfed798e04aef97d --- src/formula/AbstractFilter.h | 2 +- src/formula/Csl.h | 24 +-- src/formula/Ltl.h | 20 +-- src/formula/Prctl.h | 48 +++--- .../{Actions => actions}/AbstractAction.h | 0 .../{Actions => actions}/BoundAction.h | 44 ++--- .../{Actions => actions}/FormulaAction.h | 5 +- .../{Actions => actions}/InvertAction.h | 2 +- .../{Actions => actions}/RangeAction.h | 2 +- src/formula/{Actions => actions}/SortAction.h | 2 +- src/formula/{Csl => csl}/AbstractCslFormula.h | 0 .../{Csl => csl}/AbstractPathFormula.h | 2 +- .../{Csl => csl}/AbstractStateFormula.h | 2 +- src/formula/{Csl => csl}/And.h | 2 +- src/formula/{Csl => csl}/Ap.h | 2 +- src/formula/{Csl => csl}/CslFilter.h | 8 +- src/formula/{Csl => csl}/Eventually.h | 4 +- src/formula/{Csl => csl}/Globally.h | 4 +- src/formula/{Csl => csl}/Next.h | 4 +- src/formula/{Csl => csl}/Not.h | 2 +- src/formula/{Csl => csl}/Or.h | 2 +- .../{Csl => csl}/ProbabilisticBoundOperator.h | 4 +- .../{Csl => csl}/SteadyStateBoundOperator.h | 0 .../{Csl => csl}/TimeBoundedEventually.h | 4 +- src/formula/{Csl => csl}/TimeBoundedUntil.h | 4 +- src/formula/{Csl => csl}/Until.h | 4 +- src/formula/{Ltl => ltl}/AbstractLtlFormula.h | 0 src/formula/{Ltl => ltl}/And.h | 0 src/formula/{Ltl => ltl}/Ap.h | 0 src/formula/{Ltl => ltl}/BoundedEventually.h | 0 src/formula/{Ltl => ltl}/BoundedUntil.h | 2 +- src/formula/{Ltl => ltl}/Eventually.h | 2 +- src/formula/{Ltl => ltl}/Globally.h | 0 src/formula/{Ltl => ltl}/LtlFilter.h | 4 +- src/formula/{Ltl => ltl}/Next.h | 0 src/formula/{Ltl => ltl}/Not.h | 0 src/formula/{Ltl => ltl}/Or.h | 0 src/formula/{Ltl => ltl}/Until.h | 0 .../visitor/AbstractLtlFormulaVisitor.cpp | 0 .../visitor/AbstractLtlFormulaVisitor.h | 0 .../{Prctl => prctl}/AbstractPathFormula.h | 2 +- .../{Prctl => prctl}/AbstractPrctlFormula.h | 0 .../AbstractRewardPathFormula.h | 2 + .../{Prctl => prctl}/AbstractStateFormula.h | 2 +- src/formula/{Prctl => prctl}/And.h | 2 +- src/formula/{Prctl => prctl}/Ap.h | 2 +- .../{Prctl => prctl}/BoundedEventually.h | 4 +- .../{Prctl => prctl}/BoundedNaryUntil.h | 4 +- src/formula/{Prctl => prctl}/BoundedUntil.h | 4 +- .../{Prctl => prctl}/CumulativeReward.h | 0 src/formula/{Prctl => prctl}/Eventually.h | 4 +- src/formula/{Prctl => prctl}/Globally.h | 4 +- .../{Prctl => prctl}/InstantaneousReward.h | 0 src/formula/{Prctl => prctl}/Next.h | 4 +- src/formula/{Prctl => prctl}/Not.h | 0 src/formula/{Prctl => prctl}/Or.h | 2 +- src/formula/{Prctl => prctl}/PrctlFilter.h | 8 +- .../ProbabilisticBoundOperator.h | 0 .../{Prctl => prctl}/ReachabilityReward.h | 0 .../{Prctl => prctl}/RewardBoundOperator.h | 0 .../{Prctl => prctl}/SteadyStateReward.h | 0 src/formula/{Prctl => prctl}/Until.h | 0 src/parser/CslParser.cpp | 12 +- src/parser/CslParser.h | 2 +- src/parser/LtlFileParser.cpp | 4 +- src/parser/LtlFileParser.h | 20 ++- src/parser/LtlParser.cpp | 20 +-- src/parser/LtlParser.h | 26 ++- src/parser/PrctlFileParser.h | 2 +- src/parser/PrctlParser.cpp | 20 +-- src/parser/PrctlParser.h | 6 +- test/functional/parser/ActionTest.cpp | 157 ++++++++++++++++++ test/functional/parser/LtlParserTest.cpp | 39 +++-- 73 files changed, 366 insertions(+), 191 deletions(-) rename src/formula/{Actions => actions}/AbstractAction.h (100%) rename src/formula/{Actions => actions}/BoundAction.h (62%) rename src/formula/{Actions => actions}/FormulaAction.h (94%) rename src/formula/{Actions => actions}/InvertAction.h (96%) rename src/formula/{Actions => actions}/RangeAction.h (98%) rename src/formula/{Actions => actions}/SortAction.h (98%) rename src/formula/{Csl => csl}/AbstractCslFormula.h (100%) rename src/formula/{Csl => csl}/AbstractPathFormula.h (97%) rename src/formula/{Csl => csl}/AbstractStateFormula.h (97%) rename src/formula/{Csl => csl}/And.h (98%) rename src/formula/{Csl => csl}/Ap.h (98%) rename src/formula/{Csl => csl}/CslFilter.h (97%) rename src/formula/{Csl => csl}/Eventually.h (97%) rename src/formula/{Csl => csl}/Globally.h (97%) rename src/formula/{Csl => csl}/Next.h (97%) rename src/formula/{Csl => csl}/Not.h (98%) rename src/formula/{Csl => csl}/Or.h (98%) rename src/formula/{Csl => csl}/ProbabilisticBoundOperator.h (98%) rename src/formula/{Csl => csl}/SteadyStateBoundOperator.h (100%) rename src/formula/{Csl => csl}/TimeBoundedEventually.h (97%) rename src/formula/{Csl => csl}/TimeBoundedUntil.h (98%) rename src/formula/{Csl => csl}/Until.h (97%) rename src/formula/{Ltl => ltl}/AbstractLtlFormula.h (100%) rename src/formula/{Ltl => ltl}/And.h (100%) rename src/formula/{Ltl => ltl}/Ap.h (100%) rename src/formula/{Ltl => ltl}/BoundedEventually.h (100%) rename src/formula/{Ltl => ltl}/BoundedUntil.h (99%) rename src/formula/{Ltl => ltl}/Eventually.h (98%) rename src/formula/{Ltl => ltl}/Globally.h (100%) rename src/formula/{Ltl => ltl}/LtlFilter.h (98%) rename src/formula/{Ltl => ltl}/Next.h (100%) rename src/formula/{Ltl => ltl}/Not.h (100%) rename src/formula/{Ltl => ltl}/Or.h (100%) rename src/formula/{Ltl => ltl}/Until.h (100%) rename src/formula/{Ltl => ltl}/visitor/AbstractLtlFormulaVisitor.cpp (100%) rename src/formula/{Ltl => ltl}/visitor/AbstractLtlFormulaVisitor.h (100%) rename src/formula/{Prctl => prctl}/AbstractPathFormula.h (97%) rename src/formula/{Prctl => prctl}/AbstractPrctlFormula.h (100%) rename src/formula/{Prctl => prctl}/AbstractRewardPathFormula.h (97%) rename src/formula/{Prctl => prctl}/AbstractStateFormula.h (97%) rename src/formula/{Prctl => prctl}/And.h (98%) rename src/formula/{Prctl => prctl}/Ap.h (98%) rename src/formula/{Prctl => prctl}/BoundedEventually.h (97%) rename src/formula/{Prctl => prctl}/BoundedNaryUntil.h (98%) rename src/formula/{Prctl => prctl}/BoundedUntil.h (98%) rename src/formula/{Prctl => prctl}/CumulativeReward.h (100%) rename src/formula/{Prctl => prctl}/Eventually.h (97%) rename src/formula/{Prctl => prctl}/Globally.h (97%) rename src/formula/{Prctl => prctl}/InstantaneousReward.h (100%) rename src/formula/{Prctl => prctl}/Next.h (97%) rename src/formula/{Prctl => prctl}/Not.h (100%) rename src/formula/{Prctl => prctl}/Or.h (98%) rename src/formula/{Prctl => prctl}/PrctlFilter.h (98%) rename src/formula/{Prctl => prctl}/ProbabilisticBoundOperator.h (100%) rename src/formula/{Prctl => prctl}/ReachabilityReward.h (100%) rename src/formula/{Prctl => prctl}/RewardBoundOperator.h (100%) rename src/formula/{Prctl => prctl}/SteadyStateReward.h (100%) rename src/formula/{Prctl => prctl}/Until.h (100%) create mode 100644 test/functional/parser/ActionTest.cpp diff --git a/src/formula/AbstractFilter.h b/src/formula/AbstractFilter.h index ba95d5524..0d03d3b0d 100644 --- a/src/formula/AbstractFilter.h +++ b/src/formula/AbstractFilter.h @@ -11,7 +11,7 @@ #include <vector> #include <string> #include "src/formula/AbstractFormula.h" -#include "src/formula/Actions/AbstractAction.h" +#include "src/formula/actions/AbstractAction.h" namespace storm { namespace property { diff --git a/src/formula/Csl.h b/src/formula/Csl.h index 8e856f459..f76385f89 100644 --- a/src/formula/Csl.h +++ b/src/formula/Csl.h @@ -10,19 +10,19 @@ #include "src/modelchecker/csl/ForwardDeclarations.h" -#include "Csl/And.h" -#include "Csl/Ap.h" -#include "Csl/Next.h" -#include "Csl/Not.h" -#include "Csl/Or.h" -#include "Csl/ProbabilisticBoundOperator.h" -#include "Csl/SteadyStateBoundOperator.h" +#include "csl/And.h" +#include "csl/Ap.h" +#include "csl/Next.h" +#include "csl/Not.h" +#include "csl/Or.h" +#include "csl/ProbabilisticBoundOperator.h" +#include "csl/SteadyStateBoundOperator.h" -#include "Csl/Until.h" -#include "Csl/Eventually.h" -#include "Csl/Globally.h" -#include "Csl/TimeBoundedEventually.h" -#include "Csl/TimeBoundedUntil.h" +#include "csl/Until.h" +#include "csl/Eventually.h" +#include "csl/Globally.h" +#include "csl/TimeBoundedEventually.h" +#include "csl/TimeBoundedUntil.h" #include "modelchecker/csl/AbstractModelChecker.h" diff --git a/src/formula/Ltl.h b/src/formula/Ltl.h index cac53a8be..69551ff5c 100644 --- a/src/formula/Ltl.h +++ b/src/formula/Ltl.h @@ -10,16 +10,16 @@ #include "src/modelchecker/ltl/ForwardDeclarations.h" -#include "Ltl/And.h" -#include "Ltl/Ap.h" -#include "Ltl/BoundedEventually.h" -#include "Ltl/BoundedUntil.h" -#include "Ltl/Eventually.h" -#include "Ltl/Globally.h" -#include "Ltl/Next.h" -#include "Ltl/Not.h" -#include "Ltl/Or.h" -#include "Ltl/Until.h" +#include "ltl/And.h" +#include "ltl/Ap.h" +#include "ltl/BoundedEventually.h" +#include "ltl/BoundedUntil.h" +#include "ltl/Eventually.h" +#include "ltl/Globally.h" +#include "ltl/Next.h" +#include "ltl/Not.h" +#include "ltl/Or.h" +#include "ltl/Until.h" #include "modelchecker/ltl/AbstractModelChecker.h" diff --git a/src/formula/Prctl.h b/src/formula/Prctl.h index e174d445e..d66e92e03 100644 --- a/src/formula/Prctl.h +++ b/src/formula/Prctl.h @@ -10,30 +10,30 @@ #include "modelchecker/prctl/ForwardDeclarations.h" -#include "Prctl/And.h" -#include "Prctl/Ap.h" -#include "Prctl/BoundedUntil.h" -#include "Prctl/BoundedNaryUntil.h" -#include "Prctl/Next.h" -#include "Prctl/Not.h" -#include "Prctl/Or.h" -#include "Prctl/ProbabilisticBoundOperator.h" - -#include "Prctl/Until.h" -#include "Prctl/Eventually.h" -#include "Prctl/Globally.h" -#include "Prctl/BoundedEventually.h" - -#include "Prctl/InstantaneousReward.h" -#include "Prctl/CumulativeReward.h" -#include "Prctl/ReachabilityReward.h" -#include "Prctl/RewardBoundOperator.h" -#include "Prctl/SteadyStateReward.h" - -#include "Prctl/AbstractPrctlFormula.h" -#include "Prctl/AbstractStateFormula.h" -#include "Prctl/AbstractPathFormula.h" -#include "Prctl/AbstractRewardPathFormula.h" +#include "prctl/And.h" +#include "prctl/Ap.h" +#include "prctl/BoundedUntil.h" +#include "prctl/BoundedNaryUntil.h" +#include "prctl/Next.h" +#include "prctl/Not.h" +#include "prctl/Or.h" +#include "prctl/ProbabilisticBoundOperator.h" + +#include "prctl/Until.h" +#include "prctl/Eventually.h" +#include "prctl/Globally.h" +#include "prctl/BoundedEventually.h" + +#include "prctl/InstantaneousReward.h" +#include "prctl/CumulativeReward.h" +#include "prctl/ReachabilityReward.h" +#include "prctl/RewardBoundOperator.h" +#include "prctl/SteadyStateReward.h" + +#include "prctl/AbstractPrctlFormula.h" +#include "prctl/AbstractStateFormula.h" +#include "prctl/AbstractPathFormula.h" +#include "prctl/AbstractRewardPathFormula.h" #include "modelchecker/prctl/AbstractModelChecker.h" diff --git a/src/formula/Actions/AbstractAction.h b/src/formula/actions/AbstractAction.h similarity index 100% rename from src/formula/Actions/AbstractAction.h rename to src/formula/actions/AbstractAction.h diff --git a/src/formula/Actions/BoundAction.h b/src/formula/actions/BoundAction.h similarity index 62% rename from src/formula/Actions/BoundAction.h rename to src/formula/actions/BoundAction.h index 4b7f77cc0..f90107742 100644 --- a/src/formula/Actions/BoundAction.h +++ b/src/formula/actions/BoundAction.h @@ -8,8 +8,9 @@ #ifndef STORM_FORMULA_ACTION_BOUNDACTION_H_ #define STORM_FORMULA_ACTION_BOUNDACTION_H_ -#include "src/formula/Actions/AbstractAction.h" +#include "src/formula/actions/AbstractAction.h" #include "src/formula/ComparisonType.h" +#include "src/exceptions/InvalidArgumentException.h" namespace storm { namespace property { @@ -78,8 +79,8 @@ public: out += ">="; break; default: - LOG4CPLUS_INFO(logger, "Unknown comparison operator of value " << comparisonOperator << "."); - std::cout << "Unknown comparison operator of value " << comparisonOperator << "." << std::endl; + LOG4CPLUS_ERROR(logger, "Unknown comparison operator of value " << comparisonOperator << "."); + throw storm::exceptions::InvalidArgumentException() << "Unknown comparison operator of value " << comparisonOperator << "."; break; } out += ", "; @@ -100,25 +101,30 @@ private: if(result.pathResult.size() != 0) { - //Fill the selction by comapring the values for all previously selected states with theegiven bound using the comparison operator. - for(uint_fast64_t i = 0; i < result.stateMap.size(); i++) { - if(result.selection[result.stateMap[i]]) { + if(result.stateResult.size() != 0) { + LOG4CPLUS_WARN(logger, "Both pathResult and stateResult are set. The filter action is applied using only the pathResult."); + std::cout << "Both pathResult and stateResult are set. The filter action is applied using only the pathResult." << std::endl; + } + + //Fill the selection by comparing the values for all previously selected states with the given bound using the comparison operator. + for(uint_fast64_t i = 0; i < result.pathResult.size(); i++) { + if(result.selection[i]) { switch(comparisonOperator) { case storm::property::GREATER_EQUAL: - out.set(result.pathResult[result.stateMap[i]] >= bound); + out.set(i, result.pathResult[i] >= bound); break; case storm::property::GREATER: - out.set(result.pathResult[result.stateMap[i]] > bound); + out.set(i, result.pathResult[i] > bound); break; case storm::property::LESS_EQUAL: - out.set(result.pathResult[result.stateMap[i]] <= bound); + out.set(i, result.pathResult[i] <= bound); break; case storm::property::LESS: - out.set(result.pathResult[result.stateMap[i]] < bound); + out.set(i, result.pathResult[i] < bound); break; default: - LOG4CPLUS_INFO(logger, "Unknown comparison operator of value " << comparisonOperator << "."); - std::cout << "Unknown comparison operator of value " << comparisonOperator << "." << std::endl; + LOG4CPLUS_ERROR(logger, "Unknown comparison operator of value " << comparisonOperator << "."); + throw storm::exceptions::InvalidArgumentException() << "Unknown comparison operator of value " << comparisonOperator << "."; break; } } @@ -127,23 +133,23 @@ private: //Fill the selction by comapring the values for all previously selected states with theegiven bound using the comparison operator. for(uint_fast64_t i = 0; i < result.stateMap.size(); i++) { - if(result.selection[result.stateMap[i]]) { + if(result.selection[i]) { switch(comparisonOperator) { case storm::property::GREATER_EQUAL: - out.set(result.stateResult[result.stateMap[i]] >= bound); + out.set(i, result.stateResult[i] >= bound); break; case storm::property::GREATER: - out.set(result.stateResult[result.stateMap[i]] > bound); + out.set(i, result.stateResult[i] > bound); break; case storm::property::LESS_EQUAL: - out.set(result.stateResult[result.stateMap[i]] <= bound); + out.set(i, result.stateResult[i] <= bound); break; case storm::property::LESS: - out.set(result.stateResult[result.stateMap[i]] < bound); + out.set(i, result.stateResult[i] < bound); break; default: - LOG4CPLUS_INFO(logger, "Unknown comparison operator of value " << comparisonOperator << "."); - std::cout << "Unknown comparison operator of value " << comparisonOperator << "." << std::endl; + LOG4CPLUS_ERROR(logger, "Unknown comparison operator of value " << comparisonOperator << "."); + throw storm::exceptions::InvalidArgumentException() << "Unknown comparison operator of value " << comparisonOperator << "."; break; } } diff --git a/src/formula/Actions/FormulaAction.h b/src/formula/actions/FormulaAction.h similarity index 94% rename from src/formula/Actions/FormulaAction.h rename to src/formula/actions/FormulaAction.h index 805bc1acb..e3867c721 100644 --- a/src/formula/Actions/FormulaAction.h +++ b/src/formula/actions/FormulaAction.h @@ -8,8 +8,9 @@ #ifndef STORM_FORMULA_ACTION_FORMULAACTION_H_ #define STORM_FORMULA_ACTION_FORMULAACTION_H_ -#include "src/formula/Actions/AbstractAction.h" -#include "src/formula/Prctl/AbstractStateFormula.h" +#include "src/formula/actions/AbstractAction.h" +#include "src/formula/prctl/AbstractStateFormula.h" +#include "src/formula/csl/AbstractStateFormula.h" #include <string> diff --git a/src/formula/Actions/InvertAction.h b/src/formula/actions/InvertAction.h similarity index 96% rename from src/formula/Actions/InvertAction.h rename to src/formula/actions/InvertAction.h index 90192020c..5492e4644 100644 --- a/src/formula/Actions/InvertAction.h +++ b/src/formula/actions/InvertAction.h @@ -8,7 +8,7 @@ #ifndef STORM_FORMULA_ACTION_INVERTACTION_H_ #define STORM_FORMULA_ACTION_INVERTACTION_H_ -#include "src/formula/Actions/AbstractAction.h" +#include "src/formula/actions/AbstractAction.h" namespace storm { namespace property { diff --git a/src/formula/Actions/RangeAction.h b/src/formula/actions/RangeAction.h similarity index 98% rename from src/formula/Actions/RangeAction.h rename to src/formula/actions/RangeAction.h index ce8b0e2ae..85cf7c4af 100644 --- a/src/formula/Actions/RangeAction.h +++ b/src/formula/actions/RangeAction.h @@ -8,7 +8,7 @@ #ifndef STORM_FORMULA_ACTION_RANGEACTION_H_ #define STORM_FORMULA_ACTION_RANGEACTION_H_ -#include "src/formula/Actions/AbstractAction.h" +#include "src/formula/actions/AbstractAction.h" namespace storm { namespace property { diff --git a/src/formula/Actions/SortAction.h b/src/formula/actions/SortAction.h similarity index 98% rename from src/formula/Actions/SortAction.h rename to src/formula/actions/SortAction.h index 5a4c1c622..d75e32fd7 100644 --- a/src/formula/Actions/SortAction.h +++ b/src/formula/actions/SortAction.h @@ -8,7 +8,7 @@ #ifndef STORM_FORMULA_ACTION_SORTACTION_H_ #define STORM_FORMULA_ACTION_SORTACTION_H_ -#include "src/formula/Actions/AbstractAction.h" +#include "src/formula/actions/AbstractAction.h" #include <cctype> namespace storm { diff --git a/src/formula/Csl/AbstractCslFormula.h b/src/formula/csl/AbstractCslFormula.h similarity index 100% rename from src/formula/Csl/AbstractCslFormula.h rename to src/formula/csl/AbstractCslFormula.h diff --git a/src/formula/Csl/AbstractPathFormula.h b/src/formula/csl/AbstractPathFormula.h similarity index 97% rename from src/formula/Csl/AbstractPathFormula.h rename to src/formula/csl/AbstractPathFormula.h index 951bc6f41..d2cd10fa9 100644 --- a/src/formula/Csl/AbstractPathFormula.h +++ b/src/formula/csl/AbstractPathFormula.h @@ -16,7 +16,7 @@ template<class T> class AbstractPathFormula; } //namespace property } //namespace storm -#include "src/formula/Csl/AbstractCslFormula.h" +#include "src/formula/csl/AbstractCslFormula.h" #include "src/modelchecker/csl/ForwardDeclarations.h" #include <vector> diff --git a/src/formula/Csl/AbstractStateFormula.h b/src/formula/csl/AbstractStateFormula.h similarity index 97% rename from src/formula/Csl/AbstractStateFormula.h rename to src/formula/csl/AbstractStateFormula.h index 2bd16471b..07f227961 100644 --- a/src/formula/Csl/AbstractStateFormula.h +++ b/src/formula/csl/AbstractStateFormula.h @@ -8,7 +8,7 @@ #ifndef STORM_FORMULA_CSL_ABSTRACTSTATEFORMULA_H_ #define STORM_FORMULA_CSL_ABSTRACTSTATEFORMULA_H_ -#include "src/formula/Csl/AbstractCslFormula.h" +#include "src/formula/csl/AbstractCslFormula.h" #include "src/storage/BitVector.h" #include "src/modelchecker/csl/ForwardDeclarations.h" diff --git a/src/formula/Csl/And.h b/src/formula/csl/And.h similarity index 98% rename from src/formula/Csl/And.h rename to src/formula/csl/And.h index 1453cc30b..e8a04e79f 100644 --- a/src/formula/Csl/And.h +++ b/src/formula/csl/And.h @@ -8,7 +8,7 @@ #ifndef STORM_FORMULA_CSL_AND_H_ #define STORM_FORMULA_CSL_AND_H_ -#include "src/formula/Csl/AbstractStateFormula.h" +#include "src/formula/csl/AbstractStateFormula.h" #include "src/formula/AbstractFormulaChecker.h" #include "src/modelchecker/csl/ForwardDeclarations.h" #include <string> diff --git a/src/formula/Csl/Ap.h b/src/formula/csl/Ap.h similarity index 98% rename from src/formula/Csl/Ap.h rename to src/formula/csl/Ap.h index 66f49c503..0f59dd97b 100644 --- a/src/formula/Csl/Ap.h +++ b/src/formula/csl/Ap.h @@ -8,7 +8,7 @@ #ifndef STORM_FORMULA_CSL_AP_H_ #define STORM_FORMULA_CSL_AP_H_ -#include "src/formula/Csl/AbstractStateFormula.h" +#include "src/formula/csl/AbstractStateFormula.h" #include "src/formula/AbstractFormulaChecker.h" #include "src/modelchecker/csl/ForwardDeclarations.h" diff --git a/src/formula/Csl/CslFilter.h b/src/formula/csl/CslFilter.h similarity index 97% rename from src/formula/Csl/CslFilter.h rename to src/formula/csl/CslFilter.h index 928163fbd..c6144ad02 100644 --- a/src/formula/Csl/CslFilter.h +++ b/src/formula/csl/CslFilter.h @@ -9,12 +9,12 @@ #define STORM_FORMULA_PRCTL_CSLFILTER_H_ #include "src/formula/AbstractFilter.h" -#include "src/formula/Csl/AbstractCslFormula.h" -#include "src/formula/Csl/AbstractPathFormula.h" -#include "src/formula/Csl/AbstractStateFormula.h" +#include "src/formula/csl/AbstractCslFormula.h" +#include "src/formula/csl/AbstractPathFormula.h" +#include "src/formula/csl/AbstractStateFormula.h" #include "src/modelchecker/csl/AbstractModelChecker.h" -#include "src/formula/Actions/AbstractAction.h" +#include "src/formula/actions/AbstractAction.h" namespace storm { namespace property { diff --git a/src/formula/Csl/Eventually.h b/src/formula/csl/Eventually.h similarity index 97% rename from src/formula/Csl/Eventually.h rename to src/formula/csl/Eventually.h index 1d1f1a358..c72f0ce8e 100644 --- a/src/formula/Csl/Eventually.h +++ b/src/formula/csl/Eventually.h @@ -8,8 +8,8 @@ #ifndef STORM_FORMULA_CSL_EVENTUALLY_H_ #define STORM_FORMULA_CSL_EVENTUALLY_H_ -#include "src/formula/Csl/AbstractPathFormula.h" -#include "src/formula/Csl/AbstractStateFormula.h" +#include "src/formula/csl/AbstractPathFormula.h" +#include "src/formula/csl/AbstractStateFormula.h" #include "src/modelchecker/csl/ForwardDeclarations.h" namespace storm { diff --git a/src/formula/Csl/Globally.h b/src/formula/csl/Globally.h similarity index 97% rename from src/formula/Csl/Globally.h rename to src/formula/csl/Globally.h index 85cd32396..f4cd4e71c 100644 --- a/src/formula/Csl/Globally.h +++ b/src/formula/csl/Globally.h @@ -8,8 +8,8 @@ #ifndef STORM_FORMULA_CSL_GLOBALLY_H_ #define STORM_FORMULA_CSL_GLOBALLY_H_ -#include "src/formula/Csl/AbstractPathFormula.h" -#include "src/formula/Csl/AbstractStateFormula.h" +#include "src/formula/csl/AbstractPathFormula.h" +#include "src/formula/csl/AbstractStateFormula.h" #include "src/formula/AbstractFormulaChecker.h" #include "src/modelchecker/csl/ForwardDeclarations.h" diff --git a/src/formula/Csl/Next.h b/src/formula/csl/Next.h similarity index 97% rename from src/formula/Csl/Next.h rename to src/formula/csl/Next.h index f014190aa..e1c7d5407 100644 --- a/src/formula/Csl/Next.h +++ b/src/formula/csl/Next.h @@ -8,8 +8,8 @@ #ifndef STORM_FORMULA_CSL_NEXT_H_ #define STORM_FORMULA_CSL_NEXT_H_ -#include "src/formula/Csl/AbstractPathFormula.h" -#include "src/formula/Csl/AbstractStateFormula.h" +#include "src/formula/csl/AbstractPathFormula.h" +#include "src/formula/csl/AbstractStateFormula.h" #include "src/formula/AbstractFormulaChecker.h" namespace storm { diff --git a/src/formula/Csl/Not.h b/src/formula/csl/Not.h similarity index 98% rename from src/formula/Csl/Not.h rename to src/formula/csl/Not.h index 58ca37299..05a924819 100644 --- a/src/formula/Csl/Not.h +++ b/src/formula/csl/Not.h @@ -8,7 +8,7 @@ #ifndef STORM_FORMULA_CSL_NOT_H_ #define STORM_FORMULA_CSL_NOT_H_ -#include "src/formula/Csl/AbstractStateFormula.h" +#include "src/formula/csl/AbstractStateFormula.h" #include "src/formula/AbstractFormulaChecker.h" #include "src/modelchecker/csl/ForwardDeclarations.h" diff --git a/src/formula/Csl/Or.h b/src/formula/csl/Or.h similarity index 98% rename from src/formula/Csl/Or.h rename to src/formula/csl/Or.h index 9533b873a..9eb575b38 100644 --- a/src/formula/Csl/Or.h +++ b/src/formula/csl/Or.h @@ -8,7 +8,7 @@ #ifndef STORM_FORMULA_CSL_OR_H_ #define STORM_FORMULA_CSL_OR_H_ -#include "src/formula/Csl/AbstractStateFormula.h" +#include "src/formula/csl/AbstractStateFormula.h" #include "src/formula/AbstractFormulaChecker.h" namespace storm { diff --git a/src/formula/Csl/ProbabilisticBoundOperator.h b/src/formula/csl/ProbabilisticBoundOperator.h similarity index 98% rename from src/formula/Csl/ProbabilisticBoundOperator.h rename to src/formula/csl/ProbabilisticBoundOperator.h index d40bb90e2..48553bb85 100644 --- a/src/formula/Csl/ProbabilisticBoundOperator.h +++ b/src/formula/csl/ProbabilisticBoundOperator.h @@ -8,8 +8,8 @@ #ifndef STORM_FORMULA_CSL_PROBABILISTICBOUNDOPERATOR_H_ #define STORM_FORMULA_CSL_PROBABILISTICBOUNDOPERATOR_H_ -#include "src/formula/Csl/AbstractStateFormula.h" -#include "src/formula/Csl/AbstractPathFormula.h" +#include "src/formula/csl/AbstractStateFormula.h" +#include "src/formula/csl/AbstractPathFormula.h" #include "src/formula/ComparisonType.h" #include "utility/constants.h" diff --git a/src/formula/Csl/SteadyStateBoundOperator.h b/src/formula/csl/SteadyStateBoundOperator.h similarity index 100% rename from src/formula/Csl/SteadyStateBoundOperator.h rename to src/formula/csl/SteadyStateBoundOperator.h diff --git a/src/formula/Csl/TimeBoundedEventually.h b/src/formula/csl/TimeBoundedEventually.h similarity index 97% rename from src/formula/Csl/TimeBoundedEventually.h rename to src/formula/csl/TimeBoundedEventually.h index c80eecb4b..f8ef249cf 100644 --- a/src/formula/Csl/TimeBoundedEventually.h +++ b/src/formula/csl/TimeBoundedEventually.h @@ -8,8 +8,8 @@ #ifndef STORM_FORMULA_CSL_TIMEBOUNDEDEVENTUALLY_H_ #define STORM_FORMULA_CSL_TIMEBOUNDEDEVENTUALLY_H_ -#include "src/formula/Csl/AbstractPathFormula.h" -#include "src/formula/Csl/AbstractStateFormula.h" +#include "src/formula/csl/AbstractPathFormula.h" +#include "src/formula/csl/AbstractStateFormula.h" namespace storm { namespace property { diff --git a/src/formula/Csl/TimeBoundedUntil.h b/src/formula/csl/TimeBoundedUntil.h similarity index 98% rename from src/formula/Csl/TimeBoundedUntil.h rename to src/formula/csl/TimeBoundedUntil.h index 3da7fa968..96cb87f24 100644 --- a/src/formula/Csl/TimeBoundedUntil.h +++ b/src/formula/csl/TimeBoundedUntil.h @@ -8,8 +8,8 @@ #ifndef STORM_FORMULA_CSL_TIMEBOUNDEDUNTIL_H_ #define STORM_FORMULA_CSL_TIMEBOUNDEDUNTIL_H_ -#include "src/formula/Csl/AbstractPathFormula.h" -#include "src/formula/Csl/AbstractStateFormula.h" +#include "src/formula/csl/AbstractPathFormula.h" +#include "src/formula/csl/AbstractStateFormula.h" namespace storm { namespace property { diff --git a/src/formula/Csl/Until.h b/src/formula/csl/Until.h similarity index 97% rename from src/formula/Csl/Until.h rename to src/formula/csl/Until.h index 34b44b780..199956d37 100644 --- a/src/formula/Csl/Until.h +++ b/src/formula/csl/Until.h @@ -8,8 +8,8 @@ #ifndef STORM_FORMULA_CSL_UNTIL_H_ #define STORM_FORMULA_CSL_UNTIL_H_ -#include "src/formula/Csl/AbstractPathFormula.h" -#include "src/formula/Csl/AbstractStateFormula.h" +#include "src/formula/csl/AbstractPathFormula.h" +#include "src/formula/csl/AbstractStateFormula.h" #include "src/formula/AbstractFormulaChecker.h" namespace storm { diff --git a/src/formula/Ltl/AbstractLtlFormula.h b/src/formula/ltl/AbstractLtlFormula.h similarity index 100% rename from src/formula/Ltl/AbstractLtlFormula.h rename to src/formula/ltl/AbstractLtlFormula.h diff --git a/src/formula/Ltl/And.h b/src/formula/ltl/And.h similarity index 100% rename from src/formula/Ltl/And.h rename to src/formula/ltl/And.h diff --git a/src/formula/Ltl/Ap.h b/src/formula/ltl/Ap.h similarity index 100% rename from src/formula/Ltl/Ap.h rename to src/formula/ltl/Ap.h diff --git a/src/formula/Ltl/BoundedEventually.h b/src/formula/ltl/BoundedEventually.h similarity index 100% rename from src/formula/Ltl/BoundedEventually.h rename to src/formula/ltl/BoundedEventually.h diff --git a/src/formula/Ltl/BoundedUntil.h b/src/formula/ltl/BoundedUntil.h similarity index 99% rename from src/formula/Ltl/BoundedUntil.h rename to src/formula/ltl/BoundedUntil.h index 5daf126b8..755467ef1 100644 --- a/src/formula/Ltl/BoundedUntil.h +++ b/src/formula/ltl/BoundedUntil.h @@ -8,7 +8,7 @@ #ifndef STORM_FORMULA_LTL_BOUNDEDUNTIL_H_ #define STORM_FORMULA_LTL_BOUNDEDUNTIL_H_ -#include "src/formula/Ltl/AbstractLtlFormula.h" +#include "src/formula/ltl/AbstractLtlFormula.h" #include <cstdint> #include <string> #include "src/modelchecker/ltl/ForwardDeclarations.h" diff --git a/src/formula/Ltl/Eventually.h b/src/formula/ltl/Eventually.h similarity index 98% rename from src/formula/Ltl/Eventually.h rename to src/formula/ltl/Eventually.h index 2825292fe..983ce2de4 100644 --- a/src/formula/Ltl/Eventually.h +++ b/src/formula/ltl/Eventually.h @@ -8,7 +8,7 @@ #ifndef STORM_FORMULA_LTL_EVENTUALLY_H_ #define STORM_FORMULA_LTL_EVENTUALLY_H_ -#include "src/formula/Ltl/AbstractLtlFormula.h" +#include "src/formula/ltl/AbstractLtlFormula.h" #include "src/modelchecker/ltl/ForwardDeclarations.h" namespace storm { diff --git a/src/formula/Ltl/Globally.h b/src/formula/ltl/Globally.h similarity index 100% rename from src/formula/Ltl/Globally.h rename to src/formula/ltl/Globally.h diff --git a/src/formula/Ltl/LtlFilter.h b/src/formula/ltl/LtlFilter.h similarity index 98% rename from src/formula/Ltl/LtlFilter.h rename to src/formula/ltl/LtlFilter.h index 96fac586c..b8d7846c0 100644 --- a/src/formula/Ltl/LtlFilter.h +++ b/src/formula/ltl/LtlFilter.h @@ -10,8 +10,8 @@ #include "src/formula/AbstractFilter.h" #include "src/modelchecker/ltl/AbstractModelChecker.h" -#include "src/formula/Ltl/AbstractLtlFormula.h" -#include "src/formula/Actions/AbstractAction.h" +#include "src/formula/ltl/AbstractLtlFormula.h" +#include "src/formula/actions/AbstractAction.h" #include "src/exceptions/NotImplementedException.h" namespace storm { diff --git a/src/formula/Ltl/Next.h b/src/formula/ltl/Next.h similarity index 100% rename from src/formula/Ltl/Next.h rename to src/formula/ltl/Next.h diff --git a/src/formula/Ltl/Not.h b/src/formula/ltl/Not.h similarity index 100% rename from src/formula/Ltl/Not.h rename to src/formula/ltl/Not.h diff --git a/src/formula/Ltl/Or.h b/src/formula/ltl/Or.h similarity index 100% rename from src/formula/Ltl/Or.h rename to src/formula/ltl/Or.h diff --git a/src/formula/Ltl/Until.h b/src/formula/ltl/Until.h similarity index 100% rename from src/formula/Ltl/Until.h rename to src/formula/ltl/Until.h diff --git a/src/formula/Ltl/visitor/AbstractLtlFormulaVisitor.cpp b/src/formula/ltl/visitor/AbstractLtlFormulaVisitor.cpp similarity index 100% rename from src/formula/Ltl/visitor/AbstractLtlFormulaVisitor.cpp rename to src/formula/ltl/visitor/AbstractLtlFormulaVisitor.cpp diff --git a/src/formula/Ltl/visitor/AbstractLtlFormulaVisitor.h b/src/formula/ltl/visitor/AbstractLtlFormulaVisitor.h similarity index 100% rename from src/formula/Ltl/visitor/AbstractLtlFormulaVisitor.h rename to src/formula/ltl/visitor/AbstractLtlFormulaVisitor.h diff --git a/src/formula/Prctl/AbstractPathFormula.h b/src/formula/prctl/AbstractPathFormula.h similarity index 97% rename from src/formula/Prctl/AbstractPathFormula.h rename to src/formula/prctl/AbstractPathFormula.h index 62bb1f7f4..50040082f 100644 --- a/src/formula/Prctl/AbstractPathFormula.h +++ b/src/formula/prctl/AbstractPathFormula.h @@ -8,7 +8,7 @@ #ifndef STORM_FORMULA_PRCTL_ABSTRACTPATHFORMULA_H_ #define STORM_FORMULA_PRCTL_ABSTRACTPATHFORMULA_H_ -#include "src/formula/Prctl/AbstractPrctlFormula.h" +#include "src/formula/prctl/AbstractPrctlFormula.h" #include "src/modelchecker/prctl/ForwardDeclarations.h" #include <vector> diff --git a/src/formula/Prctl/AbstractPrctlFormula.h b/src/formula/prctl/AbstractPrctlFormula.h similarity index 100% rename from src/formula/Prctl/AbstractPrctlFormula.h rename to src/formula/prctl/AbstractPrctlFormula.h diff --git a/src/formula/Prctl/AbstractRewardPathFormula.h b/src/formula/prctl/AbstractRewardPathFormula.h similarity index 97% rename from src/formula/Prctl/AbstractRewardPathFormula.h rename to src/formula/prctl/AbstractRewardPathFormula.h index 844adb25b..d28e1003d 100644 --- a/src/formula/Prctl/AbstractRewardPathFormula.h +++ b/src/formula/prctl/AbstractRewardPathFormula.h @@ -8,6 +8,8 @@ #ifndef STORM_FORMULA_PRCTL_ABSTRACTREWARDPATHFORMULA_H_ #define STORM_FORMULA_PRCTL_ABSTRACTREWARDPATHFORMULA_H_ +#include "src/formula/prctl/AbstractPrctlFormula.h" + namespace storm { namespace property { namespace prctl { diff --git a/src/formula/Prctl/AbstractStateFormula.h b/src/formula/prctl/AbstractStateFormula.h similarity index 97% rename from src/formula/Prctl/AbstractStateFormula.h rename to src/formula/prctl/AbstractStateFormula.h index 7eed7fb6a..8af034faa 100644 --- a/src/formula/Prctl/AbstractStateFormula.h +++ b/src/formula/prctl/AbstractStateFormula.h @@ -8,7 +8,7 @@ #ifndef STORM_FORMULA_PRCTL_ABSTRACTSTATEFORMULA_H_ #define STORM_FORMULA_PRCTL_ABSTRACTSTATEFORMULA_H_ -#include "src/formula/Prctl/AbstractPrctlFormula.h" +#include "src/formula/prctl/AbstractPrctlFormula.h" #include "src/storage/BitVector.h" #include "src/modelchecker/prctl/ForwardDeclarations.h" diff --git a/src/formula/Prctl/And.h b/src/formula/prctl/And.h similarity index 98% rename from src/formula/Prctl/And.h rename to src/formula/prctl/And.h index dcda9e802..b364e3a63 100644 --- a/src/formula/Prctl/And.h +++ b/src/formula/prctl/And.h @@ -8,7 +8,7 @@ #ifndef STORM_FORMULA_PRCTL_AND_H_ #define STORM_FORMULA_PRCTL_AND_H_ -#include "src/formula/Prctl/AbstractStateFormula.h" +#include "src/formula/prctl/AbstractStateFormula.h" #include "src/formula/AbstractFormulaChecker.h" #include "src/modelchecker/prctl/ForwardDeclarations.h" #include <string> diff --git a/src/formula/Prctl/Ap.h b/src/formula/prctl/Ap.h similarity index 98% rename from src/formula/Prctl/Ap.h rename to src/formula/prctl/Ap.h index 7e234d434..21ed5b82f 100644 --- a/src/formula/Prctl/Ap.h +++ b/src/formula/prctl/Ap.h @@ -8,7 +8,7 @@ #ifndef STORM_FORMULA_PRCTL_AP_H_ #define STORM_FORMULA_PRCTL_AP_H_ -#include "src/formula/Prctl/AbstractStateFormula.h" +#include "src/formula/prctl/AbstractStateFormula.h" #include "src/formula/AbstractFormulaChecker.h" #include "src/modelchecker/prctl/ForwardDeclarations.h" diff --git a/src/formula/Prctl/BoundedEventually.h b/src/formula/prctl/BoundedEventually.h similarity index 97% rename from src/formula/Prctl/BoundedEventually.h rename to src/formula/prctl/BoundedEventually.h index 0da53493f..59e319b28 100644 --- a/src/formula/Prctl/BoundedEventually.h +++ b/src/formula/prctl/BoundedEventually.h @@ -8,8 +8,8 @@ #ifndef STORM_FORMULA_PRCTL_BOUNDEDEVENTUALLY_H_ #define STORM_FORMULA_PRCTL_BOUNDEDEVENTUALLY_H_ -#include "src/formula/Prctl/AbstractPathFormula.h" -#include "src/formula/Prctl/AbstractStateFormula.h" +#include "src/formula/prctl/AbstractPathFormula.h" +#include "src/formula/prctl/AbstractStateFormula.h" #include "src/formula/AbstractFormulaChecker.h" #include <cstdint> #include <string> diff --git a/src/formula/Prctl/BoundedNaryUntil.h b/src/formula/prctl/BoundedNaryUntil.h similarity index 98% rename from src/formula/Prctl/BoundedNaryUntil.h rename to src/formula/prctl/BoundedNaryUntil.h index 9c27158ba..7fc91830d 100644 --- a/src/formula/Prctl/BoundedNaryUntil.h +++ b/src/formula/prctl/BoundedNaryUntil.h @@ -8,8 +8,8 @@ #ifndef STORM_FORMULA_PRCTL_BOUNDEDNARYUNTIL_H_ #define STORM_FORMULA_PRCTL_BOUNDEDNARYUNTIL_H_ -#include "src/formula/Prctl/AbstractPathFormula.h" -#include "src/formula/Prctl/AbstractStateFormula.h" +#include "src/formula/prctl/AbstractPathFormula.h" +#include "src/formula/prctl/AbstractStateFormula.h" #include <cstdint> #include <string> #include <vector> diff --git a/src/formula/Prctl/BoundedUntil.h b/src/formula/prctl/BoundedUntil.h similarity index 98% rename from src/formula/Prctl/BoundedUntil.h rename to src/formula/prctl/BoundedUntil.h index d7c9d28ca..206c0a202 100644 --- a/src/formula/Prctl/BoundedUntil.h +++ b/src/formula/prctl/BoundedUntil.h @@ -8,8 +8,8 @@ #ifndef STORM_FORMULA_PRCTL_BOUNDEDUNTIL_H_ #define STORM_FORMULA_PRCTL_BOUNDEDUNTIL_H_ -#include "src/formula/Prctl/AbstractPathFormula.h" -#include "src/formula/Prctl/AbstractStateFormula.h" +#include "src/formula/prctl/AbstractPathFormula.h" +#include "src/formula/prctl/AbstractStateFormula.h" #include <cstdint> #include <string> #include "src/modelchecker/prctl/ForwardDeclarations.h" diff --git a/src/formula/Prctl/CumulativeReward.h b/src/formula/prctl/CumulativeReward.h similarity index 100% rename from src/formula/Prctl/CumulativeReward.h rename to src/formula/prctl/CumulativeReward.h diff --git a/src/formula/Prctl/Eventually.h b/src/formula/prctl/Eventually.h similarity index 97% rename from src/formula/Prctl/Eventually.h rename to src/formula/prctl/Eventually.h index 733fc924b..cbcbf8c4d 100644 --- a/src/formula/Prctl/Eventually.h +++ b/src/formula/prctl/Eventually.h @@ -8,8 +8,8 @@ #ifndef STORM_FORMULA_PRCTL_EVENTUALLY_H_ #define STORM_FORMULA_PRCTL_EVENTUALLY_H_ -#include "src/formula/Prctl/AbstractPathFormula.h" -#include "src/formula/Prctl/AbstractStateFormula.h" +#include "src/formula/prctl/AbstractPathFormula.h" +#include "src/formula/prctl/AbstractStateFormula.h" #include "src/modelchecker/prctl/ForwardDeclarations.h" namespace storm { diff --git a/src/formula/Prctl/Globally.h b/src/formula/prctl/Globally.h similarity index 97% rename from src/formula/Prctl/Globally.h rename to src/formula/prctl/Globally.h index 67a824254..49b4d6d96 100644 --- a/src/formula/Prctl/Globally.h +++ b/src/formula/prctl/Globally.h @@ -8,8 +8,8 @@ #ifndef STORM_FORMULA_PRCTL_GLOBALLY_H_ #define STORM_FORMULA_PRCTL_GLOBALLY_H_ -#include "src/formula/Prctl/AbstractPathFormula.h" -#include "src/formula/Prctl/AbstractStateFormula.h" +#include "src/formula/prctl/AbstractPathFormula.h" +#include "src/formula/prctl/AbstractStateFormula.h" #include "src/formula/AbstractFormulaChecker.h" #include "src/modelchecker/prctl/ForwardDeclarations.h" diff --git a/src/formula/Prctl/InstantaneousReward.h b/src/formula/prctl/InstantaneousReward.h similarity index 100% rename from src/formula/Prctl/InstantaneousReward.h rename to src/formula/prctl/InstantaneousReward.h diff --git a/src/formula/Prctl/Next.h b/src/formula/prctl/Next.h similarity index 97% rename from src/formula/Prctl/Next.h rename to src/formula/prctl/Next.h index 776195903..e218d036e 100644 --- a/src/formula/Prctl/Next.h +++ b/src/formula/prctl/Next.h @@ -8,8 +8,8 @@ #ifndef STORM_FORMULA_PRCTL_NEXT_H_ #define STORM_FORMULA_PRCTL_NEXT_H_ -#include "src/formula/Prctl/AbstractPathFormula.h" -#include "src/formula/Prctl/AbstractStateFormula.h" +#include "src/formula/prctl/AbstractPathFormula.h" +#include "src/formula/prctl/AbstractStateFormula.h" #include "src/formula/AbstractFormulaChecker.h" namespace storm { diff --git a/src/formula/Prctl/Not.h b/src/formula/prctl/Not.h similarity index 100% rename from src/formula/Prctl/Not.h rename to src/formula/prctl/Not.h diff --git a/src/formula/Prctl/Or.h b/src/formula/prctl/Or.h similarity index 98% rename from src/formula/Prctl/Or.h rename to src/formula/prctl/Or.h index dc92ee10a..01482bb33 100644 --- a/src/formula/Prctl/Or.h +++ b/src/formula/prctl/Or.h @@ -8,7 +8,7 @@ #ifndef STORM_FORMULA_PRCTL_OR_H_ #define STORM_FORMULA_PRCTL_OR_H_ -#include "src/formula/Prctl/AbstractStateFormula.h" +#include "src/formula/prctl/AbstractStateFormula.h" #include "src/formula/AbstractFormulaChecker.h" namespace storm { diff --git a/src/formula/Prctl/PrctlFilter.h b/src/formula/prctl/PrctlFilter.h similarity index 98% rename from src/formula/Prctl/PrctlFilter.h rename to src/formula/prctl/PrctlFilter.h index 395337b9a..f9db17d9a 100644 --- a/src/formula/Prctl/PrctlFilter.h +++ b/src/formula/prctl/PrctlFilter.h @@ -9,11 +9,11 @@ #define STORM_FORMULA_PRCTL_PRCTLFILTER_H_ #include "src/formula/AbstractFilter.h" -#include "src/formula/Prctl/AbstractPrctlFormula.h" -#include "src/formula/Prctl/AbstractPathFormula.h" -#include "src/formula/Prctl/AbstractStateFormula.h" +#include "src/formula/prctl/AbstractPrctlFormula.h" +#include "src/formula/prctl/AbstractPathFormula.h" +#include "src/formula/prctl/AbstractStateFormula.h" #include "src/modelchecker/prctl/AbstractModelChecker.h" -#include "src/formula/Actions/AbstractAction.h" +#include "src/formula/actions/AbstractAction.h" // TODO: Test if this can be can be ommitted. namespace storm { diff --git a/src/formula/Prctl/ProbabilisticBoundOperator.h b/src/formula/prctl/ProbabilisticBoundOperator.h similarity index 100% rename from src/formula/Prctl/ProbabilisticBoundOperator.h rename to src/formula/prctl/ProbabilisticBoundOperator.h diff --git a/src/formula/Prctl/ReachabilityReward.h b/src/formula/prctl/ReachabilityReward.h similarity index 100% rename from src/formula/Prctl/ReachabilityReward.h rename to src/formula/prctl/ReachabilityReward.h diff --git a/src/formula/Prctl/RewardBoundOperator.h b/src/formula/prctl/RewardBoundOperator.h similarity index 100% rename from src/formula/Prctl/RewardBoundOperator.h rename to src/formula/prctl/RewardBoundOperator.h diff --git a/src/formula/Prctl/SteadyStateReward.h b/src/formula/prctl/SteadyStateReward.h similarity index 100% rename from src/formula/Prctl/SteadyStateReward.h rename to src/formula/prctl/SteadyStateReward.h diff --git a/src/formula/Prctl/Until.h b/src/formula/prctl/Until.h similarity index 100% rename from src/formula/Prctl/Until.h rename to src/formula/prctl/Until.h diff --git a/src/parser/CslParser.cpp b/src/parser/CslParser.cpp index f7b11dd14..00a1c1db4 100644 --- a/src/parser/CslParser.cpp +++ b/src/parser/CslParser.cpp @@ -10,12 +10,12 @@ #include "src/utility/constants.h" // The action class headers. -#include "src/formula/Actions/AbstractAction.h" -#include "src/formula/Actions/BoundAction.h" -#include "src/formula/Actions/InvertAction.h" -#include "src/formula/Actions/FormulaAction.h" -#include "src/formula/Actions/RangeAction.h" -#include "src/formula/Actions/SortAction.h" +#include "src/formula/actions/AbstractAction.h" +#include "src/formula/actions/BoundAction.h" +#include "src/formula/actions/InvertAction.h" +#include "src/formula/actions/FormulaAction.h" +#include "src/formula/actions/RangeAction.h" +#include "src/formula/actions/SortAction.h" // If the parser fails due to ill-formed data, this exception is thrown. #include "src/exceptions/WrongFormatException.h" diff --git a/src/parser/CslParser.h b/src/parser/CslParser.h index ddc767438..0960f742f 100644 --- a/src/parser/CslParser.h +++ b/src/parser/CslParser.h @@ -9,7 +9,7 @@ #define STORM_PARSER_CSLPARSER_H_ #include "src/formula/Csl.h" -#include "src/formula/Csl/CslFilter.h" +#include "src/formula/csl/CslFilter.h" #include <functional> namespace storm { diff --git a/src/parser/LtlFileParser.cpp b/src/parser/LtlFileParser.cpp index d3d9459ae..8ede743a8 100644 --- a/src/parser/LtlFileParser.cpp +++ b/src/parser/LtlFileParser.cpp @@ -15,7 +15,7 @@ namespace storm { namespace parser { -std::list<storm::property::ltl::LtlFilter<double>*> LtlFileParser(std::string filename) { +std::list<storm::property::ltl::LtlFilter<double>*> LtlFileParser::parseLtlFile(std::string filename) { // Open file std::ifstream inputFileStream(filename, std::ios::in); @@ -30,7 +30,7 @@ std::list<storm::property::ltl::LtlFilter<double>*> LtlFileParser(std::string fi std::string line; //The while loop reads the input file line by line while (std::getline(inputFileStream, line)) { - result.push_back(storm::parser::LtlParser(line)); + result.push_back(storm::parser::LtlParser::parseLtlFormula(line)); } } diff --git a/src/parser/LtlFileParser.h b/src/parser/LtlFileParser.h index 7c30abc11..b8375ecec 100644 --- a/src/parser/LtlFileParser.h +++ b/src/parser/LtlFileParser.h @@ -9,20 +9,24 @@ #define LTLFILEPARSER_H_ #include "formula/Ltl.h" -#include "src/formula/Ltl/LtlFilter.h" +#include "src/formula/ltl/LtlFilter.h" #include <list> namespace storm { namespace parser { -/*! - * Parses each line of a given file as prctl formula and returns a list containing the results of the parsing. - * - * @param filename - * @return The list of parsed formulas - */ -std::list<storm::property::ltl::LtlFilter<double>*> LtlFileParser(std::string filename); +class LtlFileParser { +public: + + /*! + * Parses each line of a given file as prctl formula and returns a list containing the results of the parsing. + * + * @param filename + * @return The list of parsed formulas + */ + static std::list<storm::property::ltl::LtlFilter<double>*> parseLtlFile(std::string filename); +}; } //namespace parser } //namespace storm diff --git a/src/parser/LtlParser.cpp b/src/parser/LtlParser.cpp index 6c4787fee..2c7e09a06 100644 --- a/src/parser/LtlParser.cpp +++ b/src/parser/LtlParser.cpp @@ -11,11 +11,11 @@ #include "src/utility/constants.h" // The action class headers. -#include "src/formula/Actions/AbstractAction.h" -#include "src/formula/Actions/BoundAction.h" -#include "src/formula/Actions/InvertAction.h" -#include "src/formula/Actions/RangeAction.h" -#include "src/formula/Actions/SortAction.h" +#include "src/formula/actions/AbstractAction.h" +#include "src/formula/actions/BoundAction.h" +#include "src/formula/actions/InvertAction.h" +#include "src/formula/actions/RangeAction.h" +#include "src/formula/actions/SortAction.h" // If the parser fails due to ill-formed data, this exception is thrown. #include "src/exceptions/WrongFormatException.h" @@ -48,7 +48,7 @@ namespace storm { namespace parser { template<typename Iterator, typename Skipper> -struct LtlGrammar : qi::grammar<Iterator, storm::property::ltl::LtlFilter<double>*(), Skipper > { +struct LtlParser::LtlGrammar : qi::grammar<Iterator, storm::property::ltl::LtlFilter<double>*(), Skipper > { LtlGrammar() : LtlGrammar::base_type(start) { //This block contains helper rules that may be used several times freeIdentifierName = qi::lexeme[qi::alpha >> *(qi::alnum | qi::char_('_'))]; @@ -182,11 +182,7 @@ struct LtlGrammar : qi::grammar<Iterator, storm::property::ltl::LtlFilter<double }; -} //namespace storm -} //namespace parser - - -storm::property::ltl::LtlFilter<double>* storm::parser::LtlParser(std::string formulaString) { +storm::property::ltl::LtlFilter<double>* LtlParser::parseLtlFormula(std::string formulaString) { // Prepare iterators to input. BaseIteratorType stringIteratorBegin = formulaString.begin(); BaseIteratorType stringIteratorEnd = formulaString.end(); @@ -239,3 +235,5 @@ storm::property::ltl::LtlFilter<double>* storm::parser::LtlParser(std::string fo return result_pointer; } +} //namespace parser +} //namespace storm diff --git a/src/parser/LtlParser.h b/src/parser/LtlParser.h index bbf10d259..d3d8e426f 100644 --- a/src/parser/LtlParser.h +++ b/src/parser/LtlParser.h @@ -9,12 +9,20 @@ #define STORM_PARSER_LTLPARSER_H_ #include "src/formula/Ltl.h" -#include "src/formula/Ltl/LtlFilter.h" +#include "src/formula/ltl/LtlFilter.h" namespace storm { namespace parser { /*! + * Reads a LTL formula from a string and return the formula tree. + * + * If you want to read the formula from a file, use the LtlFileParser class instead. + */ +class LtlParser { +public: + + /*! * Reads a LTL formula from its string representation and parses it into a formula tree, consisting of * classes in the namespace storm::property. * @@ -23,13 +31,17 @@ namespace parser { * @param formulaString The string representation of the formula * @throw wrongFormatException If the input could not be parsed successfully */ -storm::property::ltl::LtlFilter<double>* LtlParser(std::string formulaString); + static storm::property::ltl::LtlFilter<double>* parseLtlFormula(std::string formulaString); -/*! - * Struct for the Ltl grammar, that Boost::Spirit uses to parse the formulas. - */ -template<typename Iterator, typename Skipper> -struct LtlGrammar; +private: + + /*! + * Struct for the Ltl grammar, that Boost::Spirit uses to parse the formulas. + */ + template<typename Iterator, typename Skipper> + struct LtlGrammar; + +}; } /* namespace parser */ } /* namespace storm */ diff --git a/src/parser/PrctlFileParser.h b/src/parser/PrctlFileParser.h index 4d914d8cc..ad29fe812 100644 --- a/src/parser/PrctlFileParser.h +++ b/src/parser/PrctlFileParser.h @@ -9,7 +9,7 @@ #define STORM_PARSER_PRCTLFILEPARSER_H_ #include "formula/Prctl.h" -#include "src/formula/Prctl/PrctlFilter.h" +#include "src/formula/prctl/PrctlFilter.h" #include <list> diff --git a/src/parser/PrctlParser.cpp b/src/parser/PrctlParser.cpp index 7675f1cd3..da2336b8b 100644 --- a/src/parser/PrctlParser.cpp +++ b/src/parser/PrctlParser.cpp @@ -3,12 +3,12 @@ #include "src/utility/constants.h" // The action class headers. -#include "src/formula/Actions/AbstractAction.h" -#include "src/formula/Actions/BoundAction.h" -#include "src/formula/Actions/InvertAction.h" -#include "src/formula/Actions/FormulaAction.h" -#include "src/formula/Actions/RangeAction.h" -#include "src/formula/Actions/SortAction.h" +#include "src/formula/actions/AbstractAction.h" +#include "src/formula/actions/BoundAction.h" +#include "src/formula/actions/InvertAction.h" +#include "src/formula/actions/FormulaAction.h" +#include "src/formula/actions/RangeAction.h" +#include "src/formula/actions/SortAction.h" // If the parser fails due to ill-formed data, this exception is thrown. #include "src/exceptions/WrongFormatException.h" @@ -248,10 +248,7 @@ struct PrctlParser::PrctlGrammar : qi::grammar<Iterator, storm::property::prctl: }; -} //namespace storm -} //namespace parser - -storm::property::prctl::PrctlFilter<double>* storm::parser::PrctlParser::parsePrctlFormula(std::string formulaString) { +storm::property::prctl::PrctlFilter<double>* PrctlParser::parsePrctlFormula(std::string formulaString) { // Prepare iterators to input. BaseIteratorType stringIteratorBegin = formulaString.begin(); BaseIteratorType stringIteratorEnd = formulaString.end(); @@ -296,3 +293,6 @@ storm::property::prctl::PrctlFilter<double>* storm::parser::PrctlParser::parsePr return result_pointer; } + +} //namespace parser +} //namespace storm diff --git a/src/parser/PrctlParser.h b/src/parser/PrctlParser.h index 6e1a55c34..b5832727e 100644 --- a/src/parser/PrctlParser.h +++ b/src/parser/PrctlParser.h @@ -2,7 +2,7 @@ #define STORM_PARSER_PRCTLPARSER_H_ #include "src/formula/Prctl.h" -#include "src/formula/Prctl/PrctlFilter.h" +#include "src/formula/prctl/PrctlFilter.h" namespace storm { namespace parser { @@ -11,10 +11,6 @@ namespace parser { * Reads a PRCTL formula from a string and return the formula tree. * * If you want to read the formula from a file, use the PrctlFileParser class instead. - * - * @note - * This class creates a PctlFormula object which can be accessed through the getFormula() method (of base - * class PrctlParser). However, it will not delete this object. */ class PrctlParser { public: diff --git a/test/functional/parser/ActionTest.cpp b/test/functional/parser/ActionTest.cpp new file mode 100644 index 000000000..41d5ab58f --- /dev/null +++ b/test/functional/parser/ActionTest.cpp @@ -0,0 +1,157 @@ +/* + * ActionTest.cpp + * + * Created on: Jun 27, 2014 + * Author: Manuel Sascha Weiand + */ + +#include "gtest/gtest.h" +#include "storm-config.h" + +#include "src/formula/actions/BoundAction.h" + +#include "src/parser/MarkovAutomatonParser.h" +#include "src/parser/DeterministicModelParser.h" +#include "src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h" +#include "src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h" +#include "src/solver/GmmxxLinearEquationSolver.h" +#include "src/exceptions/InvalidArgumentException.h" + +typedef typename storm::property::action::AbstractAction<double>::Result Result; + +TEST(ActionTest, BoundActionFunctionality) { + + // Setup the modelchecker. + storm::models::Dtmc<double> model = storm::parser::DeterministicModelParser::parseDtmc(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_actionTest.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/dtmc_actionTest.lab"); + storm::modelchecker::prctl::SparseDtmcPrctlModelChecker<double> mc(model, new storm::solver::GmmxxLinearEquationSolver<double>()); + + // Build the filter input. + // Basically the modelchecking result of "F a" on the used DTMC. + std::vector<double> pathResult = mc.checkEventually(storm::property::prctl::Eventually<double>(new storm::property::prctl::Ap<double>("a")), false); + std::vector<uint_fast64_t> stateMap(pathResult.size()); + for(uint_fast64_t i = 0; i < pathResult.size(); i++) { + stateMap[i] = i; + } + Result input(storm::storage::BitVector(pathResult.size(), true), stateMap, pathResult, storm::storage::BitVector()); + + // Test the action. + // First test that the boundAction build by the empty constructor does not change the selection. + storm::property::action::BoundAction<double> action; + Result result = action.evaluate(input, mc); + + for(auto value : result.selection) { + ASSERT_TRUE(input.selection[value]); + } + + // Test that using a strict bound can give different results than using a non-strict bound. + action = storm::property::action::BoundAction<double>(storm::property::GREATER, 0); + result = action.evaluate(input, mc); + + for(uint_fast64_t i = 0; i < result.selection.size()-2; i++) { + ASSERT_TRUE(result.selection[i]); + } + ASSERT_FALSE(result.selection[6]); + ASSERT_FALSE(result.selection[7]); + + // Check whether the state order has any effect on the selected states, which it should not. + for(uint_fast64_t i = 0; i < pathResult.size(); i++) { + stateMap[i] = pathResult.size() - i - 1; + } + + action = storm::property::action::BoundAction<double>(storm::property::GREATER, 0); + result = action.evaluate(input, mc); + + for(uint_fast64_t i = 0; i < result.selection.size()-2; i++) { + ASSERT_TRUE(result.selection[i]); + } + ASSERT_FALSE(result.selection[6]); + ASSERT_FALSE(result.selection[7]); + + // Test the functionality for state formulas instead. + input.pathResult = std::vector<double>(); + input.stateResult = mc.checkAp(storm::property::prctl::Ap<double>("a")); + action = storm::property::action::BoundAction<double>(storm::property::GREATER, 0.5); + result = action.evaluate(input, mc); + + for(uint_fast64_t i = 0; i < result.selection.size(); i++) { + if(i == 5) { + ASSERT_TRUE(result.selection[i]); + } else { + ASSERT_FALSE(result.selection[i]); + } + } + + // Make sure that the modelchecker has no influence on the result. + storm::models::MarkovAutomaton<double> ma = storm::parser::MarkovAutomatonParser::parseMarkovAutomaton(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/ma_general.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/ma_general.lab"); + storm::modelchecker::csl::SparseMarkovAutomatonCslModelChecker<double> cslMc(ma); + result = action.evaluate(input, cslMc); + + for(uint_fast64_t i = 0; i < result.selection.size(); i++) { + if(i == 5) { + ASSERT_TRUE(result.selection[i]); + } else { + ASSERT_FALSE(result.selection[i]); + } + } +} + +TEST(ActionTest, BoundActionSafety) { + + // Setup the modelchecker. + storm::models::Dtmc<double> model = storm::parser::DeterministicModelParser::parseDtmc(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_actionTest.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/dtmc_actionTest.lab"); + storm::modelchecker::prctl::SparseDtmcPrctlModelChecker<double> mc(model, new storm::solver::GmmxxLinearEquationSolver<double>()); + + // Build the filter input. + // Basically the modelchecking result of "F a" on the used DTMC. + std::vector<double> pathResult = mc.checkEventually(storm::property::prctl::Eventually<double>(new storm::property::prctl::Ap<double>("a")), false); + storm::storage::BitVector stateResult = mc.checkAp(storm::property::prctl::Ap<double>("a")); + std::vector<uint_fast64_t> stateMap(pathResult.size()); + for(uint_fast64_t i = 0; i < pathResult.size(); i++) { + stateMap[i] = i; + } + Result input(storm::storage::BitVector(pathResult.size(), true), stateMap, pathResult, storm::storage::BitVector()); + + // First, test unusual bounds. + storm::property::action::BoundAction<double> action(storm::property::LESS, -2044); + Result result; + + ASSERT_NO_THROW(result = action.evaluate(input, mc)); + ASSERT_EQ(0, result.selection.getNumberOfSetBits()); + + action = storm::property::action::BoundAction<double>(storm::property::GREATER_EQUAL, 5879); + + ASSERT_NO_THROW(result = action.evaluate(input, mc)); + ASSERT_EQ(0, result.selection.getNumberOfSetBits()); + + action = storm::property::action::BoundAction<double>(storm::property::LESS_EQUAL, 5879); + + ASSERT_NO_THROW(result = action.evaluate(input, mc)); + ASSERT_EQ(result.selection.size(), result.selection.getNumberOfSetBits()); + + // Now, check the behavior under a undefined comparison type. + action = storm::property::action::BoundAction<double>(static_cast<storm::property::ComparisonType>(10), 5879); + ASSERT_THROW(action.toString(), storm::exceptions::InvalidArgumentException); + ASSERT_THROW(action.evaluate(input, mc), storm::exceptions::InvalidArgumentException); + + // Test for a result input with both results filled. + // It should put out a warning and use the pathResult. + action = storm::property::action::BoundAction<double>(storm::property::GREATER_EQUAL, 0.5); + input.stateResult = stateResult; + + // To capture the warning, redirect cout and test the written buffer content. + std::stringstream buffer; + std::streambuf *sbuf = std::cout.rdbuf(); + std::cout.rdbuf(buffer.rdbuf()); + + ASSERT_NO_THROW(result = action.evaluate(input, mc)); + std::cout.rdbuf(sbuf); + + ASSERT_FALSE(buffer.str().empty()); + ASSERT_TRUE(result.selection[0]); + ASSERT_FALSE(result.selection[1]); + ASSERT_TRUE(result.selection[2]); + ASSERT_TRUE(result.selection[5]); + + // Check for empty input. + ASSERT_NO_THROW(result = action.evaluate(Result(), mc)); +} diff --git a/test/functional/parser/LtlParserTest.cpp b/test/functional/parser/LtlParserTest.cpp index 1da53769d..bba921506 100644 --- a/test/functional/parser/LtlParserTest.cpp +++ b/test/functional/parser/LtlParserTest.cpp @@ -12,9 +12,9 @@ TEST(LtlParserTest, parseApOnlyTest) { std::string formula = "ap"; - storm::property::ltl::AbstractLtlFormula<double>* ltlFormula = nullptr; + storm::property::ltl::LtlFilter<double>* ltlFormula = nullptr; ASSERT_NO_THROW( - ltlFormula = storm::parser::LtlParser(formula); + ltlFormula = storm::parser::LtlParser::parseLtlFormula(formula); ); ASSERT_NE(ltlFormula, nullptr); @@ -25,9 +25,9 @@ TEST(LtlParserTest, parseApOnlyTest) { TEST(LtlParserTest, parsePropositionalFormulaTest) { std::string formula = "!(a & b) | a & ! c"; - storm::property::ltl::AbstractLtlFormula<double>* ltlFormula = nullptr; + storm::property::ltl::LtlFilter<double>* ltlFormula = nullptr; ASSERT_NO_THROW( - ltlFormula = storm::parser::LtlParser(formula); + ltlFormula = storm::parser::LtlParser::parseLtlFormula(formula); ); ASSERT_NE(ltlFormula, nullptr); @@ -42,9 +42,9 @@ TEST(LtlParserTest, parsePropositionalFormulaTest) { */ TEST(LtlParserTest, parseAmbiguousFormulaTest) { std::string formula = "F & b"; - storm::property::ltl::AbstractLtlFormula<double>* ltlFormula = nullptr; + storm::property::ltl::LtlFilter<double>* ltlFormula = nullptr; ASSERT_NO_THROW( - ltlFormula = storm::parser::LtlParser(formula); + ltlFormula = storm::parser::LtlParser::parseLtlFormula(formula); ); ASSERT_NE(ltlFormula, nullptr); @@ -59,9 +59,9 @@ TEST(LtlParserTest, parseAmbiguousFormulaTest) { */ TEST(LtlParserTest, parseAmbiguousFormulaTest2) { std::string formula = "F F"; - storm::property::ltl::AbstractLtlFormula<double>* ltlFormula = nullptr; + storm::property::ltl::LtlFilter<double>* ltlFormula = nullptr; ASSERT_NO_THROW( - ltlFormula = storm::parser::LtlParser(formula); + ltlFormula = storm::parser::LtlParser::parseLtlFormula(formula); ); ASSERT_NE(ltlFormula, nullptr); @@ -72,14 +72,14 @@ TEST(LtlParserTest, parseAmbiguousFormulaTest2) { TEST(LtlParserTest, parseBoundedEventuallyFormulaTest) { std::string formula = "F<=5 a"; - storm::property::ltl::AbstractLtlFormula<double>* ltlFormula = nullptr; + storm::property::ltl::LtlFilter<double>* ltlFormula = nullptr; ASSERT_NO_THROW( - ltlFormula = storm::parser::LtlParser(formula); + ltlFormula = storm::parser::LtlParser::parseLtlFormula(formula); ); ASSERT_NE(ltlFormula, nullptr); - storm::property::ltl::BoundedEventually<double>* op = static_cast<storm::property::ltl::BoundedEventually<double>*>(ltlFormula); + storm::property::ltl::BoundedEventually<double>* op = static_cast<storm::property::ltl::BoundedEventually<double>*>(ltlFormula->getChild()); ASSERT_EQ(static_cast<uint_fast64_t>(5), op->getBound()); @@ -90,14 +90,14 @@ TEST(LtlParserTest, parseBoundedEventuallyFormulaTest) { TEST(LtlParserTest, parseBoundedUntilFormulaTest) { std::string formula = "a U<=3 b"; - storm::property::ltl::AbstractLtlFormula<double>* ltlFormula = nullptr; + storm::property::ltl::LtlFilter<double>* ltlFormula = nullptr; ASSERT_NO_THROW( - ltlFormula = storm::parser::LtlParser(formula); + ltlFormula = storm::parser::LtlParser::parseLtlFormula(formula); ); ASSERT_NE(ltlFormula, nullptr); - storm::property::ltl::BoundedUntil<double>* op = static_cast<storm::property::ltl::BoundedUntil<double>*>(ltlFormula); + storm::property::ltl::BoundedUntil<double>* op = static_cast<storm::property::ltl::BoundedUntil<double>*>(ltlFormula->getChild()); ASSERT_EQ(static_cast<uint_fast64_t>(3), op->getBound()); @@ -108,9 +108,9 @@ TEST(LtlParserTest, parseBoundedUntilFormulaTest) { TEST(LtlParserTest, parseComplexUntilTest) { std::string formula = "a U b U<=3 c"; - storm::property::ltl::AbstractLtlFormula<double>* ltlFormula = nullptr; + storm::property::ltl::LtlFilter<double>* ltlFormula = nullptr; ASSERT_NO_THROW( - ltlFormula = storm::parser::LtlParser(formula); + ltlFormula = storm::parser::LtlParser::parseLtlFormula(formula); ); ASSERT_NE(ltlFormula, nullptr); @@ -121,9 +121,9 @@ TEST(LtlParserTest, parseComplexUntilTest) { TEST(LtlParserTest, parseComplexFormulaTest) { std::string formula = "a U F b | G a & F<=3 a U<=7 b // and a comment"; - storm::property::ltl::AbstractLtlFormula<double>* ltlFormula = nullptr; + storm::property::ltl::LtlFilter<double>* ltlFormula = nullptr; ASSERT_NO_THROW( - ltlFormula = storm::parser::LtlParser(formula); + ltlFormula = storm::parser::LtlParser::parseLtlFormula(formula); ); ASSERT_NE(ltlFormula, nullptr); @@ -134,9 +134,8 @@ TEST(LtlParserTest, parseComplexFormulaTest) { TEST(LtlParserTest, wrongFormulaTest) { std::string formula = "(a | c) & +"; - storm::property::ltl::AbstractLtlFormula<double>* ltlFormula = nullptr; ASSERT_THROW( - ltlFormula = storm::parser::LtlParser(formula), + storm::parser::LtlParser::parseLtlFormula(formula), storm::exceptions::WrongFormatException ); } From ee1ebdf91db623f483d0cfd30f0a4ffbb7f79159 Mon Sep 17 00:00:00 2001 From: masawei <manuel.sascha.weiand@rwth-aachen.de> Date: Fri, 18 Jul 2014 13:02:37 +0200 Subject: [PATCH 17/30] Removed the visitor from LTL and refactured the formulas to use shared pointer in stead of standart pointer. Next up: Continue testing. Former-commit-id: 0103895e132b49667b40735838505bf61692e191 --- .../MILPMinimalLabelSetGenerator.h | 38 ++-- .../PathBasedSubsystemGenerator.h | 166 ++---------------- .../SMTMinimalCommandSetGenerator.h | 43 +++-- src/formula/AbstractFormula.h | 2 +- src/formula/AbstractFormulaChecker.h | 3 +- src/formula/PrctlFormulaChecker.h | 24 +-- src/formula/actions/FormulaAction.h | 27 ++- src/formula/csl/AbstractPathFormula.h | 4 +- src/formula/csl/AbstractStateFormula.h | 4 +- src/formula/csl/And.h | 47 +++-- src/formula/csl/Ap.h | 11 +- src/formula/csl/CslFilter.h | 31 ++-- src/formula/csl/Eventually.h | 26 ++- src/formula/csl/Globally.h | 26 ++- src/formula/csl/Next.h | 26 ++- src/formula/csl/Not.h | 32 ++-- src/formula/csl/Or.h | 49 +++--- src/formula/csl/ProbabilisticBoundOperator.h | 38 ++-- src/formula/csl/SteadyStateBoundOperator.h | 32 ++-- src/formula/csl/TimeBoundedEventually.h | 30 ++-- src/formula/csl/TimeBoundedUntil.h | 45 +++-- src/formula/csl/Until.h | 41 ++--- src/formula/ltl/AbstractLtlFormula.h | 32 +--- src/formula/ltl/And.h | 69 +++----- src/formula/ltl/Ap.h | 36 +--- src/formula/ltl/BoundedEventually.h | 68 +++---- src/formula/ltl/BoundedUntil.h | 84 +++------ src/formula/ltl/Eventually.h | 62 ++----- src/formula/ltl/Globally.h | 50 ++---- src/formula/ltl/LtlFilter.h | 13 +- src/formula/ltl/Next.h | 54 ++---- src/formula/ltl/Not.h | 54 ++---- src/formula/ltl/Or.h | 71 +++----- src/formula/ltl/Until.h | 53 +++--- .../ltl/visitor/AbstractLtlFormulaVisitor.cpp | 16 -- .../ltl/visitor/AbstractLtlFormulaVisitor.h | 72 -------- src/formula/prctl/AbstractPathFormula.h | 2 +- src/formula/prctl/AbstractRewardPathFormula.h | 2 +- src/formula/prctl/AbstractStateFormula.h | 2 +- src/formula/prctl/And.h | 47 +++-- src/formula/prctl/Ap.h | 5 +- src/formula/prctl/BoundedEventually.h | 24 ++- src/formula/prctl/BoundedNaryUntil.h | 59 +++---- src/formula/prctl/BoundedUntil.h | 48 +++-- src/formula/prctl/CumulativeReward.h | 11 +- src/formula/prctl/Eventually.h | 31 ++-- src/formula/prctl/Globally.h | 33 ++-- src/formula/prctl/InstantaneousReward.h | 9 +- src/formula/prctl/Next.h | 29 ++- src/formula/prctl/Not.h | 35 ++-- src/formula/prctl/Or.h | 52 +++--- src/formula/prctl/PrctlFilter.h | 36 ++-- .../prctl/ProbabilisticBoundOperator.h | 39 ++-- src/formula/prctl/ReachabilityReward.h | 31 ++-- src/formula/prctl/RewardBoundOperator.h | 55 +++--- src/formula/prctl/SteadyStateReward.h | 15 +- src/formula/prctl/Until.h | 46 +++-- src/modelchecker/csl/AbstractModelChecker.h | 12 +- .../SparseMarkovAutomatonCslModelChecker.h | 10 +- src/modelchecker/prctl/AbstractModelChecker.h | 14 +- .../prctl/SparseDtmcPrctlModelChecker.h | 14 +- .../prctl/SparseMdpPrctlModelChecker.h | 18 +- src/models/Dtmc.h | 4 +- src/parser/CslParser.cpp | 106 +++++------ src/parser/CslParser.h | 2 +- src/parser/LtlFileParser.cpp | 4 +- src/parser/LtlFileParser.h | 2 +- src/parser/LtlParser.cpp | 75 ++++---- src/parser/LtlParser.h | 2 +- src/parser/PrctlFileParser.cpp | 6 +- src/parser/PrctlFileParser.h | 2 +- src/parser/PrctlParser.cpp | 132 +++++++------- src/parser/PrctlParser.h | 2 +- src/storm.cpp | 21 +-- .../GmmxxDtmcPrctlModelCheckerTest.cpp | 60 +++---- .../SparseMdpPrctlModelCheckerTest.cpp | 54 ++---- test/functional/parser/ActionTest.cpp | 61 ++++++- test/functional/parser/CslParserTest.cpp | 60 +++---- test/functional/parser/LtlParserTest.cpp | 56 +++--- test/functional/parser/PrctlParserTest.cpp | 51 ++---- .../GmmxxDtmcPrctModelCheckerTest.cpp | 36 ++-- .../SparseMdpPrctlModelCheckerTest.cpp | 68 +++---- 82 files changed, 1159 insertions(+), 1803 deletions(-) delete mode 100644 src/formula/ltl/visitor/AbstractLtlFormulaVisitor.cpp delete mode 100644 src/formula/ltl/visitor/AbstractLtlFormulaVisitor.h diff --git a/src/counterexamples/MILPMinimalLabelSetGenerator.h b/src/counterexamples/MILPMinimalLabelSetGenerator.h index b73ff1590..8b151c834 100644 --- a/src/counterexamples/MILPMinimalLabelSetGenerator.h +++ b/src/counterexamples/MILPMinimalLabelSetGenerator.h @@ -1000,11 +1000,11 @@ namespace storm { * @param formulaPtr A pointer to a safety formula. The outermost operator must be a probabilistic bound operator with a strict upper bound. The nested * formula can be either an unbounded until formula or an eventually formula. */ - static void computeCounterexample(storm::ir::Program const& program, storm::models::Mdp<T> const& labeledMdp, storm::property::prctl::AbstractPrctlFormula<double> const* formulaPtr) { + static void computeCounterexample(storm::ir::Program const& program, storm::models::Mdp<T> const& labeledMdp, std::shared_ptr<storm::property::prctl::AbstractPrctlFormula<double>> const & formulaPtr) { std::cout << std::endl << "Generating minimal label counterexample for formula " << formulaPtr->toString() << std::endl; // First, we need to check whether the current formula is an Until-Formula. - storm::property::prctl::ProbabilisticBoundOperator<double> const* probBoundFormula = dynamic_cast<storm::property::prctl::ProbabilisticBoundOperator<double> const*>(formulaPtr); - if (probBoundFormula == nullptr) { + std::shared_ptr<storm::property::prctl::ProbabilisticBoundOperator<double>> probBoundFormula = std::dynamic_pointer_cast<storm::property::prctl::ProbabilisticBoundOperator<double>>(formulaPtr); + if (probBoundFormula.get() == nullptr) { LOG4CPLUS_ERROR(logger, "Illegal formula " << probBoundFormula->toString() << " for counterexample generation."); throw storm::exceptions::InvalidPropertyException() << "Illegal formula " << probBoundFormula->toString() << " for counterexample generation."; } @@ -1016,26 +1016,26 @@ namespace storm { // Now derive the probability threshold we need to exceed as well as the phi and psi states. Simultaneously, check whether the formula is of a valid shape. double bound = probBoundFormula->getBound(); - storm::property::prctl::AbstractPathFormula<double> const& pathFormula = probBoundFormula->getPathFormula(); + std::shared_ptr<storm::property::prctl::AbstractPathFormula<double>> pathFormula = probBoundFormula->getPathFormula(); storm::storage::BitVector phiStates; storm::storage::BitVector psiStates; storm::modelchecker::prctl::SparseMdpPrctlModelChecker<T> modelchecker(labeledMdp); - try { - storm::property::prctl::Until<double> const& untilFormula = dynamic_cast<storm::property::prctl::Until<double> const&>(pathFormula); - - phiStates = untilFormula.getLeft().check(modelchecker); - psiStates = untilFormula.getRight().check(modelchecker); - } catch (std::bad_cast const&) { + + std::shared_ptr<storm::property::prctl::Until<double>> untilFormula = std::dynamic_pointer_cast<storm::property::prctl::Until<double>>(pathFormula); + if(untilFormula.get() != nullptr) { + phiStates = untilFormula->getLeft()->check(modelchecker); + psiStates = untilFormula->getRight()->check(modelchecker); + + } if (std::dynamic_pointer_cast<storm::property::prctl::Eventually<double>>(pathFormula).get() != nullptr) { // If the nested formula was not an until formula, it remains to check whether it's an eventually formula. - try { - storm::property::prctl::Eventually<double> const& eventuallyFormula = dynamic_cast<storm::property::prctl::Eventually<double> const&>(pathFormula); - - phiStates = storm::storage::BitVector(labeledMdp.getNumberOfStates(), true); - psiStates = eventuallyFormula.getChild().check(modelchecker); - } catch (std::bad_cast const&) { - // If the nested formula is neither an until nor a finally formula, we throw an exception. - throw storm::exceptions::InvalidPropertyException() << "Formula nested inside probability bound operator must be an until or eventually formula for counterexample generation."; - } + std::shared_ptr<storm::property::prctl::Eventually<double>> eventuallyFormula = std::dynamic_pointer_cast<storm::property::prctl::Eventually<double>>(pathFormula); + + phiStates = storm::storage::BitVector(labeledMdp.getNumberOfStates(), true); + psiStates = eventuallyFormula->getChild()->check(modelchecker); + + } else { + // If the nested formula is neither an until nor a finally formula, we throw an exception. + throw storm::exceptions::InvalidPropertyException() << "Formula nested inside probability bound operator must be an until or eventually formula for counterexample generation."; } // Delegate the actual computation work to the function of equal name. diff --git a/src/counterexamples/PathBasedSubsystemGenerator.h b/src/counterexamples/PathBasedSubsystemGenerator.h index 11e24d00d..94a7cc955 100644 --- a/src/counterexamples/PathBasedSubsystemGenerator.h +++ b/src/counterexamples/PathBasedSubsystemGenerator.h @@ -272,138 +272,6 @@ public: LOG4CPLUS_DEBUG(logger, "Discovery done."); } - /*! - * - *//* - template <typename T> - static void doBackwardsSearch(storm::storage::SparseMatrix<T> const& transMat, storm::storage::BitVector& initStates, storm::storage::BitVector& subSysStates, storm::storage::BitVector& terminalStates, storm::storage::BitVector& allowedStates, std::vector<T>& probabilities, std::vector<uint_fast64_t>& shortestPath, T& probability) { - std::multiset<std::pair<uint_fast64_t, T>, CompareStates<T> > activeSet; - - // resize and init distances - const std::pair<uint_fast64_t, T> initDistances(0, (T) -1); - std::vector<std::pair<uint_fast64_t, T>> distances(transMat.getColumnCount(), initDistances); - - //since the transition matrix only gives a means to iterate over successors and not over predecessors and there is no Transpose for the matrix - //GraphTransitions is used - storm::models::GraphTransitions<T> backTrans(transMat, false); - - //First store all allowed predecessors of target states that are not in the subsystem - for(storm::storage::BitVector::constIndexIterator target = terminalStates.begin(); target != terminalStates.end(); ++target) { - - // if there is a terminal state that is an initial state then prob == 1 and return - if(initStates.get(*target)){ - distances[*target].first = *target; - distances[*target].second = (T) 1; - return; - } - - //iterate over predecessors - for(auto iter = backTrans.beginStateSuccessorsIterator(*target); iter != backTrans.endStateSuccessorsIterator(*target); iter++) { - //only use if allowed and not in subsys and not terminal - if(allowedStates.get(*iter) && !subSysStates.get(*iter) && !terminalStates.get(*iter)) { - //new state? - if(distances[*iter].second == (T) -1) { - // save as discovered and push into active set - distances[*iter].first = *target; //successor - distances[*iter].second = transMat.getValue(*iter, *target); //prob of shortest path - - activeSet.insert(std::pair<uint_fast64_t, T>(*iter, probabilities[*iter])); //prob of reaching some terminal state from pred. - } - else { - // state was already discovered - // is this the better transition? - if(distances[*iter].second > transMat.getValue(*iter, *target)) { - distances[*iter].first = *target; - distances[*iter].second = transMat.getValue(*iter, *target); - } - } - } - } - } - - //Now store all allowed predecessors of subsystem states that are not subsystem states themselves - for(storm::storage::BitVector::constIndexIterator sysState = subSysStates.begin(); sysState != subSysStates.end(); ++sysState) { - //iterate over predecessors - for(auto iter = backTrans.beginStateSuccessorsIterator(*sysState); iter != backTrans.endStateSuccessorsIterator(*sysState); iter++) { - //only use if allowed and not in subsys and not terminal - if(allowedStates.get(*iter) && !subSysStates.get(*iter) && !terminalStates.get(*iter)) { - //new state? - if(distances[*iter].second == (T) -1) { - // save as discovered and push into active set - distances[*iter].first = *sysState; //successor - distances[*iter].second = transMat.getValue(*iter, *sysState); //prob of shortest path - - activeSet.insert(std::pair<uint_fast64_t, T>(*iter, probabilities[*iter])); //prob of reaching some terminal state from pred. - } - else { - // state was already discovered - // is this the better transition? - if(distances[*iter].second > transMat.getValue(*iter, *sysState)) { - distances[*iter].first = *sysState; - distances[*iter].second = transMat.getValue(*iter, *sysState); - } - } - } - } - } - - LOG4CPLUS_DEBUG(logger, "Initialized."); - - // Do the backwards search - std::pair<uint_fast64_t, T> state; - uint_fast64_t activeState; - while(!activeSet.empty()) { - // copy here since using a reference leads to segfault - state = *(--activeSet.end()); - activeState = state.first; - activeSet.erase(--activeSet.end()); - - //stop on the first subsys/init state - if(initStates.get(activeState) || subSysStates.get(activeState)) break; - - // If this is a subSys or terminal state, do not consider its incoming transitions, since all relevant ones have already been considered - if(!terminalStates.get(activeState) && !subSysStates.get(activeState)) { - //iterate over predecessors - for(auto iter = backTrans.beginStateSuccessorsIterator(activeState); iter != backTrans.endStateSuccessorsIterator(activeState); iter++) { - //only if transition is not "virtual" and no selfloop - if(*iter != activeState && transMat.getValue(*iter, activeState) != (T) 0) { - //new state? - if(distances[*iter].second == (T) -1) { - // save as discovered and push into active set - distances[*iter].first = activeState; - distances[*iter].second = transMat.getValue(*iter, activeState) * distances[activeState].second; - - activeSet.insert(std::pair<uint_fast64_t, T>(*iter, probabilities[*iter])); - } - else { - // state was already discovered - // is this the better transition? - if(distances[*iter].second < transMat.getValue(*iter, activeState) * distances[activeState].second) { - distances[*iter].first = activeState; - distances[*iter].second = transMat.getValue(*iter, activeState) * distances[activeState].second; - } - } - } - } - } - } - - //get path probability - probability = distances[activeState].second; - if(probability == (T) -1) probability = 1; - - // iterate over the successors until reaching the end of the finite path - shortestPath.push_back(activeState); - activeState = distances[activeState].first; - while(!terminalStates.get(activeState) && !subSysStates.get(activeState)) { - shortestPath.push_back(activeState); - activeState = distances[activeState].first; - } - shortestPath.push_back(activeState); - } - - */ - /*! * */ @@ -507,7 +375,7 @@ public: /*! * */ - static storm::models::Dtmc<T> computeCriticalSubsystem(storm::models::Dtmc<T> & model, storm::property::prctl::AbstractStateFormula<T> const& stateFormula) { + static storm::models::Dtmc<T> computeCriticalSubsystem(storm::models::Dtmc<T> const & model, std::shared_ptr<storm::property::prctl::AbstractStateFormula<T>> const & stateFormula) { //------------------------------------------------------------- // 1. Strip and handle formulas @@ -525,27 +393,23 @@ public: // init bit vector to contain the subsystem storm::storage::BitVector subSys(model.getNumberOfStates()); - storm::property::prctl::AbstractPathFormula<T> const* pathFormulaPtr; - T bound = 0; // Strip bound operator - storm::property::prctl::ProbabilisticBoundOperator<T> const* boundOperator = dynamic_cast<storm::property::prctl::ProbabilisticBoundOperator<T> const*>(&stateFormula); + std::shared_ptr<storm::property::prctl::ProbabilisticBoundOperator<T>> boundOperator = std::dynamic_pointer_cast<storm::property::prctl::ProbabilisticBoundOperator<T>>(stateFormula); if(boundOperator == nullptr){ LOG4CPLUS_ERROR(logger, "No path bound operator at formula root."); return model.getSubDtmc(subSys); } - bound = boundOperator->getBound(); - - storm::property::prctl::AbstractPathFormula<T> const& abstractPathFormula = boundOperator->getPathFormula(); - pathFormulaPtr = &abstractPathFormula; + T bound = boundOperator->getBound(); + std::shared_ptr<storm::property::prctl::AbstractPathFormula<T>> pathFormula = boundOperator->getPathFormula();; // get "init" labeled states storm::storage::BitVector initStates = model.getLabeledStates("init"); //get real prob for formula logger.getAppender("mainFileAppender")->setThreshold(log4cplus::WARN_LOG_LEVEL); - std::vector<T> trueProbs = pathFormulaPtr->check(modelCheck, false); + std::vector<T> trueProbs = pathFormula->check(modelCheck, false); logger.getAppender("mainFileAppender")->setThreshold(log4cplus::INFO_LOG_LEVEL); T trueProb = 0; @@ -559,22 +423,22 @@ public: storm::storage::BitVector allowedStates; storm::storage::BitVector targetStates; - storm::property::prctl::Eventually<T> const* eventually = dynamic_cast<storm::property::prctl::Eventually<T> const*>(pathFormulaPtr); - storm::property::prctl::Globally<T> const* globally = dynamic_cast<storm::property::prctl::Globally<T> const*>(pathFormulaPtr); - storm::property::prctl::Until<T> const* until = dynamic_cast<storm::property::prctl::Until<T> const*>(pathFormulaPtr); - if(eventually != nullptr) { - targetStates = eventually->getChild().check(modelCheck); + std::shared_ptr<storm::property::prctl::Eventually<T>> eventually = std::dynamic_pointer_cast<storm::property::prctl::Eventually<T>>(pathFormula); + std::shared_ptr<storm::property::prctl::Globally<T>> globally = std::dynamic_pointer_cast<storm::property::prctl::Globally<T>>(pathFormula); + std::shared_ptr<storm::property::prctl::Until<T>> until = std::dynamic_pointer_cast<storm::property::prctl::Until<T>>(pathFormula); + if(eventually.get() != nullptr) { + targetStates = eventually->getChild()->check(modelCheck); allowedStates = storm::storage::BitVector(targetStates.size(), true); } - else if(globally != nullptr){ + else if(globally.get() != nullptr){ //eventually reaching a state without property visiting only states with property - allowedStates = globally->getChild().check(modelCheck); + allowedStates = globally->getChild()->check(modelCheck); targetStates = storm::storage::BitVector(allowedStates); targetStates.complement(); } - else if(until != nullptr) { - allowedStates = until->getLeft().check(modelCheck); - targetStates = until->getRight().check(modelCheck); + else if(until.get() != nullptr) { + allowedStates = until->getLeft()->check(modelCheck); + targetStates = until->getRight()->check(modelCheck); } else { LOG4CPLUS_ERROR(logger, "Strange path formula. Can't decipher."); diff --git a/src/counterexamples/SMTMinimalCommandSetGenerator.h b/src/counterexamples/SMTMinimalCommandSetGenerator.h index f95bc2806..dee532960 100644 --- a/src/counterexamples/SMTMinimalCommandSetGenerator.h +++ b/src/counterexamples/SMTMinimalCommandSetGenerator.h @@ -1773,45 +1773,44 @@ namespace storm { #endif } - static void computeCounterexample(storm::ir::Program program, std::string const& constantDefinitionString, storm::models::Mdp<T> const& labeledMdp, storm::property::prctl::AbstractPrctlFormula<double> const* formulaPtr) { + static void computeCounterexample(storm::ir::Program program, std::string const& constantDefinitionString, storm::models::Mdp<T> const& labeledMdp, std::shared_ptr<storm::property::prctl::AbstractPrctlFormula<double>> const & formulaPtr) { #ifdef STORM_HAVE_Z3 std::cout << std::endl << "Generating minimal label counterexample for formula " << formulaPtr->toString() << std::endl; // First, we need to check whether the current formula is an Until-Formula. - storm::property::prctl::ProbabilisticBoundOperator<double> const* probBoundFormula = dynamic_cast<storm::property::prctl::ProbabilisticBoundOperator<double> const*>(formulaPtr); - if (probBoundFormula == nullptr) { + std::shared_ptr<storm::property::prctl::ProbabilisticBoundOperator<double>> probBoundFormula = std::dynamic_pointer_cast<storm::property::prctl::ProbabilisticBoundOperator<double>>(formulaPtr); + if (probBoundFormula.get() == nullptr) { LOG4CPLUS_ERROR(logger, "Illegal formula " << probBoundFormula->toString() << " for counterexample generation."); throw storm::exceptions::InvalidPropertyException() << "Illegal formula " << probBoundFormula->toString() << " for counterexample generation."; } - // Check whether we were given an upper bound, because counterexample generation is limited to this case. if (probBoundFormula->getComparisonOperator() != storm::property::ComparisonType::LESS && probBoundFormula->getComparisonOperator() != storm::property::ComparisonType::LESS_EQUAL) { LOG4CPLUS_ERROR(logger, "Illegal comparison operator in formula " << probBoundFormula->toString() << ". Only upper bounds are supported for counterexample generation."); throw storm::exceptions::InvalidPropertyException() << "Illegal comparison operator in formula " << probBoundFormula->toString() << ". Only upper bounds are supported for counterexample generation."; } - bool strictBound = probBoundFormula->getComparisonOperator() == storm::property::ComparisonType::LESS; - + bool strictBound = !(probBoundFormula->getComparisonOperator() == storm::property::ComparisonType::LESS); + // Now derive the probability threshold we need to exceed as well as the phi and psi states. Simultaneously, check whether the formula is of a valid shape. double bound = probBoundFormula->getBound(); - storm::property::prctl::AbstractPathFormula<double> const& pathFormula = probBoundFormula->getPathFormula(); + std::shared_ptr<storm::property::prctl::AbstractPathFormula<double>> pathFormula = probBoundFormula->getPathFormula(); storm::storage::BitVector phiStates; storm::storage::BitVector psiStates; storm::modelchecker::prctl::SparseMdpPrctlModelChecker<T> modelchecker(labeledMdp); - try { - storm::property::prctl::Until<double> const& untilFormula = dynamic_cast<storm::property::prctl::Until<double> const&>(pathFormula); - - phiStates = untilFormula.getLeft().check(modelchecker); - psiStates = untilFormula.getRight().check(modelchecker); - } catch (std::bad_cast const& e) { + + std::shared_ptr<storm::property::prctl::Until<double>> untilFormula = std::dynamic_pointer_cast<storm::property::prctl::Until<double>>(pathFormula); + if(untilFormula.get() != nullptr) { + phiStates = untilFormula->getLeft()->check(modelchecker); + psiStates = untilFormula->getRight()->check(modelchecker); + + } if (std::dynamic_pointer_cast<storm::property::prctl::Eventually<double>>(pathFormula).get() != nullptr) { // If the nested formula was not an until formula, it remains to check whether it's an eventually formula. - try { - storm::property::prctl::Eventually<double> const& eventuallyFormula = dynamic_cast<storm::property::prctl::Eventually<double> const&>(pathFormula); - - phiStates = storm::storage::BitVector(labeledMdp.getNumberOfStates(), true); - psiStates = eventuallyFormula.getChild().check(modelchecker); - } catch (std::bad_cast const& e) { - // If the nested formula is neither an until nor a finally formula, we throw an exception. - throw storm::exceptions::InvalidPropertyException() << "Formula nested inside probability bound operator must be an until or eventually formula for counterexample generation."; - } + std::shared_ptr<storm::property::prctl::Eventually<double>> eventuallyFormula = std::dynamic_pointer_cast<storm::property::prctl::Eventually<double>>(pathFormula); + + phiStates = storm::storage::BitVector(labeledMdp.getNumberOfStates(), true); + psiStates = eventuallyFormula->getChild()->check(modelchecker); + + } else { + // If the nested formula is neither an until nor a finally formula, we throw an exception. + throw storm::exceptions::InvalidPropertyException() << "Formula nested inside probability bound operator must be an until or eventually formula for counterexample generation."; } // Delegate the actual computation work to the function of equal name. diff --git a/src/formula/AbstractFormula.h b/src/formula/AbstractFormula.h index ebe6f6e73..b1e7f262d 100644 --- a/src/formula/AbstractFormula.h +++ b/src/formula/AbstractFormula.h @@ -78,7 +78,7 @@ public: * @param checker Checker object. * @return true iff all subtrees are valid. */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const = 0; + virtual bool validate(AbstractFormulaChecker<T> const & checker) const = 0; }; } // namespace property diff --git a/src/formula/AbstractFormulaChecker.h b/src/formula/AbstractFormulaChecker.h index 0f83f3860..97c0446ee 100644 --- a/src/formula/AbstractFormulaChecker.h +++ b/src/formula/AbstractFormulaChecker.h @@ -11,6 +11,7 @@ template <class T> class AbstractFormulaChecker; #include "src/formula/AbstractFormula.h" +#include <memory> namespace storm { namespace property { @@ -64,7 +65,7 @@ class AbstractFormulaChecker { * @param formula A pointer to some formula object. * @return true iff the formula is valid. */ - virtual bool validate(const AbstractFormula<T>* formula) const = 0; + virtual bool validate(std::shared_ptr<AbstractFormula<T>> const & formula) const = 0; }; } // namespace property diff --git a/src/formula/PrctlFormulaChecker.h b/src/formula/PrctlFormulaChecker.h index f4379b47d..08b40f895 100644 --- a/src/formula/PrctlFormulaChecker.h +++ b/src/formula/PrctlFormulaChecker.h @@ -5,6 +5,7 @@ #include "src/formula/Prctl.h" #include <iostream> +#include <memory> namespace storm { namespace property { @@ -22,20 +23,19 @@ class PrctlFormulaChecker : public AbstractFormulaChecker<T> { * Implementation of AbstractFormulaChecker::validate() using code * looking exactly like the sample code given there. */ - virtual bool validate(const storm::property::abstract::AbstractFormula<T>* formula) const { + virtual bool validate(std::shared_ptr<storm::property::abstract::AbstractFormula<T>> const & formula) const { // What to support: Principles of Model Checking Def. 10.76 + syntactic sugar if ( - dynamic_cast<const storm::property::prctl::And<T>*>(formula) || - dynamic_cast<const storm::property::prctl::Ap<T>*>(formula) || - dynamic_cast<const storm::property::prctl::BoundedUntil<T>*>(formula) || - dynamic_cast<const storm::property::prctl::Eventually<T>*>(formula) || - dynamic_cast<const storm::property::prctl::Globally<T>*>(formula) || - dynamic_cast<const storm::property::prctl::Next<T>*>(formula) || - dynamic_cast<const storm::property::prctl::Not<T>*>(formula) || - dynamic_cast<const storm::property::prctl::Or<T>*>(formula) || - dynamic_cast<const storm::property::prctl::ProbabilisticNoBoundOperator<T>*>(formula) || - dynamic_cast<const storm::property::prctl::ProbabilisticBoundOperator<T>*>(formula) || - dynamic_cast<const storm::property::prctl::Until<T>*>(formula) + dynamic_pointer_cast<storm::property::prctl::And<T>>(formula) || + dynamic_pointer_cast<storm::property::prctl::Ap<T>>(formula) || + dynamic_pointer_cast<storm::property::prctl::BoundedUntil<T>>(formula) || + dynamic_pointer_cast<storm::property::prctl::Eventually<T>>(formula) || + dynamic_pointer_cast<storm::property::prctl::Globally<T>>(formula) || + dynamic_pointer_cast<storm::property::prctl::Next<T>>(formula) || + dynamic_pointer_cast<storm::property::prctl::Not<T>>(formula) || + dynamic_pointer_cast<storm::property::prctl::Or<T>>(formula) || + dynamic_pointer_cast<storm::property::prctl::ProbabilisticBoundOperator<T>>(formula) || + dynamic_pointer_cast<storm::property::prctl::Until<T>>(formula) ) { return formula->validate(*this); } diff --git a/src/formula/actions/FormulaAction.h b/src/formula/actions/FormulaAction.h index e3867c721..c22f8d7a0 100644 --- a/src/formula/actions/FormulaAction.h +++ b/src/formula/actions/FormulaAction.h @@ -26,11 +26,15 @@ class FormulaAction : public AbstractAction<T> { public: - FormulaAction(storm::property::prctl::AbstractStateFormula<T>* prctlFormula) : prctlFormula(prctlFormula), cslFormula(nullptr) { + FormulaAction() : prctlFormula(nullptr), cslFormula(nullptr) { //Intentionally left empty. } - FormulaAction(storm::property::csl::AbstractStateFormula<T>* cslFormula) : prctlFormula(nullptr), cslFormula(cslFormula) { + FormulaAction(std::shared_ptr<storm::property::prctl::AbstractStateFormula<T>> const & prctlFormula) : prctlFormula(prctlFormula), cslFormula(nullptr) { + //Intentionally left empty. + } + + FormulaAction(std::shared_ptr<storm::property::csl::AbstractStateFormula<T>> const & cslFormula) : prctlFormula(nullptr), cslFormula(cslFormula) { //Intentionally left empty. } @@ -39,12 +43,7 @@ public: * To ensure that the right destructor is called */ virtual ~FormulaAction() { - if(prctlFormula != nullptr) { - delete prctlFormula; - } - if(cslFormula != nullptr) { - delete cslFormula; - } + // Intentionally left empty. } /*! @@ -55,7 +54,7 @@ public: storm::storage::BitVector selection(result.selection); //Compute the modelchecking results of the actions state formula and deselect all states that do not satisfy it. - if(prctlFormula != nullptr) { + if(prctlFormula.get() != nullptr) { selection = selection & prctlFormula->check(mc); } @@ -70,7 +69,7 @@ public: storm::storage::BitVector selection(result.selection); //Compute the modelchecking results of the actions state formula and deselect all states that do not satisfy it. - if(cslFormula != nullptr) { + if(cslFormula.get() != nullptr) { selection = selection & cslFormula->check(mc); } @@ -82,9 +81,9 @@ public: */ virtual std::string toString() const override { std::string out = "states("; - if(prctlFormula != nullptr) { + if(prctlFormula.get() != nullptr) { out += prctlFormula->toString(); - } else if(cslFormula != nullptr) { + } else if(cslFormula.get() != nullptr) { out += cslFormula->toString(); } out += ")"; @@ -92,8 +91,8 @@ public: } private: - storm::property::prctl::AbstractStateFormula<T>* prctlFormula; - storm::property::csl::AbstractStateFormula<T>* cslFormula; + std::shared_ptr<storm::property::prctl::AbstractStateFormula<T>> prctlFormula; + std::shared_ptr<storm::property::csl::AbstractStateFormula<T>> cslFormula; }; diff --git a/src/formula/csl/AbstractPathFormula.h b/src/formula/csl/AbstractPathFormula.h index d2cd10fa9..6de58a14d 100644 --- a/src/formula/csl/AbstractPathFormula.h +++ b/src/formula/csl/AbstractPathFormula.h @@ -58,7 +58,7 @@ public: * @note This function is not implemented in this class. * @returns a new AND-object that is identical the called object. */ - virtual AbstractPathFormula<T>* clone() const = 0; + virtual std::shared_ptr<AbstractPathFormula<T>> clone() const = 0; /*! * Calls the model checker to check this formula. @@ -71,7 +71,7 @@ public: * * @returns A vector indicating the probability that the formula holds for each state. */ - virtual std::vector<T> check(const storm::modelchecker::csl::AbstractModelChecker<T>& modelChecker, bool qualitative) const = 0; + virtual std::vector<T> check(storm::modelchecker::csl::AbstractModelChecker<T> const & modelChecker, bool qualitative) const = 0; }; } //namespace csl diff --git a/src/formula/csl/AbstractStateFormula.h b/src/formula/csl/AbstractStateFormula.h index 07f227961..4a50c21b2 100644 --- a/src/formula/csl/AbstractStateFormula.h +++ b/src/formula/csl/AbstractStateFormula.h @@ -44,7 +44,7 @@ public: * @note This function is not implemented in this class. * @returns a new AND-object that is identical the called object. */ - virtual AbstractStateFormula<T>* clone() const = 0; + virtual std::shared_ptr<AbstractStateFormula<T>> clone() const = 0; /*! * Calls the model checker to check this formula. @@ -57,7 +57,7 @@ public: * * @returns A bit vector indicating all states that satisfy the formula represented by the called object. */ - virtual storm::storage::BitVector check(const storm::modelchecker::csl::AbstractModelChecker<T>& modelChecker) const = 0; + virtual storm::storage::BitVector check(storm::modelchecker::csl::AbstractModelChecker<T> const & modelChecker) const = 0; }; } //namespace csl diff --git a/src/formula/csl/And.h b/src/formula/csl/And.h index e8a04e79f..0d10fbef6 100644 --- a/src/formula/csl/And.h +++ b/src/formula/csl/And.h @@ -61,9 +61,8 @@ public: * Empty constructor. * Will create an AND-node without subnotes. Will not represent a complete formula! */ - And() { - left = NULL; - right = NULL; + And() : left(nullptr), right(nullptr){ + // Intentionally left empty. } /*! @@ -73,9 +72,8 @@ public: * @param left The left sub formula * @param right The right sub formula */ - And(AbstractStateFormula<T>* left, AbstractStateFormula<T>* right) { - this->left = left; - this->right = right; + And(std::shared_ptr<AbstractStateFormula<T>> const & left, std::shared_ptr<AbstractStateFormula<T>> const & right) : left(left), right(right) { + // Intentionally left empty. } /*! @@ -85,12 +83,7 @@ public: * (this behavior can be prevented by setting them to NULL before deletion) */ virtual ~And() { - if (left != NULL) { - delete left; - } - if (right != NULL) { - delete right; - } + // Intentionally left empty. } /*! @@ -100,13 +93,13 @@ public: * * @returns a new AND-object that is identical the called object. */ - virtual AbstractStateFormula<T>* clone() const override { - And<T>* result = new And(); + virtual std::shared_ptr<AbstractStateFormula<T>> clone() const override { + std::shared_ptr<And<T>> result(new And()); if (this->leftIsSet()) { - result->setLeft(this->getLeft().clone()); + result->setLeft(left->clone()); } if (this->rightIsSet()) { - result->setRight(this->getRight().clone()); + result->setRight(right->clone()); } return result; } @@ -142,7 +135,7 @@ public: * @param checker Formula checker object. * @return true iff all subtrees conform to some logic. */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { return checker.validate(this->left) && checker.validate(this->right); } @@ -151,7 +144,7 @@ public: * * @param newLeft the new left child. */ - void setLeft(AbstractStateFormula<T>* newLeft) { + void setLeft(std::shared_ptr<AbstractStateFormula<T>> const & newLeft) { left = newLeft; } @@ -160,22 +153,22 @@ public: * * @param newRight the new right child. */ - void setRight(AbstractStateFormula<T>* newRight) { + void setRight(std::shared_ptr<AbstractStateFormula<T>> const & newRight) { right = newRight; } /*! * @returns a pointer to the left child node */ - const AbstractStateFormula<T>& getLeft() const { - return *left; + std::shared_ptr<AbstractStateFormula<T>> const & getLeft() const { + return left; } /*! * @returns a pointer to the right child node */ - const AbstractStateFormula<T>& getRight() const { - return *right; + std::shared_ptr<AbstractStateFormula<T>> const & getRight() const { + return right; } /*! @@ -183,7 +176,7 @@ public: * @return True if the left child is set, i.e. it does not point to nullptr; false otherwise */ bool leftIsSet() const { - return left != nullptr; + return left.get() != nullptr; } /*! @@ -191,12 +184,12 @@ public: * @return True if the right child is set, i.e. it does not point to nullptr; false otherwise */ bool rightIsSet() const { - return right != nullptr; + return right.get() != nullptr; } private: - AbstractStateFormula<T>* left; - AbstractStateFormula<T>* right; + std::shared_ptr<AbstractStateFormula<T>> left; + std::shared_ptr<AbstractStateFormula<T>> right; }; diff --git a/src/formula/csl/Ap.h b/src/formula/csl/Ap.h index 0f59dd97b..6b7f8ec56 100644 --- a/src/formula/csl/Ap.h +++ b/src/formula/csl/Ap.h @@ -76,8 +76,9 @@ public: * * @returns a new AND-object that is identical the called object. */ - virtual AbstractStateFormula<T>* clone() const override { - return new Ap(this->getAp()); + virtual std::shared_ptr<AbstractStateFormula<T>> clone() const override { + std::shared_ptr<AbstractStateFormula<T>> result(new Ap(this->getAp())); + return result; } /*! @@ -89,7 +90,7 @@ public: * * @returns A bit vector indicating all states that satisfy the formula represented by the called object. */ - virtual storm::storage::BitVector check(const storm::modelchecker::csl::AbstractModelChecker<T>& modelChecker) const override { + virtual storm::storage::BitVector check(storm::modelchecker::csl::AbstractModelChecker<T> const & modelChecker) const override { return modelChecker.template as<IApModelChecker>()->checkAp(*this); } @@ -101,14 +102,14 @@ public: * @param checker Formula checker object. * @return true */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { return true; } /*! * @returns the name of the atomic proposition */ - const std::string& getAp() const { + std::string const & getAp() const { return ap; } diff --git a/src/formula/csl/CslFilter.h b/src/formula/csl/CslFilter.h index c6144ad02..b7c99df39 100644 --- a/src/formula/csl/CslFilter.h +++ b/src/formula/csl/CslFilter.h @@ -39,21 +39,20 @@ public: // Intentionally left empty. } - CslFilter(AbstractCslFormula<T>* child, OptimizingOperator opt = UNDEFINED, bool steadyStateQuery = false) : AbstractFilter<T>(opt), child(child), steadyStateQuery(steadyStateQuery) { + CslFilter(std::shared_ptr<AbstractCslFormula<T>> const & child, OptimizingOperator opt = UNDEFINED, bool steadyStateQuery = false) : AbstractFilter<T>(opt), child(child), steadyStateQuery(steadyStateQuery) { // Intentionally left empty. } - CslFilter(AbstractCslFormula<T>* child, action::AbstractAction<T>* action, OptimizingOperator opt = UNDEFINED, bool steadyStateQuery = false) : AbstractFilter<T>(action, opt), child(child), steadyStateQuery(steadyStateQuery) { + CslFilter(std::shared_ptr<AbstractCslFormula<T>> const & child, action::AbstractAction<T>* action, OptimizingOperator opt = UNDEFINED, bool steadyStateQuery = false) : AbstractFilter<T>(action, opt), child(child), steadyStateQuery(steadyStateQuery) { // Intentionally left empty } - CslFilter(AbstractCslFormula<T>* child, std::vector<action::AbstractAction<T>*> actions, OptimizingOperator opt = UNDEFINED, bool steadyStateQuery = false) : AbstractFilter<T>(actions, opt), child(child), steadyStateQuery(steadyStateQuery) { + CslFilter(std::shared_ptr<AbstractCslFormula<T>> const & child, std::vector<action::AbstractAction<T>*> actions, OptimizingOperator opt = UNDEFINED, bool steadyStateQuery = false) : AbstractFilter<T>(actions, opt), child(child), steadyStateQuery(steadyStateQuery) { // Intentionally left empty. } virtual ~CslFilter() { this->actions.clear(); - delete child; } void check(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelchecker) const { @@ -66,10 +65,10 @@ public: Result result; try { - if(dynamic_cast<AbstractStateFormula<T> *>(child) != nullptr) { - result = evaluate(modelchecker, dynamic_cast<AbstractStateFormula<T> *>(child)); - } else if (dynamic_cast<AbstractPathFormula<T> *>(child) != nullptr) { - result = evaluate(modelchecker, dynamic_cast<AbstractPathFormula<T> *>(child)); + if(std::dynamic_pointer_cast<AbstractStateFormula<T>>(child).get() != nullptr) { + result = evaluate(modelchecker, std::dynamic_pointer_cast<AbstractStateFormula<T>>(child)); + } else if (std::dynamic_pointer_cast<AbstractPathFormula<T>>(child).get() != nullptr) { + result = evaluate(modelchecker, std::dynamic_pointer_cast<AbstractPathFormula<T>>(child)); } } catch (std::exception& e) { std::cout << "Error during computation: " << e.what() << "Skipping property." << std::endl; @@ -86,7 +85,7 @@ public: virtual std::string toString() const override { std::string desc = ""; - if(dynamic_cast<AbstractStateFormula<T>*>(child) == nullptr) { + if(!std::dynamic_pointer_cast<AbstractStateFormula<T>>(child)) { // The formula is not a state formula so we have a probability query. if(this->actions.empty()){ @@ -180,19 +179,19 @@ public: return desc; } - void setChild(AbstractCslFormula<T>* child) { + void setChild(std::shared_ptr<AbstractCslFormula<T>> const & child) { this->child = child; } - AbstractCslFormula<T>* getChild() const { + std::shared_ptr<AbstractCslFormula<T>> const & getChild() const { return child; } private: - storm::storage::BitVector evaluate(storm::modelchecker::csl::AbstractModelChecker<T> const & modelchecker, AbstractStateFormula<T>* formula) const { + storm::storage::BitVector evaluate(storm::modelchecker::csl::AbstractModelChecker<T> const & modelchecker, std::shared_ptr<AbstractStateFormula<T>> const & formula) const { // First, get the model checking result. - storm::storage::BitVector result = modelchecker.checkMinMaxOperator(formula); + storm::storage::BitVector result = modelchecker.checkMinMaxOperator(*formula); if(this->opt != UNDEFINED) { // If there is an action specifying that min/max probabilities should be computed, call the appropriate method of the model checker. @@ -206,13 +205,13 @@ private: return evaluateActions(result, modelchecker); } - std::vector<T> evaluate(storm::modelchecker::csl::AbstractModelChecker<T> const & modelchecker, AbstractPathFormula<T>* formula) const { + std::vector<T> evaluate(storm::modelchecker::csl::AbstractModelChecker<T> const & modelchecker, std::shared_ptr<AbstractPathFormula<T>> const & formula) const { // First, get the model checking result. std::vector<T> result; if(this->opt != UNDEFINED) { // If there is an action specifying that min/max probabilities should be computed, call the appropriate method of the model checker. - result = modelchecker.checkMinMaxOperator(formula, this->opt == MINIMIZE ? true : false); + result = modelchecker.checkMinMaxOperator(*formula, this->opt == MINIMIZE ? true : false); } else { result = formula->check(modelchecker, false); } @@ -294,7 +293,7 @@ private: std::cout << std::endl << "-------------------------------------------" << std::endl; } - AbstractCslFormula<T>* child; + std::shared_ptr<AbstractCslFormula<T>> child; bool steadyStateQuery; }; diff --git a/src/formula/csl/Eventually.h b/src/formula/csl/Eventually.h index c72f0ce8e..8428d5f00 100644 --- a/src/formula/csl/Eventually.h +++ b/src/formula/csl/Eventually.h @@ -68,7 +68,7 @@ public: * * @param child The child node */ - Eventually(AbstractStateFormula<T>* child) : child(child){ + Eventually(std::shared_ptr<AbstractStateFormula<T>> const & child) : child(child){ // Intentionally left empty. } @@ -79,9 +79,7 @@ public: * (this behaviour can be prevented by setting the subtrees to nullptr before deletion) */ virtual ~Eventually() { - if (child != nullptr) { - delete child; - } + // Intentionally left empty. } /*! @@ -91,10 +89,10 @@ public: * * @returns a new Eventually-object that is identical the called object. */ - virtual AbstractPathFormula<T>* clone() const override { - Eventually<T>* result = new Eventually<T>(); + virtual std::shared_ptr<AbstractPathFormula<T>> clone() const override { + std::shared_ptr<Eventually<T>> result(new Eventually<T>()); if (this->childIsSet()) { - result->setChild(this->getChild().clone()); + result->setChild(child->clone()); } return result; } @@ -108,7 +106,7 @@ public: * * @returns A vector indicating the probability that the formula holds for each state. */ - virtual std::vector<T> check(const storm::modelchecker::csl::AbstractModelChecker<T>& modelChecker, bool qualitative) const override { + virtual std::vector<T> check(storm::modelchecker::csl::AbstractModelChecker<T> const & modelChecker, bool qualitative) const override { return modelChecker.template as<IEventuallyModelChecker>()->checkEventually(*this, qualitative); } @@ -127,22 +125,22 @@ public: * @param checker Formula checker object. * @return true iff the subtree conforms to some logic. */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { return checker.validate(this->child); } /*! * @returns the child node */ - const AbstractStateFormula<T>& getChild() const { - return *child; + std::shared_ptr<AbstractStateFormula<T>> const & getChild() const { + return child; } /*! * Sets the subtree * @param child the new child node */ - void setChild(AbstractStateFormula<T>* child) { + void setChild(std::shared_ptr<AbstractStateFormula<T>> const & child) { this->child = child; } @@ -151,11 +149,11 @@ public: * @return True if the child node is set, i.e. it does not point to nullptr; false otherwise */ bool childIsSet() const { - return child != nullptr; + return child.get() != nullptr; } private: - AbstractStateFormula<T>* child; + std::shared_ptr<AbstractStateFormula<T>> child; }; } //namespace csl diff --git a/src/formula/csl/Globally.h b/src/formula/csl/Globally.h index f4cd4e71c..211532efb 100644 --- a/src/formula/csl/Globally.h +++ b/src/formula/csl/Globally.h @@ -69,7 +69,7 @@ public: * * @param child The child node */ - Globally(AbstractStateFormula<T>* child) : child(child){ + Globally(std::shared_ptr<AbstractStateFormula<T>> const & child) : child(child){ // Intentionally left empty. } @@ -80,9 +80,7 @@ public: * (this behaviour can be prevented by setting the subtrees to nullptr before deletion) */ virtual ~Globally() { - if (child != nullptr) { - delete child; - } + // Intentionally left empty. } /*! @@ -92,10 +90,10 @@ public: * * @returns a new Globally-object that is identical the called object. */ - virtual AbstractPathFormula<T>* clone() const override { - Globally<T>* result = new Globally<T>(); + virtual std::shared_ptr<AbstractPathFormula<T>> clone() const override { + std::shared_ptr<Globally<T>> result(new Globally<T>()); if (this->childIsSet()) { - result->setChild(this->getChild().clone()); + result->setChild(child->clone()); } return result; } @@ -109,7 +107,7 @@ public: * * @returns A vector indicating the probability that the formula holds for each state. */ - virtual std::vector<T> check(const storm::modelchecker::csl::AbstractModelChecker<T>& modelChecker, bool qualitative) const override { + virtual std::vector<T> check(storm::modelchecker::csl::AbstractModelChecker<T> const & modelChecker, bool qualitative) const override { return modelChecker.template as<IGloballyModelChecker>()->checkGlobally(*this, qualitative); } @@ -128,22 +126,22 @@ public: * @param checker Formula checker object. * @return true iff the subtree conforms to some logic. */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { return checker.validate(this->child); } /*! * @returns the child node */ - const AbstractStateFormula<T>& getChild() const { - return *child; + AbstractStateFormula<T> const & getChild() const { + return child; } /*! * Sets the subtree * @param child the new child node */ - void setChild(AbstractStateFormula<T>* child) { + void setChild(std::shared_ptr<AbstractStateFormula<T>> const & child) { this->child = child; } @@ -152,11 +150,11 @@ public: * @return True if the child node is set, i.e. it does not point to nullptr; false otherwise */ bool childIsSet() const { - return child != nullptr; + return child.get() != nullptr; } private: - AbstractStateFormula<T>* child; + std::shared_ptr<AbstractStateFormula<T>> child; }; } //namespace csl diff --git a/src/formula/csl/Next.h b/src/formula/csl/Next.h index e1c7d5407..f8a8ae0f4 100644 --- a/src/formula/csl/Next.h +++ b/src/formula/csl/Next.h @@ -68,7 +68,7 @@ public: * * @param child The child node */ - Next(AbstractStateFormula<T>* child) : child(child){ + Next(std::shared_ptr<AbstractStateFormula<T>> const & child) : child(child) { // Intentionally left empty. } @@ -79,9 +79,7 @@ public: * (this behavior can be prevented by setting the subtrees to NULL before deletion) */ virtual ~Next() { - if (child != NULL) { - delete child; - } + // Intetionally left empty. } /*! @@ -91,10 +89,10 @@ public: * * @returns a new BoundedUntil-object that is identical the called object. */ - virtual AbstractPathFormula<T>* clone() const override { - Next<T>* result = new Next<T>(); + virtual std::shared_ptr<AbstractPathFormula<T>> clone() const override { + std::shared_ptr<Next<T>> result(new Next<T>()); if (this->childIsSet()) { - result->setChild(this->getChild().clone()); + result->setChild(child->clone()); } return result; } @@ -108,7 +106,7 @@ public: * * @returns A vector indicating the probability that the formula holds for each state. */ - virtual std::vector<T> check(const storm::modelchecker::csl::AbstractModelChecker<T>& modelChecker, bool qualitative) const override { + virtual std::vector<T> check(storm::modelchecker::csl::AbstractModelChecker<T> const & modelChecker, bool qualitative) const override { return modelChecker.template as<INextModelChecker>()->checkNext(*this, qualitative); } @@ -129,22 +127,22 @@ public: * @param checker Formula checker object. * @return true iff the subtree conforms to some logic. */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { return checker.validate(this->child); } /*! * @returns the child node */ - const AbstractStateFormula<T>& getChild() const { - return *child; + std::shared_ptr<AbstractStateFormula<T>> const & getChild() const { + return child; } /*! * Sets the subtree * @param child the new child node */ - void setChild(AbstractStateFormula<T>* child) { + void setChild(std::shared_ptr<AbstractStateFormula<T>> const & child) { this->child = child; } @@ -153,11 +151,11 @@ public: * @return True if the child node is set, i.e. it does not point to nullptr; false otherwise */ bool childIsSet() const { - return child != nullptr; + return child.get() != nullptr; } private: - AbstractStateFormula<T>* child; + std::shared_ptr<AbstractStateFormula<T>> child; }; } //namespace csl diff --git a/src/formula/csl/Not.h b/src/formula/csl/Not.h index 05a924819..002adb5bf 100644 --- a/src/formula/csl/Not.h +++ b/src/formula/csl/Not.h @@ -56,16 +56,16 @@ public: /*! * Empty constructor */ - Not() { - this->child = NULL; + Not() : child(nullptr) { + // Intentionally left empty. } /*! * Constructor * @param child The child node */ - Not(AbstractStateFormula<T>* child) { - this->child = child; + Not(std::shared_ptr<AbstractStateFormula<T>> const & child) : child(child) { + // Intentionally left empty. } /*! @@ -75,9 +75,7 @@ public: * (this behavior can be prevented by setting them to NULL before deletion) */ virtual ~Not() { - if (child != NULL) { - delete child; - } + // Intentionally left empty. } /*! @@ -87,10 +85,10 @@ public: * * @returns a new AND-object that is identical the called object. */ - virtual AbstractStateFormula<T>* clone() const override { - Not<T>* result = new Not<T>(); + virtual std::shared_ptr<AbstractStateFormula<T>> clone() const override { + std::shared_ptr<Not<T>> result(new Not<T>()); if (this->childIsSet()) { - result->setChild(this->getChild().clone()); + result->setChild(child->clone()); } return result; } @@ -104,7 +102,7 @@ public: * * @returns A bit vector indicating all states that satisfy the formula represented by the called object. */ - virtual storm::storage::BitVector check(const storm::modelchecker::csl::AbstractModelChecker<T>& modelChecker) const override { + virtual storm::storage::BitVector check(storm::modelchecker::csl::AbstractModelChecker<T> const & modelChecker) const override { return modelChecker.template as<INotModelChecker>()->checkNot(*this); } @@ -123,22 +121,22 @@ public: * @param checker Formula checker object. * @return true iff the subtree conforms to some logic. */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { return checker.validate(this->child); } /*! * @returns The child node */ - const AbstractStateFormula<T>& getChild() const { - return *child; + std::shared_ptr<AbstractStateFormula<T>> const & getChild() const { + return child; } /*! * Sets the subtree * @param child the new child node */ - void setChild(AbstractStateFormula<T>* child) { + void setChild(std::shared_ptr<AbstractStateFormula<T>> const & child) { this->child = child; } @@ -147,11 +145,11 @@ public: * @return True if the child node is set, i.e. it does not point to nullptr; false otherwise */ bool childIsSet() const { - return child != nullptr; + return child.get() != nullptr; } private: - AbstractStateFormula<T>* child; + std::shared_ptr<AbstractStateFormula<T>> child; }; } //namespace csl diff --git a/src/formula/csl/Or.h b/src/formula/csl/Or.h index 9eb575b38..fa9649f61 100644 --- a/src/formula/csl/Or.h +++ b/src/formula/csl/Or.h @@ -59,9 +59,8 @@ public: * Empty constructor. * Will create an OR-node without subnotes. Will not represent a complete formula! */ - Or() { - left = NULL; - right = NULL; + Or() : left(nullptr), right(nullptr) { + // Intentionally left empty. } /*! @@ -71,9 +70,8 @@ public: * @param left The left sub formula * @param right The right sub formula */ - Or(AbstractStateFormula<T>* left, AbstractStateFormula<T>* right) { - this->left = left; - this->right = right; + Or(std::shared_ptr<AbstractStateFormula<T>> const & left, std::shared_ptr<AbstractStateFormula<T>> const & right) : left(left), right(right) { + // Intentionally left empty. } /*! @@ -83,12 +81,7 @@ public: * (this behavior can be prevented by setting them to NULL before deletion) */ virtual ~Or() { - if (left != NULL) { - delete left; - } - if (right != NULL) { - delete right; - } + // Intentionally left empty. } /*! @@ -98,13 +91,13 @@ public: * * @returns a new AND-object that is identical the called object. */ - virtual AbstractStateFormula<T>* clone() const override { - Or<T>* result = new Or(); + virtual std::shared_ptr<AbstractStateFormula<T>> clone() const override { + std::shared_ptr<Or<T>> result(new Or()); if (this->leftIsSet()) { - result->setLeft(this->getLeft().clone()); + result->setLeft(left->clone()); } if (this->rightIsSet()) { - result->setRight(this->getRight().clone()); + result->setRight(right->clone()); } return result; } @@ -118,7 +111,7 @@ public: * * @returns A bit vector indicating all states that satisfy the formula represented by the called object. */ - virtual storm::storage::BitVector check(const storm::modelchecker::csl::AbstractModelChecker<T>& modelChecker) const override { + virtual storm::storage::BitVector check(storm::modelchecker::csl::AbstractModelChecker<T> const & modelChecker) const override { return modelChecker.template as<IOrModelChecker>()->checkOr(*this); } @@ -140,7 +133,7 @@ public: * @param checker Formula checker object. * @return true iff all subtrees conform to some logic. */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { return checker.validate(this->left) && checker.validate(this->right); } @@ -149,7 +142,7 @@ public: * * @param newLeft the new left child. */ - void setLeft(AbstractStateFormula<T>* newLeft) { + void setLeft(std::shared_ptr<AbstractStateFormula<T>> const & newLeft) { left = newLeft; } @@ -158,22 +151,22 @@ public: * * @param newRight the new right child. */ - void setRight(AbstractStateFormula<T>* newRight) { + void setRight(std::shared_ptr<AbstractStateFormula<T>> const & newRight) { right = newRight; } /*! * @returns a pointer to the left child node */ - const AbstractStateFormula<T>& getLeft() const { - return *left; + std::shared_ptr<AbstractStateFormula<T>> const & getLeft() const { + return left; } /*! * @returns a pointer to the right child node */ - const AbstractStateFormula<T>& getRight() const { - return *right; + std::shared_ptr<AbstractStateFormula<T>> const & getRight() const { + return right; } /*! @@ -181,7 +174,7 @@ public: * @return True if the left child is set, i.e. it does not point to nullptr; false otherwise */ bool leftIsSet() const { - return left != nullptr; + return left.get() != nullptr; } /*! @@ -189,12 +182,12 @@ public: * @return True if the right child is set, i.e. it does not point to nullptr; false otherwise */ bool rightIsSet() const { - return right != nullptr; + return right.get() != nullptr; } private: - AbstractStateFormula<T>* left; - AbstractStateFormula<T>* right; + std::shared_ptr<AbstractStateFormula<T>> left; + std::shared_ptr<AbstractStateFormula<T>> right; }; diff --git a/src/formula/csl/ProbabilisticBoundOperator.h b/src/formula/csl/ProbabilisticBoundOperator.h index 48553bb85..02986e3f8 100644 --- a/src/formula/csl/ProbabilisticBoundOperator.h +++ b/src/formula/csl/ProbabilisticBoundOperator.h @@ -71,7 +71,7 @@ public: * @param bound The bound for the probability * @param pathFormula The child node */ - ProbabilisticBoundOperator(storm::property::ComparisonType comparisonOperator, T bound, AbstractPathFormula<T>* pathFormula) + ProbabilisticBoundOperator(storm::property::ComparisonType comparisonOperator, T bound, std::shared_ptr<AbstractPathFormula<T>> const & pathFormula) : comparisonOperator(comparisonOperator), bound(bound), pathFormula(pathFormula) { // Intentionally left empty. } @@ -83,9 +83,7 @@ public: * (this behavior can be prevented by setting them to NULL before deletion) */ virtual ~ProbabilisticBoundOperator() { - if (pathFormula != nullptr) { - delete pathFormula; - } + // Intentionally left empty. } /*! @@ -95,11 +93,11 @@ public: * * @returns a new AND-object that is identical the called object. */ - virtual AbstractStateFormula<T>* clone() const override { - ProbabilisticBoundOperator<T>* result = new ProbabilisticBoundOperator<T>(); - result->setComparisonOperator(this->getComparisonOperator()); - result->setBound(this->getBound()); - result->setPathFormula(this->getPathFormula().clone()); + virtual std::shared_ptr<AbstractStateFormula<T>> clone() const override { + std::shared_ptr<ProbabilisticBoundOperator<T>> result(new ProbabilisticBoundOperator<T>()); + result->setComparisonOperator(comparisonOperator); + result->setBound(bound); + result->setPathFormula(pathFormula->clone()); return result; } @@ -112,7 +110,7 @@ public: * * @returns A bit vector indicating all states that satisfy the formula represented by the called object. */ - virtual storm::storage::BitVector check(const storm::modelchecker::csl::AbstractModelChecker<T>& modelChecker) const override { + virtual storm::storage::BitVector check(storm::modelchecker::csl::AbstractModelChecker<T> const & modelChecker) const override { return modelChecker.template as<IProbabilisticBoundOperatorModelChecker>()->checkProbabilisticBoundOperator(*this); } @@ -122,7 +120,7 @@ public: * @param checker Formula checker object. * @return true iff the subtree conforms to some logic. */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { return checker.validate(this->pathFormula); } @@ -148,8 +146,8 @@ public: /*! * @returns the child node (representation of a formula) */ - const AbstractPathFormula<T>& getPathFormula () const { - return *pathFormula; + std::shared_ptr<AbstractPathFormula<T>> const & getPathFormula () const { + return pathFormula; } /*! @@ -157,7 +155,7 @@ public: * * @param pathFormula the path formula that becomes the new child node */ - void setPathFormula(AbstractPathFormula<T>* pathFormula) { + void setPathFormula(std::shared_ptr<AbstractPathFormula<T>> const & pathFormula) { this->pathFormula = pathFormula; } @@ -166,13 +164,13 @@ public: * @return True if the path formula is set, i.e. it does not point to nullptr; false otherwise */ bool pathFormulaIsSet() const { - return pathFormula != nullptr; + return pathFormula.get() != nullptr; } /*! * @returns the comparison relation */ - const storm::property::ComparisonType getComparisonOperator() const { + storm::property::ComparisonType const getComparisonOperator() const { return comparisonOperator; } @@ -183,7 +181,7 @@ public: /*! * @returns the bound for the measure */ - const T& getBound() const { + T const & getBound() const { return bound; } @@ -192,11 +190,11 @@ public: * * @param bound The bound for the measure */ - void setBound(T bound) { + void setBound(T const & bound) { this->bound = bound; } - bool meetsBound(T value) const { + bool meetsBound(T const & value) const { switch (comparisonOperator) { case LESS: return value < bound; break; case LESS_EQUAL: return value <= bound; break; @@ -209,7 +207,7 @@ public: private: storm::property::ComparisonType comparisonOperator; T bound; - AbstractPathFormula<T>* pathFormula; + std::shared_ptr<AbstractPathFormula<T>> pathFormula; }; } //namespace csl diff --git a/src/formula/csl/SteadyStateBoundOperator.h b/src/formula/csl/SteadyStateBoundOperator.h index ecaad5ad4..c53823639 100644 --- a/src/formula/csl/SteadyStateBoundOperator.h +++ b/src/formula/csl/SteadyStateBoundOperator.h @@ -70,7 +70,7 @@ public: * @param bound The bound for the probability * @param stateFormula The child node */ - SteadyStateBoundOperator(storm::property::ComparisonType comparisonOperator, T bound, AbstractStateFormula<T>* stateFormula) + SteadyStateBoundOperator(storm::property::ComparisonType comparisonOperator, T bound, std::shared_ptr<AbstractStateFormula<T>> const & stateFormula) : comparisonOperator(comparisonOperator), bound(bound), stateFormula(stateFormula) { // Intentionally left empty } @@ -82,9 +82,7 @@ public: * (this behavior can be prevented by setting them to NULL before deletion) */ virtual ~SteadyStateBoundOperator() { - if (stateFormula != nullptr) { - delete stateFormula; - } + // Intentionally left empty. } /*! @@ -94,9 +92,9 @@ public: * * @returns a new BoundedUntil-object that is identical the called object. */ - virtual AbstractStateFormula<T>* clone() const override { - SteadyStateBoundOperator<T>* result = new SteadyStateBoundOperator<T>(); - result->setStateFormula(this->getStateFormula().clone()); + virtual std::shared_ptr<AbstractStateFormula<T>> clone() const override { + std::shared_ptr<SteadyStateBoundOperator<T>> result(new SteadyStateBoundOperator<T>()); + result->setStateFormula(stateFormula->clone()); return result; } @@ -109,7 +107,7 @@ public: * * @returns A vector indicating the probability that the formula holds for each state. */ - virtual storm::storage::BitVector check(const storm::modelchecker::csl::AbstractModelChecker<T>& modelChecker) const override { + virtual storm::storage::BitVector check(storm::modelchecker::csl::AbstractModelChecker<T> const & modelChecker) const override { return modelChecker.template as<ISteadyStateBoundOperatorModelChecker>()->checkSteadyStateBoundOperator(*this); } @@ -119,7 +117,7 @@ public: * @param checker Formula checker object. * @return true iff the subtree conforms to some logic. */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { return checker.validate(this->stateFormula); } @@ -144,8 +142,8 @@ public: /*! * @returns the child node (representation of a formula) */ - const AbstractStateFormula<T>& getStateFormula () const { - return *stateFormula; + std::shared_ptr<AbstractStateFormula<T>> const & getStateFormula () const { + return stateFormula; } /*! @@ -153,7 +151,7 @@ public: * * @param stateFormula the state formula that becomes the new child node */ - void setStateFormula(AbstractStateFormula<T>* stateFormula) { + void setStateFormula(std::shared_ptr<AbstractStateFormula<T>> const & stateFormula) { this->stateFormula = stateFormula; } @@ -162,13 +160,13 @@ public: * @return True if the state formula is set, i.e. it does not point to nullptr; false otherwise */ bool stateFormulaIsSet() const { - return stateFormula != nullptr; + return stateFormula.get() != nullptr; } /*! * @returns the comparison relation */ - const ComparisonType getComparisonOperator() const { + ComparisonType const getComparisonOperator() const { return comparisonOperator; } @@ -179,7 +177,7 @@ public: /*! * @returns the bound for the measure */ - const T& getBound() const { + T const & getBound() const { return bound; } @@ -188,7 +186,7 @@ public: * * @param bound The bound for the measure */ - void setBound(T bound) { + void setBound(T const & bound) { this->bound = bound; } @@ -205,7 +203,7 @@ public: private: ComparisonType comparisonOperator; T bound; - AbstractStateFormula<T>* stateFormula; + std::shared_ptr<AbstractStateFormula<T>> stateFormula; }; } //namespace csl diff --git a/src/formula/csl/TimeBoundedEventually.h b/src/formula/csl/TimeBoundedEventually.h index f8ef249cf..8564a0db3 100644 --- a/src/formula/csl/TimeBoundedEventually.h +++ b/src/formula/csl/TimeBoundedEventually.h @@ -50,14 +50,12 @@ public: setInterval(lowerBound, upperBound); } - TimeBoundedEventually(T lowerBound, T upperBound, AbstractStateFormula<T>* child) : child(child) { + TimeBoundedEventually(T lowerBound, T upperBound, std::shared_ptr<AbstractStateFormula<T>> const & child) : child(child) { setInterval(lowerBound, upperBound); } virtual ~TimeBoundedEventually() { - if (child != nullptr) { - delete child; - } + // Intentionally left empty. } /*! @@ -67,10 +65,10 @@ public: * * @returns a new BoundedUntil-object that is identical the called object. */ - virtual AbstractPathFormula<T>* clone() const override { - TimeBoundedEventually<T>* result = new TimeBoundedEventually<T>(this->getLowerBound(), this->getUpperBound()); + virtual std::shared_ptr<AbstractPathFormula<T>> clone() const override { + std::shared_ptr<TimeBoundedEventually<T>> result(new TimeBoundedEventually<T>(lowerBound, upperBound)); if (this->childIsSet()) { - result->setChild(this->getChild().clone()); + result->setChild(child->clone()); } return result; } @@ -84,7 +82,7 @@ public: * * @returns A vector indicating the probability that the formula holds for each state. */ - virtual std::vector<T> check(const storm::modelchecker::csl::AbstractModelChecker<T>& modelChecker, bool qualitative) const override { + virtual std::vector<T> check(storm::modelchecker::csl::AbstractModelChecker<T> const & modelChecker, bool qualitative) const override { return modelChecker.template as<ITimeBoundedEventuallyModelChecker>()->checkTimeBoundedEventually(*this, qualitative); } @@ -94,7 +92,7 @@ public: * @param checker Formula checker object. * @return true iff the subtree conforms to some logic. */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { return checker.validate(this->child); } @@ -120,15 +118,15 @@ public: /*! * @returns the child node */ - const AbstractStateFormula<T>& getChild() const { - return *child; + std::shared_ptr<AbstractStateFormula<T>> const & getChild() const { + return child; } /*! * Sets the subtree * @param child the new child node */ - void setChild(AbstractStateFormula<T>* child) { + void setChild(std::shared_ptr<AbstractStateFormula<T>> const & child) { this->child = child; } @@ -137,7 +135,7 @@ public: * @return True if the child is set, i.e. it does not point to nullptr; false otherwise */ bool childIsSet() const { - return child != nullptr; + return child.get() != nullptr; } /** @@ -145,7 +143,7 @@ public: * * @return lower bound of the operator. */ - T getLowerBound() const { + T const & getLowerBound() const { return lowerBound; } @@ -153,7 +151,7 @@ public: * Getter for upperBound attribute * @return upper bound of the operator. */ - T getUpperBound() const { + T const & getUpperBound() const { return upperBound; } @@ -173,7 +171,7 @@ public: } private: - AbstractStateFormula<T>* child; + std::shared_ptr<AbstractStateFormula<T>> child; T lowerBound, upperBound; }; diff --git a/src/formula/csl/TimeBoundedUntil.h b/src/formula/csl/TimeBoundedUntil.h index 96cb87f24..1bdf2f0aa 100644 --- a/src/formula/csl/TimeBoundedUntil.h +++ b/src/formula/csl/TimeBoundedUntil.h @@ -58,7 +58,7 @@ public: * @param left * @param right */ - TimeBoundedUntil(T lowerBound, T upperBound, AbstractStateFormula<T>* left, AbstractStateFormula<T>* right) : left(left), right(right) { + TimeBoundedUntil(T lowerBound, T upperBound, std::shared_ptr<AbstractStateFormula<T>> const & left, std::shared_ptr<AbstractStateFormula<T>> const & right) : left(left), right(right) { setInterval(lowerBound, upperBound); } @@ -66,12 +66,7 @@ public: * Destructor */ virtual ~TimeBoundedUntil() { - if (left != nullptr) { - delete left; - } - if (right != nullptr) { - delete right; - } + // Intentionally left empty. } /*! @@ -81,13 +76,13 @@ public: * * @returns a new BoundedUntil-object that is identical the called object. */ - virtual AbstractPathFormula<T>* clone() const override { - TimeBoundedUntil<T>* result = new TimeBoundedUntil<T>(this->getLowerBound(), this->getUpperBound()); + virtual std::shared_ptr<AbstractPathFormula<T>> clone() const override { + std::shared_ptr<TimeBoundedUntil<T>> result(new TimeBoundedUntil<T>(lowerBound, upperBound)); if (this->leftIsSet()) { - result->setLeft(this->getLeft().clone()); + result->setLeft(left->clone()); } if (this->rightIsSet()) { - result->setRight(this->getRight().clone()); + result->setRight(right->clone()); } return result; } @@ -102,7 +97,7 @@ public: * * @returns A vector indicating the probability that the formula holds for each state. */ - virtual std::vector<T> check(const storm::modelchecker::csl::AbstractModelChecker<T>& modelChecker, bool qualitative) const override { + virtual std::vector<T> check(storm::modelchecker::csl::AbstractModelChecker<T> const & modelChecker, bool qualitative) const override { return modelChecker.template as<ITimeBoundedUntilModelChecker>()->checkTimeBoundedUntil(*this, qualitative); } @@ -112,7 +107,7 @@ public: * @param checker Formula checker object. * @return true iff the subtree conforms to some logic. */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { return checker.validate(this->left) && checker.validate(this->right); } @@ -141,7 +136,7 @@ public: * * @param newLeft the new left child. */ - void setLeft(AbstractStateFormula<T>* newLeft) { + void setLeft(std::shared_ptr<AbstractStateFormula<T>> const & newLeft) { left = newLeft; } @@ -150,22 +145,22 @@ public: * * @param newRight the new right child. */ - void setRight(AbstractStateFormula<T>* newRight) { + void setRight(std::shared_ptr<AbstractStateFormula<T>> const & newRight) { right = newRight; } /*! * @returns a pointer to the left child node */ - const AbstractStateFormula<T>& getLeft() const { - return *left; + std::shared_ptr<AbstractStateFormula<T>> const & getLeft() const { + return left; } /*! * @returns a pointer to the right child node */ - const AbstractStateFormula<T>& getRight() const { - return *right; + std::shared_ptr<AbstractStateFormula<T>> const & getRight() const { + return right; } /*! @@ -173,7 +168,7 @@ public: * @return True if the left child is set, i.e. it does not point to nullptr; false otherwise */ bool leftIsSet() const { - return left != nullptr; + return left.get() != nullptr; } /*! @@ -181,7 +176,7 @@ public: * @return True if the right child is set, i.e. it does not point to nullptr; false otherwise */ bool rightIsSet() const { - return right != nullptr; + return right.get() != nullptr; } /** @@ -189,7 +184,7 @@ public: * * @return lower bound of the operator. */ - T getLowerBound() const { + T const & getLowerBound() const { return lowerBound; } @@ -197,7 +192,7 @@ public: * Getter for upperBound attribute * @return upper bound of the operator. */ - T getUpperBound() const { + T const & getUpperBound() const { return upperBound; } @@ -217,8 +212,8 @@ public: } private: - AbstractStateFormula<T>* left; - AbstractStateFormula<T>* right; + std::shared_ptr<AbstractStateFormula<T>> left; + std::shared_ptr<AbstractStateFormula<T>> right; T lowerBound, upperBound; }; diff --git a/src/formula/csl/Until.h b/src/formula/csl/Until.h index 199956d37..ea0209053 100644 --- a/src/formula/csl/Until.h +++ b/src/formula/csl/Until.h @@ -69,7 +69,7 @@ public: * @param left The left formula subtree * @param right The left formula subtree */ - Until(AbstractStateFormula<T>* left, AbstractStateFormula<T>* right) : left(left), right(right){ + Until(std::shared_ptr<AbstractStateFormula<T>> const & left, std::shared_ptr<AbstractStateFormula<T>> const & right) : left(left), right(right){ // Intentionally left empty. } @@ -80,12 +80,7 @@ public: * (this behaviour can be prevented by setting the subtrees to NULL before deletion) */ virtual ~Until() { - if (left != NULL) { - delete left; - } - if (right != NULL) { - delete right; - } + // Intentionally left empty. } /*! @@ -95,13 +90,13 @@ public: * * @returns a new BoundedUntil-object that is identical the called object. */ - virtual AbstractPathFormula<T>* clone() const override { - Until<T>* result = new Until(); + virtual std::shared_ptr<AbstractPathFormula<T>> clone() const override { + std::shared_ptr<Until<T>> result(new Until()); if (this->leftIsSet()) { - result->setLeft(this->getLeft().clone()); + result->setLeft(left->clone()); } if (this->rightIsSet()) { - result->setRight(this->getRight().clone()); + result->setRight(left->clone()); } return result; } @@ -115,7 +110,7 @@ public: * * @returns A vector indicating the probability that the formula holds for each state. */ - virtual std::vector<T> check(const storm::modelchecker::csl::AbstractModelChecker<T>& modelChecker, bool qualitative) const override { + virtual std::vector<T> check(storm::modelchecker::csl::AbstractModelChecker<T> const & modelChecker, bool qualitative) const override { return modelChecker.template as<IUntilModelChecker>()->checkUntil(*this, qualitative); } @@ -135,7 +130,7 @@ public: * @param checker Formula checker object. * @return true iff all subtrees conform to some logic. */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { return checker.validate(this->left) && checker.validate(this->right); } @@ -144,7 +139,7 @@ public: * * @param newLeft the new left child. */ - void setLeft(AbstractStateFormula<T>* newLeft) { + void setLeft(std::shared_ptr<AbstractStateFormula<T>> const & newLeft) { left = newLeft; } @@ -153,22 +148,22 @@ public: * * @param newRight the new right child. */ - void setRight(AbstractStateFormula<T>* newRight) { + void setRight(std::shared_ptr<AbstractStateFormula<T>> const & newRight) { right = newRight; } /*! * @returns a pointer to the left child node */ - const AbstractStateFormula<T>& getLeft() const { - return *left; + std::shared_ptr<AbstractStateFormula<T>> const & getLeft() const { + return left; } /*! * @returns a pointer to the right child node */ - const AbstractStateFormula<T>& getRight() const { - return *right; + std::shared_ptr<AbstractStateFormula<T>> const & getRight() const { + return right; } /*! @@ -176,7 +171,7 @@ public: * @return True if the left child is set, i.e. it does not point to nullptr; false otherwise */ bool leftIsSet() const { - return left != nullptr; + return left.get() != nullptr; } /*! @@ -184,12 +179,12 @@ public: * @return True if the right child is set, i.e. it does not point to nullptr; false otherwise */ bool rightIsSet() const { - return right != nullptr; + return right.get() != nullptr; } private: - AbstractStateFormula<T>* left; - AbstractStateFormula<T>* right; + std::shared_ptr<AbstractStateFormula<T>> left; + std::shared_ptr<AbstractStateFormula<T>> right; }; } //namespace csl diff --git a/src/formula/ltl/AbstractLtlFormula.h b/src/formula/ltl/AbstractLtlFormula.h index 0f03ded32..1c4ef1403 100644 --- a/src/formula/ltl/AbstractLtlFormula.h +++ b/src/formula/ltl/AbstractLtlFormula.h @@ -12,21 +12,6 @@ #include "src/modelchecker/ltl/ForwardDeclarations.h" #include "src/formula/AbstractFormula.h" -// Forward declaration for formula visitor -namespace storm { -namespace property { -namespace ltl { - -template <class T> -class AbstractLtlFormula; - -} -} -} - -#include "visitor/AbstractLtlFormulaVisitor.h" - - namespace storm { namespace property { namespace ltl { @@ -64,22 +49,7 @@ public: * * @returns a new AND-object that is identical the called object. */ - virtual AbstractLtlFormula<T>* clone() const = 0; - - /*! - * @brief Visits all nodes of a formula tree. - * - * @note Every subclass must implement this method. - * - * This method is given a visitor that visits each node to perform some - * task on it (e.g. Validity checks, conversion, ...). The subclasses are to - * - * - * - * @param visitor The visitor object. - * @return true iff all subtrees are valid. - */ - virtual void visit(visitor::AbstractLtlFormulaVisitor<T>& visitor) const = 0; + virtual std::shared_ptr<AbstractLtlFormula<T>> clone() const = 0; }; } /* namespace ltl */ diff --git a/src/formula/ltl/And.h b/src/formula/ltl/And.h index dee2706f6..ffc5848de 100644 --- a/src/formula/ltl/And.h +++ b/src/formula/ltl/And.h @@ -37,24 +37,6 @@ class IAndModelChecker { virtual std::vector<T> checkAnd(const And<T>& obj) const = 0; }; -/*! - * @brief Interface class for visitors that support And. - * - * All visitors that support the formula class And must inherit - * this pure virtual class. - */ -template <class T> -class IAndVisitor { - public: - /*! - * @brief Evaluates And formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual void visitAnd(const And<T>& obj) = 0; -}; - /*! * @brief * Class for an abstract formula tree with AND node as root. @@ -78,9 +60,8 @@ public: * Empty constructor. * Will create an AND-node without subnotes. Will not represent a complete formula! */ - And() { - left = NULL; - right = NULL; + And() : left(nullptr), right(nullptr){ + // Intentionally left empty. } /*! @@ -90,9 +71,8 @@ public: * @param left The left sub formula * @param right The right sub formula */ - And(AbstractLtlFormula<T>* left, AbstractLtlFormula<T>* right) { - this->left = left; - this->right = right; + And(std::shared_ptr<AbstractLtlFormula<T>> left, std::shared_ptr<AbstractLtlFormula<T>> right) : left(left), right(right) { + // Intentionally left empty. } /*! @@ -102,12 +82,7 @@ public: * (this behavior can be prevented by setting them to NULL before deletion) */ virtual ~And() { - if (left != NULL) { - delete left; - } - if (right != NULL) { - delete right; - } + // Intentionally left empty. } /*! @@ -117,13 +92,13 @@ public: * * @returns a new AND-object that is identical the called object. */ - virtual AbstractLtlFormula<T>* clone() const override { - And<T>* result = new And(); + virtual std::shared_ptr<AbstractLtlFormula<T>> clone() const override { + std::shared_ptr<And<T>> result(new And()); if (this->leftIsSet()) { - result->setLeft(this->getLeft().clone()); + result->setLeft(left->clone()); } if (this->rightIsSet()) { - result->setRight(this->getRight().clone()); + result->setRight(right->clone()); } return result; } @@ -141,10 +116,6 @@ public: return modelChecker.template as<IAndModelChecker>()->checkAnd(*this); } - virtual void visit(visitor::AbstractLtlFormulaVisitor<T>& visitor) const override { - visitor.template as<IAndVisitor>()->visitAnd(*this); - } - /*! * @returns a string representation of the formula */ @@ -163,7 +134,7 @@ public: * @param checker Formula checker object. * @return true iff all subtrees conform to some logic. */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { return checker.validate(this->left) && checker.validate(this->right); } @@ -173,7 +144,7 @@ public: * * @param newLeft the new left child. */ - void setLeft(AbstractLtlFormula<T>* newLeft) { + void setLeft(std::shared_ptr<AbstractLtlFormula<T>> const & newLeft) { left = newLeft; } @@ -182,22 +153,22 @@ public: * * @param newRight the new right child. */ - void setRight(AbstractLtlFormula<T>* newRight) { + void setRight(std::shared_ptr<AbstractLtlFormula<T>> const & newRight) { right = newRight; } /*! * @returns a pointer to the left child node */ - const AbstractLtlFormula<T>& getLeft() const { - return *left; + std::shared_ptr<AbstractLtlFormula<T>> const & getLeft() const { + return left; } /*! * @returns a pointer to the right child node */ - const AbstractLtlFormula<T>& getRight() const { - return *right; + std::shared_ptr<AbstractLtlFormula<T>> const & getRight() const { + return right; } /*! @@ -205,7 +176,7 @@ public: * @return True if the left child is set, i.e. it does not point to nullptr; false otherwise */ bool leftIsSet() const { - return left != nullptr; + return left.get() != nullptr; } /*! @@ -213,12 +184,12 @@ public: * @return True if the right child is set, i.e. it does not point to nullptr; false otherwise */ bool rightIsSet() const { - return right != nullptr; + return right.get() != nullptr; } private: - AbstractLtlFormula<T>* left; - AbstractLtlFormula<T>* right; + std::shared_ptr<AbstractLtlFormula<T>> left; + std::shared_ptr<AbstractLtlFormula<T>> right; }; diff --git a/src/formula/ltl/Ap.h b/src/formula/ltl/Ap.h index 46a5376e1..b84aff340 100644 --- a/src/formula/ltl/Ap.h +++ b/src/formula/ltl/Ap.h @@ -34,25 +34,6 @@ class IApModelChecker { virtual std::vector<T> checkAp(const Ap<T>& obj) const = 0; }; - -/*! - * @brief Interface class for visitors that support Ap. - * - * All visitors that support the formula class Ap must inherit - * this pure virtual class. - */ -template <class T> -class IApVisitor { - public: - /*! - * @brief Evaluates And formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual void visitAp(const Ap<T>& obj) = 0; -}; - /*! * @brief * Class for an abstract formula tree with atomic proposition as root. @@ -78,8 +59,8 @@ public: * * @param ap The string representing the atomic proposition */ - Ap(std::string ap) { - this->ap = ap; + Ap(std::string ap) : ap(ap) { + // Intentionally left empty. } /*! @@ -112,12 +93,9 @@ public: * * @returns a new AND-object that is identical the called object. */ - virtual AbstractLtlFormula<T>* clone() const override { - return new Ap(this->getAp()); - } - - virtual void visit(visitor::AbstractLtlFormulaVisitor<T>& visitor) const override { - visitor.template as<IApVisitor>()->visitAp(*this); + virtual std::shared_ptr<AbstractLtlFormula<T>> clone() const override { + std::shared_ptr<AbstractLtlFormula<T>> result(new Ap(this->getAp())); + return result; } /*! @@ -136,14 +114,14 @@ public: * @param checker Formula checker object. * @return true */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { return true; } /*! * @returns the name of the atomic proposition */ - const std::string& getAp() const { + std::string const & getAp() const { return ap; } diff --git a/src/formula/ltl/BoundedEventually.h b/src/formula/ltl/BoundedEventually.h index b37775a0c..40cdb4038 100644 --- a/src/formula/ltl/BoundedEventually.h +++ b/src/formula/ltl/BoundedEventually.h @@ -38,24 +38,6 @@ class IBoundedEventuallyModelChecker { virtual std::vector<T> checkBoundedEventually(const BoundedEventually<T>& obj) const = 0; }; -/*! - * @brief Interface class for visitors that support BoundedEventually. - * - * All visitors that support the formula class BoundedEventually must inherit - * this pure virtual class. - */ -template <class T> -class IBoundedEventuallyVisitor { - public: - /*! - * @brief Evaluates BoundedEventually formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual void visitBoundedEventually(const BoundedEventually<T>& obj) = 0; -}; - /*! * @brief * Class for an abstract (path) formula tree with a BoundedEventually node as root. @@ -78,9 +60,8 @@ public: /*! * Empty constructor */ - BoundedEventually() { - this->child = nullptr; - bound = 0; + BoundedEventually() : child(nullptr), bound(0) { + // Intentionally left empty. } /*! @@ -89,9 +70,8 @@ public: * @param child The child formula subtree * @param bound The maximal number of steps */ - BoundedEventually(AbstractLtlFormula<T>* child, uint_fast64_t bound) { - this->child = child; - this->bound = bound; + BoundedEventually(std::shared_ptr<AbstractLtlFormula<T>> child, uint_fast64_t bound) : child(child), bound(bound) { + // Intentionally left empty. } /*! @@ -101,9 +81,7 @@ public: * (this behaviour can be prevented by setting the subtrees to NULL before deletion) */ virtual ~BoundedEventually() { - if (child != nullptr) { - delete child; - } + // Intentionally left empty. } @@ -114,11 +92,11 @@ public: * * @returns a new BoundedUntil-object that is identical the called object. */ - virtual AbstractLtlFormula<T>* clone() const override { - BoundedEventually<T>* result = new BoundedEventually<T>(); - result->setBound(this->getBound()); + virtual std::shared_ptr<AbstractLtlFormula<T>> clone() const override { + std::shared_ptr<BoundedEventually<T>> result(new BoundedEventually<T>()); + result->setBound(bound); if (this->childIsSet()) { - result->setChild(this->getChild().clone()); + result->setChild(child->clone()); } return result; } @@ -133,14 +111,10 @@ public: * * @returns A vector indicating the probability that the formula holds for each state. */ - virtual std::vector<T> check(const storm::modelchecker::ltl::AbstractModelChecker<T>& modelChecker) const override { + virtual std::vector<T> check(storm::modelchecker::ltl::AbstractModelChecker<T> const & modelChecker) const override { return modelChecker.template as<IBoundedEventuallyModelChecker>()->checkBoundedEventually(*this); } - virtual void visit(visitor::AbstractLtlFormulaVisitor<T>& visitor) const override { - visitor.template as<IBoundedEventuallyVisitor>()->visitBoundedEventually(*this); - } - /*! * @returns a string representation of the formula */ @@ -153,27 +127,27 @@ public: } /*! - * @brief Checks if the subtree conforms to some logic. - * - * @param checker Formula checker object. - * @return true iff the subtree conforms to some logic. - */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + * @brief Checks if the subtree conforms to some logic. + * + * @param checker Formula checker object. + * @return true iff the subtree conforms to some logic. + */ + virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { return checker.validate(this->child); } /*! * @returns the child node */ - const AbstractLtlFormula<T>& getChild() const { - return *child; + std::shared_ptr<AbstractLtlFormula<T>> const & getChild() const { + return child; } /*! * Sets the subtree * @param child the new child node */ - void setChild(AbstractLtlFormula<T>* child) { + void setChild(std::shared_ptr<AbstractLtlFormula<T>> const & child) { this->child = child; } @@ -182,7 +156,7 @@ public: * @return True if the child is set, i.e. it does not point to nullptr; false otherwise */ bool childIsSet() const { - return child != nullptr; + return child.get() != nullptr; } /*! @@ -203,7 +177,7 @@ public: private: - AbstractLtlFormula<T>* child; + std::shared_ptr<AbstractLtlFormula<T>> child; uint_fast64_t bound; }; diff --git a/src/formula/ltl/BoundedUntil.h b/src/formula/ltl/BoundedUntil.h index 755467ef1..b17b901f4 100644 --- a/src/formula/ltl/BoundedUntil.h +++ b/src/formula/ltl/BoundedUntil.h @@ -37,24 +37,6 @@ class IBoundedUntilModelChecker { virtual std::vector<T> checkBoundedUntil(const BoundedUntil<T>& obj) const = 0; }; -/*! - * @brief Interface class for visitors that support BoundedUntil. - * - * All visitors that support the formula class BoundedUnitl must inherit - * this pure virtual class. - */ -template <class T> -class IBoundedUntilVisitor { - public: - /*! - * @brief Visits BoundedUntil formula. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual void visitBoundedUntil(const BoundedUntil<T>& obj) = 0; -}; - /*! * @brief * Class for an abstract (path) formula tree with a BoundedUntil node as root. @@ -78,10 +60,8 @@ public: /*! * Empty constructor */ - BoundedUntil() { - this->left = NULL; - this->right = NULL; - bound = 0; + BoundedUntil() : left(nullptr), right(nullptr), bound(0) { + // Intentionally left empty. } /*! @@ -91,11 +71,8 @@ public: * @param right The left formula subtree * @param bound The maximal number of steps */ - BoundedUntil(AbstractLtlFormula<T>* left, AbstractLtlFormula<T>* right, - uint_fast64_t bound) { - this->left = left; - this->right = right; - this->bound = bound; + BoundedUntil(std::shared_ptr<AbstractLtlFormula<T>> const & left, std::shared_ptr<AbstractLtlFormula<T>> const & right, uint_fast64_t bound) : left(left), right(right), bound(bound) { + // Intentionally left empty. } /*! @@ -105,12 +82,7 @@ public: * (this behaviour can be prevented by setting the subtrees to NULL before deletion) */ virtual ~BoundedUntil() { - if (left != NULL) { - delete left; - } - if (right != NULL) { - delete right; - } + // Intentionally left empty. } /*! @@ -120,14 +92,14 @@ public: * * @returns a new BoundedUntil-object that is identical the called object. */ - virtual AbstractLtlFormula<T>* clone() const override { - BoundedUntil<T>* result = new BoundedUntil<T>(); - result->setBound(this->getBound()); + virtual std::shared_ptr<AbstractLtlFormula<T>> clone() const override { + std::shared_ptr<BoundedUntil<T>> result(new BoundedUntil<T>()); + result->setBound(bound); if (this->leftIsSet()) { - result->setLeft(this->getLeft().clone()); + result->setLeft(left->clone()); } if (this->rightIsSet()) { - result->setRight(this->getRight().clone()); + result->setRight(right->clone()); } return result; } @@ -146,10 +118,6 @@ public: return modelChecker.template as<IBoundedUntilModelChecker>()->checkBoundedUntil(*this); } - virtual void visit(visitor::AbstractLtlFormulaVisitor<T>& visitor) const override { - visitor.template as<IBoundedUntilVisitor>()->visitBoundedUntil(*this); - } - /*! * @brief Return string representation of this formula. * @@ -168,12 +136,12 @@ public: } /*! - * @brief Checks if all subtrees conform to some logic. - * - * @param checker Formula checker object. - * @return true iff all subtrees conform to some logic. - */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + * @brief Checks if all subtrees conform to some logic. + * + * @param checker Formula checker object. + * @return true iff all subtrees conform to some logic. + */ + virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { return checker.validate(this->left) && checker.validate(this->right); } @@ -182,7 +150,7 @@ public: * * @param newLeft the new left child. */ - void setLeft(AbstractLtlFormula<T>* newLeft) { + void setLeft(std::shared_ptr<AbstractLtlFormula<T>> const & newLeft) { left = newLeft; } @@ -191,22 +159,22 @@ public: * * @param newRight the new right child. */ - void setRight(AbstractLtlFormula<T>* newRight) { + void setRight(std::shared_ptr<AbstractLtlFormula<T>> const & newRight) { right = newRight; } /*! * @returns a pointer to the left child node */ - const AbstractLtlFormula<T>& getLeft() const { - return *left; + std::shared_ptr<AbstractLtlFormula<T>> const & getLeft() const { + return left; } /*! * @returns a pointer to the right child node */ - const AbstractLtlFormula<T>& getRight() const { - return *right; + std::shared_ptr<AbstractLtlFormula<T>> const & getRight() const { + return right; } /*! @@ -214,7 +182,7 @@ public: * @return True if the left child is set, i.e. it does not point to nullptr; false otherwise */ bool leftIsSet() const { - return left != nullptr; + return left.get() != nullptr; } /*! @@ -222,7 +190,7 @@ public: * @return True if the right child is set, i.e. it does not point to nullptr; false otherwise */ bool rightIsSet() const { - return right != nullptr; + return right.get() != nullptr; } /*! @@ -242,8 +210,8 @@ public: } private: - AbstractLtlFormula<T>* left; - AbstractLtlFormula<T>* right; + std::shared_ptr<AbstractLtlFormula<T>> left; + std::shared_ptr<AbstractLtlFormula<T>> right; uint_fast64_t bound; }; diff --git a/src/formula/ltl/Eventually.h b/src/formula/ltl/Eventually.h index 983ce2de4..b8662cd69 100644 --- a/src/formula/ltl/Eventually.h +++ b/src/formula/ltl/Eventually.h @@ -35,24 +35,6 @@ class IEventuallyModelChecker { virtual std::vector<T> checkEventually(const Eventually<T>& obj) const = 0; }; -/*! - * @brief Interface class for visitors that support Eventually. - * - * All visitors that support the formula class Eventually must inherit - * this pure virtual class. - */ -template <class T> -class IEventuallyVisitor { - public: - /*! - * @brief Visits Eventually formula. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual void visitEventually(const Eventually<T>& obj) = 0; -}; - /*! * @brief * Class for an abstract (path) formula tree with an Eventually node as root. @@ -75,8 +57,8 @@ public: /*! * Empty constructor */ - Eventually() { - this->child = nullptr; + Eventually() : child(nullptr) { + // Intentionally left empty. } /*! @@ -84,8 +66,8 @@ public: * * @param child The child node */ - Eventually(AbstractLtlFormula<T>* child) { - this->child = child; + Eventually(std::shared_ptr<AbstractLtlFormula<T>> const & child) : child(child) { + // Intentionally left empty. } /*! @@ -95,9 +77,7 @@ public: * (this behaviour can be prevented by setting the subtrees to nullptr before deletion) */ virtual ~Eventually() { - if (child != nullptr) { - delete child; - } + // Intentionally left empty. } /*! @@ -107,10 +87,10 @@ public: * * @returns a new Eventually-object that is identical the called object. */ - virtual AbstractLtlFormula<T>* clone() const override { - Eventually<T>* result = new Eventually<T>(); + virtual std::shared_ptr<AbstractLtlFormula<T>> clone() const override { + std::shared_ptr<Eventually<T>> result(new Eventually<T>()); if (this->childIsSet()) { - result->setChild(this->getChild().clone()); + result->setChild(child->clone()); } return result; } @@ -128,10 +108,6 @@ public: return modelChecker.template as<IEventuallyModelChecker>()->checkEventually(*this); } - virtual void visit(visitor::AbstractLtlFormulaVisitor<T>& visitor) const override { - visitor.template as<IEventuallyVisitor>()->visitEventually(*this); - } - /*! * @returns a string representation of the formula */ @@ -142,27 +118,27 @@ public: } /*! - * @brief Checks if the subtree conforms to some logic. - * - * @param checker Formula checker object. - * @return true iff the subtree conforms to some logic. - */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + * @brief Checks if the subtree conforms to some logic. + * + * @param checker Formula checker object. + * @return true iff the subtree conforms to some logic. + */ + virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { return checker.validate(this->child); } /*! * @returns the child node */ - const AbstractLtlFormula<T>& getChild() const { - return *child; + std::shared_ptr<AbstractLtlFormula<T>> const & getChild() const { + return child; } /*! * Sets the subtree * @param child the new child node */ - void setChild(AbstractLtlFormula<T>* child) { + void setChild(std::shared_ptr<AbstractLtlFormula<T>> const & child) { this->child = child; } @@ -171,11 +147,11 @@ public: * @return True if the child node is set, i.e. it does not point to nullptr; false otherwise */ bool childIsSet() const { - return child != nullptr; + return child.get() != nullptr; } private: - AbstractLtlFormula<T>* child; + std::shared_ptr<AbstractLtlFormula<T>> child; }; } //namespace ltl diff --git a/src/formula/ltl/Globally.h b/src/formula/ltl/Globally.h index e4000cc53..50d977ee8 100644 --- a/src/formula/ltl/Globally.h +++ b/src/formula/ltl/Globally.h @@ -36,24 +36,6 @@ class IGloballyModelChecker { virtual std::vector<T> checkGlobally(const Globally<T>& obj) const = 0; }; -/*! - * @brief Interface class for visitors that support Globally. - * - * All visitors that support the formula class Globally must inherit - * this pure virtual class. - */ -template <class T> -class IGloballyVisitor { - public: - /*! - * @brief Visits Globally formula. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual void visitGlobally(const Globally<T>& obj) = 0; -}; - /*! * @brief * Class for an abstract (path) formula tree with a Globally node as root. @@ -76,8 +58,8 @@ public: /*! * Empty constructor */ - Globally() { - this->child = nullptr; + Globally() : child(nullptr) { + // Intentionally left empty. } /*! @@ -85,8 +67,8 @@ public: * * @param child The child node */ - Globally(AbstractLtlFormula<T>* child) { - this->child = child; + Globally(std::shared_ptr<AbstractLtlFormula<T>> const & child) : child(child) { + // Intentionally left empty. } /*! @@ -96,9 +78,7 @@ public: * (this behaviour can be prevented by setting the subtrees to nullptr before deletion) */ virtual ~Globally() { - if (child != nullptr) { - delete child; - } + // Intentionally left empty. } /*! @@ -108,10 +88,10 @@ public: * * @returns a new Globally-object that is identical the called object. */ - virtual AbstractLtlFormula<T>* clone() const override { - Globally<T>* result = new Globally<T>(); + virtual std::shared_ptr<AbstractLtlFormula<T>> clone() const override { + std::shared_ptr<Globally<T>> result(new Globally<T>()); if (this->childIsSet()) { - result->setChild(this->getChild().clone()); + result->setChild(child->clone()); } return result; } @@ -129,10 +109,6 @@ public: return modelChecker.template as<IGloballyModelChecker>()->checkGlobally(*this); } - virtual void visit(visitor::AbstractLtlFormulaVisitor<T>& visitor) const override { - visitor.template as<IGloballyVisitor>()->visitGlobally(*this); - } - /*! * @returns a string representation of the formula */ @@ -148,14 +124,14 @@ public: * @param checker Formula checker object. * @return true iff the subtree conforms to some logic. */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { return checker.validate(this->child); } /*! * @returns the child node */ - const AbstractLtlFormula<T>& getChild() const { + std::shared_ptr<AbstractLtlFormula<T>> const & getChild() const { return *child; } @@ -163,7 +139,7 @@ public: * Sets the subtree * @param child the new child node */ - void setChild(AbstractLtlFormula<T>* child) { + void setChild(std::shared_ptr<AbstractLtlFormula<T>> const & child) { this->child = child; } @@ -172,11 +148,11 @@ public: * @return True if the child node is set, i.e. it does not point to nullptr; false otherwise */ bool childIsSet() const { - return child != nullptr; + return child.get() != nullptr; } private: - AbstractLtlFormula<T>* child; + std::shared_ptr<AbstractLtlFormula<T>> child; }; } //namespace ltl diff --git a/src/formula/ltl/LtlFilter.h b/src/formula/ltl/LtlFilter.h index b8d7846c0..a13148b86 100644 --- a/src/formula/ltl/LtlFilter.h +++ b/src/formula/ltl/LtlFilter.h @@ -37,21 +37,20 @@ public: // Intentionally left empty. } - LtlFilter(AbstractLtlFormula<T>* child, OptimizingOperator opt = UNDEFINED) : AbstractFilter<T>(opt), child(child) { + LtlFilter(std::shared_ptr<AbstractLtlFormula<T>> const & child, OptimizingOperator opt = UNDEFINED) : AbstractFilter<T>(opt), child(child) { // Intentionally left empty. } - LtlFilter(AbstractLtlFormula<T>* child, action::AbstractAction<T>* action, OptimizingOperator opt = UNDEFINED) : AbstractFilter<T>(action, opt), child(child) { + LtlFilter(std::shared_ptr<AbstractLtlFormula<T>> const & child, action::AbstractAction<T>* action, OptimizingOperator opt = UNDEFINED) : AbstractFilter<T>(action, opt), child(child) { this->actions.push_back(action); } - LtlFilter(AbstractLtlFormula<T>* child, std::vector<action::AbstractAction<T>*> actions, OptimizingOperator opt = UNDEFINED) : AbstractFilter<T>(actions, opt), child(child) { + LtlFilter(std::shared_ptr<AbstractLtlFormula<T>> const & child, std::vector<action::AbstractAction<T>*> actions, OptimizingOperator opt = UNDEFINED) : AbstractFilter<T>(actions, opt), child(child) { // Intentionally left empty. } virtual ~LtlFilter() { this->actions.clear(); - delete child; } @@ -133,11 +132,11 @@ public: return desc; } - void setChild(AbstractLtlFormula<T>* child) { + void setChild(std::shared_ptr<AbstractLtlFormula<T>> const & child) { this->child = child; } - AbstractLtlFormula<T>* getChild() const { + std::shared_ptr<AbstractLtlFormula<T>> const & getChild() const { return child; } @@ -208,7 +207,7 @@ private: std::cout << std::endl << "-------------------------------------------" << std::endl; } - AbstractLtlFormula<T>* child; + std::shared_ptr<AbstractLtlFormula<T>> child; }; diff --git a/src/formula/ltl/Next.h b/src/formula/ltl/Next.h index eb2d5334a..ebf8edc96 100644 --- a/src/formula/ltl/Next.h +++ b/src/formula/ltl/Next.h @@ -35,24 +35,6 @@ class INextModelChecker { virtual std::vector<T> checkNext(const Next<T>& obj) const = 0; }; -/*! - * @brief Interface class for visitors that support Next. - * - * All visitors that support the formula class Next must inherit - * this pure virtual class. - */ -template <class T> -class INextVisitor { - public: - /*! - * @brief Visits Next formula. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual void visitNext(const Next<T>& obj) = 0; -}; - /*! * @brief * Class for an abstract (path) formula tree with a Next node as root. @@ -75,8 +57,8 @@ public: /*! * Empty constructor */ - Next() { - this->child = NULL; + Next() : child(nullptr) { + // Intentionally left empty. } /*! @@ -84,8 +66,8 @@ public: * * @param child The child node */ - Next(AbstractLtlFormula<T>* child) { - this->child = child; + Next(std::shared_ptr<AbstractLtlFormula<T>> const & child) : child(child) { + // Intentionally left empty. } /*! @@ -95,9 +77,7 @@ public: * (this behaviour can be prevented by setting the subtrees to NULL before deletion) */ virtual ~Next() { - if (child != NULL) { - delete child; - } + // Intentionally left empty. } /*! @@ -107,10 +87,10 @@ public: * * @returns a new BoundedUntil-object that is identical the called object. */ - virtual AbstractLtlFormula<T>* clone() const override { - Next<T>* result = new Next<T>(); + virtual std::shared_ptr<AbstractLtlFormula<T>> clone() const override { + std::shared_ptr<Next<T>> result(new Next<T>()); if (this->childIsSet()) { - result->setChild(this->getChild().clone()); + result->setChild(child->clone()); } return result; } @@ -124,14 +104,10 @@ public: * * @returns A vector indicating the probability that the formula holds for each state. */ - virtual std::vector<T> check(const storm::modelchecker::ltl::AbstractModelChecker<T>& modelChecker) const { + virtual std::vector<T> check(storm::modelchecker::ltl::AbstractModelChecker<T> const & modelChecker) const { return modelChecker.template as<INextModelChecker>()->checkNext(*this); } - virtual void visit(visitor::AbstractLtlFormulaVisitor<T>& visitor) const override { - visitor.template as<INextVisitor>()->visitNext(*this); - } - /*! * @returns a string representation of the formula */ @@ -149,22 +125,22 @@ public: * @param checker Formula checker object. * @return true iff the subtree conforms to some logic. */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { return checker.validate(this->child); } /*! * @returns the child node */ - const AbstractLtlFormula<T>& getChild() const { - return *child; + std::shared_ptr<AbstractLtlFormula<T>> const & getChild() const { + return child; } /*! * Sets the subtree * @param child the new child node */ - void setChild(AbstractLtlFormula<T>* child) { + void setChild(std::shared_ptr<AbstractLtlFormula<T>> const & child) { this->child = child; } @@ -173,11 +149,11 @@ public: * @return True if the child node is set, i.e. it does not point to nullptr; false otherwise */ bool childIsSet() const { - return child != nullptr; + return child.get() != nullptr; } private: - AbstractLtlFormula<T>* child; + std::shared_ptr<AbstractLtlFormula<T>> child; }; } //namespace ltl diff --git a/src/formula/ltl/Not.h b/src/formula/ltl/Not.h index 11cac3acf..ebc742800 100644 --- a/src/formula/ltl/Not.h +++ b/src/formula/ltl/Not.h @@ -35,24 +35,6 @@ class INotModelChecker { virtual std::vector<T> checkNot(const Not<T>& obj) const = 0; }; -/*! - * @brief Interface class for visitors that support Not. - * - * All visitors that support the formula class Not must inherit - * this pure virtual class. - */ -template <class T> -class INotVisitor { - public: - /*! - * @brief Visits Not formula. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual void visitNot(const Not<T>& obj) = 0; -}; - /*! * @brief * Class for an abstract formula tree with NOT node as root. @@ -72,16 +54,16 @@ public: /*! * Empty constructor */ - Not() { - this->child = NULL; + Not() : child(nullptr) { + // Intentionally left empty. } /*! * Constructor * @param child The child node */ - Not(AbstractLtlFormula<T>* child) { - this->child = child; + Not(std::shared_ptr<AbstractLtlFormula<T>> const & child) : child(child) { + // Intentionally left empty. } /*! @@ -91,9 +73,7 @@ public: * (this behavior can be prevented by setting them to NULL before deletion) */ virtual ~Not() { - if (child != NULL) { - delete child; - } + // Intentionally left empty. } /*! @@ -103,10 +83,10 @@ public: * * @returns a new AND-object that is identical the called object. */ - virtual AbstractLtlFormula<T>* clone() const override { - Not<T>* result = new Not<T>(); + virtual std::shared_ptr<AbstractLtlFormula<T>> clone() const override { + std::shared_ptr<Not<T>> result(new Not<T>()); if (this->childIsSet()) { - result->setChild(this->getChild().clone()); + result->setChild(child->clone()); } return result; } @@ -120,14 +100,10 @@ public: * * @returns A bit vector indicating all states that satisfy the formula represented by the called object. */ - virtual std::vector<T> check(const storm::modelchecker::ltl::AbstractModelChecker<T>& modelChecker) const override { + virtual std::vector<T> check(storm::modelchecker::ltl::AbstractModelChecker<T> const & modelChecker) const override { return modelChecker.template as<INotModelChecker>()->checkNot(*this); } - virtual void visit(visitor::AbstractLtlFormulaVisitor<T>& visitor) const override { - visitor.template as<INotVisitor>()->visitNot(*this); - } - /*! * @returns a string representation of the formula */ @@ -143,22 +119,22 @@ public: * @param checker Formula checker object. * @return true iff the subtree conforms to some logic. */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { return checker.validate(this->child); } /*! * @returns The child node */ - const AbstractLtlFormula<T>& getChild() const { - return *child; + std::shared_ptr<AbstractLtlFormula<T>> const & getChild() const { + return child; } /*! * Sets the subtree * @param child the new child node */ - void setChild(AbstractLtlFormula<T>* child) { + void setChild(std::shared_ptr<AbstractLtlFormula<T>> const & child) { this->child = child; } @@ -167,11 +143,11 @@ public: * @return True if the child node is set, i.e. it does not point to nullptr; false otherwise */ bool childIsSet() const { - return child != nullptr; + return child.get() != nullptr; } private: - AbstractLtlFormula<T>* child; + std::shared_ptr<AbstractLtlFormula<T>> child; }; } //namespace ltl diff --git a/src/formula/ltl/Or.h b/src/formula/ltl/Or.h index a11e8fc71..d2ee4a4f5 100644 --- a/src/formula/ltl/Or.h +++ b/src/formula/ltl/Or.h @@ -34,24 +34,6 @@ class IOrModelChecker { virtual std::vector<T> checkOr(const Or<T>& obj) const = 0; }; -/*! - * @brief Interface class for visitors that support Or. - * - * All visitors that support the formula class Or must inherit - * this pure virtual class. - */ -template <class T> -class IOrVisitor { - public: - /*! - * @brief Visits Or formula. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual void visitOr(const Or<T>& obj) = 0; -}; - /*! * @brief * Class for an abstract formula tree with OR node as root. @@ -75,9 +57,8 @@ public: * Empty constructor. * Will create an AND-node without subnotes. Will not represent a complete formula! */ - Or() { - left = NULL; - right = NULL; + Or() : left(nullptr), right(nullptr) { + // Intentionally left empty. } /*! @@ -87,9 +68,8 @@ public: * @param left The left sub formula * @param right The right sub formula */ - Or(AbstractLtlFormula<T>* left, AbstractLtlFormula<T>* right) { - this->left = left; - this->right = right; + Or(std::shared_ptr<AbstractLtlFormula<T>> const & left, std::shared_ptr<AbstractLtlFormula<T>> const & right) : left(left), right(right) { + // Intentionally left empty. } /*! @@ -99,12 +79,7 @@ public: * (this behavior can be prevented by setting them to NULL before deletion) */ virtual ~Or() { - if (left != NULL) { - delete left; - } - if (right != NULL) { - delete right; - } + // Intentionally left empty. } /*! @@ -114,13 +89,13 @@ public: * * @returns a new AND-object that is identical the called object. */ - virtual AbstractLtlFormula<T>* clone() const override { - Or<T>* result = new Or(); + virtual std::shared_ptr<AbstractLtlFormula<T>> clone() const override { + std::shared_ptr<Or<T>> result(new Or<T>()); if (this->leftIsSet()) { - result->setLeft(this->getLeft().clone()); + result->setLeft(left->clone()); } if (this->rightIsSet()) { - result->setRight(this->getRight().clone()); + result->setRight(right->clone()); } return result; } @@ -134,14 +109,10 @@ public: * * @returns A bit vector indicating all states that satisfy the formula represented by the called object. */ - virtual std::vector<T> check(const storm::modelchecker::ltl::AbstractModelChecker<T>& modelChecker) const override { + virtual std::vector<T> check(storm::modelchecker::ltl::AbstractModelChecker<T> const & modelChecker) const override { return modelChecker.template as<IOrModelChecker>()->checkOr(*this); } - virtual void visit(visitor::AbstractLtlFormulaVisitor<T>& visitor) const override { - visitor.template as<IOrVisitor>()->visitOr(*this); - } - /*! * @returns a string representation of the formula */ @@ -160,7 +131,7 @@ public: * @param checker Formula checker object. * @return true iff all subtrees conform to some logic. */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { return checker.validate(this->left) && checker.validate(this->right); } @@ -169,7 +140,7 @@ public: * * @param newLeft the new left child. */ - void setLeft(AbstractLtlFormula<T>* newLeft) { + void setLeft(std::shared_ptr<AbstractLtlFormula<T>> const & newLeft) { left = newLeft; } @@ -178,22 +149,22 @@ public: * * @param newRight the new right child. */ - void setRight(AbstractLtlFormula<T>* newRight) { + void setRight(std::shared_ptr<AbstractLtlFormula<T>> const & newRight) { right = newRight; } /*! * @returns a pointer to the left child node */ - const AbstractLtlFormula<T>& getLeft() const { - return *left; + std::shared_ptr<AbstractLtlFormula<T>> const & getLeft() const { + return left; } /*! * @returns a pointer to the right child node */ - const AbstractLtlFormula<T>& getRight() const { - return *right; + std::shared_ptr<AbstractLtlFormula<T>> const & getRight() const { + return right; } /*! @@ -201,7 +172,7 @@ public: * @return True if the left child is set, i.e. it does not point to nullptr; false otherwise */ bool leftIsSet() const { - return left != nullptr; + return left.get() != nullptr; } /*! @@ -209,12 +180,12 @@ public: * @return True if the right child is set, i.e. it does not point to nullptr; false otherwise */ bool rightIsSet() const { - return right != nullptr; + return right.get() != nullptr; } private: - AbstractLtlFormula<T>* left; - AbstractLtlFormula<T>* right; + std::shared_ptr<AbstractLtlFormula<T>> left; + std::shared_ptr<AbstractLtlFormula<T>> right; }; } /* namespace ltl */ diff --git a/src/formula/ltl/Until.h b/src/formula/ltl/Until.h index 596a654fe..95c999e39 100644 --- a/src/formula/ltl/Until.h +++ b/src/formula/ltl/Until.h @@ -76,9 +76,8 @@ public: /*! * Empty constructor */ - Until() { - this->left = NULL; - this->right = NULL; + Until() : left(left), right(right) { + // Intentionally left empty. } /*! @@ -87,9 +86,8 @@ public: * @param left The left formula subtree * @param right The left formula subtree */ - Until(AbstractLtlFormula<T>* left, AbstractLtlFormula<T>* right) { - this->left = left; - this->right = right; + Until(std::shared_ptr<AbstractLtlFormula<T>> const & left, std::shared_ptr<AbstractLtlFormula<T>> const & right) : left(left), right(right) { + // Intentionally left empty. } /*! @@ -99,12 +97,7 @@ public: * (this behaviour can be prevented by setting the subtrees to NULL before deletion) */ virtual ~Until() { - if (left != NULL) { - delete left; - } - if (right != NULL) { - delete right; - } + // Intentionally left empty. } /*! @@ -114,13 +107,13 @@ public: * * @returns a new BoundedUntil-object that is identical the called object. */ - virtual AbstractLtlFormula<T>* clone() const override { - Until<T>* result = new Until(); + virtual std::shared_ptr<AbstractLtlFormula<T>> clone() const override { + std::shared_ptr<Until<T>> result(new Until<T>()); if (this->leftIsSet()) { - result->setLeft(this->getLeft().clone()); + result->setLeft(left->clone()); } if (this->rightIsSet()) { - result->setRight(this->getRight().clone()); + result->setRight(right->clone()); } return result; } @@ -134,14 +127,10 @@ public: * * @returns A vector indicating the probability that the formula holds for each state. */ - virtual std::vector<T> check(const storm::modelchecker::ltl::AbstractModelChecker<T>& modelChecker) const { + virtual std::vector<T> check(storm::modelchecker::ltl::AbstractModelChecker<T> const & modelChecker) const { return modelChecker.template as<IUntilModelChecker>()->checkUntil(*this); } - virtual void visit(visitor::AbstractLtlFormulaVisitor<T>& visitor) const override { - visitor.template as<IUntilVisitor>()->visitUntil(*this); - } - /*! * @brief Return string representation of this formula. * @@ -163,7 +152,7 @@ public: * @param checker Formula checker object. * @return true iff all subtrees conform to some logic. */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { return checker.validate(this->left) && checker.validate(this->right); } @@ -172,7 +161,7 @@ public: * * @param newLeft the new left child. */ - void setLeft(AbstractLtlFormula<T>* newLeft) { + void setLeft(std::shared_ptr<AbstractLtlFormula<T>> const & newLeft) { left = newLeft; } @@ -181,22 +170,22 @@ public: * * @param newRight the new right child. */ - void setRight(AbstractLtlFormula<T>* newRight) { + void setRight(std::shared_ptr<AbstractLtlFormula<T>> const & newRight) { right = newRight; } /*! * @returns a pointer to the left child node */ - const AbstractLtlFormula<T>& getLeft() const { - return *left; + std::shared_ptr<AbstractLtlFormula<T>> const & getLeft() const { + return left; } /*! * @returns a pointer to the right child node */ - const AbstractLtlFormula<T>& getRight() const { - return *right; + std::shared_ptr<AbstractLtlFormula<T>> const & getRight() const { + return right; } /*! @@ -204,7 +193,7 @@ public: * @return True if the left child is set, i.e. it does not point to nullptr; false otherwise */ bool leftIsSet() const { - return left != nullptr; + return left.get() != nullptr; } /*! @@ -212,12 +201,12 @@ public: * @return True if the right child is set, i.e. it does not point to nullptr; false otherwise */ bool rightIsSet() const { - return right != nullptr; + return right.get() != nullptr; } private: - AbstractLtlFormula<T>* left; - AbstractLtlFormula<T>* right; + std::shared_ptr<AbstractLtlFormula<T>> left; + std::shared_ptr<AbstractLtlFormula<T>> right; }; } //namespace ltl diff --git a/src/formula/ltl/visitor/AbstractLtlFormulaVisitor.cpp b/src/formula/ltl/visitor/AbstractLtlFormulaVisitor.cpp deleted file mode 100644 index 99653fca2..000000000 --- a/src/formula/ltl/visitor/AbstractLtlFormulaVisitor.cpp +++ /dev/null @@ -1,16 +0,0 @@ -/* - * AbstractLtlFormulaVisitor.cpp - * - * Created on: 29.05.2013 - * Author: thomas - */ - -#include "AbstractLtlFormulaVisitor.h" - -namespace storm { -namespace property { -namespace visitor { - -} /* namespace visitor */ -} /* namespace property */ -} /* namespace storm */ diff --git a/src/formula/ltl/visitor/AbstractLtlFormulaVisitor.h b/src/formula/ltl/visitor/AbstractLtlFormulaVisitor.h deleted file mode 100644 index db0ff8956..000000000 --- a/src/formula/ltl/visitor/AbstractLtlFormulaVisitor.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * AbstractLtlFormulaVisitor.h - * - * Created on: 29.05.2013 - * Author: thomas - */ - -#ifndef STORM_PROPERTY_LTL_VISITOR_ABSTRACTLTLFORMULAVISITOR_H_ -#define STORM_PROPERTY_LTL_VISITOR_ABSTRACTLTLFORMULAVISITOR_H_ - -// Forward declaration of visitor -namespace storm { -namespace property { -namespace ltl { -namespace visitor { - -template <class T> -class AbstractLtlFormulaVisitor; - -} /* namespace visitor */ -} -} -} - -#include "../AbstractLtlFormula.h" -#include "log4cplus/logger.h" -#include "log4cplus/loggingmacros.h" - -#include <typeinfo> - -extern log4cplus::Logger logger; - -namespace storm { -namespace property { -namespace ltl { -namespace visitor { - -template <class T> -class AbstractLtlFormulaVisitor { -public: - virtual ~AbstractLtlFormulaVisitor() { - // TODO Auto-generated destructor stub - } - - - /*! - * Returns a pointer to the model checker object that is of the requested type as given by the template parameters. - * @returns A pointer to the model checker object that is of the requested type as given by the template parameters. - * If the model checker is not of the requested type, type casting will fail and result in an exception. - */ - template <template <class Type> class Target> - Target<T>* as() { - try { - Target<T>* target = dynamic_cast<Target<T>*>(this); - return target; - } catch (std::bad_cast& bc) { - LOG4CPLUS_ERROR(logger, "Bad cast: tried to cast " << typeid(*this).name() << " to " << typeid(Target<T>).name() << "."); - throw bc; - } - return nullptr; - } - - void visit(storm::property::ltl::AbstractLtlFormula<T> const& formula) { - formula.visit(*this); - } -}; - -} /* namespace visitor */ -} /* namespace ltl*/ -} /* namespace property */ -} /* namespace storm */ -#endif /* STORM_PROPERTY_LTL_VISITOR_ABSTRACTLTLFORMULAVISITOR_H_ */ diff --git a/src/formula/prctl/AbstractPathFormula.h b/src/formula/prctl/AbstractPathFormula.h index 50040082f..f8cb686b6 100644 --- a/src/formula/prctl/AbstractPathFormula.h +++ b/src/formula/prctl/AbstractPathFormula.h @@ -50,7 +50,7 @@ public: * @note This function is not implemented in this class. * @returns a new AND-object that is identical the called object. */ - virtual AbstractPathFormula<T>* clone() const = 0; + virtual std::shared_ptr<AbstractPathFormula<T>> clone() const = 0; /*! * Calls the model checker to check this formula. diff --git a/src/formula/prctl/AbstractRewardPathFormula.h b/src/formula/prctl/AbstractRewardPathFormula.h index d28e1003d..949ecc422 100644 --- a/src/formula/prctl/AbstractRewardPathFormula.h +++ b/src/formula/prctl/AbstractRewardPathFormula.h @@ -39,7 +39,7 @@ public: * @note This function is not implemented in this class. * @returns a new AND-object that is identical the called object. */ - virtual AbstractRewardPathFormula<T>* clone() const = 0; + virtual std::shared_ptr<AbstractRewardPathFormula<T>> clone() const = 0; /*! * Calls the model checker to check this formula. diff --git a/src/formula/prctl/AbstractStateFormula.h b/src/formula/prctl/AbstractStateFormula.h index 8af034faa..d07c169a8 100644 --- a/src/formula/prctl/AbstractStateFormula.h +++ b/src/formula/prctl/AbstractStateFormula.h @@ -44,7 +44,7 @@ public: * @note This function is not implemented in this class. * @returns a new AND-object that is identical the called object. */ - virtual AbstractStateFormula<T>* clone() const = 0; + virtual std::shared_ptr<AbstractStateFormula<T>> clone() const = 0; /*! * Calls the model checker to check this formula. diff --git a/src/formula/prctl/And.h b/src/formula/prctl/And.h index b364e3a63..f821f08d4 100644 --- a/src/formula/prctl/And.h +++ b/src/formula/prctl/And.h @@ -62,8 +62,7 @@ public: * Will create an AND-node without subnotes. Will not represent a complete formula! */ And() { - left = NULL; - right = NULL; + // Intentionally left empty. } /*! @@ -73,9 +72,8 @@ public: * @param left The left sub formula * @param right The right sub formula */ - And(AbstractStateFormula<T>* left, AbstractStateFormula<T>* right) { - this->left = left; - this->right = right; + And(std::shared_ptr<AbstractStateFormula<T>> const & left, std::shared_ptr<AbstractStateFormula<T>> const & right) : left(left), right(right) { + // Intentionally left empty. } /*! @@ -85,12 +83,7 @@ public: * (this behavior can be prevented by setting them to NULL before deletion) */ virtual ~And() { - if (left != NULL) { - delete left; - } - if (right != NULL) { - delete right; - } + // Intentionally left empty. } /*! @@ -100,13 +93,13 @@ public: * * @returns a new AND-object that is identical the called object. */ - virtual AbstractStateFormula<T>* clone() const override { - And<T>* result = new And(); + virtual std::shared_ptr<AbstractStateFormula<T>> clone() const override { + std::shared_ptr<And<T>> result(new And()); if (this->leftIsSet()) { - result->setLeft(this->getLeft().clone()); + result->setLeft(left->clone()); } if (this->rightIsSet()) { - result->setRight(this->getRight().clone()); + result->setRight(right->clone()); } return result; } @@ -151,7 +144,7 @@ public: * * @param newLeft the new left child. */ - void setLeft(AbstractStateFormula<T>* newLeft) { + void setLeft(std::shared_ptr<AbstractStateFormula<T>> const & newLeft) { left = newLeft; } @@ -160,22 +153,22 @@ public: * * @param newRight the new right child. */ - void setRight(AbstractStateFormula<T>* newRight) { + void setRight(std::shared_ptr<AbstractStateFormula<T>> const & newRight) { right = newRight; } /*! - * @returns a pointer to the left child node + * @returns a reference to the left child node */ - const AbstractStateFormula<T>& getLeft() const { - return *left; + std::shared_ptr<AbstractStateFormula<T>> const & getLeft() const { + return left; } /*! - * @returns a pointer to the right child node + * @returns a reference to the right child node */ - const AbstractStateFormula<T>& getRight() const { - return *right; + std::shared_ptr<AbstractStateFormula<T>> const & getRight() const { + return right; } /*! @@ -183,7 +176,7 @@ public: * @return True if the left child is set, i.e. it does not point to nullptr; false otherwise */ bool leftIsSet() const { - return left != nullptr; + return left.get() != nullptr; } /*! @@ -191,12 +184,12 @@ public: * @return True if the right child is set, i.e. it does not point to nullptr; false otherwise */ bool rightIsSet() const { - return right != nullptr; + return right.get() != nullptr; } private: - AbstractStateFormula<T>* left; - AbstractStateFormula<T>* right; + std::shared_ptr<AbstractStateFormula<T>> left; + std::shared_ptr<AbstractStateFormula<T>> right; }; diff --git a/src/formula/prctl/Ap.h b/src/formula/prctl/Ap.h index 21ed5b82f..906158ac9 100644 --- a/src/formula/prctl/Ap.h +++ b/src/formula/prctl/Ap.h @@ -76,8 +76,9 @@ public: * * @returns a new AND-object that is identical the called object. */ - virtual AbstractStateFormula<T>* clone() const override { - return new Ap(this->getAp()); + virtual std::shared_ptr<AbstractStateFormula<T>> clone() const override { + std::shared_ptr<AbstractStateFormula<T>> result(new Ap(this->getAp())); + return result; } /*! diff --git a/src/formula/prctl/BoundedEventually.h b/src/formula/prctl/BoundedEventually.h index 59e319b28..70e10020d 100644 --- a/src/formula/prctl/BoundedEventually.h +++ b/src/formula/prctl/BoundedEventually.h @@ -71,7 +71,7 @@ public: * @param child The child formula subtree * @param bound The maximal number of steps */ - BoundedEventually(AbstractStateFormula<T>* child, uint_fast64_t bound) : child(child), bound(bound){ + BoundedEventually(std::shared_ptr<AbstractStateFormula<T>> child, uint_fast64_t bound) : child(child), bound(bound){ // Intentionally left empty. } @@ -82,9 +82,7 @@ public: * (this behaviour can be prevented by setting the subtrees to NULL before deletion) */ virtual ~BoundedEventually() { - if (child != nullptr) { - delete child; - } + // Intentionally left empty. } /*! @@ -94,11 +92,11 @@ public: * * @returns a new BoundedUntil-object that is identical the called object. */ - virtual AbstractPathFormula<T>* clone() const override { - BoundedEventually<T>* result = new BoundedEventually<T>(); - result->setBound(this->getBound()); + virtual std::shared_ptr<AbstractPathFormula<T>> clone() const override { + std::shared_ptr<BoundedEventually<T>> result(new BoundedEventually<T>()); + result->setBound(bound); if (this->childIsSet()) { - result->setChild(this->getChild().clone()); + result->setChild(child->clone()); } return result; } @@ -141,15 +139,15 @@ public: /*! * @returns the child node */ - const AbstractStateFormula<T>& getChild() const { - return *child; + std::shared_ptr<AbstractStateFormula<T>> const & getChild() const { + return child; } /*! * Sets the subtree * @param child the new child node */ - void setChild(AbstractStateFormula<T>* child) { + void setChild(std::shared_ptr<AbstractStateFormula<T>> const & child) { this->child = child; } @@ -158,7 +156,7 @@ public: * @return True if the child is set, i.e. it does not point to nullptr; false otherwise */ bool childIsSet() const { - return child != nullptr; + return child.get() != nullptr; } /*! @@ -178,7 +176,7 @@ public: } private: - AbstractStateFormula<T>* child; + std::shared_ptr<AbstractStateFormula<T>> child; uint_fast64_t bound; }; diff --git a/src/formula/prctl/BoundedNaryUntil.h b/src/formula/prctl/BoundedNaryUntil.h index 7fc91830d..0cf02d4f4 100644 --- a/src/formula/prctl/BoundedNaryUntil.h +++ b/src/formula/prctl/BoundedNaryUntil.h @@ -69,9 +69,8 @@ public: /*! * Empty constructor */ - BoundedNaryUntil() { - this->left = nullptr; - this->right = new std::vector<std::tuple<AbstractStateFormula<T>*,T,T>>(); + BoundedNaryUntil() : left(nullptr), right() { + // Intentionally left empty. } /*! @@ -80,9 +79,8 @@ public: * @param left The left formula subtree * @param right The left formula subtree */ - BoundedNaryUntil(AbstractStateFormula<T>* left, std::vector<std::tuple<AbstractStateFormula<T>*,T,T>>* right) { - this->left = left; - this->right = right; + BoundedNaryUntil(std::shared_ptr<AbstractStateFormula<T>> const & left, std::vector<std::tuple<std::shared_ptr<AbstractStateFormula<T>>,T,T>> const & right) : left(left), right(right) { + // Intentionally left empty. } /*! @@ -92,12 +90,7 @@ public: * (this behaviour can be prevented by setting the subtrees to NULL before deletion) */ virtual ~BoundedNaryUntil() { - if (left != nullptr) { - delete left; - } - if (right != nullptr) { - delete right; - } + // Intentionally left empty. } /*! @@ -107,15 +100,15 @@ public: * * @returns a new BoundedNaryUntil-object that is identical the called object. */ - virtual AbstractPathFormula<T>* clone() const override { - BoundedNaryUntil<T>* result = new BoundedNaryUntil<T>(); + virtual std::shared_ptr<AbstractPathFormula<T>> clone() const override { + std::shared_ptr<BoundedNaryUntil<T>> result(new BoundedNaryUntil<T>()); if (this->leftIsSet()) { - result->setLeft(this->getLeft().clone()); + result->setLeft(left->clone()); } if (this->rightIsSet()) { - std::vector<std::tuple<AbstractStateFormula<T>*,T,T>>* newright = new std::vector<std::tuple<AbstractStateFormula<T>*,T,T>>(); - for (auto it = this->right->begin(); it != this->right->end(); ++it) { - newright->push_back(std::tuple<AbstractStateFormula<T>*,T,T>(std::get<0>(*it)->clone(), std::get<1>(*it), std::get<2>(*it))); + std::vector<std::tuple<std::shared_ptr<AbstractStateFormula<T>>,T,T>> newright; + for (auto it = right->begin(); it != right->end(); ++it) { + newright.push_back(std::tuple<std::shared_ptr<AbstractStateFormula<T>>,T,T>(std::get<0>(*it)->clone(), std::get<1>(*it), std::get<2>(*it))); } result->setRight(newright); } @@ -142,7 +135,7 @@ public: virtual std::string toString() const override { std::stringstream result; result << "( " << left->toString(); - for (auto it = this->right->begin(); it != this->right->end(); ++it) { + for (auto it = right->begin(); it != right->end(); ++it) { result << " U(" << std::get<1>(*it) << "," << std::get<2>(*it) << ") " << std::get<0>(*it)->toString(); } result << ")"; @@ -156,8 +149,8 @@ public: * @return true iff all subtrees conform to some logic. */ virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { - bool res = checker.validate(this->left); - for (auto it = this->right->begin(); it != this->right->end(); ++it) { + bool res = checker.validate(left); + for (auto it = right->begin(); it != right->end(); ++it) { res &= checker.validate(std::get<0>(*it)); } return res; @@ -168,11 +161,11 @@ public: * * @param newLeft the new left child. */ - void setLeft(AbstractStateFormula<T>* newLeft) { + void setLeft(std::shared_ptr<AbstractStateFormula<T>> const & newLeft) { left = newLeft; } - void setRight(std::vector<std::tuple<AbstractStateFormula<T>*,T,T>>* newRight) { + void setRight(std::vector<std::tuple<std::shared_ptr<AbstractStateFormula<T>>,T,T>> const & newRight) { right = newRight; } @@ -186,10 +179,10 @@ public: /*! * - * @return True if the right child is set, i.e. it does not point to nullptr; false otherwise + * @return True if the right child is set, i.e. it is not empty; false otherwise */ bool rightIsSet() const { - return right != nullptr; + return !(right.empty()); } /*! @@ -197,28 +190,28 @@ public: * * @param newRight the new right child. */ - void addRight(AbstractStateFormula<T>* newRight, T upperBound, T lowerBound) { - this->right->push_back(std::tuple<AbstractStateFormula<T>*,T,T>(newRight, upperBound, lowerBound)); + void addRight(std::shared_ptr<AbstractStateFormula<T>> const & newRight, T upperBound, T lowerBound) { + right.push_back(std::tuple<std::shared_ptr<AbstractStateFormula<T>>,T,T>(newRight, upperBound, lowerBound)); } /*! * @returns a pointer to the left child node */ - const AbstractStateFormula<T>& getLeft() const { - return *left; + std::shared_ptr<AbstractStateFormula<T>> const & getLeft() const { + return left; } /*! * @returns a pointer to the right child nodes. */ - const std::vector<std::tuple<AbstractStateFormula<T>*,T,T>>& getRight() const { - return *right; + std::vector<std::tuple<std::shared_ptr<AbstractStateFormula<T>>,T,T>> const & getRight() const { + return right; } private: - AbstractStateFormula<T>* left; - std::vector<std::tuple<AbstractStateFormula<T>*,T,T>>* right; + std::shared_ptr<AbstractStateFormula<T>> left; + std::vector<std::tuple<std::shared_ptr<AbstractStateFormula<T>>,T,T>> right; }; } //namespace prctl diff --git a/src/formula/prctl/BoundedUntil.h b/src/formula/prctl/BoundedUntil.h index 206c0a202..d018567eb 100644 --- a/src/formula/prctl/BoundedUntil.h +++ b/src/formula/prctl/BoundedUntil.h @@ -73,24 +73,16 @@ public: * @param right The left formula subtree * @param bound The maximal number of steps */ - BoundedUntil(AbstractStateFormula<T>* left, AbstractStateFormula<T>* right, uint_fast64_t bound) { - this->left = left; - this->right = right; - this->bound = bound; + BoundedUntil(std::shared_ptr<AbstractStateFormula<T>> const & left, std::shared_ptr<AbstractStateFormula<T>> const & right, uint_fast64_t bound) : left(left), right(right), bound(bound) { + // Intentionally left empty. } /*! * Destructor. * - * Also deletes the subtrees. - * (this behaviour can be prevented by setting the subtrees to NULL before deletion) + * Deletes the subtrees iff this object is the only owner of them. */ virtual ~BoundedUntil() { - if (left != NULL) { - delete left; - } - if (right != NULL) { - delete right; - } + // Intentionally left empty. } /*! @@ -100,14 +92,14 @@ public: * * @returns a new BoundedUntil-object that is identical the called object. */ - virtual AbstractPathFormula<T>* clone() const override { - BoundedUntil<T>* result = new BoundedUntil<T>(); - result->setBound(this->getBound()); + virtual std::shared_ptr<AbstractPathFormula<T>> clone() const override { + std::shared_ptr<BoundedUntil<T>> result(new BoundedUntil<T>()); + result->setBound(bound); if (this->leftIsSet()) { - result->setLeft(this->getLeft().clone()); + result->setLeft(left->clone()); } if (this->rightIsSet()) { - result->setRight(this->getRight().clone()); + result->setRight(right->clone()); } return result; } @@ -122,7 +114,7 @@ public: * * @returns A vector indicating the probability that the formula holds for each state. */ - virtual std::vector<T> check(const storm::modelchecker::prctl::AbstractModelChecker<T>& modelChecker, bool qualitative) const override { + virtual std::vector<T> check(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelChecker, bool qualitative) const override { return modelChecker.template as<IBoundedUntilModelChecker>()->checkBoundedUntil(*this, qualitative); } @@ -153,7 +145,7 @@ public: * * @param newLeft the new left child. */ - void setLeft(AbstractStateFormula<T>* newLeft) { + void setLeft(std::shared_ptr<AbstractStateFormula<T>> const & newLeft) { left = newLeft; } @@ -162,22 +154,22 @@ public: * * @param newRight the new right child. */ - void setRight(AbstractStateFormula<T>* newRight) { + void setRight(std::shared_ptr<AbstractStateFormula<T>> const & newRight) { right = newRight; } /*! * @returns a pointer to the left child node */ - const AbstractStateFormula<T>& getLeft() const { - return *left; + std::shared_ptr<AbstractStateFormula<T>> const & getLeft() const { + return left; } /*! * @returns a pointer to the right child node */ - const AbstractStateFormula<T>& getRight() const { - return *right; + std::shared_ptr<AbstractStateFormula<T>> const & getRight() const { + return right; } /*! @@ -185,7 +177,7 @@ public: * @return True if the left child is set, i.e. it does not point to nullptr; false otherwise */ bool leftIsSet() const { - return left != nullptr; + return left.get() != nullptr; } /*! @@ -193,7 +185,7 @@ public: * @return True if the right child is set, i.e. it does not point to nullptr; false otherwise */ bool rightIsSet() const { - return right != nullptr; + return right.get() != nullptr; } /*! @@ -213,8 +205,8 @@ public: } private: - AbstractStateFormula<T>* left; - AbstractStateFormula<T>* right; + std::shared_ptr<AbstractStateFormula<T>> left; + std::shared_ptr<AbstractStateFormula<T>> right; uint_fast64_t bound; }; diff --git a/src/formula/prctl/CumulativeReward.h b/src/formula/prctl/CumulativeReward.h index baffaecd1..84861ed91 100644 --- a/src/formula/prctl/CumulativeReward.h +++ b/src/formula/prctl/CumulativeReward.h @@ -54,7 +54,7 @@ public: * Empty constructor */ CumulativeReward() : bound(0){ - // Intentionally left empty + // Intentionally left empty. } /*! @@ -80,8 +80,9 @@ public: * * @returns a new CumulativeReward-object that is identical the called object. */ - virtual AbstractRewardPathFormula<T>* clone() const override { - return new CumulativeReward(this->getBound()); + virtual std::shared_ptr<AbstractRewardPathFormula<T>> clone() const override { + std::shared_ptr<CumulativeReward<T>> result(new CumulativeReward(this->getBound())); + return result; } @@ -94,7 +95,7 @@ public: * * @returns A vector indicating the probability that the formula holds for each state. */ - virtual std::vector<T> check(const storm::modelchecker::prctl::AbstractModelChecker<T>& modelChecker, bool qualitative) const override { + virtual std::vector<T> check(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelChecker, bool qualitative) const override { return modelChecker.template as<ICumulativeRewardModelChecker>()->checkCumulativeReward(*this, qualitative); } @@ -115,7 +116,7 @@ public: * @param checker Formula checker object. * @return true */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { return true; } diff --git a/src/formula/prctl/Eventually.h b/src/formula/prctl/Eventually.h index cbcbf8c4d..321ac872f 100644 --- a/src/formula/prctl/Eventually.h +++ b/src/formula/prctl/Eventually.h @@ -68,20 +68,17 @@ public: * * @param child The child node */ - Eventually(AbstractStateFormula<T>* child) : child(child){ + Eventually(std::shared_ptr<AbstractStateFormula<T>> const & child) : child(child){ // Intentionally left empty. } /*! * Constructor. * - * Also deletes the subtree. - * (this behaviour can be prevented by setting the subtrees to nullptr before deletion) + * Deletes the subtree iff this object is the last remaining owner of the subtree. */ virtual ~Eventually() { - if (child != nullptr) { - delete child; - } + // Intentionally left empty. } /*! @@ -91,10 +88,10 @@ public: * * @returns a new Eventually-object that is identical the called object. */ - virtual AbstractPathFormula<T>* clone() const override { - Eventually<T>* result = new Eventually<T>(); + virtual std::shared_ptr<AbstractPathFormula<T>> clone() const override { + std::shared_ptr<Eventually<T>> result(new Eventually<T>()); if (this->childIsSet()) { - result->setChild(this->getChild().clone()); + result->setChild(child->clone()); } return result; } @@ -108,7 +105,7 @@ public: * * @returns A vector indicating the probability that the formula holds for each state. */ - virtual std::vector<T> check(const storm::modelchecker::prctl::AbstractModelChecker<T>& modelChecker, bool qualitative) const override { + virtual std::vector<T> check(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelChecker, bool qualitative) const override { return modelChecker.template as<IEventuallyModelChecker>()->checkEventually(*this, qualitative); } @@ -127,22 +124,22 @@ public: * @param checker Formula checker object. * @return true iff the subtree conforms to some logic. */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { - return checker.validate(this->child); + virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { + return checker.validate(child); } /*! * @returns the child node */ - const AbstractStateFormula<T>& getChild() const { - return *child; + std::shared_ptr<AbstractStateFormula<T>> const & getChild() const { + return child; } /*! * Sets the subtree * @param child the new child node */ - void setChild(AbstractStateFormula<T>* child) { + void setChild(std::shared_ptr<AbstractStateFormula<T>> const & child) { this->child = child; } @@ -151,11 +148,11 @@ public: * @return True if the child node is set, i.e. it does not point to nullptr; false otherwise */ bool childIsSet() const { - return child != nullptr; + return child.get() != nullptr; } private: - AbstractStateFormula<T>* child; + std::shared_ptr<AbstractStateFormula<T>> child; }; } //namespace prctl diff --git a/src/formula/prctl/Globally.h b/src/formula/prctl/Globally.h index 49b4d6d96..7296a9534 100644 --- a/src/formula/prctl/Globally.h +++ b/src/formula/prctl/Globally.h @@ -69,20 +69,17 @@ public: * * @param child The child node */ - Globally(AbstractStateFormula<T>* child) : child(child){ + Globally(std::shared_ptr<AbstractStateFormula<T>> const & child) : child(child){ // Intentionally left empty. } /*! - * Constructor. + * Destructor. * - * Also deletes the subtree. - * (this behaviour can be prevented by setting the subtrees to nullptr before deletion) + * Deletes the subtree iff this object is the last remaining owner of the subtree. */ virtual ~Globally() { - if (child != nullptr) { - delete child; - } + // Intentionally left empty. } /*! @@ -92,10 +89,10 @@ public: * * @returns a new Globally-object that is identical the called object. */ - virtual AbstractPathFormula<T>* clone() const override { - Globally<T>* result = new Globally<T>(); + virtual std::shared_ptr<AbstractPathFormula<T>> clone() const override { + std::shared_ptr<Globally<T>> result(new Globally<T>()); if (this->childIsSet()) { - result->setChild(this->getChild().clone()); + result->setChild(child->clone()); } return result; } @@ -109,7 +106,7 @@ public: * * @returns A vector indicating the probability that the formula holds for each state. */ - virtual std::vector<T> check(const storm::modelchecker::prctl::AbstractModelChecker<T>& modelChecker, bool qualitative) const override { + virtual std::vector<T> check(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelChecker, bool qualitative) const override { return modelChecker.template as<IGloballyModelChecker>()->checkGlobally(*this, qualitative); } @@ -128,22 +125,22 @@ public: * @param checker Formula checker object. * @return true iff the subtree conforms to some logic. */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { - return checker.validate(this->child); + virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { + return checker.validate(child); } /*! * @returns the child node */ - const AbstractStateFormula<T>& getChild() const { - return *child; + std::shared_ptr<AbstractStateFormula<T>> const & getChild() const { + return child; } /*! * Sets the subtree * @param child the new child node */ - void setChild(AbstractStateFormula<T>* child) { + void setChild(std::shared_ptr<AbstractStateFormula<T>> const & child) { this->child = child; } @@ -152,11 +149,11 @@ public: * @return True if the child node is set, i.e. it does not point to nullptr; false otherwise */ bool childIsSet() const { - return child != nullptr; + return child.get() != nullptr; } private: - AbstractStateFormula<T>* child; + std::shared_ptr<AbstractStateFormula<T>> child; }; } //namespace prctl diff --git a/src/formula/prctl/InstantaneousReward.h b/src/formula/prctl/InstantaneousReward.h index cec958780..3a65583a6 100644 --- a/src/formula/prctl/InstantaneousReward.h +++ b/src/formula/prctl/InstantaneousReward.h @@ -82,8 +82,9 @@ public: * * @returns a new InstantaneousReward-object that is identical the called object. */ - virtual AbstractRewardPathFormula<T>* clone() const override { - return new InstantaneousReward(this->getBound()); + virtual std::shared_ptr<AbstractRewardPathFormula<T>> clone() const override { + std::shared_ptr<InstantaneousReward<T>> result(new InstantaneousReward(bound)); + return result; } @@ -96,7 +97,7 @@ public: * * @returns A vector indicating the probability that the formula holds for each state. */ - virtual std::vector<T> check(const storm::modelchecker::prctl::AbstractModelChecker<T>& modelChecker, bool qualitative) const override { + virtual std::vector<T> check(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelChecker, bool qualitative) const override { return modelChecker.template as<IInstantaneousRewardModelChecker>()->checkInstantaneousReward(*this, qualitative); } @@ -117,7 +118,7 @@ public: * @param checker Formula checker object. * @return true */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { return true; } diff --git a/src/formula/prctl/Next.h b/src/formula/prctl/Next.h index e218d036e..3cff6892a 100644 --- a/src/formula/prctl/Next.h +++ b/src/formula/prctl/Next.h @@ -68,20 +68,17 @@ public: * * @param child The child node */ - Next(AbstractStateFormula<T>* child) : child(child){ + Next(std::shared_ptr<AbstractStateFormula<T>> const & child) : child(child){ // Intentionally left empty. } /*! * Constructor. * - * Also deletes the subtree. - * (this behavior can be prevented by setting the subtrees to NULL before deletion) + * Deletes the subtree iff this object is the last remaining owner of the subtree. */ virtual ~Next() { - if (child != NULL) { - delete child; - } + // Intentionally left empty. } /*! @@ -91,10 +88,10 @@ public: * * @returns a new BoundedUntil-object that is identical the called object. */ - virtual AbstractPathFormula<T>* clone() const override { - Next<T>* result = new Next<T>(); + virtual std::shared_ptr<AbstractPathFormula<T>> clone() const override { + std::shared_ptr<Next<T>> result(new Next<T>()); if (this->childIsSet()) { - result->setChild(this->getChild().clone()); + result->setChild(child->clone()); } return result; } @@ -108,7 +105,7 @@ public: * * @returns A vector indicating the probability that the formula holds for each state. */ - virtual std::vector<T> check(const storm::modelchecker::prctl::AbstractModelChecker<T>& modelChecker, bool qualitative) const override { + virtual std::vector<T> check(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelChecker, bool qualitative) const override { return modelChecker.template as<INextModelChecker>()->checkNext(*this, qualitative); } @@ -129,22 +126,22 @@ public: * @param checker Formula checker object. * @return true iff the subtree conforms to some logic. */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { return checker.validate(this->child); } /*! * @returns the child node */ - const AbstractStateFormula<T>& getChild() const { - return *child; + std::shared_ptr<AbstractStateFormula<T>> const & getChild() const { + return child; } /*! * Sets the subtree * @param child the new child node */ - void setChild(AbstractStateFormula<T>* child) { + void setChild(std::shared_ptr<AbstractStateFormula<T>> const & child) { this->child = child; } @@ -153,11 +150,11 @@ public: * @return True if the child node is set, i.e. it does not point to nullptr; false otherwise */ bool childIsSet() const { - return child != nullptr; + return child.get() != nullptr; } private: - AbstractStateFormula<T>* child; + std::shared_ptr<AbstractStateFormula<T>> child; }; } //namespace prctl diff --git a/src/formula/prctl/Not.h b/src/formula/prctl/Not.h index 65a06be3a..49660f1af 100644 --- a/src/formula/prctl/Not.h +++ b/src/formula/prctl/Not.h @@ -56,28 +56,25 @@ public: /*! * Empty constructor */ - Not() { - this->child = NULL; + Not() : child(nullptr) { + // Intentionally left empty. } /*! * Constructor * @param child The child node */ - Not(AbstractStateFormula<T>* child) { - this->child = child; + Not(std::shared_ptr<AbstractStateFormula<T>> child) : child(child) { + // Intentionally left empty. } /*! * Destructor * - * Also deletes the subtree - * (this behavior can be prevented by setting them to NULL before deletion) + * Deletes the subtree iff this object is the last remaining owner of the subtree. */ virtual ~Not() { - if (child != NULL) { - delete child; - } + // Intentionally left empty. } /*! @@ -87,10 +84,10 @@ public: * * @returns a new AND-object that is identical the called object. */ - virtual AbstractStateFormula<T>* clone() const override { - Not<T>* result = new Not<T>(); + virtual std::shared_ptr<AbstractStateFormula<T>> clone() const override { + std::shared_ptr<Not<T>> result(new Not<T>()); if (this->childIsSet()) { - result->setChild(this->getChild().clone()); + result->setChild(child->clone()); } return result; } @@ -104,7 +101,7 @@ public: * * @returns A bit vector indicating all states that satisfy the formula represented by the called object. */ - virtual storm::storage::BitVector check(const storm::modelchecker::prctl::AbstractModelChecker<T>& modelChecker) const override { + virtual storm::storage::BitVector check(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelChecker) const override { return modelChecker.template as<INotModelChecker>()->checkNot(*this); } @@ -123,22 +120,22 @@ public: * @param checker Formula checker object. * @return true iff the subtree conforms to some logic. */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { return checker.validate(this->child); } /*! * @returns The child node */ - const AbstractStateFormula<T>& getChild() const { - return *child; + std::shared_ptr<AbstractStateFormula<T>> const & getChild() const { + return child; } /*! * Sets the subtree * @param child the new child node */ - void setChild(AbstractStateFormula<T>* child) { + void setChild(std::shared_ptr<AbstractStateFormula<T>> const & child) { this->child = child; } @@ -147,11 +144,11 @@ public: * @return True if the child node is set, i.e. it does not point to nullptr; false otherwise */ bool childIsSet() const { - return child != nullptr; + return child.get() != nullptr; } private: - AbstractStateFormula<T>* child; + std::shared_ptr<AbstractStateFormula<T>> child; }; } //namespace prctl diff --git a/src/formula/prctl/Or.h b/src/formula/prctl/Or.h index 01482bb33..004b633c7 100644 --- a/src/formula/prctl/Or.h +++ b/src/formula/prctl/Or.h @@ -59,9 +59,8 @@ public: * Empty constructor. * Will create an OR-node without subnotes. Will not represent a complete formula! */ - Or() { - left = NULL; - right = NULL; + Or() : left(nullptr), right(nullptr) { + // Intentionally left empty. } /*! @@ -71,24 +70,17 @@ public: * @param left The left sub formula * @param right The right sub formula */ - Or(AbstractStateFormula<T>* left, AbstractStateFormula<T>* right) { - this->left = left; - this->right = right; + Or(std::shared_ptr<AbstractStateFormula<T>> left, std::shared_ptr<AbstractStateFormula<T>> right) : left(left), right(right) { + // Intentionally left empty. } /*! * Destructor. * - * The subtrees are deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) + * Deletes the subtree iff this object is the last remaining owner of the subtree. */ virtual ~Or() { - if (left != NULL) { - delete left; - } - if (right != NULL) { - delete right; - } + // Intentionally left empty. } /*! @@ -98,13 +90,13 @@ public: * * @returns a new AND-object that is identical the called object. */ - virtual AbstractStateFormula<T>* clone() const override { - Or<T>* result = new Or(); + virtual std::shared_ptr<AbstractStateFormula<T>> clone() const override { + std::shared_ptr<Or<T>> result(new Or()); if (this->leftIsSet()) { - result->setLeft(this->getLeft().clone()); + result->setLeft(left->clone()); } if (this->rightIsSet()) { - result->setRight(this->getRight().clone()); + result->setRight(right->clone()); } return result; } @@ -118,7 +110,7 @@ public: * * @returns A bit vector indicating all states that satisfy the formula represented by the called object. */ - virtual storm::storage::BitVector check(const storm::modelchecker::prctl::AbstractModelChecker<T>& modelChecker) const override { + virtual storm::storage::BitVector check(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelChecker) const override { return modelChecker.template as<IOrModelChecker>()->checkOr(*this); } @@ -140,7 +132,7 @@ public: * @param checker Formula checker object. * @return true iff all subtrees conform to some logic. */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { return checker.validate(this->left) && checker.validate(this->right); } @@ -149,7 +141,7 @@ public: * * @param newLeft the new left child. */ - void setLeft(AbstractStateFormula<T>* newLeft) { + void setLeft(std::shared_ptr<AbstractStateFormula<T>> const & newLeft) { left = newLeft; } @@ -158,22 +150,22 @@ public: * * @param newRight the new right child. */ - void setRight(AbstractStateFormula<T>* newRight) { + void setRight(std::shared_ptr<AbstractStateFormula<T>> const & newRight) { right = newRight; } /*! * @returns a pointer to the left child node */ - const AbstractStateFormula<T>& getLeft() const { - return *left; + std::shared_ptr<AbstractStateFormula<T>> const & getLeft() const { + return left; } /*! * @returns a pointer to the right child node */ - const AbstractStateFormula<T>& getRight() const { - return *right; + std::shared_ptr<AbstractStateFormula<T>> const & getRight() const { + return right; } /*! @@ -181,7 +173,7 @@ public: * @return True if the left child is set, i.e. it does not point to nullptr; false otherwise */ bool leftIsSet() const { - return left != nullptr; + return left.get() != nullptr; } /*! @@ -189,12 +181,12 @@ public: * @return True if the right child is set, i.e. it does not point to nullptr; false otherwise */ bool rightIsSet() const { - return right != nullptr; + return right.get() != nullptr; } private: - AbstractStateFormula<T>* left; - AbstractStateFormula<T>* right; + std::shared_ptr<AbstractStateFormula<T>> left; + std::shared_ptr<AbstractStateFormula<T>> right; }; diff --git a/src/formula/prctl/PrctlFilter.h b/src/formula/prctl/PrctlFilter.h index f9db17d9a..2f45b0ba3 100644 --- a/src/formula/prctl/PrctlFilter.h +++ b/src/formula/prctl/PrctlFilter.h @@ -25,6 +25,7 @@ namespace action { } #include <algorithm> +#include <memory> namespace storm { namespace property { @@ -41,21 +42,20 @@ public: // Intentionally left empty. } - PrctlFilter(AbstractPrctlFormula<T>* child, OptimizingOperator opt = UNDEFINED) : AbstractFilter<T>(opt), child(child) { + PrctlFilter(std::shared_ptr<AbstractPrctlFormula<T>> const & child, OptimizingOperator opt = UNDEFINED) : AbstractFilter<T>(opt), child(child) { // Intentionally left empty. } - PrctlFilter(AbstractPrctlFormula<T>* child, action::AbstractAction<T>* action, OptimizingOperator opt = UNDEFINED) : AbstractFilter<T>(action, opt), child(child) { + PrctlFilter(std::shared_ptr<AbstractPrctlFormula<T>> const & child, action::AbstractAction<T>* action, OptimizingOperator opt = UNDEFINED) : AbstractFilter<T>(action, opt), child(child) { // Intentionally left empty. } - PrctlFilter(AbstractPrctlFormula<T>* child, std::vector<action::AbstractAction<T>*> actions, OptimizingOperator opt = UNDEFINED) : AbstractFilter<T>(actions, opt), child(child) { + PrctlFilter(std::shared_ptr<AbstractPrctlFormula<T>> const & child, std::vector<action::AbstractAction<T>*> actions, OptimizingOperator opt = UNDEFINED) : AbstractFilter<T>(actions, opt), child(child) { // Intentionally left empty. } virtual ~PrctlFilter() { this->actions.clear(); - delete child; } void check(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelchecker) const { @@ -68,12 +68,12 @@ public: Result result; try { - if(dynamic_cast<AbstractStateFormula<T> *>(child) != nullptr) { - result = evaluate(modelchecker, dynamic_cast<AbstractStateFormula<T> *>(child)); - } else if (dynamic_cast<AbstractPathFormula<T> *>(child) != nullptr) { - result = evaluate(modelchecker, dynamic_cast<AbstractPathFormula<T> *>(child)); - } else if (dynamic_cast<AbstractRewardPathFormula<T> *>(child) != nullptr) { - result = evaluate(modelchecker, dynamic_cast<AbstractRewardPathFormula<T> *>(child)); + if(dynamic_cast<AbstractStateFormula<T> *>(child.get()) != nullptr) { + result = evaluate(modelchecker, std::dynamic_pointer_cast<AbstractStateFormula<T>>(child)); + } else if (dynamic_cast<AbstractPathFormula<T> *>(child.get()) != nullptr) { + result = evaluate(modelchecker, std::dynamic_pointer_cast<AbstractPathFormula<T>>(child)); + } else if (dynamic_cast<AbstractRewardPathFormula<T> *>(child.get()) != nullptr) { + result = evaluate(modelchecker, std::dynamic_pointer_cast<AbstractRewardPathFormula<T>>(child)); } } catch (std::exception& e) { std::cout << "Error during computation: " << e.what() << "Skipping property." << std::endl; @@ -90,14 +90,14 @@ public: virtual std::string toString() const override { std::string desc = ""; - if(dynamic_cast<AbstractStateFormula<T>*>(child) == nullptr) { + if(!std::dynamic_pointer_cast<AbstractStateFormula<T>>(child)) { // The formula is not a state formula so we either have a probability query or a reward query. if(this->actions.empty()){ // There is exactly one action in the list, the minmax action. Again, we do legacy support- - if(dynamic_cast<AbstractPathFormula<T>*>(child) != nullptr) { + if(std::dynamic_pointer_cast<AbstractPathFormula<T>>(child)) { // It is a probability query. desc += "P "; @@ -184,17 +184,17 @@ public: return desc; } - void setChild(AbstractPrctlFormula<T>* child) { + void setChild(std::shared_ptr<AbstractPrctlFormula<T>> const & child) { this->child = child; } - AbstractPrctlFormula<T>* getChild() const { + std::shared_ptr<AbstractPrctlFormula<T>> const & getChild() const { return child; } private: - Result evaluate(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelchecker, AbstractStateFormula<T> * formula) const { + Result evaluate(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelchecker, std::shared_ptr<AbstractStateFormula<T>> const & formula) const { // First, get the model checking result. Result result; @@ -209,7 +209,7 @@ private: return evaluateActions(result, modelchecker); } - Result evaluate(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelchecker, AbstractPathFormula<T> * formula) const { + Result evaluate(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelchecker, std::shared_ptr<AbstractPathFormula<T>> const & formula) const { // First, get the model checking result. Result result; @@ -224,7 +224,7 @@ private: return evaluateActions(result, modelchecker); } - Result evaluate(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelchecker, AbstractRewardPathFormula<T> * formula) const { + Result evaluate(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelchecker, std::shared_ptr<AbstractRewardPathFormula<T>> const & formula) const { // First, get the model checking result. Result result; @@ -313,7 +313,7 @@ private: std::cout << std::endl << "-------------------------------------------" << std::endl; } - AbstractPrctlFormula<T>* child; + std::shared_ptr<AbstractPrctlFormula<T>> child; }; } //namespace prctl diff --git a/src/formula/prctl/ProbabilisticBoundOperator.h b/src/formula/prctl/ProbabilisticBoundOperator.h index e1c325ef2..0fbe1339c 100644 --- a/src/formula/prctl/ProbabilisticBoundOperator.h +++ b/src/formula/prctl/ProbabilisticBoundOperator.h @@ -71,7 +71,7 @@ public: * @param bound The bound for the probability * @param pathFormula The child node */ - ProbabilisticBoundOperator(storm::property::ComparisonType comparisonOperator, T bound, AbstractPathFormula<T>* pathFormula) + ProbabilisticBoundOperator(storm::property::ComparisonType comparisonOperator, T bound, std::shared_ptr<AbstractPathFormula<T>> const & pathFormula) : comparisonOperator(comparisonOperator), bound(bound), pathFormula(pathFormula) { // Intentionally left empty. } @@ -79,13 +79,10 @@ public: /*! * Destructor * - * The subtree is deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) + * Deletes the subtree iff this object is the last remaining owner of the subtree. */ virtual ~ProbabilisticBoundOperator() { - if (pathFormula != nullptr) { - delete pathFormula; - } + // Intentionally left empty. } /*! @@ -95,11 +92,11 @@ public: * * @returns a new AND-object that is identical the called object. */ - virtual AbstractStateFormula<T>* clone() const override { - ProbabilisticBoundOperator<T>* result = new ProbabilisticBoundOperator<T>(); - result->setComparisonOperator(this->getComparisonOperator()); - result->setBound(this->getBound()); - result->setPathFormula(this->getPathFormula().clone()); + virtual std::shared_ptr<AbstractStateFormula<T>> clone() const override { + std::shared_ptr<ProbabilisticBoundOperator<T>> result(new ProbabilisticBoundOperator<T>()); + result->setComparisonOperator(comparisonOperator); + result->setBound(bound); + result->setPathFormula(pathFormula->clone()); return result; } @@ -112,7 +109,7 @@ public: * * @returns A bit vector indicating all states that satisfy the formula represented by the called object. */ - virtual storm::storage::BitVector check(const storm::modelchecker::prctl::AbstractModelChecker<T>& modelChecker) const override { + virtual storm::storage::BitVector check(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelChecker) const override { return modelChecker.template as<IProbabilisticBoundOperatorModelChecker>()->checkProbabilisticBoundOperator(*this); } @@ -122,8 +119,8 @@ public: * @param checker Formula checker object. * @return true iff the subtree conforms to some logic. */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { - return checker.validate(this->pathFormula); + virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { + return checker.validate(pathFormula); } /*! @@ -148,8 +145,8 @@ public: /*! * @returns the child node (representation of a formula) */ - const AbstractPathFormula<T>& getPathFormula () const { - return *pathFormula; + std::shared_ptr<AbstractPathFormula<T>> const & getPathFormula () const { + return pathFormula; } /*! @@ -157,7 +154,7 @@ public: * * @param pathFormula the path formula that becomes the new child node */ - void setPathFormula(AbstractPathFormula<T>* pathFormula) { + void setPathFormula(std::shared_ptr<AbstractPathFormula<T>> const & pathFormula) { this->pathFormula = pathFormula; } @@ -166,13 +163,13 @@ public: * @return True if the path formula is set, i.e. it does not point to nullptr; false otherwise */ bool pathFormulaIsSet() const { - return pathFormula != nullptr; + return pathFormula.get() != nullptr; } /*! * @returns the comparison relation */ - const storm::property::ComparisonType getComparisonOperator() const { + storm::property::ComparisonType const getComparisonOperator() const { return comparisonOperator; } @@ -183,7 +180,7 @@ public: /*! * @returns the bound for the measure */ - const T& getBound() const { + T const & getBound() const { return bound; } @@ -209,7 +206,7 @@ public: private: storm::property::ComparisonType comparisonOperator; T bound; - AbstractPathFormula<T>* pathFormula; + std::shared_ptr<AbstractPathFormula<T>> pathFormula; }; } //namespace prctl diff --git a/src/formula/prctl/ReachabilityReward.h b/src/formula/prctl/ReachabilityReward.h index 5f88343da..eacc49e3e 100644 --- a/src/formula/prctl/ReachabilityReward.h +++ b/src/formula/prctl/ReachabilityReward.h @@ -64,20 +64,17 @@ public: * * @param child The child node */ - ReachabilityReward(AbstractStateFormula<T>* child) : child(child){ + ReachabilityReward(std::shared_ptr<AbstractStateFormula<T>> child) : child(child){ // Intentionally left empty } /*! - * Constructor. + * Destructor. * - * Also deletes the subtree. - * (this behaviour can be prevented by setting the subtrees to nullptr before deletion) + * Deletes the subtree iff this object is the last remaining owner of the subtree. */ virtual ~ReachabilityReward() { - if (child != nullptr) { - delete child; - } + // Intentionally left empty. } /*! @@ -87,10 +84,10 @@ public: * * @returns a new ReachabilityReward-object that is identical the called object. */ - virtual AbstractRewardPathFormula<T>* clone() const override { - ReachabilityReward<T>* result = new ReachabilityReward<T>(); + virtual std::shared_ptr<AbstractRewardPathFormula<T>> clone() const override { + std::shared_ptr<ReachabilityReward<T>> result(new ReachabilityReward<T>()); if (this->childIsSet()) { - result->setChild(this->getChild().clone()); + result->setChild(child->clone()); } return result; } @@ -104,7 +101,7 @@ public: * * @returns A vector indicating the probability that the formula holds for each state. */ - virtual std::vector<T> check(const storm::modelchecker::prctl::AbstractModelChecker<T>& modelChecker, bool qualitative) const override { + virtual std::vector<T> check(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelChecker, bool qualitative) const override { return modelChecker.template as<IReachabilityRewardModelChecker>()->checkReachabilityReward(*this, qualitative); } @@ -123,22 +120,22 @@ public: * @param checker Formula checker object. * @return true iff the subtree conforms to some logic. */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { return checker.validate(this->child); } /*! * @returns the child node */ - const AbstractStateFormula<T>& getChild() const { - return *child; + std::shared_ptr<AbstractStateFormula<T>> const & getChild() const { + return child; } /*! * Sets the subtree * @param child the new child node */ - void setChild(AbstractStateFormula<T>* child) { + void setChild(std::shared_ptr<AbstractStateFormula<T>> const & child) { this->child = child; } @@ -147,11 +144,11 @@ public: * @return True if the child node is set, i.e. it does not point to nullptr; false otherwise */ bool childIsSet() const { - return child != nullptr; + return child.get() != nullptr; } private: - AbstractStateFormula<T>* child; + std::shared_ptr<AbstractStateFormula<T>> child; }; } //namespace prctl diff --git a/src/formula/prctl/RewardBoundOperator.h b/src/formula/prctl/RewardBoundOperator.h index ac9b721cc..15fbd5886 100644 --- a/src/formula/prctl/RewardBoundOperator.h +++ b/src/formula/prctl/RewardBoundOperator.h @@ -69,7 +69,7 @@ public: * @param bound The bound for the probability * @param pathFormula The child node */ - RewardBoundOperator(storm::property::ComparisonType comparisonOperator, T bound, AbstractRewardPathFormula<T>* pathFormula) + RewardBoundOperator(storm::property::ComparisonType comparisonOperator, T bound, std::shared_ptr<AbstractRewardPathFormula<T>> const & pathFormula) : comparisonOperator(comparisonOperator), bound(bound), pathFormula(pathFormula) { // Intentionally left empty } @@ -77,13 +77,10 @@ public: /*! * Destructor * - * The subtree is deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) + * Deletes the subtree iff this object is the last remaining owner of the subtree. */ virtual ~RewardBoundOperator() { - if (pathFormula != nullptr) { - delete pathFormula; - } + // Intentionally left empty. } /*! @@ -93,11 +90,11 @@ public: * * @returns a new AND-object that is identical the called object. */ - virtual AbstractStateFormula<T>* clone() const override { - RewardBoundOperator<T>* result = new RewardBoundOperator<T>(); - result->setComparisonOperator(this->getComparisonOperator()); - result->setBound(this->getBound()); - result->setPathFormula(this->getPathFormula().clone()); + virtual std::shared_ptr<AbstractStateFormula<T>> clone() const override { + std::shared_ptr<RewardBoundOperator<T>> result(new RewardBoundOperator<T>()); + result->setComparisonOperator(comparisonOperator); + result->setBound(bound); + result->setPathFormula(pathFormula->clone()); return result; } @@ -110,7 +107,7 @@ public: * * @returns A bit vector indicating all states that satisfy the formula represented by the called object. */ - virtual storm::storage::BitVector check(const storm::modelchecker::prctl::AbstractModelChecker<T>& modelChecker) const override { + virtual storm::storage::BitVector check(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelChecker) const override { return modelChecker.template as<IRewardBoundOperatorModelChecker>()->checkRewardBoundOperator(*this); } @@ -120,7 +117,7 @@ public: * @param checker Formula checker object. * @return true iff the subtree conforms to some logic. */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { return checker.validate(this->pathFormula); } @@ -130,10 +127,10 @@ public: virtual std::string toString() const override { std::string result = "R "; switch (comparisonOperator) { - case LESS: result += "<"; break; - case LESS_EQUAL: result += "<="; break; - case GREATER: result += ">"; break; - case GREATER_EQUAL: result += ">="; break; + case LESS: result += "<"; break; + case LESS_EQUAL: result += "<="; break; + case GREATER: result += ">"; break; + case GREATER_EQUAL: result += ">="; break; } result += " "; result += std::to_string(bound); @@ -146,8 +143,8 @@ public: /*! * @returns the child node (representation of a formula) */ - const AbstractRewardPathFormula<T>& getPathFormula () const { - return *pathFormula; + std::shared_ptr<AbstractRewardPathFormula<T>> const & getPathFormula () const { + return pathFormula; } /*! @@ -155,7 +152,7 @@ public: * * @param pathFormula the path formula that becomes the new child node */ - void setPathFormula(AbstractRewardPathFormula<T>* pathFormula) { + void setPathFormula(std::shared_ptr<AbstractRewardPathFormula<T>> const & pathFormula) { this->pathFormula = pathFormula; } @@ -164,13 +161,13 @@ public: * @return True if the path formula is set, i.e. it does not point to nullptr; false otherwise */ bool pathFormulaIsSet() const { - return pathFormula != nullptr; + return pathFormula.get() != nullptr; } /*! * @returns the comparison relation */ - const storm::property::ComparisonType getComparisonOperator() const { + storm::property::ComparisonType const getComparisonOperator() const { return comparisonOperator; } @@ -181,7 +178,7 @@ public: /*! * @returns the bound for the measure */ - const T& getBound() const { + T const & getBound() const { return bound; } @@ -196,18 +193,18 @@ public: bool meetsBound(T value) const { switch (comparisonOperator) { - case LESS: return value < bound; break; - case LESS_EQUAL: return value <= bound; break; - case GREATER: return value > bound; break; - case GREATER_EQUAL: return value >= bound; break; - default: return false; + case LESS: return value < bound; break; + case LESS_EQUAL: return value <= bound; break; + case GREATER: return value > bound; break; + case GREATER_EQUAL: return value >= bound; break; + default: return false; } } private: storm::property::ComparisonType comparisonOperator; T bound; - AbstractRewardPathFormula<T>* pathFormula; + std::shared_ptr<AbstractRewardPathFormula<T>> pathFormula; }; } //namespace prctl diff --git a/src/formula/prctl/SteadyStateReward.h b/src/formula/prctl/SteadyStateReward.h index 86624d876..d7dfc5416 100644 --- a/src/formula/prctl/SteadyStateReward.h +++ b/src/formula/prctl/SteadyStateReward.h @@ -50,11 +50,11 @@ public: * Empty constructor */ SteadyStateReward() { - // Intentionally left empty - + // Intentionally left empty. } + virtual ~SteadyStateReward() { - // Intentionally left empty + // Intentionally left empty. } /*! @@ -64,8 +64,9 @@ public: * * @returns a new SteadyState-object that is identical the called object. */ - virtual AbstractRewardPathFormula<T>* clone() const override { - return new SteadyStateReward<T>(); + virtual std::shared_ptr<AbstractRewardPathFormula<T>> clone() const override { + std::shared_ptr<SteadyStateReward<T>> result(new SteadyStateReward<T>()); + return result; } /*! @@ -77,7 +78,7 @@ public: * * @returns A vector indicating the probability that the formula holds for each state. */ - virtual std::vector<T> check(const storm::modelchecker::prctl::AbstractModelChecker<T>& modelChecker, bool qualitative) const override { + virtual std::vector<T> check(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelChecker, bool qualitative) const override { return modelChecker.template as<ISteadyStateRewardModelChecker>()->checkSteadyStateReward(*this, qualitative); } @@ -96,7 +97,7 @@ public: * @param checker Formula checker object. * @return true */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { + virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { return true; } }; diff --git a/src/formula/prctl/Until.h b/src/formula/prctl/Until.h index 1bca7037b..3d8a5f4e2 100644 --- a/src/formula/prctl/Until.h +++ b/src/formula/prctl/Until.h @@ -70,23 +70,17 @@ public: * @param left The left formula subtree * @param right The left formula subtree */ - Until(AbstractStateFormula<T>* left, AbstractStateFormula<T>* right) : left(left), right(right){ + Until(std::shared_ptr<AbstractStateFormula<T>> const & left, std::shared_ptr<AbstractStateFormula<T>> const & right) : left(left), right(right){ // Intentionally left empty. } /*! * Destructor. * - * Also deletes the subtrees. - * (this behaviour can be prevented by setting the subtrees to NULL before deletion) + * Deletes the subtrees iff this object is the last remaining owner of the subtree to be deleted. */ virtual ~Until() { - if (left != NULL) { - delete left; - } - if (right != NULL) { - delete right; - } + // Intentionally left empty. } /*! @@ -96,13 +90,13 @@ public: * * @returns a new BoundedUntil-object that is identical the called object. */ - virtual AbstractPathFormula<T>* clone() const override { - Until<T>* result = new Until(); + virtual std::shared_ptr<AbstractPathFormula<T>> clone() const override { + std::shared_ptr<Until<T>> result(new Until()); if (this->leftIsSet()) { - result->setLeft(this->getLeft().clone()); + result->setLeft(left->clone()); } if (this->rightIsSet()) { - result->setRight(this->getRight().clone()); + result->setRight(right->clone()); } return result; } @@ -116,7 +110,7 @@ public: * * @returns A vector indicating the probability that the formula holds for each state. */ - virtual std::vector<T> check(const storm::modelchecker::prctl::AbstractModelChecker<T>& modelChecker, bool qualitative) const override { + virtual std::vector<T> check(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelChecker, bool qualitative) const override { return modelChecker.template as<IUntilModelChecker>()->checkUntil(*this, qualitative); } @@ -136,8 +130,8 @@ public: * @param checker Formula checker object. * @return true iff all subtrees conform to some logic. */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { - return checker.validate(this->left) && checker.validate(this->right); + virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { + return checker.validate(left) && checker.validate(right); } /*! @@ -145,7 +139,7 @@ public: * * @param newLeft the new left child. */ - void setLeft(AbstractStateFormula<T>* newLeft) { + void setLeft(std::shared_ptr<AbstractStateFormula<T>> const & newLeft) { left = newLeft; } @@ -154,22 +148,22 @@ public: * * @param newRight the new right child. */ - void setRight(AbstractStateFormula<T>* newRight) { + void setRight(std::shared_ptr<AbstractStateFormula<T>> const & newRight) { right = newRight; } /*! * @returns a pointer to the left child node */ - const AbstractStateFormula<T>& getLeft() const { - return *left; + std::shared_ptr<AbstractStateFormula<T>> const & getLeft() const { + return left; } /*! * @returns a pointer to the right child node */ - const AbstractStateFormula<T>& getRight() const { - return *right; + std::shared_ptr<AbstractStateFormula<T>> const & getRight() const { + return right; } /*! @@ -177,7 +171,7 @@ public: * @return True if the left child is set, i.e. it does not point to nullptr; false otherwise */ bool leftIsSet() const { - return left != nullptr; + return left.get() != nullptr; } /*! @@ -185,12 +179,12 @@ public: * @return True if the right child is set, i.e. it does not point to nullptr; false otherwise */ bool rightIsSet() const { - return right != nullptr; + return right.get() != nullptr; } private: - AbstractStateFormula<T>* left; - AbstractStateFormula<T>* right; + std::shared_ptr<AbstractStateFormula<T>> left; + std::shared_ptr<AbstractStateFormula<T>> right; }; } //namespace prctl diff --git a/src/modelchecker/csl/AbstractModelChecker.h b/src/modelchecker/csl/AbstractModelChecker.h index 3e6fcf546..af7d28f86 100644 --- a/src/modelchecker/csl/AbstractModelChecker.h +++ b/src/modelchecker/csl/AbstractModelChecker.h @@ -134,8 +134,8 @@ public: * @returns The set of states satisfying the formula represented by a bit vector. */ storm::storage::BitVector checkAnd(storm::property::csl::And<Type> const& formula) const { - storm::storage::BitVector result = formula.getLeft().check(*this); - storm::storage::BitVector right = formula.getRight().check(*this); + storm::storage::BitVector result = formula.getLeft()->check(*this); + storm::storage::BitVector right = formula.getRight()->check(*this); result &= right; return result; } @@ -147,8 +147,8 @@ public: * @returns The set of states satisfying the formula represented by a bit vector. */ storm::storage::BitVector checkOr(storm::property::csl::Or<Type> const& formula) const { - storm::storage::BitVector result = formula.getLeft().check(*this); - storm::storage::BitVector right = formula.getRight().check(*this); + storm::storage::BitVector result = formula.getLeft()->check(*this); + storm::storage::BitVector right = formula.getRight()->check(*this); result |= right; return result; } @@ -160,7 +160,7 @@ public: * @returns The set of states satisfying the formula represented by a bit vector. */ storm::storage::BitVector checkNot(const storm::property::csl::Not<Type>& formula) const { - storm::storage::BitVector result = formula.getChild().check(*this); + storm::storage::BitVector result = formula.getChild()->check(*this); result.complement(); return result; } @@ -174,7 +174,7 @@ public: */ virtual storm::storage::BitVector checkProbabilisticBoundOperator(storm::property::csl::ProbabilisticBoundOperator<Type> const& formula) const { // First, we need to compute the probability for satisfying the path formula for each state. - std::vector<Type> quantitativeResult = formula.getPathFormula().check(*this, false); + std::vector<Type> quantitativeResult = formula.getPathFormula()->check(*this, false); // Create resulting bit vector that will hold the yes/no-answer for every state. storm::storage::BitVector result(quantitativeResult.size()); diff --git a/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h b/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h index e5aa4d075..0b4c6bd43 100644 --- a/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h +++ b/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h @@ -65,7 +65,7 @@ public: } // First, we need to compute the probability for satisfying the path formula for each state. - std::vector<ValueType> quantitativeResult = formula.getPathFormula().check(*this, false); + std::vector<ValueType> quantitativeResult = formula.getPathFormula()->check(*this, false); //Remove the minimizing operator entry from the stack. this->minimumOperatorStack.pop(); @@ -91,8 +91,8 @@ public: throw storm::exceptions::InvalidArgumentException() << "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."; } - storm::storage::BitVector leftStates = formula.getLeft().check(*this); - storm::storage::BitVector rightStates = formula.getRight().check(*this); + storm::storage::BitVector leftStates = formula.getLeft()->check(*this); + storm::storage::BitVector rightStates = formula.getRight()->check(*this); return computeUnboundedUntilProbabilities(this->minimumOperatorStack.top(), leftStates, rightStates, qualitative).first; } @@ -111,7 +111,7 @@ public: throw storm::exceptions::InvalidArgumentException() << "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."; } - storm::storage::BitVector goalStates = formula.getChild().check(*this); + storm::storage::BitVector goalStates = formula.getChild()->check(*this); return this->checkTimeBoundedEventually(this->minimumOperatorStack.top(), goalStates, formula.getLowerBound(), formula.getUpperBound()); } @@ -126,7 +126,7 @@ public: throw storm::exceptions::InvalidArgumentException() << "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."; } - storm::storage::BitVector subFormulaStates = formula.getChild().check(*this); + storm::storage::BitVector subFormulaStates = formula.getChild()->check(*this); return computeUnboundedUntilProbabilities(this->minimumOperatorStack.top(), storm::storage::BitVector(this->getModel().getNumberOfStates(), true), subFormulaStates, qualitative).first; } diff --git a/src/modelchecker/prctl/AbstractModelChecker.h b/src/modelchecker/prctl/AbstractModelChecker.h index e877cc672..7158ee9ff 100644 --- a/src/modelchecker/prctl/AbstractModelChecker.h +++ b/src/modelchecker/prctl/AbstractModelChecker.h @@ -149,8 +149,8 @@ public: * @return The set of states satisfying the formula represented by a bit vector. */ storm::storage::BitVector checkAnd(storm::property::prctl::And<Type> const& formula) const { - storm::storage::BitVector result = formula.getLeft().check(*this); - storm::storage::BitVector right = formula.getRight().check(*this); + storm::storage::BitVector result = formula.getLeft()->check(*this); + storm::storage::BitVector right = formula.getRight()->check(*this); result &= right; return result; } @@ -162,8 +162,8 @@ public: * @return The set of states satisfying the formula represented by a bit vector. */ storm::storage::BitVector checkOr(storm::property::prctl::Or<Type> const& formula) const { - storm::storage::BitVector result = formula.getLeft().check(*this); - storm::storage::BitVector right = formula.getRight().check(*this); + storm::storage::BitVector result = formula.getLeft()->check(*this); + storm::storage::BitVector right = formula.getRight()->check(*this); result |= right; return result; } @@ -175,7 +175,7 @@ public: * @return The set of states satisfying the formula represented by a bit vector. */ storm::storage::BitVector checkNot(const storm::property::prctl::Not<Type>& formula) const { - storm::storage::BitVector result = formula.getChild().check(*this); + storm::storage::BitVector result = formula.getChild()->check(*this); result.complement(); return result; } @@ -189,7 +189,7 @@ public: */ virtual storm::storage::BitVector checkProbabilisticBoundOperator(storm::property::prctl::ProbabilisticBoundOperator<Type> const& formula) const { // First, we need to compute the probability for satisfying the path formula for each state. - std::vector<Type> quantitativeResult = formula.getPathFormula().check(*this, false); + std::vector<Type> quantitativeResult = formula.getPathFormula()->check(*this, false); // Create resulting bit vector that will hold the yes/no-answer for every state. storm::storage::BitVector result(quantitativeResult.size()); @@ -213,7 +213,7 @@ public: */ virtual storm::storage::BitVector checkRewardBoundOperator(const storm::property::prctl::RewardBoundOperator<Type>& formula) const { // First, we need to compute the probability for satisfying the path formula for each state. - std::vector<Type> quantitativeResult = formula.getPathFormula().check(*this, false); + std::vector<Type> quantitativeResult = formula.getPathFormula()->check(*this, false); // Create resulting bit vector that will hold the yes/no-answer for every state. storm::storage::BitVector result(quantitativeResult.size()); diff --git a/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h b/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h index acdb6945c..74557fbea 100644 --- a/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h +++ b/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h @@ -72,7 +72,7 @@ public: * checker. If the qualitative flag is set, exact probabilities might not be computed. */ virtual std::vector<Type> checkBoundedUntil(storm::property::prctl::BoundedUntil<Type> const& formula, bool qualitative) const { - return this->checkBoundedUntil(formula.getLeft().check(*this), formula.getRight().check(*this), formula.getBound(), qualitative); + return this->checkBoundedUntil(formula.getLeft()->check(*this), formula.getRight()->check(*this), formula.getBound(), qualitative); } /*! @@ -147,7 +147,7 @@ public: */ virtual std::vector<Type> checkNext(storm::property::prctl::Next<Type> const& formula, bool qualitative) const { // First, we need to compute the states that satisfy the child formula of the next-formula. - storm::storage::BitVector nextStates = formula.getChild().check(*this); + storm::storage::BitVector nextStates = formula.getChild()->check(*this); // Create the vector with which to multiply and initialize it correctly. std::vector<Type> result(this->getModel().getNumberOfStates()); @@ -175,7 +175,7 @@ public: * checker. If the qualitative flag is set, exact probabilities might not be computed. */ virtual std::vector<Type> checkBoundedEventually(storm::property::prctl::BoundedEventually<Type> const& formula, bool qualitative) const { - return this->checkBoundedUntil(storm::storage::BitVector(this->getModel().getNumberOfStates(), true), formula.getChild().check(*this), formula.getBound(), qualitative); + return this->checkBoundedUntil(storm::storage::BitVector(this->getModel().getNumberOfStates(), true), formula.getChild()->check(*this), formula.getBound(), qualitative); } /*! @@ -191,7 +191,7 @@ public: */ virtual std::vector<Type> checkEventually(storm::property::prctl::Eventually<Type> const& formula, bool qualitative) const { // Create equivalent temporary until formula and check it. - storm::property::prctl::Until<Type> temporaryUntilFormula(new storm::property::prctl::Ap<Type>("true"), formula.getChild().clone()); + storm::property::prctl::Until<Type> temporaryUntilFormula(std::shared_ptr<storm::property::prctl::Ap<Type>>(new storm::property::prctl::Ap<Type>("true")), formula.getChild()); return this->checkUntil(temporaryUntilFormula, qualitative); } @@ -208,7 +208,7 @@ public: */ virtual std::vector<Type> checkGlobally(storm::property::prctl::Globally<Type> const& formula, bool qualitative) const { // Create "equivalent" (equivalent up to negation) temporary eventually formula and check it. - storm::property::prctl::Eventually<Type> temporaryEventuallyFormula(new storm::property::prctl::Not<Type>(formula.getChild().clone())); + storm::property::prctl::Eventually<Type> temporaryEventuallyFormula(std::shared_ptr<storm::property::prctl::Not<Type>>(new storm::property::prctl::Not<Type>(formula.getChild()))); std::vector<Type> result = this->checkEventually(temporaryEventuallyFormula, qualitative); // Now subtract the resulting vector from the constant one vector to obtain final result. @@ -229,7 +229,7 @@ public: * checker. If the qualitative flag is set, exact probabilities might not be computed. */ virtual std::vector<Type> checkUntil(storm::property::prctl::Until<Type> const& formula, bool qualitative) const { - return this->checkUntil(formula.getLeft().check(*this), formula.getRight().check(*this), qualitative); + return this->checkUntil(formula.getLeft()->check(*this), formula.getRight()->check(*this), qualitative); } /*! @@ -405,7 +405,7 @@ public: } // Determine the states for which the target predicate holds. - storm::storage::BitVector targetStates = formula.getChild().check(*this); + storm::storage::BitVector targetStates = formula.getChild()->check(*this); // Determine which states have a reward of infinity by definition. storm::storage::BitVector trueStates(this->getModel().getNumberOfStates(), true); diff --git a/src/modelchecker/prctl/SparseMdpPrctlModelChecker.h b/src/modelchecker/prctl/SparseMdpPrctlModelChecker.h index c68c1057f..23613d185 100644 --- a/src/modelchecker/prctl/SparseMdpPrctlModelChecker.h +++ b/src/modelchecker/prctl/SparseMdpPrctlModelChecker.h @@ -87,7 +87,7 @@ namespace storm { } // First, we need to compute the probability for satisfying the path formula for each state. - std::vector<Type> quantitativeResult = formula.getPathFormula().check(*this, false); + std::vector<Type> quantitativeResult = formula.getPathFormula()->check(*this, false); //Remove the minimizing operator entry from the stack. this->minimumOperatorStack.pop(); @@ -124,7 +124,7 @@ namespace storm { } // First, we need to compute the probability for satisfying the path formula for each state. - std::vector<Type> quantitativeResult = formula.getPathFormula().check(*this, false); + std::vector<Type> quantitativeResult = formula.getPathFormula()->check(*this, false); //Remove the minimizing operator entry from the stack. this->minimumOperatorStack.pop(); @@ -219,7 +219,7 @@ namespace storm { * checker. If the qualitative flag is set, exact probabilities might not be computed. */ virtual std::vector<Type> checkBoundedUntil(storm::property::prctl::BoundedUntil<Type> const& formula, bool qualitative) const { - return checkBoundedUntil(formula.getLeft().check(*this), formula.getRight().check(*this), formula.getBound(), qualitative); + return checkBoundedUntil(formula.getLeft()->check(*this), formula.getRight()->check(*this), formula.getBound(), qualitative); } /*! @@ -261,7 +261,7 @@ namespace storm { * checker. If the qualitative flag is set, exact probabilities might not be computed. */ virtual std::vector<Type> checkNext(const storm::property::prctl::Next<Type>& formula, bool qualitative) const { - return checkNext(formula.getChild().check(*this), qualitative); + return checkNext(formula.getChild()->check(*this), qualitative); } /*! @@ -277,7 +277,7 @@ namespace storm { */ virtual std::vector<Type> checkBoundedEventually(const storm::property::prctl::BoundedEventually<Type>& formula, bool qualitative) const { // Create equivalent temporary bounded until formula and check it. - storm::property::prctl::BoundedUntil<Type> temporaryBoundedUntilFormula(new storm::property::prctl::Ap<Type>("true"), formula.getChild().clone(), formula.getBound()); + storm::property::prctl::BoundedUntil<Type> temporaryBoundedUntilFormula(std::shared_ptr<storm::property::prctl::Ap<Type>>(new storm::property::prctl::Ap<Type>("true")), formula.getChild(), formula.getBound()); return this->checkBoundedUntil(temporaryBoundedUntilFormula, qualitative); } @@ -294,7 +294,7 @@ namespace storm { */ virtual std::vector<Type> checkEventually(const storm::property::prctl::Eventually<Type>& formula, bool qualitative) const { // Create equivalent temporary until formula and check it. - storm::property::prctl::Until<Type> temporaryUntilFormula(new storm::property::prctl::Ap<Type>("true"), formula.getChild().clone()); + storm::property::prctl::Until<Type> temporaryUntilFormula(std::shared_ptr<storm::property::prctl::Ap<Type>>(new storm::property::prctl::Ap<Type>("true")), formula.getChild()); return this->checkUntil(temporaryUntilFormula, qualitative); } @@ -311,7 +311,7 @@ namespace storm { */ virtual std::vector<Type> checkGlobally(const storm::property::prctl::Globally<Type>& formula, bool qualitative) const { // Create "equivalent" temporary eventually formula and check it. - storm::property::prctl::Eventually<Type> temporaryEventuallyFormula(new storm::property::prctl::Not<Type>(formula.getChild().clone())); + storm::property::prctl::Eventually<Type> temporaryEventuallyFormula(std::shared_ptr<storm::property::prctl::Not<Type>>(new storm::property::prctl::Not<Type>(formula.getChild()))); std::vector<Type> result = this->checkEventually(temporaryEventuallyFormula, qualitative); // Now subtract the resulting vector from the constant one vector to obtain final result. @@ -340,7 +340,7 @@ namespace storm { throw storm::exceptions::InvalidArgumentException() << "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."; } - return this->checkUntil(this->minimumOperatorStack.top(), formula.getLeft().check(*this), formula.getRight().check(*this), qualitative).first; + return this->checkUntil(this->minimumOperatorStack.top(), formula.getLeft()->check(*this), formula.getRight()->check(*this), qualitative).first; } /*! @@ -525,7 +525,7 @@ namespace storm { throw storm::exceptions::InvalidArgumentException() << "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."; } - return this->checkReachabilityReward(this->minimumOperatorStack.top(), formula.getChild().check(*this), qualitative).first; + return this->checkReachabilityReward(this->minimumOperatorStack.top(), formula.getChild()->check(*this), qualitative).first; } /*! diff --git a/src/models/Dtmc.h b/src/models/Dtmc.h index b599774f9..b43800342 100644 --- a/src/models/Dtmc.h +++ b/src/models/Dtmc.h @@ -133,7 +133,7 @@ public: * Waring: If the vector does not have the correct size, it will be resized. * @return The sub-Dtmc. */ - storm::models::Dtmc<T> getSubDtmc(storm::storage::BitVector& subSysStates) { + storm::models::Dtmc<T> getSubDtmc(storm::storage::BitVector& subSysStates) const { // Is there any state in the subsystem? @@ -159,7 +159,7 @@ public: } // 1. Get all necessary information from the old transition matrix - storm::storage::SparseMatrix<T> const& origMat = this->getTransitionMatrix(); + storm::storage::SparseMatrix<T> const & origMat = this->getTransitionMatrix(); // Iterate over all rows. Count the number of all transitions from the old system to be // transfered to the new one. Also build a mapping from the state number of the old system diff --git a/src/parser/CslParser.cpp b/src/parser/CslParser.cpp index 00a1c1db4..c28d31b0a 100644 --- a/src/parser/CslParser.cpp +++ b/src/parser/CslParser.cpp @@ -36,16 +36,18 @@ // Some typedefs and namespace definitions to reduce code size. +#define MAKE(Type, ...) phoenix::construct<std::shared_ptr<Type>>(phoenix::new_<Type>(__VA_ARGS__)) typedef std::string::const_iterator BaseIteratorType; typedef boost::spirit::classic::position_iterator2<BaseIteratorType> PositionIteratorType; namespace qi = boost::spirit::qi; namespace phoenix = boost::phoenix; +namespace csl = storm::property::csl; namespace storm { namespace parser { template<typename Iterator, typename Skipper> -struct CslParser::CslGrammar : qi::grammar<Iterator, storm::property::csl::CslFilter<double>*(), Skipper > { +struct CslParser::CslGrammar : qi::grammar<Iterator, std::shared_ptr<csl::CslFilter<double>>(), Skipper > { CslGrammar() : CslGrammar::base_type(start) { //This block contains helper rules that may be used several times freeIdentifierName = qi::lexeme[qi::alpha >> *(qi::alnum | qi::char_('_'))]; @@ -65,13 +67,13 @@ struct CslParser::CslGrammar : qi::grammar<Iterator, storm::property::csl::CslFi stateFormula %= orFormula; stateFormula.name("state formula"); orFormula = andFormula[qi::_val = qi::_1] > *(qi::lit("|") > andFormula)[qi::_val = - phoenix::new_<storm::property::csl::Or<double>>(qi::_val, qi::_1)]; + MAKE(csl::Or<double>, qi::_val, qi::_1)]; orFormula.name("or formula"); andFormula = notFormula[qi::_val = qi::_1] > *(qi::lit("&") > notFormula)[qi::_val = - phoenix::new_<storm::property::csl::And<double>>(qi::_val, qi::_1)]; + MAKE(csl::And<double>, qi::_val, qi::_1)]; andFormula.name("and formula"); notFormula = atomicStateFormula[qi::_val = qi::_1] | (qi::lit("!") > atomicStateFormula)[qi::_val = - phoenix::new_<storm::property::csl::Not<double>>(qi::_1)]; + MAKE(csl::Not<double>, qi::_1)]; notFormula.name("not formula"); //This block defines rules for "atomic" state formulas @@ -79,16 +81,16 @@ struct CslParser::CslGrammar : qi::grammar<Iterator, storm::property::csl::CslFi atomicStateFormula %= probabilisticBoundOperator | steadyStateBoundOperator | atomicProposition | qi::lit("(") >> stateFormula >> qi::lit(")"); atomicStateFormula.name("atomic state formula"); atomicProposition = (freeIdentifierName)[qi::_val = - phoenix::new_<storm::property::csl::Ap<double>>(qi::_1)]; + MAKE(csl::Ap<double>, qi::_1)]; atomicProposition.name("atomic proposition"); probabilisticBoundOperator = ( (qi::lit("P") >> comparisonType > qi::double_ > qi::lit("[") > pathFormula > qi::lit("]"))[qi::_val = - phoenix::new_<storm::property::csl::ProbabilisticBoundOperator<double> >(qi::_1, qi::_2, qi::_3)] + MAKE(csl::ProbabilisticBoundOperator<double> , qi::_1, qi::_2, qi::_3)] ); probabilisticBoundOperator.name("probabilistic bound operator"); steadyStateBoundOperator = ( (qi::lit("S") >> comparisonType > qi::double_ > qi::lit("[") > stateFormula > qi::lit("]"))[qi::_val = - phoenix::new_<storm::property::csl::SteadyStateBoundOperator<double> >(qi::_1, qi::_2, qi::_3)] + MAKE(csl::SteadyStateBoundOperator<double> , qi::_1, qi::_2, qi::_3)] ); steadyStateBoundOperator.name("steady state bound operator"); @@ -97,33 +99,33 @@ struct CslParser::CslGrammar : qi::grammar<Iterator, storm::property::csl::CslFi pathFormula.name("path formula"); timeBoundedEventually = ( (qi::lit("F") >> qi::lit("[") > qi::double_ > qi::lit(",") > qi::double_ > qi::lit("]") > stateFormula)[qi::_val = - phoenix::new_<storm::property::csl::TimeBoundedEventually<double>>(qi::_1, qi::_2, qi::_3)] | + MAKE(csl::TimeBoundedEventually<double>, qi::_1, qi::_2, qi::_3)] | (qi::lit("F") >> (qi::lit("<=") | qi::lit("<")) > qi::double_ > stateFormula)[qi::_val = - phoenix::new_<storm::property::csl::TimeBoundedEventually<double>>(0, qi::_1, qi::_2)] | + MAKE(csl::TimeBoundedEventually<double>, 0, qi::_1, qi::_2)] | (qi::lit("F") >> (qi::lit(">=") | qi::lit(">")) > qi::double_ > stateFormula)[qi::_val = - phoenix::new_<storm::property::csl::TimeBoundedEventually<double>>(qi::_1, std::numeric_limits<double>::infinity(), qi::_2)] + MAKE(csl::TimeBoundedEventually<double>, qi::_1, std::numeric_limits<double>::infinity(), qi::_2)] ); timeBoundedEventually.name("time bounded eventually"); eventually = (qi::lit("F") > stateFormula)[qi::_val = - phoenix::new_<storm::property::csl::Eventually<double> >(qi::_1)]; + MAKE(csl::Eventually<double> , qi::_1)]; eventually.name("eventually"); next = (qi::lit("X") > stateFormula)[qi::_val = - phoenix::new_<storm::property::csl::Next<double> >(qi::_1)]; + MAKE(csl::Next<double> , qi::_1)]; next.name("next"); globally = (qi::lit("G") > stateFormula)[qi::_val = - phoenix::new_<storm::property::csl::Globally<double> >(qi::_1)]; + MAKE(csl::Globally<double> , qi::_1)]; globally.name("globally"); timeBoundedUntil = ( - (stateFormula[qi::_a = phoenix::construct<std::shared_ptr<storm::property::csl::AbstractStateFormula<double>>>(qi::_1)] >> qi::lit("U") >> qi::lit("[") > qi::double_ > qi::lit(",") > qi::double_ > qi::lit("]") > stateFormula) - [qi::_val = phoenix::new_<storm::property::csl::TimeBoundedUntil<double>>(qi::_2, qi::_3, phoenix::bind(&storm::property::csl::AbstractStateFormula<double>::clone, phoenix::bind(&std::shared_ptr<storm::property::csl::AbstractStateFormula<double>>::get, qi::_a)), qi::_4)] | - (stateFormula[qi::_a = phoenix::construct<std::shared_ptr<storm::property::csl::AbstractStateFormula<double>>>(qi::_1)] >> qi::lit("U") >> (qi::lit("<=") | qi::lit("<")) > qi::double_ > stateFormula) - [qi::_val = phoenix::new_<storm::property::csl::TimeBoundedUntil<double>>(0, qi::_2, phoenix::bind(&storm::property::csl::AbstractStateFormula<double>::clone, phoenix::bind(&std::shared_ptr<storm::property::csl::AbstractStateFormula<double>>::get, qi::_a)), qi::_3)] | - (stateFormula[qi::_a = phoenix::construct<std::shared_ptr<storm::property::csl::AbstractStateFormula<double>>>(qi::_1)] >> qi::lit("U") >> (qi::lit(">=") | qi::lit(">")) > qi::double_ > stateFormula) - [qi::_val = phoenix::new_<storm::property::csl::TimeBoundedUntil<double>>(qi::_2, std::numeric_limits<double>::infinity(), phoenix::bind(&storm::property::csl::AbstractStateFormula<double>::clone, phoenix::bind(&std::shared_ptr<storm::property::csl::AbstractStateFormula<double>>::get, qi::_a)), qi::_3)] + (stateFormula[qi::_a = qi::_1] >> qi::lit("U") >> qi::lit("[") > qi::double_ > qi::lit(",") > qi::double_ > qi::lit("]") > stateFormula) + [qi::_val = MAKE(csl::TimeBoundedUntil<double>, qi::_2, qi::_3, qi::_a, qi::_4)] | + (stateFormula[qi::_a = qi::_1] >> qi::lit("U") >> (qi::lit("<=") | qi::lit("<")) > qi::double_ > stateFormula) + [qi::_val = MAKE(csl::TimeBoundedUntil<double>, 0, qi::_2, qi::_a, qi::_3)] | + (stateFormula[qi::_a = qi::_1] >> qi::lit("U") >> (qi::lit(">=") | qi::lit(">")) > qi::double_ > stateFormula) + [qi::_val = MAKE(csl::TimeBoundedUntil<double>, qi::_2, std::numeric_limits<double>::infinity(), qi::_a, qi::_3)] ); timeBoundedUntil.name("time bounded until"); - until = (stateFormula[qi::_a = phoenix::construct<std::shared_ptr<storm::property::csl::AbstractStateFormula<double>>>(qi::_1)] >> qi::lit("U") > stateFormula)[qi::_val = - phoenix::new_<storm::property::csl::Until<double>>(phoenix::bind(&storm::property::csl::AbstractStateFormula<double>::clone, phoenix::bind(&std::shared_ptr<storm::property::csl::AbstractStateFormula<double>>::get, qi::_a)), qi::_2)]; + until = (stateFormula[qi::_a = qi::_1] >> qi::lit("U") > stateFormula)[qi::_val = + MAKE(csl::Until<double>, qi::_a, qi::_2)]; until.name("until formula"); formula = (pathFormula | stateFormula); @@ -134,14 +136,14 @@ struct CslParser::CslGrammar : qi::grammar<Iterator, storm::property::csl::CslFi noBoundOperator.name("no bound operator"); probabilisticNoBoundOperator = (qi::lit("P") >> qi::lit("min") >> qi::lit("=") >> qi::lit("?") >> qi::lit("[") >> pathFormula >> qi::lit("]"))[qi::_val = - phoenix::new_<storm::property::csl::CslFilter<double>>(qi::_1, storm::property::MINIMIZE)] | + MAKE(csl::CslFilter<double>, qi::_1, storm::property::MINIMIZE)] | (qi::lit("P") >> qi::lit("max") >> qi::lit("=") >> qi::lit("?") >> qi::lit("[") >> pathFormula >> qi::lit("]"))[qi::_val = - phoenix::new_<storm::property::csl::CslFilter<double>>(qi::_1, storm::property::MAXIMIZE)] | + MAKE(csl::CslFilter<double>, qi::_1, storm::property::MAXIMIZE)] | (qi::lit("P") >> qi::lit("=") >> qi::lit("?") >> qi::lit("[") >> pathFormula >> qi::lit("]"))[qi::_val = - phoenix::new_<storm::property::csl::CslFilter<double>>(qi::_1)]; + MAKE(csl::CslFilter<double>, qi::_1)]; probabilisticNoBoundOperator.name("probabilistic no bound operator"); steadyStateNoBoundOperator = (qi::lit("S") >> qi::lit("=") >> qi::lit("?") >> qi::lit("[") >> stateFormula >> qi::lit("]"))[qi::_val = - phoenix::new_<storm::property::csl::CslFilter<double>>(qi::_1, storm::property::UNDEFINED, true)]; + MAKE(csl::CslFilter<double>, qi::_1, storm::property::UNDEFINED, true)]; steadyStateNoBoundOperator.name("steady state no bound operator"); // This block defines rules for parsing filter actions. @@ -178,11 +180,11 @@ struct CslParser::CslGrammar : qi::grammar<Iterator, storm::property::csl::CslFi abstractAction.name("filter action"); filter = (qi::lit("filter") >> qi::lit("[") >> +abstractAction >> qi::lit("]") >> qi::lit("(") >> formula >> qi::lit(")"))[qi::_val = - phoenix::new_<storm::property::csl::CslFilter<double>>(qi::_2, qi::_1)] | + MAKE(csl::CslFilter<double>, qi::_2, qi::_1)] | (noBoundOperator)[qi::_val = qi::_1] | (formula)[qi::_val = - phoenix::new_<storm::property::csl::CslFilter<double>>(qi::_1)]; + MAKE(csl::CslFilter<double>, qi::_1)]; filter.name("CSL formula filter"); @@ -191,12 +193,12 @@ struct CslParser::CslGrammar : qi::grammar<Iterator, storm::property::csl::CslFi } - qi::rule<Iterator, storm::property::csl::CslFilter<double>*(), Skipper> start; - qi::rule<Iterator, storm::property::csl::CslFilter<double>*(), Skipper> filter; + qi::rule<Iterator, std::shared_ptr<csl::CslFilter<double>>(), Skipper> start; + qi::rule<Iterator, std::shared_ptr<csl::CslFilter<double>>(), Skipper> filter; - qi::rule<Iterator, storm::property::csl::CslFilter<double>*(), Skipper> noBoundOperator; - qi::rule<Iterator, storm::property::csl::CslFilter<double>*(), Skipper> probabilisticNoBoundOperator; - qi::rule<Iterator, storm::property::csl::CslFilter<double>*(), Skipper> steadyStateNoBoundOperator; + qi::rule<Iterator, std::shared_ptr<csl::CslFilter<double>>(), Skipper> noBoundOperator; + qi::rule<Iterator, std::shared_ptr<csl::CslFilter<double>>(), Skipper> probabilisticNoBoundOperator; + qi::rule<Iterator, std::shared_ptr<csl::CslFilter<double>>(), Skipper> steadyStateNoBoundOperator; qi::rule<Iterator, storm::property::action::AbstractAction<double>*(), Skipper> abstractAction; qi::rule<Iterator, storm::property::action::BoundAction<double>*(), Skipper> boundAction; @@ -205,26 +207,26 @@ struct CslParser::CslGrammar : qi::grammar<Iterator, storm::property::csl::CslFi qi::rule<Iterator, storm::property::action::RangeAction<double>*(), Skipper> rangeAction; qi::rule<Iterator, storm::property::action::SortAction<double>*(), Skipper> sortAction; - qi::rule<Iterator, storm::property::csl::AbstractCslFormula<double>*(), Skipper> formula; - qi::rule<Iterator, storm::property::csl::AbstractCslFormula<double>*(), Skipper> comment; + qi::rule<Iterator, std::shared_ptr<csl::AbstractCslFormula<double>>(), Skipper> formula; + qi::rule<Iterator, std::shared_ptr<csl::AbstractCslFormula<double>>(), Skipper> comment; - qi::rule<Iterator, storm::property::csl::AbstractStateFormula<double>*(), Skipper> stateFormula; - qi::rule<Iterator, storm::property::csl::AbstractStateFormula<double>*(), Skipper> atomicStateFormula; + qi::rule<Iterator, std::shared_ptr<csl::AbstractStateFormula<double>>(), Skipper> stateFormula; + qi::rule<Iterator, std::shared_ptr<csl::AbstractStateFormula<double>>(), Skipper> atomicStateFormula; - qi::rule<Iterator, storm::property::csl::AbstractStateFormula<double>*(), Skipper> andFormula; - qi::rule<Iterator, storm::property::csl::AbstractStateFormula<double>*(), Skipper> atomicProposition; - qi::rule<Iterator, storm::property::csl::AbstractStateFormula<double>*(), Skipper> orFormula; - qi::rule<Iterator, storm::property::csl::AbstractStateFormula<double>*(), Skipper> notFormula; - qi::rule<Iterator, storm::property::csl::ProbabilisticBoundOperator<double>*(), Skipper> probabilisticBoundOperator; - qi::rule<Iterator, storm::property::csl::SteadyStateBoundOperator<double>*(), Skipper> steadyStateBoundOperator; + qi::rule<Iterator, std::shared_ptr<csl::AbstractStateFormula<double>>(), Skipper> andFormula; + qi::rule<Iterator, std::shared_ptr<csl::AbstractStateFormula<double>>(), Skipper> atomicProposition; + qi::rule<Iterator, std::shared_ptr<csl::AbstractStateFormula<double>>(), Skipper> orFormula; + qi::rule<Iterator, std::shared_ptr<csl::AbstractStateFormula<double>>(), Skipper> notFormula; + qi::rule<Iterator, std::shared_ptr<csl::ProbabilisticBoundOperator<double>>(), Skipper> probabilisticBoundOperator; + qi::rule<Iterator, std::shared_ptr<csl::SteadyStateBoundOperator<double>>(), Skipper> steadyStateBoundOperator; - qi::rule<Iterator, storm::property::csl::AbstractPathFormula<double>*(), Skipper> pathFormula; - qi::rule<Iterator, storm::property::csl::TimeBoundedEventually<double>*(), Skipper> timeBoundedEventually; - qi::rule<Iterator, storm::property::csl::Eventually<double>*(), Skipper> eventually; - qi::rule<Iterator, storm::property::csl::Next<double>*(), Skipper> next; - qi::rule<Iterator, storm::property::csl::Globally<double>*(), Skipper> globally; - qi::rule<Iterator, storm::property::csl::TimeBoundedUntil<double>*(), qi::locals< std::shared_ptr<storm::property::csl::AbstractStateFormula<double>>>, Skipper> timeBoundedUntil; - qi::rule<Iterator, storm::property::csl::Until<double>*(), qi::locals< std::shared_ptr<storm::property::csl::AbstractStateFormula<double>>>, Skipper> until; + qi::rule<Iterator, std::shared_ptr<csl::AbstractPathFormula<double>>(), Skipper> pathFormula; + qi::rule<Iterator, std::shared_ptr<csl::TimeBoundedEventually<double>>(), Skipper> timeBoundedEventually; + qi::rule<Iterator, std::shared_ptr<csl::Eventually<double>>(), Skipper> eventually; + qi::rule<Iterator, std::shared_ptr<csl::Next<double>>(), Skipper> next; + qi::rule<Iterator, std::shared_ptr<csl::Globally<double>>(), Skipper> globally; + qi::rule<Iterator, std::shared_ptr<csl::TimeBoundedUntil<double>>(), qi::locals< std::shared_ptr<storm::property::csl::AbstractStateFormula<double>>>, Skipper> timeBoundedUntil; + qi::rule<Iterator, std::shared_ptr<csl::Until<double>>(), qi::locals< std::shared_ptr<storm::property::csl::AbstractStateFormula<double>>>, Skipper> until; qi::rule<Iterator, std::string(), Skipper> freeIdentifierName; @@ -233,7 +235,7 @@ struct CslParser::CslGrammar : qi::grammar<Iterator, storm::property::csl::CslFi }; -storm::property::csl::CslFilter<double>* CslParser::parseCslFormula(std::string formulaString) { +std::shared_ptr<storm::property::csl::CslFilter<double>> CslParser::parseCslFormula(std::string formulaString) { // Prepare iterators to input. BaseIteratorType stringIteratorBegin = formulaString.begin(); BaseIteratorType stringIteratorEnd = formulaString.end(); @@ -242,7 +244,7 @@ storm::property::csl::CslFilter<double>* CslParser::parseCslFormula(std::string // Prepare resulting intermediate representation of input. - storm::property::csl::CslFilter<double>* result_pointer = nullptr; + std::shared_ptr<storm::property::csl::CslFilter<double>> result_pointer(nullptr); CslGrammar<PositionIteratorType, BOOST_TYPEOF(boost::spirit::ascii::space)> grammar; @@ -279,7 +281,7 @@ storm::property::csl::CslFilter<double>* CslParser::parseCslFormula(std::string // The syntax can be so wrong that no rule can be matched at all // In that case, no expectation failure is thrown, but the parser just returns nullptr // Then, of course the result is not usable, hence we throw a WrongFormatException, too. - if (result_pointer == nullptr) { + if (!result_pointer) { throw storm::exceptions::WrongFormatException() << "Syntax error in formula"; } diff --git a/src/parser/CslParser.h b/src/parser/CslParser.h index 0960f742f..9e9b85da5 100644 --- a/src/parser/CslParser.h +++ b/src/parser/CslParser.h @@ -27,7 +27,7 @@ public: * @param formulaString The string representation of the formula * @throw wrongFormatException If the input could not be parsed successfully */ - static storm::property::csl::CslFilter<double>* parseCslFormula(std::string formulaString); + static std::shared_ptr<storm::property::csl::CslFilter<double>> parseCslFormula(std::string formulaString); private: diff --git a/src/parser/LtlFileParser.cpp b/src/parser/LtlFileParser.cpp index 8ede743a8..e056a99ee 100644 --- a/src/parser/LtlFileParser.cpp +++ b/src/parser/LtlFileParser.cpp @@ -15,7 +15,7 @@ namespace storm { namespace parser { -std::list<storm::property::ltl::LtlFilter<double>*> LtlFileParser::parseLtlFile(std::string filename) { +std::list<std::shared_ptr<storm::property::ltl::LtlFilter<double>>> LtlFileParser::parseLtlFile(std::string filename) { // Open file std::ifstream inputFileStream(filename, std::ios::in); @@ -24,7 +24,7 @@ std::list<storm::property::ltl::LtlFilter<double>*> LtlFileParser::parseLtlFile( throw storm::exceptions::FileIoException() << message << filename; } - std::list<storm::property::ltl::LtlFilter<double>*> result; + std::list<std::shared_ptr<storm::property::ltl::LtlFilter<double>>> result; while(!inputFileStream.eof()) { std::string line; diff --git a/src/parser/LtlFileParser.h b/src/parser/LtlFileParser.h index b8375ecec..2fd73d10f 100644 --- a/src/parser/LtlFileParser.h +++ b/src/parser/LtlFileParser.h @@ -25,7 +25,7 @@ public: * @param filename * @return The list of parsed formulas */ - static std::list<storm::property::ltl::LtlFilter<double>*> parseLtlFile(std::string filename); + static std::list<std::shared_ptr<storm::property::ltl::LtlFilter<double>>> parseLtlFile(std::string filename); }; } //namespace parser diff --git a/src/parser/LtlParser.cpp b/src/parser/LtlParser.cpp index 2c7e09a06..3bc614243 100644 --- a/src/parser/LtlParser.cpp +++ b/src/parser/LtlParser.cpp @@ -36,11 +36,12 @@ // Some typedefs and namespace definitions to reduce code size. +#define MAKE(Type, ...) phoenix::construct<std::shared_ptr<Type>>(phoenix::new_<Type>(__VA_ARGS__)) typedef std::string::const_iterator BaseIteratorType; typedef boost::spirit::classic::position_iterator2<BaseIteratorType> PositionIteratorType; namespace qi = boost::spirit::qi; namespace phoenix = boost::phoenix; - +namespace ltl = storm::property::ltl; namespace storm { @@ -48,7 +49,7 @@ namespace storm { namespace parser { template<typename Iterator, typename Skipper> -struct LtlParser::LtlGrammar : qi::grammar<Iterator, storm::property::ltl::LtlFilter<double>*(), Skipper > { +struct LtlParser::LtlGrammar : qi::grammar<Iterator, std::shared_ptr<storm::property::ltl::LtlFilter<double>>(), Skipper > { LtlGrammar() : LtlGrammar::base_type(start) { //This block contains helper rules that may be used several times freeIdentifierName = qi::lexeme[qi::alpha >> *(qi::alnum | qi::char_('_'))]; @@ -70,16 +71,16 @@ struct LtlParser::LtlGrammar : qi::grammar<Iterator, storm::property::ltl::LtlFi formula %= orFormula; formula.name("LTL formula"); orFormula = andFormula[qi::_val = qi::_1] > *(qi::lit("|") > andFormula)[qi::_val = - phoenix::new_<storm::property::ltl::Or<double>>(qi::_val, qi::_1)]; + MAKE(ltl::Or<double>, qi::_val, qi::_1)]; orFormula.name("LTL formula"); andFormula = untilFormula[qi::_val = qi::_1] > *(qi::lit("&") > untilFormula)[qi::_val = - phoenix::new_<storm::property::ltl::And<double>>(qi::_val, qi::_1)]; + MAKE(ltl::And<double>, qi::_val, qi::_1)]; andFormula.name("LTL formula"); untilFormula = notFormula[qi::_val = qi::_1] > - *((qi::lit("U") >> qi::lit("<=") > qi::int_ > notFormula)[qi::_val = phoenix::new_<storm::property::ltl::BoundedUntil<double>>(qi::_val, qi::_2, qi::_1)] | - (qi::lit("U") > notFormula)[qi::_val = phoenix::new_<storm::property::ltl::Until<double>>(qi::_val, qi::_1)]); + *((qi::lit("U") >> qi::lit("<=") > qi::int_ > notFormula)[qi::_val = MAKE(ltl::BoundedUntil<double>, qi::_val, qi::_2, qi::_1)] | + (qi::lit("U") > notFormula)[qi::_val = MAKE(ltl::Until<double>, qi::_val, qi::_1)]); notFormula = atomicLtlFormula[qi::_val = qi::_1] | (qi::lit("!") > atomicLtlFormula)[qi::_val = - phoenix::new_<storm::property::ltl::Not<double>>(qi::_1)]; + MAKE(ltl::Not<double>, qi::_1)]; notFormula.name("LTL formula"); //This block defines rules for "atomic" state formulas @@ -87,23 +88,23 @@ struct LtlParser::LtlGrammar : qi::grammar<Iterator, storm::property::ltl::LtlFi atomicLtlFormula %= pathFormula | atomicProposition | qi::lit("(") >> formula >> qi::lit(")"); atomicLtlFormula.name("LTL formula"); atomicProposition = (freeIdentifierName)[qi::_val = - phoenix::new_<storm::property::ltl::Ap<double>>(qi::_1)]; + MAKE(ltl::Ap<double>, qi::_1)]; atomicProposition.name("LTL formula"); //This block defines rules for parsing probabilistic path formulas pathFormula = (boundedEventually | eventually | globally | next); pathFormula.name("LTL formula"); boundedEventually = (qi::lit("F") >> qi::lit("<=") > qi::int_ > formula)[qi::_val = - phoenix::new_<storm::property::ltl::BoundedEventually<double>>(qi::_2, qi::_1)]; + MAKE(ltl::BoundedEventually<double>, qi::_2, qi::_1)]; boundedEventually.name("LTL formula"); eventually = (qi::lit("F") >> formula)[qi::_val = - phoenix::new_<storm::property::ltl::Eventually<double> >(qi::_1)]; + MAKE(ltl::Eventually<double>, qi::_1)]; eventually.name("LTL formula"); globally = (qi::lit("G") >> formula)[qi::_val = - phoenix::new_<storm::property::ltl::Globally<double> >(qi::_1)]; + MAKE(ltl::Globally<double>, qi::_1)]; globally.name("LTL formula"); next = (qi::lit("X") >> formula)[qi::_val = - phoenix::new_<storm::property::ltl::Next<double> >(qi::_1)]; + MAKE(ltl::Next<double>, qi::_1)]; next.name("LTL formula"); // This block defines rules for parsing filter actions. @@ -136,21 +137,21 @@ struct LtlParser::LtlGrammar : qi::grammar<Iterator, storm::property::ltl::LtlFi abstractAction.name("filter action"); filter = (qi::lit("filter") >> qi::lit("[") >> +abstractAction >> qi::lit("]") > qi::lit("(") >> formula >> qi::lit(")"))[qi::_val = - phoenix::new_<storm::property::ltl::LtlFilter<double>>(qi::_2, qi::_1)] | + MAKE(ltl::LtlFilter<double>, qi::_2, qi::_1)] | (qi::lit("filter") >> qi::lit("[") >> qi::lit("max") > +abstractAction >> qi::lit("]") >> qi::lit("(") >> formula >> qi::lit(")"))[qi::_val = - phoenix::new_<storm::property::ltl::LtlFilter<double>>(qi::_2, qi::_1, storm::property::MAXIMIZE)] | + MAKE(ltl::LtlFilter<double>, qi::_2, qi::_1, storm::property::MAXIMIZE)] | (qi::lit("filter") >> qi::lit("[") >> qi::lit("min") > +abstractAction >> qi::lit("]") >> qi::lit("(") >> formula >> qi::lit(")"))[qi::_val = - phoenix::new_<storm::property::ltl::LtlFilter<double>>(qi::_2, qi::_1, storm::property::MINIMIZE)] | + MAKE(ltl::LtlFilter<double>, qi::_2, qi::_1, storm::property::MINIMIZE)] | (formula)[qi::_val = - phoenix::new_<storm::property::ltl::LtlFilter<double>>(qi::_1)]; + MAKE(ltl::LtlFilter<double>, qi::_1)]; filter.name("PRCTL formula filter"); - start = (((filter) > (comment | qi::eps))[qi::_val = qi::_1] | comment[qi::_val = nullptr] ) > qi::eoi; + start = (((filter) > (comment | qi::eps))[qi::_val = qi::_1] | comment[qi::_val = MAKE(ltl::LtlFilter<double>, nullptr)] ) > qi::eoi; start.name("LTL formula"); } - qi::rule<Iterator, storm::property::ltl::LtlFilter<double>*(), Skipper> start; - qi::rule<Iterator, storm::property::ltl::LtlFilter<double>*(), Skipper> filter; + qi::rule<Iterator, std::shared_ptr<storm::property::ltl::LtlFilter<double>>(), Skipper> start; + qi::rule<Iterator, std::shared_ptr<storm::property::ltl::LtlFilter<double>>(), Skipper> filter; qi::rule<Iterator, storm::property::action::AbstractAction<double>*(), Skipper> abstractAction; qi::rule<Iterator, storm::property::action::BoundAction<double>*(), Skipper> boundAction; @@ -158,23 +159,23 @@ struct LtlParser::LtlGrammar : qi::grammar<Iterator, storm::property::ltl::LtlFi qi::rule<Iterator, storm::property::action::RangeAction<double>*(), Skipper> rangeAction; qi::rule<Iterator, storm::property::action::SortAction<double>*(), Skipper> sortAction; - qi::rule<Iterator, storm::property::ltl::AbstractLtlFormula<double>*(), Skipper> comment; - qi::rule<Iterator, storm::property::ltl::AbstractLtlFormula<double>*(), Skipper> formula; - qi::rule<Iterator, storm::property::ltl::AbstractLtlFormula<double>*(), Skipper> atomicLtlFormula; + qi::rule<Iterator, std::shared_ptr<storm::property::ltl::AbstractLtlFormula<double>>(), Skipper> comment; + qi::rule<Iterator, std::shared_ptr<storm::property::ltl::AbstractLtlFormula<double>>(), Skipper> formula; + qi::rule<Iterator, std::shared_ptr<storm::property::ltl::AbstractLtlFormula<double>>(), Skipper> atomicLtlFormula; - qi::rule<Iterator, storm::property::ltl::AbstractLtlFormula<double>*(), Skipper> andFormula; - qi::rule<Iterator, storm::property::ltl::AbstractLtlFormula<double>*(), Skipper> untilFormula; - qi::rule<Iterator, storm::property::ltl::AbstractLtlFormula<double>*(), Skipper> atomicProposition; - qi::rule<Iterator, storm::property::ltl::AbstractLtlFormula<double>*(), Skipper> orFormula; - qi::rule<Iterator, storm::property::ltl::AbstractLtlFormula<double>*(), Skipper> notFormula; + qi::rule<Iterator, std::shared_ptr<storm::property::ltl::AbstractLtlFormula<double>>(), Skipper> andFormula; + qi::rule<Iterator, std::shared_ptr<storm::property::ltl::AbstractLtlFormula<double>>(), Skipper> untilFormula; + qi::rule<Iterator, std::shared_ptr<storm::property::ltl::AbstractLtlFormula<double>>(), Skipper> atomicProposition; + qi::rule<Iterator, std::shared_ptr<storm::property::ltl::AbstractLtlFormula<double>>(), Skipper> orFormula; + qi::rule<Iterator, std::shared_ptr<storm::property::ltl::AbstractLtlFormula<double>>(), Skipper> notFormula; - qi::rule<Iterator, storm::property::ltl::AbstractLtlFormula<double>*(), Skipper> pathFormula; - qi::rule<Iterator, storm::property::ltl::BoundedEventually<double>*(), Skipper> boundedEventually; - qi::rule<Iterator, storm::property::ltl::Eventually<double>*(), Skipper> eventually; - qi::rule<Iterator, storm::property::ltl::Globally<double>*(), Skipper> globally; - qi::rule<Iterator, storm::property::ltl::Next<double>*(), Skipper> next; - qi::rule<Iterator, storm::property::ltl::AbstractLtlFormula<double>*(), qi::locals< std::shared_ptr<storm::property::ltl::AbstractLtlFormula<double>>>, Skipper> boundedUntil; - qi::rule<Iterator, storm::property::ltl::AbstractLtlFormula<double>*(), qi::locals< std::shared_ptr<storm::property::ltl::AbstractLtlFormula<double>>>, Skipper> until; + qi::rule<Iterator, std::shared_ptr<storm::property::ltl::AbstractLtlFormula<double>>(), Skipper> pathFormula; + qi::rule<Iterator, std::shared_ptr<storm::property::ltl::BoundedEventually<double>>(), Skipper> boundedEventually; + qi::rule<Iterator, std::shared_ptr<storm::property::ltl::Eventually<double>>(), Skipper> eventually; + qi::rule<Iterator, std::shared_ptr<storm::property::ltl::Globally<double>>(), Skipper> globally; + qi::rule<Iterator, std::shared_ptr<storm::property::ltl::Next<double>>(), Skipper> next; + qi::rule<Iterator, std::shared_ptr<storm::property::ltl::AbstractLtlFormula<double>>(), qi::locals< std::shared_ptr<storm::property::ltl::AbstractLtlFormula<double>>>, Skipper> boundedUntil; + qi::rule<Iterator, std::shared_ptr<storm::property::ltl::AbstractLtlFormula<double>>(), qi::locals< std::shared_ptr<storm::property::ltl::AbstractLtlFormula<double>>>, Skipper> until; qi::rule<Iterator, std::string(), Skipper> freeIdentifierName; qi::rule<Iterator, storm::property::ComparisonType(), Skipper> comparisonType; @@ -182,7 +183,7 @@ struct LtlParser::LtlGrammar : qi::grammar<Iterator, storm::property::ltl::LtlFi }; -storm::property::ltl::LtlFilter<double>* LtlParser::parseLtlFormula(std::string formulaString) { +std::shared_ptr<storm::property::ltl::LtlFilter<double>> LtlParser::parseLtlFormula(std::string formulaString) { // Prepare iterators to input. BaseIteratorType stringIteratorBegin = formulaString.begin(); BaseIteratorType stringIteratorEnd = formulaString.end(); @@ -191,7 +192,7 @@ storm::property::ltl::LtlFilter<double>* LtlParser::parseLtlFormula(std::string // Prepare resulting intermediate representation of input. - storm::property::ltl::LtlFilter<double>* result_pointer = nullptr; + std::shared_ptr<storm::property::ltl::LtlFilter<double>> result_pointer(nullptr); LtlGrammar<PositionIteratorType, BOOST_TYPEOF(boost::spirit::ascii::space)> grammar; @@ -228,7 +229,7 @@ storm::property::ltl::LtlFilter<double>* LtlParser::parseLtlFormula(std::string // The syntax can be so wrong that no rule can be matched at all // In that case, no expectation failure is thrown, but the parser just returns nullptr // Then, of course the result is not usable, hence we throw a WrongFormatException, too. - if (result_pointer == nullptr) { + if (!result_pointer) { throw storm::exceptions::WrongFormatException() << "Syntax error in formula"; } diff --git a/src/parser/LtlParser.h b/src/parser/LtlParser.h index d3d8e426f..e5f24dec3 100644 --- a/src/parser/LtlParser.h +++ b/src/parser/LtlParser.h @@ -31,7 +31,7 @@ public: * @param formulaString The string representation of the formula * @throw wrongFormatException If the input could not be parsed successfully */ - static storm::property::ltl::LtlFilter<double>* parseLtlFormula(std::string formulaString); + static std::shared_ptr<storm::property::ltl::LtlFilter<double>> parseLtlFormula(std::string formulaString); private: diff --git a/src/parser/PrctlFileParser.cpp b/src/parser/PrctlFileParser.cpp index ca5905e4e..323d5984b 100644 --- a/src/parser/PrctlFileParser.cpp +++ b/src/parser/PrctlFileParser.cpp @@ -14,7 +14,7 @@ namespace storm { namespace parser { -std::list<storm::property::prctl::PrctlFilter<double>*> PrctlFileParser::parsePrctlFile(std::string filename) { +std::list<std::shared_ptr<storm::property::prctl::PrctlFilter<double>>> PrctlFileParser::parsePrctlFile(std::string filename) { // Open file std::ifstream inputFileStream; inputFileStream.open(filename, std::ios::in); @@ -24,12 +24,12 @@ std::list<storm::property::prctl::PrctlFilter<double>*> PrctlFileParser::parsePr throw storm::exceptions::FileIoException() << message << filename; } - std::list<storm::property::prctl::PrctlFilter<double>*> result; + std::list<std::shared_ptr<storm::property::prctl::PrctlFilter<double>>> result; std::string line; //The while loop reads the input file line by line while (std::getline(inputFileStream, line)) { - storm::property::prctl::PrctlFilter<double>* formula = PrctlParser::parsePrctlFormula(line); + std::shared_ptr<storm::property::prctl::PrctlFilter<double>> formula = PrctlParser::parsePrctlFormula(line); if (formula != nullptr) { //lines containing comments will be skipped. LOG4CPLUS_INFO(logger, "Parsed formula \"" + line + "\" into \"" + formula->toString() + "\""); diff --git a/src/parser/PrctlFileParser.h b/src/parser/PrctlFileParser.h index ad29fe812..c992ddf03 100644 --- a/src/parser/PrctlFileParser.h +++ b/src/parser/PrctlFileParser.h @@ -25,7 +25,7 @@ public: * @param filename * @return The list of parsed formulas */ - static std::list<storm::property::prctl::PrctlFilter<double>*> parsePrctlFile(std::string filename); + static std::list<std::shared_ptr<storm::property::prctl::PrctlFilter<double>>> parsePrctlFile(std::string filename); }; diff --git a/src/parser/PrctlParser.cpp b/src/parser/PrctlParser.cpp index da2336b8b..6f3dc8812 100644 --- a/src/parser/PrctlParser.cpp +++ b/src/parser/PrctlParser.cpp @@ -17,6 +17,7 @@ #include <boost/typeof/typeof.hpp> #include <boost/spirit/include/qi.hpp> #include <boost/spirit/include/phoenix.hpp> +#include <boost/spirit/include/phoenix_function.hpp> // Include headers for spirit iterators. Needed for diagnostics and input stream iteration. #include <boost/spirit/include/classic_position_iterator.hpp> @@ -28,11 +29,13 @@ #include <map> -// Some typedefs and namespace definitions to reduce code size. +// Some typedefs, namespace definitions and a macro to reduce code size. +#define MAKE(Type, ...) phoenix::construct<std::shared_ptr<Type>>(phoenix::new_<Type>(__VA_ARGS__)) typedef std::string::const_iterator BaseIteratorType; typedef boost::spirit::classic::position_iterator2<BaseIteratorType> PositionIteratorType; namespace qi = boost::spirit::qi; namespace phoenix = boost::phoenix; +namespace prctl = storm::property::prctl; namespace storm { @@ -40,7 +43,7 @@ namespace storm { namespace parser { template<typename Iterator, typename Skipper> -struct PrctlParser::PrctlGrammar : qi::grammar<Iterator, storm::property::prctl::PrctlFilter<double>*(), Skipper > { +struct PrctlParser::PrctlGrammar : qi::grammar<Iterator, std::shared_ptr<storm::property::prctl::PrctlFilter<double>>(), Skipper > { PrctlGrammar() : PrctlGrammar::base_type(start) { // This block contains helper rules that may be used several times freeIdentifierName = qi::lexeme[qi::alpha >> *(qi::alnum | qi::char_('_'))]; @@ -60,13 +63,13 @@ struct PrctlParser::PrctlGrammar : qi::grammar<Iterator, storm::property::prctl: stateFormula %= orFormula; stateFormula.name("state formula"); orFormula = andFormula[qi::_val = qi::_1] > *(qi::lit("|") > andFormula)[qi::_val = - phoenix::new_<storm::property::prctl::Or<double>>(qi::_val, qi::_1)]; + MAKE(prctl::Or<double>, qi::_val, qi::_1)]; orFormula.name("or formula"); andFormula = notFormula[qi::_val = qi::_1] > *(qi::lit("&") > notFormula)[qi::_val = - phoenix::new_<storm::property::prctl::And<double>>(qi::_val, qi::_1)]; + MAKE(prctl::And<double>, qi::_val, qi::_1)]; andFormula.name("and formula"); notFormula = atomicStateFormula[qi::_val = qi::_1] | (qi::lit("!") > atomicStateFormula)[qi::_val = - phoenix::new_<storm::property::prctl::Not<double>>(qi::_1)]; + MAKE(prctl::Not<double>, qi::_1)]; notFormula.name("not formula"); // This block defines rules for "atomic" state formulas @@ -74,51 +77,52 @@ struct PrctlParser::PrctlGrammar : qi::grammar<Iterator, storm::property::prctl: atomicStateFormula %= probabilisticBoundOperator | rewardBoundOperator | atomicProposition | qi::lit("(") >> stateFormula >> qi::lit(")") | qi::lit("[") >> stateFormula >> qi::lit("]"); atomicStateFormula.name("atomic state formula"); atomicProposition = (freeIdentifierName)[qi::_val = - phoenix::new_<storm::property::prctl::Ap<double>>(qi::_1)]; + MAKE(prctl::Ap<double>, qi::_1)]; atomicProposition.name("atomic proposition"); probabilisticBoundOperator = ((qi::lit("P") >> comparisonType > qi::double_ > qi::lit("[") > pathFormula > qi::lit("]"))[qi::_val = - phoenix::new_<storm::property::prctl::ProbabilisticBoundOperator<double> >(qi::_1, qi::_2, qi::_3)]); + MAKE(prctl::ProbabilisticBoundOperator<double>, qi::_1, qi::_2, qi::_3)]); probabilisticBoundOperator.name("probabilistic bound operator"); rewardBoundOperator = ((qi::lit("R") >> comparisonType > qi::double_ > qi::lit("[") > rewardPathFormula > qi::lit("]"))[qi::_val = - phoenix::new_<storm::property::prctl::RewardBoundOperator<double> >(qi::_1, qi::_2, qi::_3)]); + MAKE(prctl::RewardBoundOperator<double>, qi::_1, qi::_2, qi::_3)]); rewardBoundOperator.name("reward bound operator"); // This block defines rules for parsing probabilistic path formulas pathFormula = (boundedEventually | eventually | next | globally | boundedUntil | until | qi::lit("(") >> pathFormula >> qi::lit(")") | qi::lit("[") >> pathFormula >> qi::lit("]")); pathFormula.name("path formula"); boundedEventually = (qi::lit("F") >> qi::lit("<=") > qi::int_ > stateFormula)[qi::_val = - phoenix::new_<storm::property::prctl::BoundedEventually<double>>(qi::_2, qi::_1)]; + MAKE(prctl::BoundedEventually<double>, qi::_2, qi::_1)]; boundedEventually.name("path formula (for probabilistic operator)"); eventually = (qi::lit("F") > stateFormula)[qi::_val = - phoenix::new_<storm::property::prctl::Eventually<double> >(qi::_1)]; + MAKE(prctl::Eventually<double>, qi::_1)]; eventually.name("path formula (for probabilistic operator)"); next = (qi::lit("X") > stateFormula)[qi::_val = - phoenix::new_<storm::property::prctl::Next<double> >(qi::_1)]; + MAKE(prctl::Next<double>, qi::_1)]; next.name("path formula (for probabilistic operator)"); globally = (qi::lit("G") > stateFormula)[qi::_val = - phoenix::new_<storm::property::prctl::Globally<double> >(qi::_1)]; + MAKE(prctl::Globally<double>, qi::_1)]; globally.name("path formula (for probabilistic operator)"); - boundedUntil = (stateFormula[qi::_a = phoenix::construct<std::shared_ptr<storm::property::prctl::AbstractStateFormula<double>>>(qi::_1)] >> qi::lit("U") >> qi::lit("<=") > qi::int_ > stateFormula) - [qi::_val = phoenix::new_<storm::property::prctl::BoundedUntil<double>>(phoenix::bind(&storm::property::prctl::AbstractStateFormula<double>::clone, phoenix::bind(&std::shared_ptr<storm::property::prctl::AbstractStateFormula<double>>::get, qi::_a)), qi::_3, qi::_2)]; + boundedUntil = (stateFormula[qi::_a = qi::_1] >> qi::lit("U") >> qi::lit("<=") > qi::int_ > stateFormula)[qi::_val = + MAKE(prctl::BoundedUntil<double>, qi::_a, qi::_3, qi::_2)]; boundedUntil.name("path formula (for probabilistic operator)"); - until = (stateFormula[qi::_a = phoenix::construct<std::shared_ptr<storm::property::prctl::AbstractStateFormula<double>>>(qi::_1)] >> qi::lit("U") > stateFormula)[qi::_val = - phoenix::new_<storm::property::prctl::Until<double>>(phoenix::bind(&storm::property::prctl::AbstractStateFormula<double>::clone, phoenix::bind(&std::shared_ptr<storm::property::prctl::AbstractStateFormula<double>>::get, qi::_a)), qi::_2)]; + until = (stateFormula[qi::_a = qi::_1] >> qi::lit("U") > stateFormula)[qi::_val = + MAKE(prctl::Until<double>, qi::_a, qi::_2)]; until.name("path formula (for probabilistic operator)"); // This block defines rules for parsing reward path formulas. rewardPathFormula = (cumulativeReward | reachabilityReward | instantaneousReward | steadyStateReward | qi::lit("(") >> rewardPathFormula >> qi::lit(")") | qi::lit("[") >> rewardPathFormula >> qi::lit("]")); rewardPathFormula.name("path formula (for reward operator)"); cumulativeReward = (qi::lit("C") > qi::lit("<=") > qi::double_)[qi::_val = - phoenix::new_<storm::property::prctl::CumulativeReward<double>>(qi::_1)]; + MAKE(prctl::CumulativeReward<double>, qi::_1)]; cumulativeReward.name("path formula (for reward operator)"); reachabilityReward = (qi::lit("F") > stateFormula)[qi::_val = - phoenix::new_<storm::property::prctl::ReachabilityReward<double>>(qi::_1)]; + MAKE(prctl::ReachabilityReward<double>, qi::_1)]; reachabilityReward.name("path formula (for reward operator)"); instantaneousReward = (qi::lit("I") > qi::lit("=") > qi::double_)[qi::_val = - phoenix::new_<storm::property::prctl::InstantaneousReward<double>>(qi::_1)]; + MAKE(prctl::InstantaneousReward<double>, qi::_1)]; instantaneousReward.name("path formula (for reward operator)"); - steadyStateReward = (qi::lit("S"))[qi::_val = phoenix::new_<storm::property::prctl::SteadyStateReward<double>>()]; + steadyStateReward = (qi::lit("S"))[qi::_val = + MAKE(prctl::SteadyStateReward<double>, )]; formula = (pathFormula | stateFormula); formula.name("PRCTL formula"); @@ -130,21 +134,21 @@ struct PrctlParser::PrctlGrammar : qi::grammar<Iterator, storm::property::prctl: noBoundOperator.name("no bound operator"); probabilisticNoBoundOperator = ( (qi::lit("P") >> qi::lit("min") >> qi::lit("=") > qi::lit("?") >> pathFormula )[qi::_val = - phoenix::new_<storm::property::prctl::PrctlFilter<double> >(qi::_1, storm::property::MINIMIZE)] | + MAKE(prctl::PrctlFilter<double>, qi::_1, storm::property::MINIMIZE)] | (qi::lit("P") >> qi::lit("max") >> qi::lit("=") > qi::lit("?") >> pathFormula )[qi::_val = - phoenix::new_<storm::property::prctl::PrctlFilter<double> >(qi::_1, storm::property::MAXIMIZE)] | + MAKE(prctl::PrctlFilter<double>, qi::_1, storm::property::MAXIMIZE)] | (qi::lit("P") >> qi::lit("=") > qi::lit("?") >> pathFormula )[qi::_val = - phoenix::new_<storm::property::prctl::PrctlFilter<double> >(qi::_1)] + MAKE(prctl::PrctlFilter<double>, qi::_1)] ); probabilisticNoBoundOperator.name("no bound operator"); rewardNoBoundOperator = ( (qi::lit("R") >> qi::lit("min") >> qi::lit("=") > qi::lit("?") >> rewardPathFormula )[qi::_val = - phoenix::new_<storm::property::prctl::PrctlFilter<double> >(qi::_1, storm::property::MINIMIZE)] | + MAKE(prctl::PrctlFilter<double>, qi::_1, storm::property::MINIMIZE)] | (qi::lit("R") >> qi::lit("max") >> qi::lit("=") > qi::lit("?") >> rewardPathFormula )[qi::_val = - phoenix::new_<storm::property::prctl::PrctlFilter<double> >(qi::_1, storm::property::MAXIMIZE)] | + MAKE(prctl::PrctlFilter<double>, qi::_1, storm::property::MAXIMIZE)] | (qi::lit("R") >> qi::lit("=") >> qi::lit("?") >> rewardPathFormula )[qi::_val = - phoenix::new_<storm::property::prctl::PrctlFilter<double> >(qi::_1)] + MAKE(prctl::PrctlFilter<double>, qi::_1)] ); rewardNoBoundOperator.name("no bound operator"); @@ -184,28 +188,28 @@ struct PrctlParser::PrctlGrammar : qi::grammar<Iterator, storm::property::prctl: abstractAction.name("filter action"); filter = (qi::lit("filter") >> qi::lit("[") >> +abstractAction >> qi::lit("]") > qi::lit("(") >> formula >> qi::lit(")"))[qi::_val = - phoenix::new_<storm::property::prctl::PrctlFilter<double>>(qi::_2, qi::_1)] | + MAKE(prctl::PrctlFilter<double>, qi::_2, qi::_1)] | (qi::lit("filter") >> qi::lit("[") >> qi::lit("max") > +abstractAction >> qi::lit("]") >> qi::lit("(") >> formula >> qi::lit(")"))[qi::_val = - phoenix::new_<storm::property::prctl::PrctlFilter<double>>(qi::_2, qi::_1, storm::property::MAXIMIZE)] | + MAKE(prctl::PrctlFilter<double>, qi::_2, qi::_1, storm::property::MAXIMIZE)] | (qi::lit("filter") >> qi::lit("[") >> qi::lit("min") > +abstractAction >> qi::lit("]") >> qi::lit("(") >> formula >> qi::lit(")"))[qi::_val = - phoenix::new_<storm::property::prctl::PrctlFilter<double>>(qi::_2, qi::_1, storm::property::MINIMIZE)] | + MAKE(prctl::PrctlFilter<double>, qi::_2, qi::_1, storm::property::MINIMIZE)] | (noBoundOperator)[qi::_val = qi::_1] | (formula)[qi::_val = - phoenix::new_<storm::property::prctl::PrctlFilter<double>>(qi::_1)]; + MAKE(prctl::PrctlFilter<double>, qi::_1)]; filter.name("PRCTL formula filter"); - start = (((filter) > (comment | qi::eps))[qi::_val = qi::_1] | comment[qi::_val = nullptr]) > qi::eoi; + start = (((filter) > (comment | qi::eps))[qi::_val = qi::_1] | comment[qi::_val = MAKE(prctl::PrctlFilter<double>, nullptr)]) > qi::eoi; start.name("PRCTL formula filter"); } - qi::rule<Iterator, storm::property::prctl::PrctlFilter<double>*(), Skipper> start; - qi::rule<Iterator, storm::property::prctl::PrctlFilter<double>*(), Skipper> filter; + qi::rule<Iterator, std::shared_ptr<storm::property::prctl::PrctlFilter<double>>(), Skipper> start; + qi::rule<Iterator, std::shared_ptr<storm::property::prctl::PrctlFilter<double>>(), Skipper> filter; - qi::rule<Iterator, storm::property::prctl::PrctlFilter<double>*(), Skipper> noBoundOperator; - qi::rule<Iterator, storm::property::prctl::PrctlFilter<double>*(), Skipper> probabilisticNoBoundOperator; - qi::rule<Iterator, storm::property::prctl::PrctlFilter<double>*(), Skipper> rewardNoBoundOperator; + qi::rule<Iterator, std::shared_ptr<storm::property::prctl::PrctlFilter<double>>(), Skipper> noBoundOperator; + qi::rule<Iterator, std::shared_ptr<storm::property::prctl::PrctlFilter<double>>(), Skipper> probabilisticNoBoundOperator; + qi::rule<Iterator, std::shared_ptr<storm::property::prctl::PrctlFilter<double>>(), Skipper> rewardNoBoundOperator; qi::rule<Iterator, storm::property::action::AbstractAction<double>*(), Skipper> abstractAction; qi::rule<Iterator, storm::property::action::BoundAction<double>*(), Skipper> boundAction; @@ -214,41 +218,40 @@ struct PrctlParser::PrctlGrammar : qi::grammar<Iterator, storm::property::prctl: qi::rule<Iterator, storm::property::action::RangeAction<double>*(), Skipper> rangeAction; qi::rule<Iterator, storm::property::action::SortAction<double>*(), Skipper> sortAction; - qi::rule<Iterator, storm::property::prctl::AbstractPrctlFormula<double>*(), Skipper> formula; - qi::rule<Iterator, storm::property::prctl::AbstractPrctlFormula<double>*(), Skipper> comment; + qi::rule<Iterator, std::shared_ptr<storm::property::prctl::AbstractPrctlFormula<double>>(), Skipper> formula; + qi::rule<Iterator, std::shared_ptr<storm::property::prctl::AbstractPrctlFormula<double>>(), Skipper> comment; - qi::rule<Iterator, storm::property::prctl::AbstractStateFormula<double>*(), Skipper> stateFormula; - qi::rule<Iterator, storm::property::prctl::AbstractStateFormula<double>*(), Skipper> atomicStateFormula; + qi::rule<Iterator, std::shared_ptr<storm::property::prctl::AbstractStateFormula<double>>(), Skipper> stateFormula; + qi::rule<Iterator, std::shared_ptr<storm::property::prctl::AbstractStateFormula<double>>(), Skipper> atomicStateFormula; - qi::rule<Iterator, storm::property::prctl::AbstractStateFormula<double>*(), Skipper> andFormula; - qi::rule<Iterator, storm::property::prctl::AbstractStateFormula<double>*(), Skipper> atomicProposition; - qi::rule<Iterator, storm::property::prctl::AbstractStateFormula<double>*(), Skipper> orFormula; - qi::rule<Iterator, storm::property::prctl::AbstractStateFormula<double>*(), Skipper> notFormula; - qi::rule<Iterator, storm::property::prctl::ProbabilisticBoundOperator<double>*(), Skipper> probabilisticBoundOperator; - qi::rule<Iterator, storm::property::prctl::RewardBoundOperator<double>*(), Skipper> rewardBoundOperator; + qi::rule<Iterator, std::shared_ptr<storm::property::prctl::AbstractStateFormula<double>>(), Skipper> andFormula; + qi::rule<Iterator, std::shared_ptr<storm::property::prctl::AbstractStateFormula<double>>(), Skipper> atomicProposition; + qi::rule<Iterator, std::shared_ptr<storm::property::prctl::AbstractStateFormula<double>>(), Skipper> orFormula; + qi::rule<Iterator, std::shared_ptr<storm::property::prctl::AbstractStateFormula<double>>(), Skipper> notFormula; + qi::rule<Iterator, std::shared_ptr<storm::property::prctl::ProbabilisticBoundOperator<double>>(), Skipper> probabilisticBoundOperator; + qi::rule<Iterator, std::shared_ptr<storm::property::prctl::RewardBoundOperator<double>>(), Skipper> rewardBoundOperator; - qi::rule<Iterator, storm::property::prctl::AbstractPathFormula<double>*(), Skipper> pathFormula; - qi::rule<Iterator, storm::property::prctl::BoundedEventually<double>*(), Skipper> boundedEventually; - qi::rule<Iterator, storm::property::prctl::Eventually<double>*(), Skipper> eventually; - qi::rule<Iterator, storm::property::prctl::Next<double>*(), Skipper> next; - qi::rule<Iterator, storm::property::prctl::Globally<double>*(), Skipper> globally; - qi::rule<Iterator, storm::property::prctl::BoundedUntil<double>*(), qi::locals< std::shared_ptr<storm::property::prctl::AbstractStateFormula<double>>>, Skipper> boundedUntil; - qi::rule<Iterator, storm::property::prctl::Until<double>*(), qi::locals< std::shared_ptr<storm::property::prctl::AbstractStateFormula<double>>>, Skipper> until; + qi::rule<Iterator, std::shared_ptr<storm::property::prctl::AbstractPathFormula<double>>(), Skipper> pathFormula; + qi::rule<Iterator, std::shared_ptr<storm::property::prctl::BoundedEventually<double>>(), Skipper> boundedEventually; + qi::rule<Iterator, std::shared_ptr<storm::property::prctl::Eventually<double>>(), Skipper> eventually; + qi::rule<Iterator, std::shared_ptr<storm::property::prctl::Next<double>>(), Skipper> next; + qi::rule<Iterator, std::shared_ptr<storm::property::prctl::Globally<double>>(), Skipper> globally; + qi::rule<Iterator, std::shared_ptr<storm::property::prctl::BoundedUntil<double>>(), qi::locals< std::shared_ptr<storm::property::prctl::AbstractStateFormula<double>>>, Skipper> boundedUntil; + qi::rule<Iterator, std::shared_ptr<storm::property::prctl::Until<double>>(), qi::locals< std::shared_ptr<storm::property::prctl::AbstractStateFormula<double>>>, Skipper> until; - qi::rule<Iterator, storm::property::prctl::AbstractRewardPathFormula<double>*(), Skipper> rewardPathFormula; - qi::rule<Iterator, storm::property::prctl::CumulativeReward<double>*(), Skipper> cumulativeReward; - qi::rule<Iterator, storm::property::prctl::ReachabilityReward<double>*(), Skipper> reachabilityReward; - qi::rule<Iterator, storm::property::prctl::InstantaneousReward<double>*(), Skipper> instantaneousReward; - qi::rule<Iterator, storm::property::prctl::SteadyStateReward<double>*(), Skipper> steadyStateReward; + qi::rule<Iterator, std::shared_ptr<storm::property::prctl::AbstractRewardPathFormula<double>>(), Skipper> rewardPathFormula; + qi::rule<Iterator, std::shared_ptr<storm::property::prctl::CumulativeReward<double>>(), Skipper> cumulativeReward; + qi::rule<Iterator, std::shared_ptr<storm::property::prctl::ReachabilityReward<double>>(), Skipper> reachabilityReward; + qi::rule<Iterator, std::shared_ptr<storm::property::prctl::InstantaneousReward<double>>(), Skipper> instantaneousReward; + qi::rule<Iterator, std::shared_ptr<storm::property::prctl::SteadyStateReward<double>>(), Skipper> steadyStateReward; qi::rule<Iterator, std::string(), Skipper> freeIdentifierName; qi::rule<Iterator, storm::property::ComparisonType(), Skipper> comparisonType; qi::rule<Iterator, storm::property::action::SortAction<double>::SortingCategory(), Skipper> sortingCategory; - }; -storm::property::prctl::PrctlFilter<double>* PrctlParser::parsePrctlFormula(std::string formulaString) { +std::shared_ptr<storm::property::prctl::PrctlFilter<double>> PrctlParser::parsePrctlFormula(std::string formulaString) { // Prepare iterators to input. BaseIteratorType stringIteratorBegin = formulaString.begin(); BaseIteratorType stringIteratorEnd = formulaString.end(); @@ -257,7 +260,7 @@ storm::property::prctl::PrctlFilter<double>* PrctlParser::parsePrctlFormula(std: // Prepare resulting intermediate representation of input. - storm::property::prctl::PrctlFilter<double>* result_pointer = nullptr; + std::shared_ptr<storm::property::prctl::PrctlFilter<double>> result_pointer(nullptr); PrctlGrammar<PositionIteratorType, BOOST_TYPEOF(boost::spirit::ascii::space)> grammar; @@ -291,6 +294,13 @@ storm::property::prctl::PrctlFilter<double>* PrctlParser::parsePrctlFormula(std: throw storm::exceptions::WrongFormatException() << msg.str(); } + // The syntax can be so wrong that no rule can be matched at all + // In that case, no expectation failure is thrown, but the parser just returns nullptr + // Then, of course the result is not usable, hence we throw a WrongFormatException, too. + if (!result_pointer) { + throw storm::exceptions::WrongFormatException() << "Syntax error in formula"; + } + return result_pointer; } diff --git a/src/parser/PrctlParser.h b/src/parser/PrctlParser.h index b5832727e..f8d5d6e78 100644 --- a/src/parser/PrctlParser.h +++ b/src/parser/PrctlParser.h @@ -25,7 +25,7 @@ public: * @throw wrongFormatException If the input could not be parsed successfully * @return A pointer to the parsed Prctl formula. If the line just contained a comment a nullptr will be returned instead. */ - static storm::property::prctl::PrctlFilter<double>* parsePrctlFormula(std::string formulaString); + static std::shared_ptr<storm::property::prctl::PrctlFilter<double>> parsePrctlFormula(std::string formulaString); private: diff --git a/src/storm.cpp b/src/storm.cpp index 5b4e06309..2896bd4b9 100644 --- a/src/storm.cpp +++ b/src/storm.cpp @@ -285,11 +285,10 @@ void checkPrctlFormulae(storm::modelchecker::prctl::AbstractModelChecker<double> if (s->isSet("prctl")) { std::string const chosenPrctlFile = s->getOptionByLongName("prctl").getArgument(0).getValueAsString(); LOG4CPLUS_INFO(logger, "Parsing prctl file: " << chosenPrctlFile << "."); - std::list<storm::property::prctl::PrctlFilter<double>*> formulaList = storm::parser::PrctlFileParser::parsePrctlFile(chosenPrctlFile); + std::list<std::shared_ptr<storm::property::prctl::PrctlFilter<double>>> formulaList = storm::parser::PrctlFileParser::parsePrctlFile(chosenPrctlFile); for (auto formula : formulaList) { formula->check(modelchecker); - delete formula; } } } @@ -339,7 +338,7 @@ void checkPrctlFormulae(storm::modelchecker::prctl::AbstractModelChecker<double> std::string const chosenPrctlFile = s->getOptionByLongName("prctl").getArgument(0).getValueAsString(); LOG4CPLUS_INFO(logger, "Parsing prctl file: " << chosenPrctlFile << "."); - std::list<storm::property::prctl::PrctlFilter<double>*> formulaList = storm::parser::PrctlFileParser::parsePrctlFile(chosenPrctlFile); + std::list<std::shared_ptr<storm::property::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) { @@ -369,13 +368,12 @@ void checkPrctlFormulae(storm::modelchecker::prctl::AbstractModelChecker<double> for (auto formula : formulaList) { // First check if it is a formula type for which a counterexample can be generated. - if (dynamic_cast<storm::property::prctl::AbstractStateFormula<double> const*>(formula->getChild()) == nullptr) { + if (std::dynamic_pointer_cast<storm::property::prctl::AbstractStateFormula<double>>(formula->getChild()).get() == nullptr) { LOG4CPLUS_ERROR(logger, "Unexpected kind of formula. Expected a state formula."); - delete formula; continue; } - storm::property::prctl::AbstractStateFormula<double> const& stateForm = static_cast<storm::property::prctl::AbstractStateFormula<double> const&>(*(formula->getChild())); + std::shared_ptr<storm::property::prctl::AbstractStateFormula<double>> stateForm = std::static_pointer_cast<storm::property::prctl::AbstractStateFormula<double>>(formula->getChild()); // Do some output std::cout << "Generating counterexample for formula " << fIndex << ":" << std::endl; @@ -389,13 +387,12 @@ void checkPrctlFormulae(storm::modelchecker::prctl::AbstractModelChecker<double> // Also raise the logger threshold for the log file, so that the model check infos aren't logged (useless and there are lots of them) // Lower it again after the model check. logger.getAppender("mainFileAppender")->setThreshold(log4cplus::WARN_LOG_LEVEL); - storm::storage::BitVector result = stateForm.check(*createPrctlModelChecker(dtmc)); + storm::storage::BitVector result = stateForm->check(*createPrctlModelChecker(dtmc)); logger.getAppender("mainFileAppender")->setThreshold(log4cplus::INFO_LOG_LEVEL); if((result & dtmc.getInitialStates()).getNumberOfSetBits() == dtmc.getInitialStates().getNumberOfSetBits()) { std::cout << "Formula is satisfied. Can not generate counterexample.\n\n" << std::endl; LOG4CPLUS_INFO(logger, "Formula is satisfied. Can not generate counterexample."); - delete formula; continue; } @@ -418,7 +415,6 @@ void checkPrctlFormulae(storm::modelchecker::prctl::AbstractModelChecker<double> } fIndex++; - delete formula; } } @@ -552,18 +548,15 @@ int main(const int argc, const char* argv[]) { // Now parse the property file and receive the list of parsed formulas. std::string const& propertyFile = s->getOptionByLongName("mincmd").getArgumentByName("propertyFile").getValueAsString(); - std::list<storm::property::prctl::PrctlFilter<double>*> formulaList = storm::parser::PrctlFileParser::parsePrctlFile(propertyFile); + std::list<std::shared_ptr<storm::property::prctl::PrctlFilter<double>>> formulaList = storm::parser::PrctlFileParser::parsePrctlFile(propertyFile); // Now generate the counterexamples for each formula. - for (storm::property::prctl::PrctlFilter<double>* formulaPtr : formulaList) { + for (auto formulaPtr : formulaList) { if (useMILP) { storm::counterexamples::MILPMinimalLabelSetGenerator<double>::computeCounterexample(program, *mdp, formulaPtr->getChild()); } else { storm::counterexamples::SMTMinimalCommandSetGenerator<double>::computeCounterexample(program, constants, *mdp, formulaPtr->getChild()); } - - // Once we are done with the formula, delete it. - delete formulaPtr; } } else if (s->isSet("prctl")) { // Determine which engine is to be used to choose the right model checker. diff --git a/test/functional/modelchecker/GmmxxDtmcPrctlModelCheckerTest.cpp b/test/functional/modelchecker/GmmxxDtmcPrctlModelCheckerTest.cpp index ac90211b5..15d0a7814 100644 --- a/test/functional/modelchecker/GmmxxDtmcPrctlModelCheckerTest.cpp +++ b/test/functional/modelchecker/GmmxxDtmcPrctlModelCheckerTest.cpp @@ -22,41 +22,33 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, Die) { storm::modelchecker::prctl::SparseDtmcPrctlModelChecker<double> mc(*dtmc, new storm::solver::GmmxxLinearEquationSolver<double>()); - storm::property::prctl::Ap<double>* apFormula = new storm::property::prctl::Ap<double>("one"); - storm::property::prctl::Eventually<double>* eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); + auto apFormula = std::make_shared<storm::property::prctl::Ap<double>>("one"); + auto eventuallyFormula = std::make_shared<storm::property::prctl::Eventually<double>>(apFormula); std::vector<double> result = eventuallyFormula->check(mc, false); ASSERT_LT(std::abs(result[0] - ((double)1.0/6.0)), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete eventuallyFormula; - - apFormula = new storm::property::prctl::Ap<double>("two"); - eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); + apFormula = std::make_shared<storm::property::prctl::Ap<double>>("two"); + eventuallyFormula = std::make_shared<storm::property::prctl::Eventually<double>>(apFormula); result = eventuallyFormula->check(mc, false); ASSERT_LT(std::abs(result[0] - ((double)1.0/6.0)), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete eventuallyFormula; - - apFormula = new storm::property::prctl::Ap<double>("three"); - eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); + apFormula = std::make_shared<storm::property::prctl::Ap<double>>("three"); + eventuallyFormula = std::make_shared<storm::property::prctl::Eventually<double>>(apFormula); result = eventuallyFormula->check(mc, false); ASSERT_LT(std::abs(result[0] - ((double)1.0/6.0)), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete eventuallyFormula; - - storm::property::prctl::Ap<double>* done = new storm::property::prctl::Ap<double>("done"); - storm::property::prctl::ReachabilityReward<double>* reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward<double>(done); + auto done = std::make_shared<storm::property::prctl::Ap<double>>("done"); + auto reachabilityRewardFormula = std::make_shared<storm::property::prctl::ReachabilityReward<double>>(done); result = reachabilityRewardFormula->check(mc, false); ASSERT_LT(std::abs(result[0] - ((double)11/3)), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - - delete reachabilityRewardFormula; } TEST(GmmxxDtmcPrctlModelCheckerTest, Crowds) { @@ -74,32 +66,26 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, Crowds) { storm::modelchecker::prctl::SparseDtmcPrctlModelChecker<double> mc(*dtmc, new storm::solver::GmmxxLinearEquationSolver<double>()); - storm::property::prctl::Ap<double>* apFormula = new storm::property::prctl::Ap<double>("observe0Greater1"); - storm::property::prctl::Eventually<double>* eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); + auto apFormula = std::make_shared<storm::property::prctl::Ap<double>>("observe0Greater1"); + auto eventuallyFormula = std::make_shared<storm::property::prctl::Eventually<double>>(apFormula); std::vector<double> result = eventuallyFormula->check(mc, false); ASSERT_LT(std::abs(result[0] - 0.3328800375801578281), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete eventuallyFormula; - - apFormula = new storm::property::prctl::Ap<double>("observeIGreater1"); - eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); + apFormula = std::make_shared<storm::property::prctl::Ap<double>>("observeIGreater1"); + eventuallyFormula = std::make_shared<storm::property::prctl::Eventually<double>>(apFormula); result = eventuallyFormula->check(mc, false); ASSERT_LT(std::abs(result[0] - 0.1522194965), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete eventuallyFormula; - - apFormula = new storm::property::prctl::Ap<double>("observeOnlyTrueSender"); - eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); + apFormula = std::make_shared<storm::property::prctl::Ap<double>>("observeOnlyTrueSender"); + eventuallyFormula = std::make_shared<storm::property::prctl::Eventually<double>>(apFormula); result = eventuallyFormula->check(mc, false); ASSERT_LT(std::abs(result[0] - 0.32153724292835045), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - - delete eventuallyFormula; } TEST(GmmxxDtmcPrctlModelCheckerTest, SynchronousLeader) { @@ -116,30 +102,24 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, SynchronousLeader) { storm::modelchecker::prctl::SparseDtmcPrctlModelChecker<double> mc(*dtmc, new storm::solver::GmmxxLinearEquationSolver<double>()); - storm::property::prctl::Ap<double>* apFormula = new storm::property::prctl::Ap<double>("elected"); - storm::property::prctl::Eventually<double>* eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); + auto apFormula = std::make_shared<storm::property::prctl::Ap<double>>("elected"); + auto eventuallyFormula = std::make_shared<storm::property::prctl::Eventually<double>>(apFormula); std::vector<double> result = eventuallyFormula->check(mc, false); ASSERT_LT(std::abs(result[0] - 1.0), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete eventuallyFormula; - - apFormula = new storm::property::prctl::Ap<double>("elected"); - storm::property::prctl::BoundedUntil<double>* boundedUntilFormula = new storm::property::prctl::BoundedUntil<double>(new storm::property::prctl::Ap<double>("true"), apFormula, 20); + apFormula = std::make_shared<storm::property::prctl::Ap<double>>("elected"); + auto boundedUntilFormula = std::make_shared<storm::property::prctl::BoundedUntil<double>>(std::make_shared<storm::property::prctl::Ap<double>>("true"), apFormula, 20); result = boundedUntilFormula->check(mc, false); ASSERT_LT(std::abs(result[0] - 0.9999965911265462636), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete boundedUntilFormula; - - apFormula = new storm::property::prctl::Ap<double>("elected"); - storm::property::prctl::ReachabilityReward<double>* reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward<double>(apFormula); + apFormula = std::make_shared<storm::property::prctl::Ap<double>>("elected"); + auto reachabilityRewardFormula = std::make_shared<storm::property::prctl::ReachabilityReward<double>>(apFormula); result = reachabilityRewardFormula->check(mc, false); ASSERT_LT(std::abs(result[0] - 1.044879046), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - - delete reachabilityRewardFormula; } diff --git a/test/functional/modelchecker/SparseMdpPrctlModelCheckerTest.cpp b/test/functional/modelchecker/SparseMdpPrctlModelCheckerTest.cpp index f3d817c9f..bc423ad02 100644 --- a/test/functional/modelchecker/SparseMdpPrctlModelCheckerTest.cpp +++ b/test/functional/modelchecker/SparseMdpPrctlModelCheckerTest.cpp @@ -19,8 +19,8 @@ TEST(SparseMdpPrctlModelCheckerTest, Dice) { storm::modelchecker::prctl::SparseMdpPrctlModelChecker<double> mc(*mdp, std::shared_ptr<storm::solver::NativeNondeterministicLinearEquationSolver<double>>(new storm::solver::NativeNondeterministicLinearEquationSolver<double>())); - storm::property::prctl::Ap<double>* apFormula = new storm::property::prctl::Ap<double>("two"); - storm::property::prctl::Eventually<double>* eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); + auto apFormula = std::make_shared<storm::property::prctl::Ap<double>>("two"); + auto eventuallyFormula = std::make_shared<storm::property::prctl::Eventually<double>>(apFormula); std::vector<double> result = mc.checkOptimizingOperator(*eventuallyFormula, true); @@ -29,11 +29,9 @@ TEST(SparseMdpPrctlModelCheckerTest, Dice) { result = mc.checkOptimizingOperator(*eventuallyFormula, false); ASSERT_LT(std::abs(result[0] - 0.0277777612209320068), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - - delete eventuallyFormula; - apFormula = new storm::property::prctl::Ap<double>("three"); - eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); + apFormula = std::make_shared<storm::property::prctl::Ap<double>>("three"); + eventuallyFormula = std::make_shared<storm::property::prctl::Eventually<double>>(apFormula); result = mc.checkOptimizingOperator(*eventuallyFormula, true); @@ -42,11 +40,9 @@ TEST(SparseMdpPrctlModelCheckerTest, Dice) { result = mc.checkOptimizingOperator(*eventuallyFormula, false); ASSERT_LT(std::abs(result[0] - 0.0555555224418640136), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - - delete eventuallyFormula; - apFormula = new storm::property::prctl::Ap<double>("four"); - eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); + apFormula = std::make_shared<storm::property::prctl::Ap<double>>("four"); + eventuallyFormula = std::make_shared<storm::property::prctl::Eventually<double>>(apFormula); result = mc.checkOptimizingOperator(*eventuallyFormula, true); @@ -56,10 +52,8 @@ TEST(SparseMdpPrctlModelCheckerTest, Dice) { ASSERT_LT(std::abs(result[0] - 0.083333283662796020508), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete eventuallyFormula; - - apFormula = new storm::property::prctl::Ap<double>("done"); - storm::property::prctl::ReachabilityReward<double>* reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward<double>(apFormula); + apFormula = std::make_shared<storm::property::prctl::Ap<double>>("done"); + auto reachabilityRewardFormula = std::make_shared<storm::property::prctl::ReachabilityReward<double>>(apFormula); result = mc.checkOptimizingOperator(*reachabilityRewardFormula, true); @@ -68,8 +62,6 @@ TEST(SparseMdpPrctlModelCheckerTest, Dice) { result = mc.checkOptimizingOperator(*reachabilityRewardFormula, false); ASSERT_LT(std::abs(result[0] - 7.333329499), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - - delete reachabilityRewardFormula; abstractModel = storm::parser::AutoParser::parseModel(STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.tra", STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.lab", STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.flip.state.rew", ""); @@ -79,8 +71,8 @@ TEST(SparseMdpPrctlModelCheckerTest, Dice) { storm::modelchecker::prctl::SparseMdpPrctlModelChecker<double> stateRewardModelChecker(*stateRewardMdp, std::shared_ptr<storm::solver::NativeNondeterministicLinearEquationSolver<double>>(new storm::solver::NativeNondeterministicLinearEquationSolver<double>())); - apFormula = new storm::property::prctl::Ap<double>("done"); - reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward<double>(apFormula); + apFormula = std::make_shared<storm::property::prctl::Ap<double>>("done"); + reachabilityRewardFormula = std::make_shared<storm::property::prctl::ReachabilityReward<double>>(apFormula); result = stateRewardModelChecker.checkOptimizingOperator(*reachabilityRewardFormula, true); @@ -89,8 +81,6 @@ TEST(SparseMdpPrctlModelCheckerTest, Dice) { result = stateRewardModelChecker.checkOptimizingOperator(*reachabilityRewardFormula, false); ASSERT_LT(std::abs(result[0] - 7.333329499), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - - delete reachabilityRewardFormula; abstractModel = storm::parser::AutoParser::parseModel(STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.tra", STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.lab", STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.flip.state.rew", STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.flip.trans.rew"); @@ -100,8 +90,8 @@ TEST(SparseMdpPrctlModelCheckerTest, Dice) { storm::modelchecker::prctl::SparseMdpPrctlModelChecker<double> stateAndTransitionRewardModelChecker(*stateAndTransitionRewardMdp, std::shared_ptr<storm::solver::NativeNondeterministicLinearEquationSolver<double>>(new storm::solver::NativeNondeterministicLinearEquationSolver<double>())); - apFormula = new storm::property::prctl::Ap<double>("done"); - reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward<double>(apFormula); + apFormula = std::make_shared<storm::property::prctl::Ap<double>>("done"); + reachabilityRewardFormula = std::make_shared<storm::property::prctl::ReachabilityReward<double>>(apFormula); result = stateAndTransitionRewardModelChecker.checkOptimizingOperator(*reachabilityRewardFormula, true); @@ -110,8 +100,6 @@ TEST(SparseMdpPrctlModelCheckerTest, Dice) { result = stateAndTransitionRewardModelChecker.checkOptimizingOperator(*reachabilityRewardFormula, false); ASSERT_LT(std::abs(result[0] - 14.666658998), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - - delete reachabilityRewardFormula; } TEST(SparseMdpPrctlModelCheckerTest, AsynchronousLeader) { @@ -127,8 +115,8 @@ TEST(SparseMdpPrctlModelCheckerTest, AsynchronousLeader) { storm::modelchecker::prctl::SparseMdpPrctlModelChecker<double> mc(*mdp, std::shared_ptr<storm::solver::NativeNondeterministicLinearEquationSolver<double>>(new storm::solver::NativeNondeterministicLinearEquationSolver<double>())); - storm::property::prctl::Ap<double>* apFormula = new storm::property::prctl::Ap<double>("elected"); - storm::property::prctl::Eventually<double>* eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); + auto apFormula = std::make_shared<storm::property::prctl::Ap<double>>("elected"); + auto eventuallyFormula = std::make_shared<storm::property::prctl::Eventually<double>>(apFormula); std::vector<double> result = mc.checkOptimizingOperator(*eventuallyFormula, true); @@ -138,10 +126,8 @@ TEST(SparseMdpPrctlModelCheckerTest, AsynchronousLeader) { ASSERT_LT(std::abs(result[0] - 1), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete eventuallyFormula; - - apFormula = new storm::property::prctl::Ap<double>("elected"); - storm::property::prctl::BoundedEventually<double>* boundedEventuallyFormula = new storm::property::prctl::BoundedEventually<double>(apFormula, 25); + apFormula = std::make_shared<storm::property::prctl::Ap<double>>("elected"); + auto boundedEventuallyFormula = std::make_shared<storm::property::prctl::BoundedEventually<double>>(apFormula, 25); result = mc.checkOptimizingOperator(*boundedEventuallyFormula, true); @@ -151,10 +137,8 @@ TEST(SparseMdpPrctlModelCheckerTest, AsynchronousLeader) { ASSERT_LT(std::abs(result[0] - 0.0625), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete boundedEventuallyFormula; - - apFormula = new storm::property::prctl::Ap<double>("elected"); - storm::property::prctl::ReachabilityReward<double>* reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward<double>(apFormula); + apFormula = std::make_shared<storm::property::prctl::Ap<double>>("elected"); + auto reachabilityRewardFormula = std::make_shared<storm::property::prctl::ReachabilityReward<double>>(apFormula); result = mc.checkOptimizingOperator(*reachabilityRewardFormula, true); @@ -163,6 +147,4 @@ TEST(SparseMdpPrctlModelCheckerTest, AsynchronousLeader) { result = mc.checkOptimizingOperator(*reachabilityRewardFormula, false); ASSERT_LT(std::abs(result[0] - 4.285689611), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - - delete reachabilityRewardFormula; } diff --git a/test/functional/parser/ActionTest.cpp b/test/functional/parser/ActionTest.cpp index 41d5ab58f..5454c5787 100644 --- a/test/functional/parser/ActionTest.cpp +++ b/test/functional/parser/ActionTest.cpp @@ -9,6 +9,7 @@ #include "storm-config.h" #include "src/formula/actions/BoundAction.h" +#include "src/formula/actions/FormulaAction.h" #include "src/parser/MarkovAutomatonParser.h" #include "src/parser/DeterministicModelParser.h" @@ -27,7 +28,7 @@ TEST(ActionTest, BoundActionFunctionality) { // Build the filter input. // Basically the modelchecking result of "F a" on the used DTMC. - std::vector<double> pathResult = mc.checkEventually(storm::property::prctl::Eventually<double>(new storm::property::prctl::Ap<double>("a")), false); + std::vector<double> pathResult = mc.checkEventually(storm::property::prctl::Eventually<double>(std::make_shared<storm::property::prctl::Ap<double>>("a")), false); std::vector<uint_fast64_t> stateMap(pathResult.size()); for(uint_fast64_t i = 0; i < pathResult.size(); i++) { stateMap[i] = i; @@ -53,6 +54,15 @@ TEST(ActionTest, BoundActionFunctionality) { ASSERT_FALSE(result.selection[6]); ASSERT_FALSE(result.selection[7]); + // Test whether the filter actually uses the selection given by the input. + action = storm::property::action::BoundAction<double>(storm::property::LESS, 0.5); + result = action.evaluate(result, mc); + + ASSERT_FALSE(result.selection[0]); + ASSERT_TRUE(result.selection[1]); + ASSERT_FALSE(result.selection[6]); + ASSERT_FALSE(result.selection[7]); + // Check whether the state order has any effect on the selected states, which it should not. for(uint_fast64_t i = 0; i < pathResult.size(); i++) { stateMap[i] = pathResult.size() - i - 1; @@ -103,7 +113,7 @@ TEST(ActionTest, BoundActionSafety) { // Build the filter input. // Basically the modelchecking result of "F a" on the used DTMC. - std::vector<double> pathResult = mc.checkEventually(storm::property::prctl::Eventually<double>(new storm::property::prctl::Ap<double>("a")), false); + std::vector<double> pathResult = mc.checkEventually(storm::property::prctl::Eventually<double>(std::make_shared<storm::property::prctl::Ap<double>>("a")), false); storm::storage::BitVector stateResult = mc.checkAp(storm::property::prctl::Ap<double>("a")); std::vector<uint_fast64_t> stateMap(pathResult.size()); for(uint_fast64_t i = 0; i < pathResult.size(); i++) { @@ -155,3 +165,50 @@ TEST(ActionTest, BoundActionSafety) { // Check for empty input. ASSERT_NO_THROW(result = action.evaluate(Result(), mc)); } + +TEST(ActionTest, FormulaActionFunctionality) { + + // Setup the modelchecker. + storm::models::Dtmc<double> model = storm::parser::DeterministicModelParser::parseDtmc(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_actionTest.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/dtmc_actionTest.lab"); + storm::modelchecker::prctl::SparseDtmcPrctlModelChecker<double> mc(model, new storm::solver::GmmxxLinearEquationSolver<double>()); + + // Build the filter input. + // Basically the modelchecking result of "F a" on the used DTMC. + std::vector<double> pathResult = mc.checkEventually(storm::property::prctl::Eventually<double>(std::make_shared<storm::property::prctl::Ap<double>>("a")), false); + std::vector<uint_fast64_t> stateMap(pathResult.size()); + for(uint_fast64_t i = 0; i < pathResult.size(); i++) { + stateMap[i] = i; + } + Result input(storm::storage::BitVector(pathResult.size(), true), stateMap, pathResult, storm::storage::BitVector()); + Result result; + + // Test the action. + // First test that the empty action does no change to the input. + storm::property::action::FormulaAction<double> action; + input.selection.set(0,false); + ASSERT_NO_THROW(result = action.evaluate(input, mc)); + for(uint_fast64_t i = 0; i < pathResult.size(); i++) { + if(i != 0) { + ASSERT_TRUE(result.selection[i]); + } else { + ASSERT_FALSE(result.selection[i]); + } + ASSERT_EQ(i, stateMap[i]); + ASSERT_EQ(input.pathResult, result.pathResult); + } + ASSERT_TRUE(result.stateResult.size() == 0); + input.selection.set(0,true); + + // Now test the general functionality for both results of path and state formulas. + action = storm::property::action::FormulaAction<double>(std::make_shared<storm::property::prctl::ProbabilisticBoundOperator<double>>(storm::property::LESS, 0.5, std::make_shared<storm::property::prctl::Eventually<double>>(std::make_shared<storm::property::prctl::Ap<double>>("b")))); + ASSERT_NO_THROW(result = action.evaluate(input, mc)); + ASSERT_TRUE(result.selection[0]); + ASSERT_TRUE(result.selection[1]); + ASSERT_TRUE(result.selection[2]); + ASSERT_FALSE(result.selection[3]); + ASSERT_FALSE(result.selection[4]); + ASSERT_TRUE(result.selection[5]); + ASSERT_FALSE(result.selection[6]); + ASSERT_FALSE(result.selection[7]); + +} diff --git a/test/functional/parser/CslParserTest.cpp b/test/functional/parser/CslParserTest.cpp index 929d72c71..ff0a4f4d1 100644 --- a/test/functional/parser/CslParserTest.cpp +++ b/test/functional/parser/CslParserTest.cpp @@ -10,154 +10,140 @@ #include "src/parser/CslParser.h" #include "src/exceptions/WrongFormatException.h" +namespace csl = storm::property::csl; + TEST(CslParserTest, parseApOnlyTest) { std::string input = "ap"; - storm::property::csl::CslFilter<double>* formula = nullptr; + std::shared_ptr<csl::CslFilter<double>> formula(nullptr); ASSERT_NO_THROW( formula = storm::parser::CslParser::parseCslFormula(input); ); // The parser did not falsely recognize the input as a comment. - ASSERT_NE(formula, nullptr); + ASSERT_NE(formula.get(), nullptr); // The input was parsed correctly. ASSERT_EQ(input, formula->toString()); - - delete formula; } TEST(CslParserTest, parsePropositionalFormulaTest) { std::string input = "!(a & b) | a & ! c"; - storm::property::csl::CslFilter<double>* formula = nullptr; + std::shared_ptr<csl::CslFilter<double>> formula(nullptr); ASSERT_NO_THROW( formula = storm::parser::CslParser::parseCslFormula(input); ); // The parser did not falsely recognize the input as a comment. - ASSERT_NE(formula, nullptr); + ASSERT_NE(formula.get(), nullptr); // The input was parsed correctly. ASSERT_EQ("(!(a & b) | (a & !c))", formula->toString()); - - delete formula; } TEST(CslParserTest, parseProbabilisticFormulaTest) { std::string input = "P > 0.5 [ F a ]"; - storm::property::csl::CslFilter<double>* formula = nullptr; + std::shared_ptr<csl::CslFilter<double>> formula(nullptr); ASSERT_NO_THROW( formula = storm::parser::CslParser::parseCslFormula(input); ); // The parser did not falsely recognize the input as a comment. - ASSERT_NE(formula, nullptr); + ASSERT_NE(formula.get(), nullptr); - ASSERT_NE(dynamic_cast<storm::property::csl::ProbabilisticBoundOperator<double>*>(formula->getChild()), nullptr); - storm::property::csl::ProbabilisticBoundOperator<double>* op = static_cast<storm::property::csl::ProbabilisticBoundOperator<double>*>(formula->getChild()); + auto op = std::dynamic_pointer_cast<storm::property::csl::ProbabilisticBoundOperator<double>>(formula->getChild()); + ASSERT_NE(op.get(), nullptr); ASSERT_EQ(storm::property::GREATER, op->getComparisonOperator()); ASSERT_EQ(0.5, op->getBound()); // Test the string representation for the parsed formula. ASSERT_EQ("P > 0.500000 (F a)", formula->toString()); - - delete formula; } TEST(CslParserTest, parseSteadyStateBoundFormulaTest) { std::string input = "S >= 15 [ P < 0.2 [ a U<=3 b ] ]"; - storm::property::csl::CslFilter<double>* formula = nullptr; + std::shared_ptr<csl::CslFilter<double>> formula(nullptr); ASSERT_NO_THROW( formula = storm::parser::CslParser::parseCslFormula(input); ); // The parser did not falsely recognize the input as a comment. - ASSERT_NE(formula, nullptr); + ASSERT_NE(formula.get(), nullptr); - storm::property::csl::SteadyStateBoundOperator<double>* op = static_cast<storm::property::csl::SteadyStateBoundOperator<double>*>(formula->getChild()); + auto op = std::dynamic_pointer_cast<storm::property::csl::SteadyStateBoundOperator<double>>(formula->getChild()); + ASSERT_NE(op.get(), nullptr); ASSERT_EQ(storm::property::GREATER_EQUAL, op->getComparisonOperator()); ASSERT_EQ(15.0, op->getBound()); // Test the string representation for the parsed formula. ASSERT_EQ("S >= 15.000000 (P < 0.200000 (a U[0.000000,3.000000] b))", formula->toString()); - - delete formula; } TEST(CslParserTest, parseSteadyStateNoBoundFormulaTest) { std::string input = "S = ? [ P <= 0.5 [ F<=3 a ] ]"; - storm::property::csl::CslFilter<double>* formula = nullptr; + std::shared_ptr<csl::CslFilter<double>> formula(nullptr); ASSERT_NO_THROW( formula = storm::parser::CslParser::parseCslFormula(input); ); // The parser did not falsely recognize the input as a comment. - ASSERT_NE(formula, nullptr); + ASSERT_NE(formula.get(), nullptr); // The input was parsed correctly. ASSERT_EQ("S = ? (P <= 0.500000 (F[0.000000,3.000000] a))", formula->toString()); - - delete formula; } TEST(CslParserTest, parseProbabilisticNoBoundFormulaTest) { std::string input = "P = ? [ a U [3,4] b & (!c) ]"; - storm::property::csl::CslFilter<double>* formula = nullptr; + std::shared_ptr<csl::CslFilter<double>> formula(nullptr); ASSERT_NO_THROW( formula = storm::parser::CslParser::parseCslFormula(input); ); // The parser did not falsely recognize the input as a comment. - ASSERT_NE(formula, nullptr); + ASSERT_NE(formula.get(), nullptr); // The input was parsed correctly. ASSERT_EQ("P = ? (a U[3.000000,4.000000] (b & !c))", formula->toString()); - - delete formula; } TEST(CslParserTest, parseComplexFormulaTest) { std::string input = "S<=0.5 [ P <= 0.5 [ a U c ] ] & (P > 0.5 [ G b] | !P < 0.4 [ G P>0.9 [F >=7 a & b] ]) //and a comment"; - storm::property::csl::CslFilter<double>* formula = nullptr; + std::shared_ptr<csl::CslFilter<double>> formula(nullptr); ASSERT_NO_THROW( formula = storm::parser::CslParser::parseCslFormula(input); ); // The parser did not falsely recognize the input as a comment. - ASSERT_NE(formula, nullptr); + ASSERT_NE(formula.get(), nullptr); // The input was parsed correctly. ASSERT_EQ("(S <= 0.500000 (P <= 0.500000 (a U c)) & (P > 0.500000 (G b) | !P < 0.400000 (G P > 0.900000 (F>=7.000000 (a & b)))))", formula->toString()); - - delete formula; } TEST(CslParserTest, wrongProbabilisticFormulaTest) { std::string input = "P > 0.5 [ a ]"; - storm::property::csl::CslFilter<double>* formula = nullptr; + std::shared_ptr<csl::CslFilter<double>> formula(nullptr); ASSERT_THROW( formula = storm::parser::CslParser::parseCslFormula(input), storm::exceptions::WrongFormatException ); - delete formula; } TEST(CslParserTest, wrongFormulaTest) { std::string input = "(a | b) & +"; - storm::property::csl::CslFilter<double>* formula = nullptr; + std::shared_ptr<csl::CslFilter<double>> formula(nullptr); ASSERT_THROW( formula = storm::parser::CslParser::parseCslFormula(input), storm::exceptions::WrongFormatException ); - delete formula; } TEST(CslParserTest, wrongFormulaTest2) { std::string input = "P>0 [ F & a ]"; - storm::property::csl::CslFilter<double>* formula = nullptr; + std::shared_ptr<csl::CslFilter<double>> formula(nullptr); ASSERT_THROW( formula = storm::parser::CslParser::parseCslFormula(input), storm::exceptions::WrongFormatException ); - delete formula; } diff --git a/test/functional/parser/LtlParserTest.cpp b/test/functional/parser/LtlParserTest.cpp index bba921506..0ccda625a 100644 --- a/test/functional/parser/LtlParserTest.cpp +++ b/test/functional/parser/LtlParserTest.cpp @@ -10,30 +10,28 @@ #include "src/parser/LtlParser.h" #include "src/exceptions/WrongFormatException.h" +namespace ltl = storm::property::ltl; + TEST(LtlParserTest, parseApOnlyTest) { std::string formula = "ap"; - storm::property::ltl::LtlFilter<double>* ltlFormula = nullptr; + std::shared_ptr<storm::property::ltl::LtlFilter<double>> ltlFormula(nullptr); ASSERT_NO_THROW( ltlFormula = storm::parser::LtlParser::parseLtlFormula(formula); ); - ASSERT_NE(ltlFormula, nullptr); + ASSERT_NE(ltlFormula.get(), nullptr); ASSERT_EQ(ltlFormula->toString(), formula); - - delete ltlFormula; } TEST(LtlParserTest, parsePropositionalFormulaTest) { std::string formula = "!(a & b) | a & ! c"; - storm::property::ltl::LtlFilter<double>* ltlFormula = nullptr; + std::shared_ptr<ltl::LtlFilter<double>> ltlFormula(nullptr); ASSERT_NO_THROW( ltlFormula = storm::parser::LtlParser::parseLtlFormula(formula); ); - ASSERT_NE(ltlFormula, nullptr); + ASSERT_NE(ltlFormula.get(), nullptr); ASSERT_EQ(ltlFormula->toString(), "(!(a & b) | (a & !c))"); - - delete ltlFormula; } /*! @@ -42,15 +40,13 @@ TEST(LtlParserTest, parsePropositionalFormulaTest) { */ TEST(LtlParserTest, parseAmbiguousFormulaTest) { std::string formula = "F & b"; - storm::property::ltl::LtlFilter<double>* ltlFormula = nullptr; + std::shared_ptr<ltl::LtlFilter<double>> ltlFormula(nullptr); ASSERT_NO_THROW( ltlFormula = storm::parser::LtlParser::parseLtlFormula(formula); ); - ASSERT_NE(ltlFormula, nullptr); + ASSERT_NE(ltlFormula.get(), nullptr); ASSERT_EQ(ltlFormula->toString(), "(F & b)"); - - delete ltlFormula; } /*! @@ -59,77 +55,69 @@ TEST(LtlParserTest, parseAmbiguousFormulaTest) { */ TEST(LtlParserTest, parseAmbiguousFormulaTest2) { std::string formula = "F F"; - storm::property::ltl::LtlFilter<double>* ltlFormula = nullptr; + std::shared_ptr<ltl::LtlFilter<double>> ltlFormula(nullptr); ASSERT_NO_THROW( ltlFormula = storm::parser::LtlParser::parseLtlFormula(formula); ); - ASSERT_NE(ltlFormula, nullptr); + ASSERT_NE(ltlFormula.get(), nullptr); ASSERT_EQ(ltlFormula->toString(), "F F"); - - delete ltlFormula; } TEST(LtlParserTest, parseBoundedEventuallyFormulaTest) { std::string formula = "F<=5 a"; - storm::property::ltl::LtlFilter<double>* ltlFormula = nullptr; + std::shared_ptr<ltl::LtlFilter<double>> ltlFormula(nullptr); ASSERT_NO_THROW( ltlFormula = storm::parser::LtlParser::parseLtlFormula(formula); ); - ASSERT_NE(ltlFormula, nullptr); + ASSERT_NE(ltlFormula.get(), nullptr); - storm::property::ltl::BoundedEventually<double>* op = static_cast<storm::property::ltl::BoundedEventually<double>*>(ltlFormula->getChild()); + std::shared_ptr<storm::property::ltl::BoundedEventually<double>> op = std::dynamic_pointer_cast<storm::property::ltl::BoundedEventually<double>>(ltlFormula->getChild()); + ASSERT_NE(op.get(), nullptr); ASSERT_EQ(static_cast<uint_fast64_t>(5), op->getBound()); ASSERT_EQ(ltlFormula->toString(), "F<=5 a"); - - delete ltlFormula; } TEST(LtlParserTest, parseBoundedUntilFormulaTest) { std::string formula = "a U<=3 b"; - storm::property::ltl::LtlFilter<double>* ltlFormula = nullptr; + std::shared_ptr<ltl::LtlFilter<double>> ltlFormula(nullptr); ASSERT_NO_THROW( ltlFormula = storm::parser::LtlParser::parseLtlFormula(formula); ); - ASSERT_NE(ltlFormula, nullptr); + ASSERT_NE(ltlFormula.get(), nullptr); - storm::property::ltl::BoundedUntil<double>* op = static_cast<storm::property::ltl::BoundedUntil<double>*>(ltlFormula->getChild()); + std::shared_ptr<storm::property::ltl::BoundedUntil<double>> op = std::dynamic_pointer_cast<storm::property::ltl::BoundedUntil<double>>(ltlFormula->getChild()); + ASSERT_NE(op.get(), nullptr); ASSERT_EQ(static_cast<uint_fast64_t>(3), op->getBound()); ASSERT_EQ(ltlFormula->toString(), "(a U<=3 b)"); - - delete ltlFormula; } TEST(LtlParserTest, parseComplexUntilTest) { std::string formula = "a U b U<=3 c"; - storm::property::ltl::LtlFilter<double>* ltlFormula = nullptr; + std::shared_ptr<ltl::LtlFilter<double>> ltlFormula(nullptr); ASSERT_NO_THROW( ltlFormula = storm::parser::LtlParser::parseLtlFormula(formula); ); - ASSERT_NE(ltlFormula, nullptr); + ASSERT_NE(ltlFormula.get(), nullptr); ASSERT_EQ(ltlFormula->toString(), "((a U b) U<=3 c)"); - - delete ltlFormula; } TEST(LtlParserTest, parseComplexFormulaTest) { std::string formula = "a U F b | G a & F<=3 a U<=7 b // and a comment"; - storm::property::ltl::LtlFilter<double>* ltlFormula = nullptr; + std::shared_ptr<ltl::LtlFilter<double>> ltlFormula(nullptr); ASSERT_NO_THROW( ltlFormula = storm::parser::LtlParser::parseLtlFormula(formula); ); - ASSERT_NE(ltlFormula, nullptr); + ASSERT_NE(ltlFormula.get(), nullptr); ASSERT_EQ(ltlFormula->toString(), "(a U F (b | G (a & F<=3 (a U<=7 b))))"); - - delete ltlFormula; } TEST(LtlParserTest, wrongFormulaTest) { diff --git a/test/functional/parser/PrctlParserTest.cpp b/test/functional/parser/PrctlParserTest.cpp index 49b618ee7..1d5e59349 100644 --- a/test/functional/parser/PrctlParserTest.cpp +++ b/test/functional/parser/PrctlParserTest.cpp @@ -11,9 +11,11 @@ #include "src/parser/PrctlParser.h" #include "src/exceptions/WrongFormatException.h" +namespace prctl = storm::property::prctl; + TEST(PrctlParserTest, parseApOnlyTest) { std::string input = "ap"; - storm::property::prctl::PrctlFilter<double>* formula = nullptr; + std::shared_ptr<prctl::PrctlFilter<double>> formula(nullptr); ASSERT_NO_THROW( formula = storm::parser::PrctlParser::parsePrctlFormula(input) ); @@ -23,14 +25,11 @@ TEST(PrctlParserTest, parseApOnlyTest) { // The input was parsed correctly. ASSERT_EQ(input, formula->toString()); - - delete formula; - } TEST(PrctlParserTest, parsePropositionalFormulaTest) { std::string input = "!(a & b) | a & ! c"; - storm::property::prctl::PrctlFilter<double>* formula = nullptr; + std::shared_ptr<prctl::PrctlFilter<double>> formula(nullptr); ASSERT_NO_THROW( formula = storm::parser::PrctlParser::parsePrctlFormula(input) ); @@ -40,14 +39,11 @@ TEST(PrctlParserTest, parsePropositionalFormulaTest) { // The input was parsed correctly. ASSERT_EQ("(!(a & b) | (a & !c))", formula->toString()); - - delete formula; - } TEST(PrctlParserTest, parseProbabilisticFormulaTest) { std::string input = "P > 0.5 [ F a ]"; - storm::property::prctl::PrctlFilter<double>* formula = nullptr; + std::shared_ptr<prctl::PrctlFilter<double>> formula(nullptr); ASSERT_NO_THROW( formula = storm::parser::PrctlParser::parsePrctlFormula(input) ); @@ -56,22 +52,19 @@ TEST(PrctlParserTest, parseProbabilisticFormulaTest) { ASSERT_NE(formula, nullptr); - ASSERT_NE(dynamic_cast<storm::property::prctl::ProbabilisticBoundOperator<double>*>(formula->getChild()), nullptr); - storm::property::prctl::ProbabilisticBoundOperator<double>* op = static_cast<storm::property::prctl::ProbabilisticBoundOperator<double>*>(formula->getChild()); + ASSERT_NE(std::dynamic_pointer_cast<prctl::ProbabilisticBoundOperator<double>>(formula->getChild()).get(), nullptr); + std::shared_ptr<prctl::ProbabilisticBoundOperator<double>> op = std::static_pointer_cast<prctl::ProbabilisticBoundOperator<double>>(formula->getChild()); ASSERT_EQ(storm::property::GREATER, op->getComparisonOperator()); ASSERT_EQ(0.5, op->getBound()); // Test the string representation for the parsed formula. ASSERT_EQ("P > 0.500000 (F a)", formula->toString()); - - delete formula; - } TEST(PrctlParserTest, parseRewardFormulaTest) { std::string input = "R >= 15 [ I=5 ]"; - storm::property::prctl::PrctlFilter<double>* formula = nullptr; + std::shared_ptr<prctl::PrctlFilter<double>>formula(nullptr); ASSERT_NO_THROW( formula = storm::parser::PrctlParser::parsePrctlFormula(input); ); @@ -79,21 +72,19 @@ TEST(PrctlParserTest, parseRewardFormulaTest) { // The parser did not falsely recognize the input as a comment. ASSERT_NE(formula, nullptr); - ASSERT_NE(dynamic_cast<storm::property::prctl::RewardBoundOperator<double>*>(formula->getChild()), nullptr); - storm::property::prctl::RewardBoundOperator<double>* op = static_cast<storm::property::prctl::RewardBoundOperator<double>*>(formula->getChild()); + ASSERT_NE(std::dynamic_pointer_cast<prctl::RewardBoundOperator<double>>(formula->getChild()).get(), nullptr); + std::shared_ptr<prctl::RewardBoundOperator<double>> op = std::static_pointer_cast<prctl::RewardBoundOperator<double>>(formula->getChild()); ASSERT_EQ(storm::property::GREATER_EQUAL, op->getComparisonOperator()); ASSERT_EQ(15.0, op->getBound()); // Test the string representation for the parsed formula. ASSERT_EQ("R >= 15.000000 (I=5)", formula->toString()); - - delete formula; } TEST(PrctlParserTest, parseRewardNoBoundFormulaTest) { std::string input = "R = ? [ F a ]"; - storm::property::prctl::PrctlFilter<double>* formula = nullptr; + std::shared_ptr<prctl::PrctlFilter<double>> formula(nullptr); ASSERT_NO_THROW( formula = storm::parser::PrctlParser::parsePrctlFormula(input) ); @@ -103,13 +94,11 @@ TEST(PrctlParserTest, parseRewardNoBoundFormulaTest) { // The input was parsed correctly. ASSERT_EQ("R = ? (F a)", formula->toString()); - - delete formula; } TEST(PrctlParserTest, parseProbabilisticNoBoundFormulaTest) { std::string input = "P = ? [ a U <= 4 b & (!c) ]"; - storm::property::prctl::PrctlFilter<double>* formula = nullptr; + std::shared_ptr<prctl::PrctlFilter<double>> formula(nullptr); ASSERT_NO_THROW( formula = storm::parser::PrctlParser::parsePrctlFormula(input) ); @@ -119,13 +108,11 @@ TEST(PrctlParserTest, parseProbabilisticNoBoundFormulaTest) { // The input was parsed correctly. ASSERT_EQ("P = ? (a U<=4 (b & !c))", formula->toString()); - - delete formula; } TEST(PrctlParserTest, parseComplexFormulaTest) { std::string input = "R<=0.5 [ S ] & (R > 15 [ C<=0.5 ] | !P < 0.4 [ G P>0.9 [F<=7 a & b] ])"; - storm::property::prctl::PrctlFilter<double>* formula = nullptr; + std::shared_ptr<prctl::PrctlFilter<double>> formula(nullptr); ASSERT_NO_THROW( formula = storm::parser::PrctlParser::parsePrctlFormula(input) ); @@ -135,35 +122,29 @@ TEST(PrctlParserTest, parseComplexFormulaTest) { // The input was parsed correctly. ASSERT_EQ("(R <= 0.500000 (S) & (R > 15.000000 (C <= 0.500000) | !P < 0.400000 (G P > 0.900000 (F<=7 (a & b)))))", formula->toString()); - - delete formula; } TEST(PrctlParserTest, wrongProbabilisticFormulaTest) { - storm::property::prctl::PrctlFilter<double>* formula = nullptr; + std::shared_ptr<prctl::PrctlFilter<double>> formula(nullptr); ASSERT_THROW( formula = storm::parser::PrctlParser::parsePrctlFormula("P > 0.5 [ a ]"), storm::exceptions::WrongFormatException ); - - delete formula; } TEST(PrctlParserTest, wrongFormulaTest) { - storm::property::prctl::PrctlFilter<double>* formula = nullptr; + std::shared_ptr<prctl::PrctlFilter<double>> formula(nullptr); ASSERT_THROW( formula = storm::parser::PrctlParser::parsePrctlFormula("(a | b) & +"), storm::exceptions::WrongFormatException ); - delete formula; } TEST(PrctlParserTest, wrongFormulaTest2) { - storm::property::prctl::PrctlFilter<double>* formula = nullptr; + std::shared_ptr<prctl::PrctlFilter<double>> formula(nullptr); ASSERT_THROW( formula = storm::parser::PrctlParser::parsePrctlFormula("P>0 [ F & a ]"), storm::exceptions::WrongFormatException ); - delete formula; } diff --git a/test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp b/test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp index 3e2b3c347..2d2850ac2 100644 --- a/test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp +++ b/test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp @@ -21,8 +21,8 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, Crowds) { storm::modelchecker::prctl::SparseDtmcPrctlModelChecker<double> mc(*dtmc, new storm::solver::GmmxxLinearEquationSolver<double>()); - storm::property::prctl::Ap<double>* apFormula = new storm::property::prctl::Ap<double>("observe0Greater1"); - storm::property::prctl::Eventually<double>* eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); + auto apFormula = std::make_shared<storm::property::prctl::Ap<double>>("observe0Greater1"); + auto eventuallyFormula = std::make_shared<storm::property::prctl::Eventually<double>>(apFormula); LOG4CPLUS_WARN(logger, "Model Checking P=? [F observe0Greater1] on crowds/crowds20_5..."); std::vector<double> result = eventuallyFormula->check(mc, false); @@ -30,10 +30,8 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, Crowds) { ASSERT_LT(std::abs(result[0] - 0.2296800237), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete eventuallyFormula; - - apFormula = new storm::property::prctl::Ap<double>("observeIGreater1"); - eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); + apFormula = std::make_shared<storm::property::prctl::Ap<double>>("observeIGreater1"); + eventuallyFormula = std::make_shared<storm::property::prctl::Eventually<double>>(apFormula); LOG4CPLUS_WARN(logger, "Model Checking P=? [F observeIGreater1] on crowds/crowds20_5..."); result = eventuallyFormula->check(mc, false); @@ -41,18 +39,14 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, Crowds) { ASSERT_LT(std::abs(result[0] - 0.05073232193), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete eventuallyFormula; - - apFormula = new storm::property::prctl::Ap<double>("observeOnlyTrueSender"); - eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); + apFormula = std::make_shared<storm::property::prctl::Ap<double>>("observeOnlyTrueSender"); + eventuallyFormula = std::make_shared<storm::property::prctl::Eventually<double>>(apFormula); LOG4CPLUS_WARN(logger, "Model Checking P=? [F observeOnlyTrueSender] on crowds/crowds20_5..."); result = eventuallyFormula->check(mc, false); LOG4CPLUS_WARN(logger, "Done."); ASSERT_LT(std::abs(result[0] - 0.22742171078), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - - delete eventuallyFormula; } @@ -71,8 +65,8 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, SynchronousLeader) { storm::modelchecker::prctl::SparseDtmcPrctlModelChecker<double> mc(*dtmc, new storm::solver::GmmxxLinearEquationSolver<double>()); - storm::property::prctl::Ap<double>* apFormula = new storm::property::prctl::Ap<double>("elected"); - storm::property::prctl::Eventually<double>* eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); + auto apFormula = std::make_shared<storm::property::prctl::Ap<double>>("elected"); + auto eventuallyFormula = std::make_shared<storm::property::prctl::Eventually<double>>(apFormula); LOG4CPLUS_WARN(logger, "Model Checking P=? [F elected] on synchronous_leader/leader6_8..."); std::vector<double> result = eventuallyFormula->check(mc, false); @@ -80,10 +74,8 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, SynchronousLeader) { ASSERT_LT(std::abs(result[0] - 1.0), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete eventuallyFormula; - - apFormula = new storm::property::prctl::Ap<double>("elected"); - storm::property::prctl::BoundedUntil<double>* boundedUntilFormula = new storm::property::prctl::BoundedUntil<double>(new storm::property::prctl::Ap<double>("true"), apFormula, 20); + apFormula = std::make_shared<storm::property::prctl::Ap<double>>("elected"); + auto boundedUntilFormula = std::make_shared<storm::property::prctl::BoundedUntil<double>>(std::make_shared<storm::property::prctl::Ap<double>>("true"), apFormula, 20); LOG4CPLUS_WARN(logger, "Model Checking P=? [F<=20 elected] on synchronous_leader/leader6_8..."); result = boundedUntilFormula->check(mc, false); @@ -91,16 +83,12 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, SynchronousLeader) { ASSERT_LT(std::abs(result[0] - 0.9993949793), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete boundedUntilFormula; - - apFormula = new storm::property::prctl::Ap<double>("elected"); - storm::property::prctl::ReachabilityReward<double>* reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward<double>(apFormula); + apFormula = std::make_shared<storm::property::prctl::Ap<double>>("elected"); + auto reachabilityRewardFormula = std::make_shared<storm::property::prctl::ReachabilityReward<double>>(apFormula); LOG4CPLUS_WARN(logger, "Model Checking R=? [F elected] on synchronous_leader/leader6_8..."); result = reachabilityRewardFormula->check(mc, false); LOG4CPLUS_WARN(logger, "Done."); ASSERT_LT(std::abs(result[0] - 1.025106273), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - - delete reachabilityRewardFormula; } diff --git a/test/performance/modelchecker/SparseMdpPrctlModelCheckerTest.cpp b/test/performance/modelchecker/SparseMdpPrctlModelCheckerTest.cpp index 259fb6c73..3152e0b6d 100644 --- a/test/performance/modelchecker/SparseMdpPrctlModelCheckerTest.cpp +++ b/test/performance/modelchecker/SparseMdpPrctlModelCheckerTest.cpp @@ -19,8 +19,8 @@ TEST(SparseMdpPrctlModelCheckerTest, AsynchronousLeader) { storm::modelchecker::prctl::SparseMdpPrctlModelChecker<double> mc(*mdp, std::shared_ptr<storm::solver::NativeNondeterministicLinearEquationSolver<double>>(new storm::solver::NativeNondeterministicLinearEquationSolver<double>())); - storm::property::prctl::Ap<double>* apFormula = new storm::property::prctl::Ap<double>("elected"); - storm::property::prctl::Eventually<double>* eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); + auto apFormula = std::make_shared<storm::property::prctl::Ap<double>>("elected"); + auto eventuallyFormula = std::make_shared<storm::property::prctl::Eventually<double>>(apFormula); std::vector<double> result = mc.checkOptimizingOperator(*eventuallyFormula, true); @@ -30,10 +30,8 @@ TEST(SparseMdpPrctlModelCheckerTest, AsynchronousLeader) { ASSERT_LT(std::abs(result[0] - 1.0), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete eventuallyFormula; - - apFormula = new storm::property::prctl::Ap<double>("elected"); - storm::property::prctl::BoundedEventually<double>* boundedEventuallyFormula = new storm::property::prctl::BoundedEventually<double>(apFormula, 25); + apFormula = std::make_shared<storm::property::prctl::Ap<double>>("elected"); + auto boundedEventuallyFormula = std::make_shared<storm::property::prctl::BoundedEventually<double>>(apFormula, 25); result = mc.checkOptimizingOperator(*boundedEventuallyFormula, true); @@ -43,10 +41,8 @@ TEST(SparseMdpPrctlModelCheckerTest, AsynchronousLeader) { ASSERT_LT(std::abs(result[0] - 0.0), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete boundedEventuallyFormula; - - apFormula = new storm::property::prctl::Ap<double>("elected"); - storm::property::prctl::ReachabilityReward<double>* reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward<double>(apFormula); + apFormula = std::make_shared<storm::property::prctl::Ap<double>>("elected"); + auto reachabilityRewardFormula = std::make_shared<storm::property::prctl::ReachabilityReward<double>>(apFormula); result = mc.checkOptimizingOperator(*reachabilityRewardFormula, true); @@ -55,8 +51,6 @@ TEST(SparseMdpPrctlModelCheckerTest, AsynchronousLeader) { result = mc.checkOptimizingOperator(*reachabilityRewardFormula, false); ASSERT_LT(std::abs(result[0] - 6.1724344), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - - delete reachabilityRewardFormula; } TEST(SparseMdpPrctlModelCheckerTest, Consensus) { @@ -75,51 +69,43 @@ TEST(SparseMdpPrctlModelCheckerTest, Consensus) { storm::modelchecker::prctl::SparseMdpPrctlModelChecker<double> mc(*mdp, std::shared_ptr<storm::solver::NativeNondeterministicLinearEquationSolver<double>>(new storm::solver::NativeNondeterministicLinearEquationSolver<double>())); - storm::property::prctl::Ap<double>* apFormula = new storm::property::prctl::Ap<double>("finished"); - storm::property::prctl::Eventually<double>* eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); + auto apFormula = std::make_shared<storm::property::prctl::Ap<double>>("finished"); + auto eventuallyFormula = std::make_shared<storm::property::prctl::Eventually<double>>(apFormula); std::vector<double> result = mc.checkOptimizingOperator(*eventuallyFormula, true); ASSERT_LT(std::abs(result[31168] - 1.0), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - - delete eventuallyFormula; - apFormula = new storm::property::prctl::Ap<double>("finished"); - storm::property::prctl::Ap<double>* apFormula2 = new storm::property::prctl::Ap<double>("all_coins_equal_0"); - storm::property::prctl::And<double>* andFormula = new storm::property::prctl::And<double>(apFormula, apFormula2); - eventuallyFormula = new storm::property::prctl::Eventually<double>(andFormula); + apFormula = std::make_shared<storm::property::prctl::Ap<double>>("finished"); + auto apFormula2 = std::make_shared<storm::property::prctl::Ap<double>>("all_coins_equal_0"); + auto andFormula = std::make_shared<storm::property::prctl::And<double>>(apFormula, apFormula2); + eventuallyFormula = std::make_shared<storm::property::prctl::Eventually<double>>(andFormula); result = mc.checkOptimizingOperator(*eventuallyFormula, true); ASSERT_LT(std::abs(result[31168] - 0.4374282832), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - - delete eventuallyFormula; - apFormula = new storm::property::prctl::Ap<double>("finished"); - apFormula2 = new storm::property::prctl::Ap<double>("all_coins_equal_1"); - andFormula = new storm::property::prctl::And<double>(apFormula, apFormula2); - eventuallyFormula = new storm::property::prctl::Eventually<double>(andFormula); + apFormula = std::make_shared<storm::property::prctl::Ap<double>>("finished"); + apFormula2 = std::make_shared<storm::property::prctl::Ap<double>>("all_coins_equal_1"); + andFormula = std::make_shared<storm::property::prctl::And<double>>(apFormula, apFormula2); + eventuallyFormula = std::make_shared<storm::property::prctl::Eventually<double>>(andFormula); result = mc.checkOptimizingOperator(*eventuallyFormula, false); ASSERT_LT(std::abs(result[31168] - 0.5293286369), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - - delete eventuallyFormula; - apFormula = new storm::property::prctl::Ap<double>("finished"); - apFormula2 = new storm::property::prctl::Ap<double>("agree"); - storm::property::prctl::Not<double>* notFormula = new storm::property::prctl::Not<double>(apFormula2); - andFormula = new storm::property::prctl::And<double>(apFormula, notFormula); - eventuallyFormula = new storm::property::prctl::Eventually<double>(andFormula); + apFormula = std::make_shared<storm::property::prctl::Ap<double>>("finished"); + apFormula2 = std::make_shared<storm::property::prctl::Ap<double>>("agree"); + auto notFormula = std::make_shared<storm::property::prctl::Not<double>>(apFormula2); + andFormula = std::make_shared<storm::property::prctl::And<double>>(apFormula, notFormula); + eventuallyFormula = std::make_shared<storm::property::prctl::Eventually<double>>(andFormula); result = mc.checkOptimizingOperator(*eventuallyFormula, false); ASSERT_LT(std::abs(result[31168] - 0.10414097), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - - delete eventuallyFormula; - apFormula = new storm::property::prctl::Ap<double>("finished"); - storm::property::prctl::BoundedEventually<double>* boundedEventuallyFormula = new storm::property::prctl::BoundedEventually<double>(apFormula, 50ull); + apFormula = std::make_shared<storm::property::prctl::Ap<double>>("finished"); + auto boundedEventuallyFormula = std::make_shared<storm::property::prctl::BoundedEventually<double>>(apFormula, 50ull); result = mc.checkOptimizingOperator(*boundedEventuallyFormula, true); @@ -129,10 +115,8 @@ TEST(SparseMdpPrctlModelCheckerTest, Consensus) { ASSERT_LT(std::abs(result[31168] - 0.0), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete boundedEventuallyFormula; - - apFormula = new storm::property::prctl::Ap<double>("finished"); - storm::property::prctl::ReachabilityReward<double>* reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward<double>(apFormula); + apFormula = std::make_shared<storm::property::prctl::Ap<double>>("finished"); + auto reachabilityRewardFormula = std::make_shared<storm::property::prctl::ReachabilityReward<double>>(apFormula); result = mc.checkOptimizingOperator(*reachabilityRewardFormula, true); @@ -141,6 +125,4 @@ TEST(SparseMdpPrctlModelCheckerTest, Consensus) { result = mc.checkOptimizingOperator(*reachabilityRewardFormula, false); ASSERT_LT(std::abs(result[31168] - 2183.142422), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - - delete reachabilityRewardFormula; } From 2c59dd6f32277a5aa3e6c7f4a1a0d895aef3b0c4 Mon Sep 17 00:00:00 2001 From: masawei <manuel.sascha.weiand@rwth-aachen.de> Date: Mon, 21 Jul 2014 16:36:34 +0200 Subject: [PATCH 18/30] Finished unit tests for the actions. Next up: Update the parser tests. Former-commit-id: c0db7bd1d4ed52c8b38c2e3565bc50f699331e55 --- src/formula/actions/RangeAction.h | 6 +- src/formula/actions/SortAction.h | 8 +- test/functional/parser/ActionTest.cpp | 365 +++++++++++++++++++++++++- 3 files changed, 369 insertions(+), 10 deletions(-) diff --git a/src/formula/actions/RangeAction.h b/src/formula/actions/RangeAction.h index 85cf7c4af..ccb66fe00 100644 --- a/src/formula/actions/RangeAction.h +++ b/src/formula/actions/RangeAction.h @@ -26,11 +26,11 @@ public: } /*! - * Excluding the state with position to. + * Including the state with position to. */ RangeAction(uint_fast64_t from, uint_fast64_t to) : from(from), to(to) { if(from > to) { - throw storm::exceptions::IllegalArgumentException() << "The end of the range is lower than its beginning"; + throw storm::exceptions::IllegalArgumentValueException() << "The end of the range is lower than its beginning"; } } @@ -103,7 +103,7 @@ private: } //Fill the output vector. - for(uint_fast64_t i=0; i < end; i++) { + for(uint_fast64_t i=0; i <= end; i++) { out.set(result.stateMap[from + i], result.selection[result.stateMap[from + i]]); } diff --git a/src/formula/actions/SortAction.h b/src/formula/actions/SortAction.h index d75e32fd7..35bc31026 100644 --- a/src/formula/actions/SortAction.h +++ b/src/formula/actions/SortAction.h @@ -137,9 +137,9 @@ private: // Sort the state map. if(ascending) { - std::sort(outMap.begin(), outMap.end(), [&] (uint_fast64_t a, uint_fast64_t b) -> bool { return values[a] <= values[b]; }); + std::sort(outMap.begin(), outMap.end(), [&] (uint_fast64_t a, uint_fast64_t b) -> bool { return values[a] == values[b] ? a < b : values[a] < values[b]; }); } else { - std::sort(outMap.begin(), outMap.end(), [&] (uint_fast64_t a, uint_fast64_t b) -> bool { return values[a] >= values[b]; }); + std::sort(outMap.begin(), outMap.end(), [&] (uint_fast64_t a, uint_fast64_t b) -> bool { return values[a] == values[b] ? a < b : values[a] > values[b]; }); } return outMap; @@ -155,9 +155,9 @@ private: // Sort the state map. if(ascending) { - std::sort(outMap.begin(), outMap.end(), [&] (uint_fast64_t a, uint_fast64_t b) -> bool { return values[a] <= values[b]; }); + std::sort(outMap.begin(), outMap.end(), [&] (uint_fast64_t a, uint_fast64_t b) -> bool { return values[a] == values[b] ? a < b : values[a] < values[b]; }); } else { - std::sort(outMap.begin(), outMap.end(), [&] (uint_fast64_t a, uint_fast64_t b) -> bool { return values[a] >= values[b]; }); + std::sort(outMap.begin(), outMap.end(), [&] (uint_fast64_t a, uint_fast64_t b) -> bool { return values[a] == values[b] ? a < b : values[a] > values[b]; }); } return outMap; diff --git a/test/functional/parser/ActionTest.cpp b/test/functional/parser/ActionTest.cpp index 5454c5787..647d8464f 100644 --- a/test/functional/parser/ActionTest.cpp +++ b/test/functional/parser/ActionTest.cpp @@ -10,6 +10,9 @@ #include "src/formula/actions/BoundAction.h" #include "src/formula/actions/FormulaAction.h" +#include "src/formula/actions/InvertAction.h" +#include "src/formula/actions/RangeAction.h" +#include "src/formula/actions/SortAction.h" #include "src/parser/MarkovAutomatonParser.h" #include "src/parser/DeterministicModelParser.h" @@ -175,6 +178,7 @@ TEST(ActionTest, FormulaActionFunctionality) { // Build the filter input. // Basically the modelchecking result of "F a" on the used DTMC. std::vector<double> pathResult = mc.checkEventually(storm::property::prctl::Eventually<double>(std::make_shared<storm::property::prctl::Ap<double>>("a")), false); + storm::storage::BitVector stateResult = mc.checkAp(storm::property::prctl::Ap<double>("c")); std::vector<uint_fast64_t> stateMap(pathResult.size()); for(uint_fast64_t i = 0; i < pathResult.size(); i++) { stateMap[i] = i; @@ -193,13 +197,13 @@ TEST(ActionTest, FormulaActionFunctionality) { } else { ASSERT_FALSE(result.selection[i]); } - ASSERT_EQ(i, stateMap[i]); - ASSERT_EQ(input.pathResult, result.pathResult); + ASSERT_EQ(i, result.stateMap[i]); + ASSERT_EQ(input.pathResult[i], result.pathResult[i]); } ASSERT_TRUE(result.stateResult.size() == 0); input.selection.set(0,true); - // Now test the general functionality for both results of path and state formulas. + // Now test the general functionality. action = storm::property::action::FormulaAction<double>(std::make_shared<storm::property::prctl::ProbabilisticBoundOperator<double>>(storm::property::LESS, 0.5, std::make_shared<storm::property::prctl::Eventually<double>>(std::make_shared<storm::property::prctl::Ap<double>>("b")))); ASSERT_NO_THROW(result = action.evaluate(input, mc)); ASSERT_TRUE(result.selection[0]); @@ -211,4 +215,359 @@ TEST(ActionTest, FormulaActionFunctionality) { ASSERT_FALSE(result.selection[6]); ASSERT_FALSE(result.selection[7]); + // Check that the actual modelchecking results are not touched. + ASSERT_EQ(input.stateResult.size(), result.stateResult.size()); + ASSERT_EQ(input.pathResult.size(), result.pathResult.size()); + for(uint_fast64_t i = 0; i < input.pathResult.size(); i++) { + ASSERT_EQ(input.pathResult[i], result.pathResult[i]); + } + + // Do the same but this time using a state result instead of a path result. + input.pathResult = std::vector<double>(); + input.stateResult = stateResult; + ASSERT_NO_THROW(result = action.evaluate(input, mc)); + ASSERT_TRUE(result.selection[0]); + ASSERT_TRUE(result.selection[1]); + ASSERT_TRUE(result.selection[2]); + ASSERT_FALSE(result.selection[3]); + ASSERT_FALSE(result.selection[4]); + ASSERT_TRUE(result.selection[5]); + ASSERT_FALSE(result.selection[6]); + ASSERT_FALSE(result.selection[7]); + + ASSERT_EQ(input.stateResult.size(), result.stateResult.size()); + ASSERT_EQ(input.pathResult.size(), result.pathResult.size()); + for(uint_fast64_t i = 0; i < input.stateResult.size(); i++) { + ASSERT_EQ(input.stateResult[i], result.stateResult[i]); + } +} + +TEST(ActionTest, FormulaActionSafety){ + // Setup the modelchecker. + storm::models::Dtmc<double> model = storm::parser::DeterministicModelParser::parseDtmc(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_actionTest.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/dtmc_actionTest.lab"); + storm::modelchecker::prctl::SparseDtmcPrctlModelChecker<double> mc(model, new storm::solver::GmmxxLinearEquationSolver<double>()); + + // Build the filter input. + // Basically the modelchecking result of "F a" on the used DTMC. + std::vector<double> pathResult = mc.checkEventually(storm::property::prctl::Eventually<double>(std::make_shared<storm::property::prctl::Ap<double>>("a")), false); + std::vector<uint_fast64_t> stateMap(pathResult.size()); + for(uint_fast64_t i = 0; i < pathResult.size(); i++) { + stateMap[i] = i; + } + Result input(storm::storage::BitVector(pathResult.size(), true), stateMap, pathResult, storm::storage::BitVector()); + Result result; + + // Check that constructing the action using a nullptr and using an empty constructor leads to the same behavior. + storm::property::action::FormulaAction<double> action(std::shared_ptr<storm::property::csl::AbstractStateFormula<double>>(nullptr)); + input.selection.set(0,false); + ASSERT_NO_THROW(result = action.evaluate(input, mc)); + for(uint_fast64_t i = 0; i < pathResult.size(); i++) { + if(i != 0) { + ASSERT_TRUE(result.selection[i]); + } else { + ASSERT_FALSE(result.selection[i]); + } + ASSERT_EQ(i, result.stateMap[i]); + ASSERT_EQ(input.pathResult[i], result.pathResult[i]); + } + ASSERT_TRUE(result.stateResult.size() == 0); + input.selection.set(0,true); + ASSERT_NO_THROW(action.toString()); +} + +TEST(ActionTest, InvertActionFunctionality){ + // Setup the modelchecker. + storm::models::Dtmc<double> model = storm::parser::DeterministicModelParser::parseDtmc(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_actionTest.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/dtmc_actionTest.lab"); + storm::modelchecker::prctl::SparseDtmcPrctlModelChecker<double> mc(model, new storm::solver::GmmxxLinearEquationSolver<double>()); + + // Build the filter input. + // Basically the modelchecking result of "F a" on the used DTMC. + std::vector<double> pathResult = mc.checkEventually(storm::property::prctl::Eventually<double>(std::make_shared<storm::property::prctl::Ap<double>>("a")), false); + storm::storage::BitVector stateResult = mc.checkAp(storm::property::prctl::Ap<double>("c")); + std::vector<uint_fast64_t> stateMap(pathResult.size()); + for(uint_fast64_t i = 0; i < pathResult.size(); i++) { + stateMap[i] = pathResult.size()-i-1; + } + Result input(storm::storage::BitVector(pathResult.size(), true), stateMap, pathResult, storm::storage::BitVector()); + Result result; + + // Check whether the selection becomes inverted while the rest stays the same. + storm::property::action::InvertAction<double> action; + input.selection.set(0,false); + ASSERT_NO_THROW(result = action.evaluate(input, mc)); + for(uint_fast64_t i = 0; i < pathResult.size(); i++) { + if(i != 0) { + ASSERT_FALSE(result.selection[i]); + } else { + ASSERT_TRUE(result.selection[i]); + } + ASSERT_EQ(pathResult.size()-i-1, result.stateMap[i]); + ASSERT_EQ(input.pathResult[i], result.pathResult[i]); + } + ASSERT_TRUE(result.stateResult.size() == 0); + input.selection.set(0,true); + ASSERT_NO_THROW(action.toString()); +} + +TEST(ActionTest, RangeActionFunctionality){ + // Setup the modelchecker. + storm::models::Dtmc<double> model = storm::parser::DeterministicModelParser::parseDtmc(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_actionTest.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/dtmc_actionTest.lab"); + storm::modelchecker::prctl::SparseDtmcPrctlModelChecker<double> mc(model, new storm::solver::GmmxxLinearEquationSolver<double>()); + + // Build the filter input. + // Basically the modelchecking result of "F a" on the used DTMC. + std::vector<double> pathResult = mc.checkEventually(storm::property::prctl::Eventually<double>(std::make_shared<storm::property::prctl::Ap<double>>("a")), false); + storm::storage::BitVector stateResult = mc.checkAp(storm::property::prctl::Ap<double>("c")); + std::vector<uint_fast64_t> stateMap(pathResult.size()); + for(uint_fast64_t i = 0; i < pathResult.size(); i++) { + stateMap[i] = i; + } + Result input(storm::storage::BitVector(pathResult.size(), true), stateMap, pathResult, storm::storage::BitVector()); + Result result; + + // Test if the action selects the first 3 states in relation to the order given by the stateMap. + // First in index order. + storm::property::action::RangeAction<double> action(0,2); + ASSERT_NO_THROW(result = action.evaluate(input, mc)); + for(uint_fast64_t i = 0; i < result.selection.size(); i++) { + ASSERT_EQ(input.stateMap[i], result.stateMap[i]); + } + for(uint_fast64_t i = 0; i < 3; i++) { + ASSERT_TRUE(result.selection[i]); + } + for(uint_fast64_t i = 3; i < result.selection.size(); i++) { + ASSERT_FALSE(result.selection[i]); + } + input.selection.clear(); + input.selection.complement(); + + // Now against index order. + for(uint_fast64_t i = 0; i < input.pathResult.size(); i++) { + input.stateMap[i] = input.pathResult.size()-i-1; + } + ASSERT_NO_THROW(result = action.evaluate(input, mc)); + for(uint_fast64_t i = 0; i < result.selection.size(); i++) { + ASSERT_EQ(input.stateMap[i], result.stateMap[i]); + } + for(uint_fast64_t i = 0; i < 3; i++) { + ASSERT_TRUE(result.selection[result.selection.size()-i-1]); + } + for(uint_fast64_t i = 3; i < result.selection.size(); i++) { + ASSERT_FALSE(result.selection[result.selection.size()-i-1]); + } + input.selection.clear(); + input.selection.complement(); + + // Finally test a random order. + std::srand(time(nullptr)); + uint_fast64_t pos1, pos2, temp; + for(uint_fast64_t i = 0; i < 100; i++) { + // Randomly select two positions. + pos1 = rand() % result.selection.size(); + pos2 = rand() % result.selection.size(); + + // Swap the values there. + temp = input.stateMap[pos1]; + input.stateMap[pos1] = input.stateMap[pos2]; + input.stateMap[pos2] = temp; + } + ASSERT_NO_THROW(result = action.evaluate(input, mc)); + for(uint_fast64_t i = 0; i < 8; i++) { + ASSERT_EQ(input.stateMap[i], result.stateMap[i]); + } + for(uint_fast64_t i = 0; i < 3; i++) { + ASSERT_TRUE(result.selection[result.stateMap[i]]); + } + for(uint_fast64_t i = 3; i < result.selection.size(); i++) { + ASSERT_FALSE(result.selection[result.stateMap[i]]); + } + + // Test that specifying and interval of (i,i) selects only state i. + for(uint_fast64_t i = 0; i < input.selection.size(); i++) { + action = storm::property::action::RangeAction<double>(i,i); + ASSERT_NO_THROW(result = action.evaluate(input, mc)); + ASSERT_EQ(1, result.selection.getNumberOfSetBits()); + ASSERT_TRUE(result.selection[result.stateMap[i]]); + } +} + +TEST(ActionTest, RangeActionSafety){ + // Setup the modelchecker. + storm::models::Dtmc<double> model = storm::parser::DeterministicModelParser::parseDtmc(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_actionTest.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/dtmc_actionTest.lab"); + storm::modelchecker::prctl::SparseDtmcPrctlModelChecker<double> mc(model, new storm::solver::GmmxxLinearEquationSolver<double>()); + + // Build the filter input. + // Basically the modelchecking result of "F a" on the used DTMC. + std::vector<double> pathResult = mc.checkEventually(storm::property::prctl::Eventually<double>(std::make_shared<storm::property::prctl::Ap<double>>("a")), false); + storm::storage::BitVector stateResult = mc.checkAp(storm::property::prctl::Ap<double>("c")); + std::vector<uint_fast64_t> stateMap(pathResult.size()); + for(uint_fast64_t i = 0; i < pathResult.size(); i++) { + stateMap[i] = i; + } + Result input(storm::storage::BitVector(pathResult.size(), true), stateMap, pathResult, storm::storage::BitVector()); + Result result; + + // Test invalid ranges. + + // To capture the warning, redirect cout and test the written buffer content. + std::stringstream buffer; + std::streambuf * sbuf = std::cout.rdbuf(); + std::cout.rdbuf(buffer.rdbuf()); + + storm::property::action::RangeAction<double> action(0,42); + ASSERT_NO_THROW(result = action.evaluate(input, mc)); + ASSERT_TRUE(result.selection.full()); + + ASSERT_FALSE(buffer.str().empty()); + buffer.str(""); + + action = storm::property::action::RangeAction<double>(42,98); + ASSERT_NO_THROW(result = action.evaluate(input, mc)); + ASSERT_TRUE(result.selection.empty()); + + ASSERT_FALSE(buffer.str().empty()); + std::cout.rdbuf(sbuf); + + ASSERT_THROW(storm::property::action::RangeAction<double>(3,1), storm::exceptions::IllegalArgumentValueException); +} + +TEST(ActionTest, SortActionFunctionality){ + // Setup the modelchecker. + storm::models::Dtmc<double> model = storm::parser::DeterministicModelParser::parseDtmc(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_actionTest.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/dtmc_actionTest.lab"); + storm::modelchecker::prctl::SparseDtmcPrctlModelChecker<double> mc(model, new storm::solver::GmmxxLinearEquationSolver<double>()); + + // Build the filter input. + // Basically the modelchecking result of "F a" on the used DTMC. + std::vector<double> pathResult = mc.checkEventually(storm::property::prctl::Eventually<double>(std::make_shared<storm::property::prctl::Ap<double>>("a")), false); + storm::storage::BitVector stateResult = mc.checkAp(storm::property::prctl::Ap<double>("c")); + std::vector<uint_fast64_t> stateMap(pathResult.size()); + for(uint_fast64_t i = 0; i < pathResult.size(); i++) { + stateMap[i] = pathResult.size()-i-1; + } + Result input(storm::storage::BitVector(pathResult.size(), true), stateMap, pathResult, storm::storage::BitVector()); + Result result; + + // Test that sorting preserves everything except the state map. + storm::property::action::SortAction<double> action; + ASSERT_NO_THROW(action.toString()); + input.selection.set(0,false); + ASSERT_NO_THROW(result = action.evaluate(input, mc)); + for(uint_fast64_t i = 0; i < pathResult.size(); i++) { + if(i != 0) { + ASSERT_TRUE(result.selection[i]); + } else { + ASSERT_FALSE(result.selection[i]); + } + ASSERT_EQ(i, result.stateMap[i]); + ASSERT_EQ(input.pathResult[i], result.pathResult[i]); + } + ASSERT_TRUE(result.stateResult.size() == 0); + input.selection.set(0,true); + + // Test sorting cases. Note that the input selection should be irrelevant for the resulting state order. + // 1) index, ascending -> see above + // 2) index descending + input.selection.set(3,false); + action = storm::property::action::SortAction<double>(storm::property::action::SortAction<double>::INDEX, false); + ASSERT_NO_THROW(result = action.evaluate(input, mc)); + for(uint_fast64_t i = 0; i < pathResult.size(); i++) { + ASSERT_EQ(pathResult.size()-i-1, result.stateMap[i]); + } + + // 3) value, ascending + action = storm::property::action::SortAction<double>(storm::property::action::SortAction<double>::VALUE); + ASSERT_NO_THROW(result = action.evaluate(input, mc)); + ASSERT_EQ(6, result.stateMap[0]); + ASSERT_EQ(7, result.stateMap[1]); + ASSERT_EQ(3, result.stateMap[2]); + ASSERT_EQ(4, result.stateMap[3]); + ASSERT_EQ(1, result.stateMap[4]); + ASSERT_EQ(0, result.stateMap[5]); + ASSERT_EQ(2, result.stateMap[6]); + ASSERT_EQ(5, result.stateMap[7]); + + // 3) value, decending + action = storm::property::action::SortAction<double>(storm::property::action::SortAction<double>::VALUE, false); + ASSERT_NO_THROW(result = action.evaluate(input, mc)); + ASSERT_EQ(5, result.stateMap[0]); + ASSERT_EQ(2, result.stateMap[1]); + ASSERT_EQ(0, result.stateMap[2]); + ASSERT_EQ(1, result.stateMap[3]); + ASSERT_EQ(4, result.stateMap[4]); + ASSERT_EQ(3, result.stateMap[5]); + ASSERT_EQ(6, result.stateMap[6]); + ASSERT_EQ(7, result.stateMap[7]); + + // Check that this also works for state results instead. + input.pathResult = std::vector<double>(); + input.stateResult = stateResult; + + action = storm::property::action::SortAction<double>(storm::property::action::SortAction<double>::VALUE); + ASSERT_NO_THROW(result = action.evaluate(input, mc)); + ASSERT_EQ(5, result.stateMap[0]); + ASSERT_EQ(6, result.stateMap[1]); + ASSERT_EQ(7, result.stateMap[2]); + ASSERT_EQ(0, result.stateMap[3]); + ASSERT_EQ(1, result.stateMap[4]); + ASSERT_EQ(2, result.stateMap[5]); + ASSERT_EQ(3, result.stateMap[6]); + ASSERT_EQ(4, result.stateMap[7]); + + action = storm::property::action::SortAction<double>(storm::property::action::SortAction<double>::VALUE, false); + ASSERT_NO_THROW(result = action.evaluate(input, mc)); + ASSERT_EQ(0, result.stateMap[0]); + ASSERT_EQ(1, result.stateMap[1]); + ASSERT_EQ(2, result.stateMap[2]); + ASSERT_EQ(3, result.stateMap[3]); + ASSERT_EQ(4, result.stateMap[4]); + ASSERT_EQ(5, result.stateMap[5]); + ASSERT_EQ(6, result.stateMap[6]); + ASSERT_EQ(7, result.stateMap[7]); + + // Test if the resulting order does not depend on the input order. + input.stateResult = storm::storage::BitVector(); + input.pathResult = pathResult; + + action = storm::property::action::SortAction<double>(storm::property::action::SortAction<double>::INDEX); + ASSERT_NO_THROW(input = action.evaluate(input, mc)); + action = storm::property::action::SortAction<double>(storm::property::action::SortAction<double>::VALUE); + ASSERT_NO_THROW(result = action.evaluate(input, mc)); + ASSERT_EQ(6, result.stateMap[0]); + ASSERT_EQ(7, result.stateMap[1]); + ASSERT_EQ(3, result.stateMap[2]); + ASSERT_EQ(4, result.stateMap[3]); + ASSERT_EQ(1, result.stateMap[4]); + ASSERT_EQ(0, result.stateMap[5]); + ASSERT_EQ(2, result.stateMap[6]); + ASSERT_EQ(5, result.stateMap[7]); + +} + +TEST(ActionTest, SortActionSafety){ + // Check that the path result has priority over the state result if for some erronous reason both are given. + // Setup the modelchecker. + storm::models::Dtmc<double> model = storm::parser::DeterministicModelParser::parseDtmc(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_actionTest.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/dtmc_actionTest.lab"); + storm::modelchecker::prctl::SparseDtmcPrctlModelChecker<double> mc(model, new storm::solver::GmmxxLinearEquationSolver<double>()); + + // Build the filter input. + // Basically the modelchecking result of "F a" on the used DTMC. + std::vector<double> pathResult = mc.checkEventually(storm::property::prctl::Eventually<double>(std::make_shared<storm::property::prctl::Ap<double>>("a")), false); + storm::storage::BitVector stateResult = mc.checkAp(storm::property::prctl::Ap<double>("c")); + std::vector<uint_fast64_t> stateMap(pathResult.size()); + for(uint_fast64_t i = 0; i < pathResult.size(); i++) { + stateMap[i] = pathResult.size()-i-1; + } + Result input(storm::storage::BitVector(pathResult.size(), true), stateMap, pathResult, stateResult); + Result result; + + storm::property::action::SortAction<double> action(storm::property::action::SortAction<double>::VALUE); + ASSERT_NO_THROW(result = action.evaluate(input, mc)); + ASSERT_EQ(6, result.stateMap[0]); + ASSERT_EQ(7, result.stateMap[1]); + ASSERT_EQ(3, result.stateMap[2]); + ASSERT_EQ(4, result.stateMap[3]); + ASSERT_EQ(1, result.stateMap[4]); + ASSERT_EQ(0, result.stateMap[5]); + ASSERT_EQ(2, result.stateMap[6]); + ASSERT_EQ(5, result.stateMap[7]); } From 1c4d7b9ef93b9a27585b5f165b27d1e11de54eb4 Mon Sep 17 00:00:00 2001 From: masawei <manuel.sascha.weiand@rwth-aachen.de> Date: Thu, 7 Aug 2014 15:34:03 +0200 Subject: [PATCH 19/30] Some more testing. Former-commit-id: 3105a0bf3b183212387c1998fa3e20abf44ea999 --- .../MILPMinimalLabelSetGenerator.h | 2 +- .../PathBasedSubsystemGenerator.h | 2 +- src/formula/actions/FormulaAction.h | 2 +- src/formula/actions/RangeAction.h | 6 +- src/formula/actions/SortAction.h | 4 +- src/formula/prctl/Next.h | 4 +- src/formula/prctl/PrctlFilter.h | 28 +++++-- .../prctl/ProbabilisticBoundOperator.h | 30 +++---- src/formula/prctl/RewardBoundOperator.h | 30 +++---- src/modelchecker/prctl/AbstractModelChecker.h | 4 +- .../prctl/SparseMdpPrctlModelChecker.h | 4 +- src/parser/PrctlParser.cpp | 27 +++--- .../{parser => modelchecker}/ActionTest.cpp | 0 test/functional/modelchecker/FilterTest.cpp | 83 +++++++++++++++++++ test/functional/parser/PrctlParserTest.cpp | 73 ++++++++++++++++ 15 files changed, 231 insertions(+), 68 deletions(-) rename test/functional/{parser => modelchecker}/ActionTest.cpp (100%) create mode 100644 test/functional/modelchecker/FilterTest.cpp diff --git a/src/counterexamples/MILPMinimalLabelSetGenerator.h b/src/counterexamples/MILPMinimalLabelSetGenerator.h index 8b151c834..7e57fff60 100644 --- a/src/counterexamples/MILPMinimalLabelSetGenerator.h +++ b/src/counterexamples/MILPMinimalLabelSetGenerator.h @@ -1016,7 +1016,7 @@ namespace storm { // Now derive the probability threshold we need to exceed as well as the phi and psi states. Simultaneously, check whether the formula is of a valid shape. double bound = probBoundFormula->getBound(); - std::shared_ptr<storm::property::prctl::AbstractPathFormula<double>> pathFormula = probBoundFormula->getPathFormula(); + std::shared_ptr<storm::property::prctl::AbstractPathFormula<double>> pathFormula = probBoundFormula->getChild(); storm::storage::BitVector phiStates; storm::storage::BitVector psiStates; storm::modelchecker::prctl::SparseMdpPrctlModelChecker<T> modelchecker(labeledMdp); diff --git a/src/counterexamples/PathBasedSubsystemGenerator.h b/src/counterexamples/PathBasedSubsystemGenerator.h index 94a7cc955..2713643bf 100644 --- a/src/counterexamples/PathBasedSubsystemGenerator.h +++ b/src/counterexamples/PathBasedSubsystemGenerator.h @@ -402,7 +402,7 @@ public: return model.getSubDtmc(subSys); } T bound = boundOperator->getBound(); - std::shared_ptr<storm::property::prctl::AbstractPathFormula<T>> pathFormula = boundOperator->getPathFormula();; + std::shared_ptr<storm::property::prctl::AbstractPathFormula<T>> pathFormula = boundOperator->getChild(); // get "init" labeled states storm::storage::BitVector initStates = model.getLabeledStates("init"); diff --git a/src/formula/actions/FormulaAction.h b/src/formula/actions/FormulaAction.h index c22f8d7a0..9ac3ad861 100644 --- a/src/formula/actions/FormulaAction.h +++ b/src/formula/actions/FormulaAction.h @@ -80,7 +80,7 @@ public: * */ virtual std::string toString() const override { - std::string out = "states("; + std::string out = "formula("; if(prctlFormula.get() != nullptr) { out += prctlFormula->toString(); } else if(cslFormula.get() != nullptr) { diff --git a/src/formula/actions/RangeAction.h b/src/formula/actions/RangeAction.h index ccb66fe00..382492d49 100644 --- a/src/formula/actions/RangeAction.h +++ b/src/formula/actions/RangeAction.h @@ -87,16 +87,16 @@ private: uint_fast64_t end = to - from; // Safety check for access bounds. - if(from > result.stateMap.size()) { + if(from >= result.stateMap.size()) { LOG4CPLUS_WARN(logger, "Range begins behind the end of the states by " << to - result.stateMap.size() << ". No state was selected."); std::cout << "Range begins behind the end of the states by " << to - result.stateMap.size() << ". No state was selected." << std::endl; return Result(out, result.stateMap, result.pathResult, result.stateResult); } - if(to > result.stateMap.size()) { + if(to >= result.stateMap.size()) { - end = result.selection.size() - from; + end = result.selection.size() - from - 1; LOG4CPLUS_WARN(logger, "Range ends behind the end of the states by " << to - result.stateMap.size() << ". The range has been cut at the last state."); std::cout << "Range ends behind the end of the states by " << to - result.stateMap.size() << ". The range has been cut at the last state." << std::endl; diff --git a/src/formula/actions/SortAction.h b/src/formula/actions/SortAction.h index 35bc31026..ea676dfd4 100644 --- a/src/formula/actions/SortAction.h +++ b/src/formula/actions/SortAction.h @@ -65,7 +65,7 @@ public: * */ virtual std::string toString() const override { - std::string out = "sort, "; + std::string out = "sort("; switch (category) { case INDEX: out += "index"; @@ -79,7 +79,7 @@ public: break; } out += ", "; - out += ascending ? "ascending" : "descending"; + out += ascending ? "ascending)" : "descending)"; return out; } diff --git a/src/formula/prctl/Next.h b/src/formula/prctl/Next.h index 3cff6892a..49b66c062 100644 --- a/src/formula/prctl/Next.h +++ b/src/formula/prctl/Next.h @@ -113,10 +113,8 @@ public: * @returns a string representation of the formula */ virtual std::string toString() const override { - std::string result = "("; - result += " X "; + std::string result = "X "; result += child->toString(); - result += ")"; return result; } diff --git a/src/formula/prctl/PrctlFilter.h b/src/formula/prctl/PrctlFilter.h index 2f45b0ba3..161a9d3f8 100644 --- a/src/formula/prctl/PrctlFilter.h +++ b/src/formula/prctl/PrctlFilter.h @@ -65,6 +65,11 @@ public: LOG4CPLUS_INFO(logger, "Model checking formula\t" << this->toString()); std::cout << "Model checking formula:\t" << this->toString() << std::endl; + writeOut(evaluate(modelchecker), modelchecker); + } + + Result evaluate(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelchecker) const { + Result result; try { @@ -78,13 +83,9 @@ public: } catch (std::exception& e) { std::cout << "Error during computation: " << e.what() << "Skipping property." << std::endl; LOG4CPLUS_ERROR(logger, "Error during computation: " << e.what() << "Skipping property."); - std::cout << std::endl << "-------------------------------------------" << std::endl; - - return; } - writeOut(result, modelchecker); - + return result; } virtual std::string toString() const override { @@ -239,12 +240,14 @@ private: return evaluateActions(result, modelchecker); } - Result evaluateActions(Result result, storm::modelchecker::prctl::AbstractModelChecker<T> const & modelchecker) const { + Result evaluateActions(Result const & input, storm::modelchecker::prctl::AbstractModelChecker<T> const & modelchecker) const { // Init the state selection and state map vectors. - result.selection = storm::storage::BitVector(result.stateResult.size(), true); - result.stateMap = std::vector<uint_fast64_t>(result.selection.size()); - for(uint_fast64_t i = 0; i < result.selection.size(); i++) { + Result result = input; + uint_fast64_t size = result.stateResult.size() == 0 ? result.pathResult.size() : result.stateResult.size(); + result.selection = storm::storage::BitVector(size, true); + result.stateMap = std::vector<uint_fast64_t>(size); + for(uint_fast64_t i = 0; i < size; i++) { result.stateMap[i] = i; } @@ -258,6 +261,13 @@ private: void writeOut(Result const & result, storm::modelchecker::prctl::AbstractModelChecker<T> const & modelchecker) const { + // Test if there is anything to write out. + // The selection size should only be 0 if an error occurred during the evaluation (since a model with 0 states is invalid). + if(result.selection.size() == 0) { + std::cout << std::endl << "-------------------------------------------" << std::endl; + return; + } + // Test for the kind of result. Values or states. if(!result.pathResult.empty()) { diff --git a/src/formula/prctl/ProbabilisticBoundOperator.h b/src/formula/prctl/ProbabilisticBoundOperator.h index 0fbe1339c..e1557ce04 100644 --- a/src/formula/prctl/ProbabilisticBoundOperator.h +++ b/src/formula/prctl/ProbabilisticBoundOperator.h @@ -60,7 +60,7 @@ public: /*! * Empty constructor */ - ProbabilisticBoundOperator() : comparisonOperator(LESS), bound(0), pathFormula(nullptr) { + ProbabilisticBoundOperator() : comparisonOperator(LESS), bound(0), child(nullptr) { // Intentionally left empty. } @@ -69,10 +69,10 @@ public: * * @param comparisonOperator The relation for the bound. * @param bound The bound for the probability - * @param pathFormula The child node + * @param child The child node */ - ProbabilisticBoundOperator(storm::property::ComparisonType comparisonOperator, T bound, std::shared_ptr<AbstractPathFormula<T>> const & pathFormula) - : comparisonOperator(comparisonOperator), bound(bound), pathFormula(pathFormula) { + ProbabilisticBoundOperator(storm::property::ComparisonType comparisonOperator, T bound, std::shared_ptr<AbstractPathFormula<T>> const & child) + : comparisonOperator(comparisonOperator), bound(bound), child(child) { // Intentionally left empty. } @@ -96,7 +96,7 @@ public: std::shared_ptr<ProbabilisticBoundOperator<T>> result(new ProbabilisticBoundOperator<T>()); result->setComparisonOperator(comparisonOperator); result->setBound(bound); - result->setPathFormula(pathFormula->clone()); + result->setChild(child->clone()); return result; } @@ -120,7 +120,7 @@ public: * @return true iff the subtree conforms to some logic. */ virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { - return checker.validate(pathFormula); + return checker.validate(child); } /*! @@ -137,7 +137,7 @@ public: result += " "; result += std::to_string(bound); result += " ("; - result += pathFormula->toString(); + result += child->toString(); result += ")"; return result; } @@ -145,25 +145,25 @@ public: /*! * @returns the child node (representation of a formula) */ - std::shared_ptr<AbstractPathFormula<T>> const & getPathFormula () const { - return pathFormula; + std::shared_ptr<AbstractPathFormula<T>> const & getChild () const { + return child; } /*! * Sets the child node * - * @param pathFormula the path formula that becomes the new child node + * @param child the path formula that becomes the new child node */ - void setPathFormula(std::shared_ptr<AbstractPathFormula<T>> const & pathFormula) { - this->pathFormula = pathFormula; + void setChild(std::shared_ptr<AbstractPathFormula<T>> const & child) { + this->child = child; } /*! * * @return True if the path formula is set, i.e. it does not point to nullptr; false otherwise */ - bool pathFormulaIsSet() const { - return pathFormula.get() != nullptr; + bool childIsSet() const { + return child.get() != nullptr; } /*! @@ -206,7 +206,7 @@ public: private: storm::property::ComparisonType comparisonOperator; T bound; - std::shared_ptr<AbstractPathFormula<T>> pathFormula; + std::shared_ptr<AbstractPathFormula<T>> child; }; } //namespace prctl diff --git a/src/formula/prctl/RewardBoundOperator.h b/src/formula/prctl/RewardBoundOperator.h index 15fbd5886..cfebea0d6 100644 --- a/src/formula/prctl/RewardBoundOperator.h +++ b/src/formula/prctl/RewardBoundOperator.h @@ -58,7 +58,7 @@ public: /*! * Empty constructor */ - RewardBoundOperator() : comparisonOperator(LESS), bound(0), pathFormula(nullptr){ + RewardBoundOperator() : comparisonOperator(LESS), bound(0), child(nullptr){ // Intentionally left empty } @@ -67,10 +67,10 @@ public: * * @param comparisonOperator The relation for the bound. * @param bound The bound for the probability - * @param pathFormula The child node + * @param child The child node */ - RewardBoundOperator(storm::property::ComparisonType comparisonOperator, T bound, std::shared_ptr<AbstractRewardPathFormula<T>> const & pathFormula) - : comparisonOperator(comparisonOperator), bound(bound), pathFormula(pathFormula) { + RewardBoundOperator(storm::property::ComparisonType comparisonOperator, T bound, std::shared_ptr<AbstractRewardPathFormula<T>> const & child) + : comparisonOperator(comparisonOperator), bound(bound), child(child) { // Intentionally left empty } @@ -94,7 +94,7 @@ public: std::shared_ptr<RewardBoundOperator<T>> result(new RewardBoundOperator<T>()); result->setComparisonOperator(comparisonOperator); result->setBound(bound); - result->setPathFormula(pathFormula->clone()); + result->setChild(child->clone()); return result; } @@ -118,7 +118,7 @@ public: * @return true iff the subtree conforms to some logic. */ virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { - return checker.validate(this->pathFormula); + return checker.validate(this->child); } /*! @@ -135,7 +135,7 @@ public: result += " "; result += std::to_string(bound); result += " ("; - result += pathFormula->toString(); + result += child->toString(); result += ")"; return result; } @@ -143,25 +143,25 @@ public: /*! * @returns the child node (representation of a formula) */ - std::shared_ptr<AbstractRewardPathFormula<T>> const & getPathFormula () const { - return pathFormula; + std::shared_ptr<AbstractRewardPathFormula<T>> const & getChild () const { + return child; } /*! * Sets the child node * - * @param pathFormula the path formula that becomes the new child node + * @param child the path formula that becomes the new child node */ - void setPathFormula(std::shared_ptr<AbstractRewardPathFormula<T>> const & pathFormula) { - this->pathFormula = pathFormula; + void setChild(std::shared_ptr<AbstractRewardPathFormula<T>> const & child) { + this->child = child; } /*! * * @return True if the path formula is set, i.e. it does not point to nullptr; false otherwise */ - bool pathFormulaIsSet() const { - return pathFormula.get() != nullptr; + bool childIsSet() const { + return child.get() != nullptr; } /*! @@ -204,7 +204,7 @@ public: private: storm::property::ComparisonType comparisonOperator; T bound; - std::shared_ptr<AbstractRewardPathFormula<T>> pathFormula; + std::shared_ptr<AbstractRewardPathFormula<T>> child; }; } //namespace prctl diff --git a/src/modelchecker/prctl/AbstractModelChecker.h b/src/modelchecker/prctl/AbstractModelChecker.h index 7158ee9ff..f33cd8952 100644 --- a/src/modelchecker/prctl/AbstractModelChecker.h +++ b/src/modelchecker/prctl/AbstractModelChecker.h @@ -189,7 +189,7 @@ public: */ virtual storm::storage::BitVector checkProbabilisticBoundOperator(storm::property::prctl::ProbabilisticBoundOperator<Type> const& formula) const { // First, we need to compute the probability for satisfying the path formula for each state. - std::vector<Type> quantitativeResult = formula.getPathFormula()->check(*this, false); + std::vector<Type> quantitativeResult = formula.getChild()->check(*this, false); // Create resulting bit vector that will hold the yes/no-answer for every state. storm::storage::BitVector result(quantitativeResult.size()); @@ -213,7 +213,7 @@ public: */ virtual storm::storage::BitVector checkRewardBoundOperator(const storm::property::prctl::RewardBoundOperator<Type>& formula) const { // First, we need to compute the probability for satisfying the path formula for each state. - std::vector<Type> quantitativeResult = formula.getPathFormula()->check(*this, false); + std::vector<Type> quantitativeResult = formula.getChild()->check(*this, false); // Create resulting bit vector that will hold the yes/no-answer for every state. storm::storage::BitVector result(quantitativeResult.size()); diff --git a/src/modelchecker/prctl/SparseMdpPrctlModelChecker.h b/src/modelchecker/prctl/SparseMdpPrctlModelChecker.h index 23613d185..239a0a37f 100644 --- a/src/modelchecker/prctl/SparseMdpPrctlModelChecker.h +++ b/src/modelchecker/prctl/SparseMdpPrctlModelChecker.h @@ -87,7 +87,7 @@ namespace storm { } // First, we need to compute the probability for satisfying the path formula for each state. - std::vector<Type> quantitativeResult = formula.getPathFormula()->check(*this, false); + std::vector<Type> quantitativeResult = formula.getChild()->check(*this, false); //Remove the minimizing operator entry from the stack. this->minimumOperatorStack.pop(); @@ -124,7 +124,7 @@ namespace storm { } // First, we need to compute the probability for satisfying the path formula for each state. - std::vector<Type> quantitativeResult = formula.getPathFormula()->check(*this, false); + std::vector<Type> quantitativeResult = formula.getChild()->check(*this, false); //Remove the minimizing operator entry from the stack. this->minimumOperatorStack.pop(); diff --git a/src/parser/PrctlParser.cpp b/src/parser/PrctlParser.cpp index 6f3dc8812..35036ffcf 100644 --- a/src/parser/PrctlParser.cpp +++ b/src/parser/PrctlParser.cpp @@ -79,11 +79,10 @@ struct PrctlParser::PrctlGrammar : qi::grammar<Iterator, std::shared_ptr<storm:: atomicProposition = (freeIdentifierName)[qi::_val = MAKE(prctl::Ap<double>, qi::_1)]; atomicProposition.name("atomic proposition"); - probabilisticBoundOperator = ((qi::lit("P") >> comparisonType > qi::double_ > qi::lit("[") > pathFormula > qi::lit("]"))[qi::_val = + probabilisticBoundOperator = ((qi::lit("P") >> comparisonType > qi::double_ > pathFormula)[qi::_val = MAKE(prctl::ProbabilisticBoundOperator<double>, qi::_1, qi::_2, qi::_3)]); - probabilisticBoundOperator.name("probabilistic bound operator"); - rewardBoundOperator = ((qi::lit("R") >> comparisonType > qi::double_ > qi::lit("[") > rewardPathFormula > qi::lit("]"))[qi::_val = + rewardBoundOperator = ((qi::lit("R") >> comparisonType > qi::double_ > rewardPathFormula)[qi::_val = MAKE(prctl::RewardBoundOperator<double>, qi::_1, qi::_2, qi::_3)]); rewardBoundOperator.name("reward bound operator"); @@ -92,22 +91,22 @@ struct PrctlParser::PrctlGrammar : qi::grammar<Iterator, std::shared_ptr<storm:: pathFormula.name("path formula"); boundedEventually = (qi::lit("F") >> qi::lit("<=") > qi::int_ > stateFormula)[qi::_val = MAKE(prctl::BoundedEventually<double>, qi::_2, qi::_1)]; - boundedEventually.name("path formula (for probabilistic operator)"); + boundedEventually.name("bounded eventually"); eventually = (qi::lit("F") > stateFormula)[qi::_val = MAKE(prctl::Eventually<double>, qi::_1)]; - eventually.name("path formula (for probabilistic operator)"); + eventually.name("eventually"); next = (qi::lit("X") > stateFormula)[qi::_val = MAKE(prctl::Next<double>, qi::_1)]; - next.name("path formula (for probabilistic operator)"); + next.name("next"); globally = (qi::lit("G") > stateFormula)[qi::_val = MAKE(prctl::Globally<double>, qi::_1)]; - globally.name("path formula (for probabilistic operator)"); + globally.name("globally"); boundedUntil = (stateFormula[qi::_a = qi::_1] >> qi::lit("U") >> qi::lit("<=") > qi::int_ > stateFormula)[qi::_val = MAKE(prctl::BoundedUntil<double>, qi::_a, qi::_3, qi::_2)]; - boundedUntil.name("path formula (for probabilistic operator)"); + boundedUntil.name("boundedUntil"); until = (stateFormula[qi::_a = qi::_1] >> qi::lit("U") > stateFormula)[qi::_val = MAKE(prctl::Until<double>, qi::_a, qi::_2)]; - until.name("path formula (for probabilistic operator)"); + until.name("until"); // This block defines rules for parsing reward path formulas. rewardPathFormula = (cumulativeReward | reachabilityReward | instantaneousReward | steadyStateReward | qi::lit("(") >> rewardPathFormula >> qi::lit(")") | qi::lit("[") >> rewardPathFormula >> qi::lit("]")); @@ -175,16 +174,16 @@ struct PrctlParser::PrctlGrammar : qi::grammar<Iterator, std::shared_ptr<storm:: rangeAction.name("range action"); sortAction = ( - (qi::lit("sort") > qi::lit("(") >> sortingCategory >> qi::lit(")"))[qi::_val = + (qi::lit("sort") >> qi::lit("(") >> sortingCategory >> qi::lit(")"))[qi::_val = phoenix::new_<storm::property::action::SortAction<double>>(qi::_1)] | - (qi::lit("sort") > qi::lit("(") >> sortingCategory >> qi::lit(", ") >> qi::lit("asc") > qi::lit(")"))[qi::_val = + (qi::lit("sort") >> qi::lit("(") >> sortingCategory >> qi::lit(", ") >> (qi::lit("ascending") | qi::lit("asc")) > qi::lit(")"))[qi::_val = phoenix::new_<storm::property::action::SortAction<double>>(qi::_1, true)] | - (qi::lit("sort") > qi::lit("(") >> sortingCategory >> qi::lit(", ") >> qi::lit("desc") > qi::lit(")"))[qi::_val = + (qi::lit("sort") >> qi::lit("(") >> sortingCategory >> qi::lit(", ") >> (qi::lit("descending") | qi::lit("desc")) > qi::lit(")"))[qi::_val = phoenix::new_<storm::property::action::SortAction<double>>(qi::_1, false)] ); sortAction.name("sort action"); - abstractAction = (boundAction | invertAction | formulaAction | rangeAction | sortAction) >> (qi::eps | qi::lit(";")); + abstractAction = (boundAction | invertAction | formulaAction | rangeAction | sortAction) >> (qi::lit(";") | qi::eps); abstractAction.name("filter action"); filter = (qi::lit("filter") >> qi::lit("[") >> +abstractAction >> qi::lit("]") > qi::lit("(") >> formula >> qi::lit(")"))[qi::_val = @@ -200,7 +199,7 @@ struct PrctlParser::PrctlGrammar : qi::grammar<Iterator, std::shared_ptr<storm:: filter.name("PRCTL formula filter"); start = (((filter) > (comment | qi::eps))[qi::_val = qi::_1] | comment[qi::_val = MAKE(prctl::PrctlFilter<double>, nullptr)]) > qi::eoi; - start.name("PRCTL formula filter"); + start.name("start"); } diff --git a/test/functional/parser/ActionTest.cpp b/test/functional/modelchecker/ActionTest.cpp similarity index 100% rename from test/functional/parser/ActionTest.cpp rename to test/functional/modelchecker/ActionTest.cpp diff --git a/test/functional/modelchecker/FilterTest.cpp b/test/functional/modelchecker/FilterTest.cpp new file mode 100644 index 000000000..e8ce4b156 --- /dev/null +++ b/test/functional/modelchecker/FilterTest.cpp @@ -0,0 +1,83 @@ +/* + * FilterTest.cpp + * + * Created on: Aug 6, 2014 + * Author: Manuel Sascha Weiand + */ + +#include "gtest/gtest.h" +#include "storm-config.h" +#include "src/models/Dtmc.h" +#include "src/parser/DeterministicModelParser.h" +#include "src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h" +#include "src/solver/GmmxxLinearEquationSolver.h" +#include "src/formula/prctl/PrctlFilter.h" +#include "src/formula/csl/CslFilter.h" +#include "src/formula/ltl/LtlFilter.h" +#include "src/parser/PrctlParser.h" + +#include <regex> + +typedef typename storm::property::prctl::PrctlFilter<double>::Result Result; + +TEST(PrctlFilterTest, generalFunctionality) { + // Test filter queries of increasing complexity. + + // Setup model and modelchecker. + storm::models::Dtmc<double> model = storm::parser::DeterministicModelParser::parseDtmc(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_actionTest.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/dtmc_actionTest.lab"); + storm::modelchecker::prctl::SparseDtmcPrctlModelChecker<double> mc(model, new storm::solver::GmmxxLinearEquationSolver<double>()); + + // Find the best valued state to finally reach a 'b' state. + std::string input = "filter[sort(value, descending); range(0,0)](F b)"; + std::shared_ptr<storm::property::prctl::PrctlFilter<double>> formula(nullptr); + ASSERT_NO_THROW( + formula = storm::parser::PrctlParser::parsePrctlFormula(input) + ); + + // Here we test if the check method gives the correct result. + // To capture the output, redirect cout and test the written buffer content. + std::stringstream buffer; + std::streambuf *sbuf = std::cout.rdbuf(); + std::cout.rdbuf(buffer.rdbuf()); + + formula->check(mc); + + std::string output = buffer.str(); + ASSERT_NE(std::string::npos, output.find("\t6: 1")); + + // Reset cout to the original buffer. + std::cout.rdbuf(sbuf); + + // The remaining queries use evaluate directly as its easier to work with in a test environment. + // Get the probability to reach a b state for all states but those that cannot reach a 'b' state or are 'b' states themselves. + // Sorted by value; highest first. + input = "filter[formula(P<=0(F b) | b); invert; sort(value, desc)](F b)"; + ASSERT_NO_THROW( + formula = storm::parser::PrctlParser::parsePrctlFormula(input) + ); + + Result result = formula->evaluate(mc); + + // Test the selection. + ASSERT_EQ(5, result.selection.getNumberOfSetBits()); + ASSERT_TRUE(result.selection[0]); + ASSERT_TRUE(result.selection[1]); + ASSERT_TRUE(result.selection[2]); + ASSERT_TRUE(result.selection[3]); + ASSERT_TRUE(result.selection[4]); + ASSERT_FALSE(result.selection[5]); + ASSERT_FALSE(result.selection[6]); + ASSERT_FALSE(result.selection[7]); + + // Test the sorting. + ASSERT_EQ(3, result.stateMap[0]); + ASSERT_EQ(4, result.stateMap[1]); + ASSERT_EQ(1, result.stateMap[2]); + ASSERT_EQ(0, result.stateMap[3]); + ASSERT_EQ(2, result.stateMap[4]); + ASSERT_EQ(5, result.stateMap[5]); + ASSERT_EQ(6, result.stateMap[6]); + ASSERT_EQ(7, result.stateMap[7]); +} + + diff --git a/test/functional/parser/PrctlParserTest.cpp b/test/functional/parser/PrctlParserTest.cpp index 1d5e59349..7f482f63e 100644 --- a/test/functional/parser/PrctlParserTest.cpp +++ b/test/functional/parser/PrctlParserTest.cpp @@ -10,6 +10,11 @@ #include "storm-config.h" #include "src/parser/PrctlParser.h" #include "src/exceptions/WrongFormatException.h" +#include "src/formula/actions/FormulaAction.h" +#include "src/formula/actions/InvertAction.h" +#include "src/formula/actions/SortAction.h" +#include "src/formula/actions/RangeAction.h" +#include "src/formula/actions/BoundAction.h" namespace prctl = storm::property::prctl; @@ -41,6 +46,35 @@ TEST(PrctlParserTest, parsePropositionalFormulaTest) { ASSERT_EQ("(!(a & b) | (a & !c))", formula->toString()); } +TEST(PrctlParserTest, parsePathFormulaTest) { + std::string input = "X( P<0.9 (a U b))"; + std::shared_ptr<prctl::PrctlFilter<double>> formula(nullptr); + ASSERT_NO_THROW( + formula = storm::parser::PrctlParser::parsePrctlFormula(input) + ); + + // The parser did not falsely recognize the input as a comment. + ASSERT_NE(formula, nullptr); + + // The input was parsed correctly. + ASSERT_NE(std::dynamic_pointer_cast<prctl::Next<double>>(formula->getChild()).get(), nullptr); + auto nextFormula = std::dynamic_pointer_cast<prctl::Next<double>>(formula->getChild()); + ASSERT_NE(std::dynamic_pointer_cast<prctl::ProbabilisticBoundOperator<double>>(nextFormula->getChild()).get(), nullptr); + auto probBoundFormula = std::dynamic_pointer_cast<prctl::ProbabilisticBoundOperator<double>>(nextFormula->getChild()); + ASSERT_NE(std::dynamic_pointer_cast<prctl::Until<double>>(probBoundFormula->getChild()).get(), nullptr); + auto untilFormula = std::dynamic_pointer_cast<prctl::Until<double>>(probBoundFormula->getChild()); + ASSERT_NE(std::dynamic_pointer_cast<prctl::Ap<double>>(untilFormula->getLeft()).get(), nullptr); + ASSERT_NE(std::dynamic_pointer_cast<prctl::Ap<double>>(untilFormula->getRight()).get(), nullptr); + ASSERT_EQ("a", std::dynamic_pointer_cast<prctl::Ap<double>>(untilFormula->getLeft())->getAp()); + ASSERT_EQ("b", std::dynamic_pointer_cast<prctl::Ap<double>>(untilFormula->getRight())->getAp()); + ASSERT_EQ(0.9, probBoundFormula->getBound()); + ASSERT_EQ(storm::property::LESS, probBoundFormula->getComparisonOperator()); + + + // The string representation is also correct. + ASSERT_EQ("P = ? (X P < 0.900000 (a U b))", formula->toString()); +} + TEST(PrctlParserTest, parseProbabilisticFormulaTest) { std::string input = "P > 0.5 [ F a ]"; std::shared_ptr<prctl::PrctlFilter<double>> formula(nullptr); @@ -124,6 +158,45 @@ TEST(PrctlParserTest, parseComplexFormulaTest) { ASSERT_EQ("(R <= 0.500000 (S) & (R > 15.000000 (C <= 0.500000) | !P < 0.400000 (G P > 0.900000 (F<=7 (a & b)))))", formula->toString()); } +TEST(PrctlParserTest, parsePrctlFilterTest) { + std::string input = "filter[formula(b); invert; bound(<, 0.5); sort(value); range(0,3)](F a)"; + std::shared_ptr<prctl::PrctlFilter<double>> formula(nullptr); + ASSERT_NO_THROW( + formula = storm::parser::PrctlParser::parsePrctlFormula(input) + ); + + // The parser did not falsely recognize the input as a comment. + ASSERT_NE(formula, nullptr); + + ASSERT_EQ(5, formula->getActionCount()); + ASSERT_NE(dynamic_cast<storm::property::action::FormulaAction<double>*>(formula->getAction(0)), nullptr); + ASSERT_NE(dynamic_cast<storm::property::action::InvertAction<double>*>(formula->getAction(1)), nullptr); + ASSERT_NE(dynamic_cast<storm::property::action::BoundAction<double>*>(formula->getAction(2)), nullptr); + ASSERT_NE(dynamic_cast<storm::property::action::SortAction<double>*>(formula->getAction(3)), nullptr); + ASSERT_NE(dynamic_cast<storm::property::action::RangeAction<double>*>(formula->getAction(4)), nullptr); + + // The input was parsed correctly. + ASSERT_EQ("filter[formula(b); invert; bound(<, 0.500000); sort(value, ascending); range(0, 3)](F a)", formula->toString()); +} + +TEST(PrctlParserTest, commentTest) { + std::string input = "// This is a comment. And this is a commented out formula: R = ? [ F a ]"; + std::shared_ptr<prctl::PrctlFilter<double>> formula(nullptr); + ASSERT_NO_THROW( + formula = storm::parser::PrctlParser::parsePrctlFormula(input) + ); + + // The parser recognized the input as a comment. + ASSERT_NE(nullptr, formula.get()); + + // Test if the parser recognizes the comment at the end of a line. + input = "R = ? [ F a ] // This is a comment."; + ASSERT_NO_THROW( + formula = storm::parser::PrctlParser::parsePrctlFormula(input) + ); + ASSERT_EQ("R = ? (F a)", formula->toString()); +} + TEST(PrctlParserTest, wrongProbabilisticFormulaTest) { std::shared_ptr<prctl::PrctlFilter<double>> formula(nullptr); From b7357c2cf99e66a17a84181e5a9867116f988688 Mon Sep 17 00:00:00 2001 From: masawei <manuel.sascha.weiand@rwth-aachen.de> Date: Sun, 10 Aug 2014 22:23:15 +0200 Subject: [PATCH 20/30] Testing, noticed that vectors of pointers are not good. Changing that. Former-commit-id: 460854c49ce25cc56351b1bf68457f146fc3da2c --- src/formula/AbstractFilter.h | 8 +- test/functional/modelchecker/FilterTest.cpp | 93 ++++++++++++++++++--- 2 files changed, 86 insertions(+), 15 deletions(-) diff --git a/src/formula/AbstractFilter.h b/src/formula/AbstractFilter.h index 0d03d3b0d..d0f9aa60e 100644 --- a/src/formula/AbstractFilter.h +++ b/src/formula/AbstractFilter.h @@ -71,17 +71,15 @@ public: } void addAction(action::AbstractAction<T>* action) { - actions.push_back(action); + if(action != nullptr) { + actions.push_back(action); + } } void removeAction() { actions.pop_back(); } - action::AbstractAction<T>* getAction(uint_fast64_t pos) const { - return actions[pos]; - } - uint_fast64_t getActionCount() const { return actions.size(); } diff --git a/test/functional/modelchecker/FilterTest.cpp b/test/functional/modelchecker/FilterTest.cpp index e8ce4b156..65fa50e7a 100644 --- a/test/functional/modelchecker/FilterTest.cpp +++ b/test/functional/modelchecker/FilterTest.cpp @@ -16,9 +16,9 @@ #include "src/formula/ltl/LtlFilter.h" #include "src/parser/PrctlParser.h" -#include <regex> +#include <memory> -typedef typename storm::property::prctl::PrctlFilter<double>::Result Result; +typedef typename storm::property::action::AbstractAction<double>::Result Result; TEST(PrctlFilterTest, generalFunctionality) { // Test filter queries of increasing complexity. @@ -70,14 +70,87 @@ TEST(PrctlFilterTest, generalFunctionality) { ASSERT_FALSE(result.selection[7]); // Test the sorting. - ASSERT_EQ(3, result.stateMap[0]); - ASSERT_EQ(4, result.stateMap[1]); - ASSERT_EQ(1, result.stateMap[2]); - ASSERT_EQ(0, result.stateMap[3]); - ASSERT_EQ(2, result.stateMap[4]); - ASSERT_EQ(5, result.stateMap[5]); - ASSERT_EQ(6, result.stateMap[6]); - ASSERT_EQ(7, result.stateMap[7]); + ASSERT_EQ(6, result.stateMap[0]); + ASSERT_EQ(7, result.stateMap[1]); + ASSERT_EQ(3, result.stateMap[2]); + ASSERT_EQ(4, result.stateMap[3]); + ASSERT_EQ(1, result.stateMap[4]); + ASSERT_EQ(0, result.stateMap[5]); + ASSERT_EQ(2, result.stateMap[6]); + ASSERT_EQ(5, result.stateMap[7]); + + // Get the probability for reaching a 'd' state only for those states that have a probability to do so of at most 0.5. + // Sorted by value; lowest first. + input = "filter[bound(<, 0.5); sort(value, ascending)](F d)"; + ASSERT_NO_THROW( + formula = storm::parser::PrctlParser::parsePrctlFormula(input) + ); + + result = formula->evaluate(mc); + + // Test the selection. + ASSERT_EQ(4, result.selection.getNumberOfSetBits()); + ASSERT_FALSE(result.selection[0]); + ASSERT_FALSE(result.selection[1]); + ASSERT_FALSE(result.selection[2]); + ASSERT_TRUE(result.selection[3]); + ASSERT_FALSE(result.selection[4]); + ASSERT_TRUE(result.selection[5]); + ASSERT_TRUE(result.selection[6]); + ASSERT_TRUE(result.selection[7]); + + // Test the sorting. + ASSERT_EQ(5, result.stateMap[0]); + ASSERT_EQ(6, result.stateMap[1]); + ASSERT_EQ(7, result.stateMap[2]); + ASSERT_EQ(3, result.stateMap[3]); + ASSERT_EQ(4, result.stateMap[4]); + ASSERT_EQ(1, result.stateMap[5]); + ASSERT_EQ(0, result.stateMap[6]); + ASSERT_EQ(2, result.stateMap[7]); + + // Get the three highest indexed states reaching an 'a' state with probability at most 0.3. + input = "filter[sort(value); range(5,7); sort(index, descending)](P<=0.3(F a))"; + ASSERT_NO_THROW( + formula = storm::parser::PrctlParser::parsePrctlFormula(input) + ); + + result = formula->evaluate(mc); + + // Test the selection. + ASSERT_EQ(3, result.selection.getNumberOfSetBits()); + ASSERT_FALSE(result.selection[0]); + ASSERT_FALSE(result.selection[1]); + ASSERT_FALSE(result.selection[2]); + ASSERT_TRUE(result.selection[3]); + ASSERT_FALSE(result.selection[4]); + ASSERT_FALSE(result.selection[5]); + ASSERT_TRUE(result.selection[6]); + ASSERT_TRUE(result.selection[7]); + + // Test the sorting. + ASSERT_EQ(7, result.stateMap[0]); + ASSERT_EQ(6, result.stateMap[1]); + ASSERT_EQ(5, result.stateMap[2]); + ASSERT_EQ(4, result.stateMap[3]); + ASSERT_EQ(3, result.stateMap[4]); + ASSERT_EQ(2, result.stateMap[5]); + ASSERT_EQ(1, result.stateMap[6]); + ASSERT_EQ(0, result.stateMap[7]); + +} + +TEST(PrctlFilterTest, Safety) { + // Setup model and modelchecker. + storm::models::Dtmc<double> model = storm::parser::DeterministicModelParser::parseDtmc(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_actionTest.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/dtmc_actionTest.lab"); + storm::modelchecker::prctl::SparseDtmcPrctlModelChecker<double> mc(model, new storm::solver::GmmxxLinearEquationSolver<double>()); + + // Make a stub formula as child. + auto apFormula = std::make_shared<storm::property::prctl::Ap<double>>("a"); + + auto formula = std::make_shared<storm::property::prctl::PrctlFilter<double>>(apFormula, nullptr); + + ASSERT_NO_THROW(formula->check(mc)); } From 33386f4c5f2576e87a0fc884710a00dac892a21c Mon Sep 17 00:00:00 2001 From: masawei <manuel.sascha.weiand@rwth-aachen.de> Date: Mon, 11 Aug 2014 00:02:13 +0200 Subject: [PATCH 21/30] Changed the actions in the filters to be shared_ptr instead of raw pointers. This prevents memory leaks when a filter is destructed. - Also handled nullptr actions. |- They are checked for in the constructor as well as in the add method and filtered out. No segfaults do to nullptr actions anymore. Former-commit-id: 84b3b2a978509f13dc62763d05058b3653ba482b --- src/formula/AbstractFilter.h | 52 ++++++++++++++++++---- src/formula/csl/CslFilter.h | 4 +- src/formula/ltl/LtlFilter.h | 4 +- src/formula/prctl/PrctlFilter.h | 6 +-- src/parser/CslParser.cpp | 36 +++++++-------- src/parser/LtlParser.cpp | 32 ++++++------- src/parser/PrctlParser.cpp | 28 ++++++------ test/functional/parser/PrctlParserTest.cpp | 10 ++--- 8 files changed, 104 insertions(+), 68 deletions(-) diff --git a/src/formula/AbstractFilter.h b/src/formula/AbstractFilter.h index d0f9aa60e..59bc935fa 100644 --- a/src/formula/AbstractFilter.h +++ b/src/formula/AbstractFilter.h @@ -30,16 +30,42 @@ public: // Intentionally left empty. } - AbstractFilter(action::AbstractAction<T>* action, OptimizingOperator opt = UNDEFINED) : opt(opt) { - actions.push_back(action); + AbstractFilter(std::shared_ptr<action::AbstractAction<T>> const & action, OptimizingOperator opt = UNDEFINED) : opt(opt) { + if(action.get() != nullptr) { + actions.push_back(action); + } } - AbstractFilter(std::vector<action::AbstractAction<T>*> actions, OptimizingOperator opt = UNDEFINED) : actions(actions), opt(opt) { - // Intentionally left empty. + AbstractFilter(std::vector<std::shared_ptr<action::AbstractAction<T>>> const & actions, OptimizingOperator opt = UNDEFINED) { + // Filter out all nullptr actions. + // First detect that there is at least one. + uint_fast64_t emptyCount = 0; + for(uint_fast64_t i = 0; i < actions.size(); i++) { + if (actions[i].get() == nullptr) { + emptyCount++; + } + } + + if(emptyCount > 0) { + // There is at least one nullptr action. + // Allocate space for the non null actions. + this->actions = std::vector<std::shared_ptr<action::AbstractAction<T>>>(actions.size() - emptyCount); + + // Fill the vector. Note: For most implementations of the standard there will be no reallocation in the vector while doing this. + for(auto action : actions){ + if(action.get() != nullptr) { + this->actions.push_back(action); + } + } + } else { + this->actions = actions; + } + + this->opt = opt; } virtual ~AbstractFilter() { - actions.clear(); + // Intentionally left empty. } virtual std::string toString() const { @@ -70,8 +96,8 @@ public: return desc; } - void addAction(action::AbstractAction<T>* action) { - if(action != nullptr) { + void addAction(std::shared_ptr<action::AbstractAction<T>> const & action) { + if(action.get() != nullptr) { actions.push_back(action); } } @@ -80,6 +106,16 @@ public: actions.pop_back(); } + std::shared_ptr<action::AbstractAction<T>> getAction(uint_fast64_t position) { + // Make sure the chosen position is not beyond the end of the vector. + // If it is so return the last element. + if(position < actions.size()) { + return actions[position]; + } else { + return actions[actions.size()-1]; + } + } + uint_fast64_t getActionCount() const { return actions.size(); } @@ -94,7 +130,7 @@ public: protected: - std::vector<action::AbstractAction<T>*> actions; + std::vector<std::shared_ptr<action::AbstractAction<T>>> actions; OptimizingOperator opt; }; diff --git a/src/formula/csl/CslFilter.h b/src/formula/csl/CslFilter.h index b7c99df39..fffd78663 100644 --- a/src/formula/csl/CslFilter.h +++ b/src/formula/csl/CslFilter.h @@ -43,11 +43,11 @@ public: // Intentionally left empty. } - CslFilter(std::shared_ptr<AbstractCslFormula<T>> const & child, action::AbstractAction<T>* action, OptimizingOperator opt = UNDEFINED, bool steadyStateQuery = false) : AbstractFilter<T>(action, opt), child(child), steadyStateQuery(steadyStateQuery) { + CslFilter(std::shared_ptr<AbstractCslFormula<T>> const & child, std::shared_ptr<action::AbstractAction<T>> const & action, OptimizingOperator opt = UNDEFINED, bool steadyStateQuery = false) : AbstractFilter<T>(action, opt), child(child), steadyStateQuery(steadyStateQuery) { // Intentionally left empty } - CslFilter(std::shared_ptr<AbstractCslFormula<T>> const & child, std::vector<action::AbstractAction<T>*> actions, OptimizingOperator opt = UNDEFINED, bool steadyStateQuery = false) : AbstractFilter<T>(actions, opt), child(child), steadyStateQuery(steadyStateQuery) { + CslFilter(std::shared_ptr<AbstractCslFormula<T>> const & child, std::vector<std::shared_ptr<action::AbstractAction<T>>> const & actions, OptimizingOperator opt = UNDEFINED, bool steadyStateQuery = false) : AbstractFilter<T>(actions, opt), child(child), steadyStateQuery(steadyStateQuery) { // Intentionally left empty. } diff --git a/src/formula/ltl/LtlFilter.h b/src/formula/ltl/LtlFilter.h index a13148b86..d35b9fd46 100644 --- a/src/formula/ltl/LtlFilter.h +++ b/src/formula/ltl/LtlFilter.h @@ -41,11 +41,11 @@ public: // Intentionally left empty. } - LtlFilter(std::shared_ptr<AbstractLtlFormula<T>> const & child, action::AbstractAction<T>* action, OptimizingOperator opt = UNDEFINED) : AbstractFilter<T>(action, opt), child(child) { + LtlFilter(std::shared_ptr<AbstractLtlFormula<T>> const & child, std::shared_ptr<action::AbstractAction<T>> const & action, OptimizingOperator opt = UNDEFINED) : AbstractFilter<T>(action, opt), child(child) { this->actions.push_back(action); } - LtlFilter(std::shared_ptr<AbstractLtlFormula<T>> const & child, std::vector<action::AbstractAction<T>*> actions, OptimizingOperator opt = UNDEFINED) : AbstractFilter<T>(actions, opt), child(child) { + LtlFilter(std::shared_ptr<AbstractLtlFormula<T>> const & child, std::vector<std::shared_ptr<action::AbstractAction<T>>> const & actions, OptimizingOperator opt = UNDEFINED) : AbstractFilter<T>(actions, opt), child(child) { // Intentionally left empty. } diff --git a/src/formula/prctl/PrctlFilter.h b/src/formula/prctl/PrctlFilter.h index 161a9d3f8..48967486e 100644 --- a/src/formula/prctl/PrctlFilter.h +++ b/src/formula/prctl/PrctlFilter.h @@ -46,16 +46,16 @@ public: // Intentionally left empty. } - PrctlFilter(std::shared_ptr<AbstractPrctlFormula<T>> const & child, action::AbstractAction<T>* action, OptimizingOperator opt = UNDEFINED) : AbstractFilter<T>(action, opt), child(child) { + PrctlFilter(std::shared_ptr<AbstractPrctlFormula<T>> const & child, std::shared_ptr<action::AbstractAction<T>> const & action, OptimizingOperator opt = UNDEFINED) : AbstractFilter<T>(action, opt), child(child) { // Intentionally left empty. } - PrctlFilter(std::shared_ptr<AbstractPrctlFormula<T>> const & child, std::vector<action::AbstractAction<T>*> actions, OptimizingOperator opt = UNDEFINED) : AbstractFilter<T>(actions, opt), child(child) { + PrctlFilter(std::shared_ptr<AbstractPrctlFormula<T>> const & child, std::vector<std::shared_ptr<action::AbstractAction<T>>> const & actions, OptimizingOperator opt = UNDEFINED) : AbstractFilter<T>(actions, opt), child(child) { // Intentionally left empty. } virtual ~PrctlFilter() { - this->actions.clear(); + // Intentionally left empty. } void check(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelchecker) const { diff --git a/src/parser/CslParser.cpp b/src/parser/CslParser.cpp index c28d31b0a..f0a51afa6 100644 --- a/src/parser/CslParser.cpp +++ b/src/parser/CslParser.cpp @@ -148,35 +148,35 @@ struct CslParser::CslGrammar : qi::grammar<Iterator, std::shared_ptr<csl::CslFil // This block defines rules for parsing filter actions. boundAction = (qi::lit("bound") > qi::lit("(") >> comparisonType >> qi::lit(",") >> qi::double_ >> qi::lit(")"))[qi::_val = - phoenix::new_<storm::property::action::BoundAction<double>>(qi::_1, qi::_2)]; + MAKE(storm::property::action::BoundAction<double> ,qi::_1, qi::_2)]; boundAction.name("bound action"); - invertAction = qi::lit("invert")[qi::_val = phoenix::new_<storm::property::action::InvertAction<double>>()]; + invertAction = qi::lit("invert")[qi::_val = MAKE(storm::property::action::InvertAction<double>, )]; invertAction.name("invert action"); formulaAction = (qi::lit("formula") > qi::lit("(") >> stateFormula >> qi::lit(")"))[qi::_val = - phoenix::new_<storm::property::action::FormulaAction<double>>(qi::_1)]; + MAKE(storm::property::action::FormulaAction<double>, qi::_1)]; formulaAction.name("formula action"); rangeAction = ( (qi::lit("range") >> qi::lit("(") >> qi::uint_ >> qi::lit(",") > qi::uint_ >> qi::lit(")"))[qi::_val = - phoenix::new_<storm::property::action::RangeAction<double>>(qi::_1, qi::_2)] | + MAKE(storm::property::action::RangeAction<double>, qi::_1, qi::_2)] | (qi::lit("range") >> qi::lit("(") >> qi::uint_ >> qi::lit(")"))[qi::_val = - phoenix::new_<storm::property::action::RangeAction<double>>(qi::_1, qi::_1 + 1)] + MAKE(storm::property::action::RangeAction<double>, qi::_1, qi::_1 + 1)] ); rangeAction.name("range action"); sortAction = ( - (qi::lit("sort") > qi::lit("(") >> sortingCategory >> qi::lit(")"))[qi::_val = - phoenix::new_<storm::property::action::SortAction<double>>(qi::_1)] | - (qi::lit("sort") > qi::lit("(") >> sortingCategory >> qi::lit(", ") >> qi::lit("asc") > qi::lit(")"))[qi::_val = - phoenix::new_<storm::property::action::SortAction<double>>(qi::_1, true)] | - (qi::lit("sort") > qi::lit("(") >> sortingCategory >> qi::lit(", ") >> qi::lit("desc") > qi::lit(")"))[qi::_val = - phoenix::new_<storm::property::action::SortAction<double>>(qi::_1, false)] + (qi::lit("sort") >> qi::lit("(") >> sortingCategory >> qi::lit(")"))[qi::_val = + MAKE(storm::property::action::SortAction<double>, qi::_1)] | + (qi::lit("sort") >> qi::lit("(") >> sortingCategory >> qi::lit(", ") >> (qi::lit("ascending") | qi::lit("asc")) > qi::lit(")"))[qi::_val = + MAKE(storm::property::action::SortAction<double>, qi::_1, true)] | + (qi::lit("sort") >> qi::lit("(") >> sortingCategory >> qi::lit(", ") >> (qi::lit("descending") | qi::lit("desc")) > qi::lit(")"))[qi::_val = + MAKE(storm::property::action::SortAction<double>, qi::_1, false)] ); sortAction.name("sort action"); - abstractAction = (boundAction | invertAction | formulaAction | rangeAction | sortAction) >> (qi::eps | qi::lit(";")); + abstractAction = (boundAction | invertAction | formulaAction | rangeAction | sortAction) >> (qi::lit(";") | qi::eps); abstractAction.name("filter action"); filter = (qi::lit("filter") >> qi::lit("[") >> +abstractAction >> qi::lit("]") >> qi::lit("(") >> formula >> qi::lit(")"))[qi::_val = @@ -200,12 +200,12 @@ struct CslParser::CslGrammar : qi::grammar<Iterator, std::shared_ptr<csl::CslFil qi::rule<Iterator, std::shared_ptr<csl::CslFilter<double>>(), Skipper> probabilisticNoBoundOperator; qi::rule<Iterator, std::shared_ptr<csl::CslFilter<double>>(), Skipper> steadyStateNoBoundOperator; - qi::rule<Iterator, storm::property::action::AbstractAction<double>*(), Skipper> abstractAction; - qi::rule<Iterator, storm::property::action::BoundAction<double>*(), Skipper> boundAction; - qi::rule<Iterator, storm::property::action::InvertAction<double>*(), Skipper> invertAction; - qi::rule<Iterator, storm::property::action::FormulaAction<double>*(), Skipper> formulaAction; - qi::rule<Iterator, storm::property::action::RangeAction<double>*(), Skipper> rangeAction; - qi::rule<Iterator, storm::property::action::SortAction<double>*(), Skipper> sortAction; + qi::rule<Iterator, std::shared_ptr<storm::property::action::AbstractAction<double>>(), Skipper> abstractAction; + qi::rule<Iterator, std::shared_ptr<storm::property::action::BoundAction<double>>(), Skipper> boundAction; + qi::rule<Iterator, std::shared_ptr<storm::property::action::InvertAction<double>>(), Skipper> invertAction; + qi::rule<Iterator, std::shared_ptr<storm::property::action::FormulaAction<double>>(), Skipper> formulaAction; + qi::rule<Iterator, std::shared_ptr<storm::property::action::RangeAction<double>>(), Skipper> rangeAction; + qi::rule<Iterator, std::shared_ptr<storm::property::action::SortAction<double>>(), Skipper> sortAction; qi::rule<Iterator, std::shared_ptr<csl::AbstractCslFormula<double>>(), Skipper> formula; qi::rule<Iterator, std::shared_ptr<csl::AbstractCslFormula<double>>(), Skipper> comment; diff --git a/src/parser/LtlParser.cpp b/src/parser/LtlParser.cpp index 3bc614243..25d62d241 100644 --- a/src/parser/LtlParser.cpp +++ b/src/parser/LtlParser.cpp @@ -109,31 +109,31 @@ struct LtlParser::LtlGrammar : qi::grammar<Iterator, std::shared_ptr<storm::prop // This block defines rules for parsing filter actions. boundAction = (qi::lit("bound") > qi::lit("(") >> comparisonType >> qi::lit(",") >> qi::double_ >> qi::lit(")"))[qi::_val = - phoenix::new_<storm::property::action::BoundAction<double>>(qi::_1, qi::_2)]; + MAKE(storm::property::action::BoundAction<double> ,qi::_1, qi::_2)]; boundAction.name("bound action"); - invertAction = qi::lit("invert")[qi::_val = phoenix::new_<storm::property::action::InvertAction<double>>()]; + invertAction = qi::lit("invert")[qi::_val = MAKE(storm::property::action::InvertAction<double>, )]; invertAction.name("invert action"); rangeAction = ( (qi::lit("range") >> qi::lit("(") >> qi::uint_ >> qi::lit(",") > qi::uint_ >> qi::lit(")"))[qi::_val = - phoenix::new_<storm::property::action::RangeAction<double>>(qi::_1, qi::_2)] | + MAKE(storm::property::action::RangeAction<double>, qi::_1, qi::_2)] | (qi::lit("range") >> qi::lit("(") >> qi::uint_ >> qi::lit(")"))[qi::_val = - phoenix::new_<storm::property::action::RangeAction<double>>(qi::_1, qi::_1 + 1)] + MAKE(storm::property::action::RangeAction<double>, qi::_1, qi::_1 + 1)] ); rangeAction.name("range action"); sortAction = ( - (qi::lit("sort") > qi::lit("(") >> sortingCategory >> qi::lit(")"))[qi::_val = - phoenix::new_<storm::property::action::SortAction<double>>(qi::_1)] | - (qi::lit("sort") > qi::lit("(") >> sortingCategory >> qi::lit(", ") >> qi::lit("asc") > qi::lit(")"))[qi::_val = - phoenix::new_<storm::property::action::SortAction<double>>(qi::_1, true)] | - (qi::lit("sort") > qi::lit("(") >> sortingCategory >> qi::lit(", ") >> qi::lit("desc") > qi::lit(")"))[qi::_val = - phoenix::new_<storm::property::action::SortAction<double>>(qi::_1, false)] + (qi::lit("sort") >> qi::lit("(") >> sortingCategory >> qi::lit(")"))[qi::_val = + MAKE(storm::property::action::SortAction<double>, qi::_1)] | + (qi::lit("sort") >> qi::lit("(") >> sortingCategory >> qi::lit(", ") >> (qi::lit("ascending") | qi::lit("asc")) > qi::lit(")"))[qi::_val = + MAKE(storm::property::action::SortAction<double>, qi::_1, true)] | + (qi::lit("sort") >> qi::lit("(") >> sortingCategory >> qi::lit(", ") >> (qi::lit("descending") | qi::lit("desc")) > qi::lit(")"))[qi::_val = + MAKE(storm::property::action::SortAction<double>, qi::_1, false)] ); sortAction.name("sort action"); - abstractAction = (boundAction | invertAction | rangeAction | sortAction) >> (qi::eps | qi::lit(";")); + abstractAction = (boundAction | invertAction | rangeAction | sortAction) >> (qi::lit(";") | qi::eps); abstractAction.name("filter action"); filter = (qi::lit("filter") >> qi::lit("[") >> +abstractAction >> qi::lit("]") > qi::lit("(") >> formula >> qi::lit(")"))[qi::_val = @@ -153,11 +153,11 @@ struct LtlParser::LtlGrammar : qi::grammar<Iterator, std::shared_ptr<storm::prop qi::rule<Iterator, std::shared_ptr<storm::property::ltl::LtlFilter<double>>(), Skipper> start; qi::rule<Iterator, std::shared_ptr<storm::property::ltl::LtlFilter<double>>(), Skipper> filter; - qi::rule<Iterator, storm::property::action::AbstractAction<double>*(), Skipper> abstractAction; - qi::rule<Iterator, storm::property::action::BoundAction<double>*(), Skipper> boundAction; - qi::rule<Iterator, storm::property::action::InvertAction<double>*(), Skipper> invertAction; - qi::rule<Iterator, storm::property::action::RangeAction<double>*(), Skipper> rangeAction; - qi::rule<Iterator, storm::property::action::SortAction<double>*(), Skipper> sortAction; + qi::rule<Iterator, std::shared_ptr<storm::property::action::AbstractAction<double>>(), Skipper> abstractAction; + qi::rule<Iterator, std::shared_ptr<storm::property::action::BoundAction<double>>(), Skipper> boundAction; + qi::rule<Iterator, std::shared_ptr<storm::property::action::InvertAction<double>>(), Skipper> invertAction; + qi::rule<Iterator, std::shared_ptr<storm::property::action::RangeAction<double>>(), Skipper> rangeAction; + qi::rule<Iterator, std::shared_ptr<storm::property::action::SortAction<double>>(), Skipper> sortAction; qi::rule<Iterator, std::shared_ptr<storm::property::ltl::AbstractLtlFormula<double>>(), Skipper> comment; qi::rule<Iterator, std::shared_ptr<storm::property::ltl::AbstractLtlFormula<double>>(), Skipper> formula; diff --git a/src/parser/PrctlParser.cpp b/src/parser/PrctlParser.cpp index 35036ffcf..b31b621bb 100644 --- a/src/parser/PrctlParser.cpp +++ b/src/parser/PrctlParser.cpp @@ -155,31 +155,31 @@ struct PrctlParser::PrctlGrammar : qi::grammar<Iterator, std::shared_ptr<storm:: // This block defines rules for parsing filter actions. boundAction = (qi::lit("bound") > qi::lit("(") >> comparisonType >> qi::lit(",") >> qi::double_ >> qi::lit(")"))[qi::_val = - phoenix::new_<storm::property::action::BoundAction<double>>(qi::_1, qi::_2)]; + MAKE(storm::property::action::BoundAction<double> ,qi::_1, qi::_2)]; boundAction.name("bound action"); - invertAction = qi::lit("invert")[qi::_val = phoenix::new_<storm::property::action::InvertAction<double>>()]; + invertAction = qi::lit("invert")[qi::_val = MAKE(storm::property::action::InvertAction<double>, )]; invertAction.name("invert action"); formulaAction = (qi::lit("formula") > qi::lit("(") >> stateFormula >> qi::lit(")"))[qi::_val = - phoenix::new_<storm::property::action::FormulaAction<double>>(qi::_1)]; + MAKE(storm::property::action::FormulaAction<double>, qi::_1)]; formulaAction.name("formula action"); rangeAction = ( (qi::lit("range") >> qi::lit("(") >> qi::uint_ >> qi::lit(",") > qi::uint_ >> qi::lit(")"))[qi::_val = - phoenix::new_<storm::property::action::RangeAction<double>>(qi::_1, qi::_2)] | + MAKE(storm::property::action::RangeAction<double>, qi::_1, qi::_2)] | (qi::lit("range") >> qi::lit("(") >> qi::uint_ >> qi::lit(")"))[qi::_val = - phoenix::new_<storm::property::action::RangeAction<double>>(qi::_1, qi::_1 + 1)] + MAKE(storm::property::action::RangeAction<double>, qi::_1, qi::_1 + 1)] ); rangeAction.name("range action"); sortAction = ( (qi::lit("sort") >> qi::lit("(") >> sortingCategory >> qi::lit(")"))[qi::_val = - phoenix::new_<storm::property::action::SortAction<double>>(qi::_1)] | + MAKE(storm::property::action::SortAction<double>, qi::_1)] | (qi::lit("sort") >> qi::lit("(") >> sortingCategory >> qi::lit(", ") >> (qi::lit("ascending") | qi::lit("asc")) > qi::lit(")"))[qi::_val = - phoenix::new_<storm::property::action::SortAction<double>>(qi::_1, true)] | + MAKE(storm::property::action::SortAction<double>, qi::_1, true)] | (qi::lit("sort") >> qi::lit("(") >> sortingCategory >> qi::lit(", ") >> (qi::lit("descending") | qi::lit("desc")) > qi::lit(")"))[qi::_val = - phoenix::new_<storm::property::action::SortAction<double>>(qi::_1, false)] + MAKE(storm::property::action::SortAction<double>, qi::_1, false)] ); sortAction.name("sort action"); @@ -210,12 +210,12 @@ struct PrctlParser::PrctlGrammar : qi::grammar<Iterator, std::shared_ptr<storm:: qi::rule<Iterator, std::shared_ptr<storm::property::prctl::PrctlFilter<double>>(), Skipper> probabilisticNoBoundOperator; qi::rule<Iterator, std::shared_ptr<storm::property::prctl::PrctlFilter<double>>(), Skipper> rewardNoBoundOperator; - qi::rule<Iterator, storm::property::action::AbstractAction<double>*(), Skipper> abstractAction; - qi::rule<Iterator, storm::property::action::BoundAction<double>*(), Skipper> boundAction; - qi::rule<Iterator, storm::property::action::InvertAction<double>*(), Skipper> invertAction; - qi::rule<Iterator, storm::property::action::FormulaAction<double>*(), Skipper> formulaAction; - qi::rule<Iterator, storm::property::action::RangeAction<double>*(), Skipper> rangeAction; - qi::rule<Iterator, storm::property::action::SortAction<double>*(), Skipper> sortAction; + qi::rule<Iterator, std::shared_ptr<storm::property::action::AbstractAction<double>>(), Skipper> abstractAction; + qi::rule<Iterator, std::shared_ptr<storm::property::action::BoundAction<double>>(), Skipper> boundAction; + qi::rule<Iterator, std::shared_ptr<storm::property::action::InvertAction<double>>(), Skipper> invertAction; + qi::rule<Iterator, std::shared_ptr<storm::property::action::FormulaAction<double>>(), Skipper> formulaAction; + qi::rule<Iterator, std::shared_ptr<storm::property::action::RangeAction<double>>(), Skipper> rangeAction; + qi::rule<Iterator, std::shared_ptr<storm::property::action::SortAction<double>>(), Skipper> sortAction; qi::rule<Iterator, std::shared_ptr<storm::property::prctl::AbstractPrctlFormula<double>>(), Skipper> formula; qi::rule<Iterator, std::shared_ptr<storm::property::prctl::AbstractPrctlFormula<double>>(), Skipper> comment; diff --git a/test/functional/parser/PrctlParserTest.cpp b/test/functional/parser/PrctlParserTest.cpp index 7f482f63e..ee86d92e8 100644 --- a/test/functional/parser/PrctlParserTest.cpp +++ b/test/functional/parser/PrctlParserTest.cpp @@ -169,11 +169,11 @@ TEST(PrctlParserTest, parsePrctlFilterTest) { ASSERT_NE(formula, nullptr); ASSERT_EQ(5, formula->getActionCount()); - ASSERT_NE(dynamic_cast<storm::property::action::FormulaAction<double>*>(formula->getAction(0)), nullptr); - ASSERT_NE(dynamic_cast<storm::property::action::InvertAction<double>*>(formula->getAction(1)), nullptr); - ASSERT_NE(dynamic_cast<storm::property::action::BoundAction<double>*>(formula->getAction(2)), nullptr); - ASSERT_NE(dynamic_cast<storm::property::action::SortAction<double>*>(formula->getAction(3)), nullptr); - ASSERT_NE(dynamic_cast<storm::property::action::RangeAction<double>*>(formula->getAction(4)), nullptr); + ASSERT_NE(std::dynamic_pointer_cast<storm::property::action::FormulaAction<double>>(formula->getAction(0)).get(), nullptr); + ASSERT_NE(std::dynamic_pointer_cast<storm::property::action::InvertAction<double>>(formula->getAction(1)).get(), nullptr); + ASSERT_NE(std::dynamic_pointer_cast<storm::property::action::BoundAction<double>>(formula->getAction(2)).get(), nullptr); + ASSERT_NE(std::dynamic_pointer_cast<storm::property::action::SortAction<double>>(formula->getAction(3)).get(), nullptr); + ASSERT_NE(std::dynamic_pointer_cast<storm::property::action::RangeAction<double>>(formula->getAction(4)).get(), nullptr); // The input was parsed correctly. ASSERT_EQ("filter[formula(b); invert; bound(<, 0.500000); sort(value, ascending); range(0, 3)](F a)", formula->toString()); From 2687809591bcab658079cb83ece72f69e87718ab Mon Sep 17 00:00:00 2001 From: masawei <manuel.sascha.weiand@rwth-aachen.de> Date: Tue, 12 Aug 2014 02:07:03 +0200 Subject: [PATCH 22/30] Finished testing of Csl. Former-commit-id: 91172a1b89e1f172cb39201cb7f2e2774c00fba4 --- src/formula/AbstractFilter.h | 2 +- src/formula/csl/CslFilter.h | 51 +++-- src/formula/csl/Next.h | 4 +- src/formula/csl/ProbabilisticBoundOperator.h | 30 +-- src/modelchecker/csl/AbstractModelChecker.h | 2 +- .../SparseMarkovAutomatonCslModelChecker.h | 2 +- src/parser/CslParser.cpp | 34 +-- src/parser/PrctlParser.cpp | 4 +- test/functional/modelchecker/FilterTest.cpp | 210 +++++++++++++++++- test/functional/parser/CslParserTest.cpp | 75 ++++++- 10 files changed, 350 insertions(+), 64 deletions(-) diff --git a/src/formula/AbstractFilter.h b/src/formula/AbstractFilter.h index 59bc935fa..f1e7017f7 100644 --- a/src/formula/AbstractFilter.h +++ b/src/formula/AbstractFilter.h @@ -49,7 +49,7 @@ public: if(emptyCount > 0) { // There is at least one nullptr action. // Allocate space for the non null actions. - this->actions = std::vector<std::shared_ptr<action::AbstractAction<T>>>(actions.size() - emptyCount); + this->actions.reserve(actions.size() - emptyCount); // Fill the vector. Note: For most implementations of the standard there will be no reallocation in the vector while doing this. for(auto action : actions){ diff --git a/src/formula/csl/CslFilter.h b/src/formula/csl/CslFilter.h index fffd78663..d09902760 100644 --- a/src/formula/csl/CslFilter.h +++ b/src/formula/csl/CslFilter.h @@ -55,13 +55,18 @@ public: this->actions.clear(); } - void check(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelchecker) const { + void check(storm::modelchecker::csl::AbstractModelChecker<T> const & modelchecker) const { // Write out the formula to be checked. std::cout << std::endl; LOG4CPLUS_INFO(logger, "Model checking formula\t" << this->toString()); std::cout << "Model checking formula:\t" << this->toString() << std::endl; + writeOut(evaluate(modelchecker), modelchecker); + + } + + Result evaluate(storm::modelchecker::csl::AbstractModelChecker<T> const & modelchecker) const { Result result; try { @@ -73,13 +78,9 @@ public: } catch (std::exception& e) { std::cout << "Error during computation: " << e.what() << "Skipping property." << std::endl; LOG4CPLUS_ERROR(logger, "Error during computation: " << e.what() << "Skipping property."); - std::cout << std::endl << "-------------------------------------------" << std::endl; - - return; } - writeOut(result, modelchecker); - + return result; } virtual std::string toString() const override { @@ -121,10 +122,10 @@ public: for(auto action : this->actions) { desc += action->toString(); - desc += ", "; + desc += "; "; } - // Remove the last ", ". + // Remove the last "; ". desc.pop_back(); desc.pop_back(); @@ -151,10 +152,10 @@ public: for(auto action : this->actions) { desc += action->toString(); - desc += ", "; + desc += "; "; } - // Remove the last ", ". + // Remove the last "; ". desc.pop_back(); desc.pop_back(); @@ -189,15 +190,15 @@ public: private: - storm::storage::BitVector evaluate(storm::modelchecker::csl::AbstractModelChecker<T> const & modelchecker, std::shared_ptr<AbstractStateFormula<T>> const & formula) const { + Result evaluate(storm::modelchecker::csl::AbstractModelChecker<T> const & modelchecker, std::shared_ptr<AbstractStateFormula<T>> const & formula) const { // First, get the model checking result. - storm::storage::BitVector result = modelchecker.checkMinMaxOperator(*formula); + Result result; if(this->opt != UNDEFINED) { // If there is an action specifying that min/max probabilities should be computed, call the appropriate method of the model checker. - result = modelchecker.checkMinMaxOperator(formula, this->opt == MINIMIZE ? true : false); + result.stateResult = modelchecker.checkMinMaxOperator(*formula, this->opt == MINIMIZE ? true : false); } else { - result = formula->check(modelchecker); + result.stateResult = formula->check(modelchecker); } @@ -205,15 +206,15 @@ private: return evaluateActions(result, modelchecker); } - std::vector<T> evaluate(storm::modelchecker::csl::AbstractModelChecker<T> const & modelchecker, std::shared_ptr<AbstractPathFormula<T>> const & formula) const { + Result evaluate(storm::modelchecker::csl::AbstractModelChecker<T> const & modelchecker, std::shared_ptr<AbstractPathFormula<T>> const & formula) const { // First, get the model checking result. - std::vector<T> result; + Result result; if(this->opt != UNDEFINED) { // If there is an action specifying that min/max probabilities should be computed, call the appropriate method of the model checker. - result = modelchecker.checkMinMaxOperator(*formula, this->opt == MINIMIZE ? true : false); + result.pathResult = modelchecker.checkMinMaxOperator(*formula, this->opt == MINIMIZE ? true : false); } else { - result = formula->check(modelchecker, false); + result.pathResult = formula->check(modelchecker, false); } // Now apply all filter actions and return the result. @@ -223,8 +224,9 @@ private: Result evaluateActions(Result result, storm::modelchecker::csl::AbstractModelChecker<T> const & modelchecker) const { // Init the state selection and state map vectors. - result.selection = storm::storage::BitVector(result.stateResult.size(), true); - result.stateMap = std::vector<uint_fast64_t>(result.selection.size()); + uint_fast64_t size = result.stateResult.size() == 0 ? result.pathResult.size() : result.stateResult.size(); + result.selection = storm::storage::BitVector(size, true); + result.stateMap = std::vector<uint_fast64_t>(size); for(uint_fast64_t i = 0; i < result.selection.size(); i++) { result.stateMap[i] = i; } @@ -236,7 +238,14 @@ private: return result; } - void writeOut(Result const & result, storm::modelchecker::prctl::AbstractModelChecker<T> const & modelchecker) const { + void writeOut(Result const & result, storm::modelchecker::csl::AbstractModelChecker<T> const & modelchecker) const { + + // Test if there is anything to write out. + // The selection size should only be 0 if an error occurred during the evaluation (since a model with 0 states is invalid). + if(result.selection.size() == 0) { + std::cout << std::endl << "-------------------------------------------" << std::endl; + return; + } // Test for the kind of result. Values or states. if(!result.pathResult.empty()) { diff --git a/src/formula/csl/Next.h b/src/formula/csl/Next.h index f8a8ae0f4..3148377a6 100644 --- a/src/formula/csl/Next.h +++ b/src/formula/csl/Next.h @@ -114,10 +114,8 @@ public: * @returns a string representation of the formula */ virtual std::string toString() const override { - std::string result = "("; - result += " X "; + std::string result = "X "; result += child->toString(); - result += ")"; return result; } diff --git a/src/formula/csl/ProbabilisticBoundOperator.h b/src/formula/csl/ProbabilisticBoundOperator.h index 02986e3f8..6d0e0d6a3 100644 --- a/src/formula/csl/ProbabilisticBoundOperator.h +++ b/src/formula/csl/ProbabilisticBoundOperator.h @@ -60,7 +60,7 @@ public: /*! * Empty constructor */ - ProbabilisticBoundOperator() : comparisonOperator(LESS), bound(0), pathFormula(nullptr) { + ProbabilisticBoundOperator() : comparisonOperator(LESS), bound(0), child(nullptr) { // Intentionally left empty. } @@ -69,10 +69,10 @@ public: * * @param comparisonOperator The relation for the bound. * @param bound The bound for the probability - * @param pathFormula The child node + * @param child The child node */ - ProbabilisticBoundOperator(storm::property::ComparisonType comparisonOperator, T bound, std::shared_ptr<AbstractPathFormula<T>> const & pathFormula) - : comparisonOperator(comparisonOperator), bound(bound), pathFormula(pathFormula) { + ProbabilisticBoundOperator(storm::property::ComparisonType comparisonOperator, T bound, std::shared_ptr<AbstractPathFormula<T>> const & child) + : comparisonOperator(comparisonOperator), bound(bound), child(child) { // Intentionally left empty. } @@ -97,7 +97,7 @@ public: std::shared_ptr<ProbabilisticBoundOperator<T>> result(new ProbabilisticBoundOperator<T>()); result->setComparisonOperator(comparisonOperator); result->setBound(bound); - result->setPathFormula(pathFormula->clone()); + result->setChild(child->clone()); return result; } @@ -121,7 +121,7 @@ public: * @return true iff the subtree conforms to some logic. */ virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { - return checker.validate(this->pathFormula); + return checker.validate(this->child); } /*! @@ -138,7 +138,7 @@ public: result += " "; result += std::to_string(bound); result += " ("; - result += pathFormula->toString(); + result += child->toString(); result += ")"; return result; } @@ -146,25 +146,25 @@ public: /*! * @returns the child node (representation of a formula) */ - std::shared_ptr<AbstractPathFormula<T>> const & getPathFormula () const { - return pathFormula; + std::shared_ptr<AbstractPathFormula<T>> const & getChild () const { + return child; } /*! * Sets the child node * - * @param pathFormula the path formula that becomes the new child node + * @param child the path formula that becomes the new child node */ - void setPathFormula(std::shared_ptr<AbstractPathFormula<T>> const & pathFormula) { - this->pathFormula = pathFormula; + void setChild(std::shared_ptr<AbstractPathFormula<T>> const & child) { + this->child = child; } /*! * * @return True if the path formula is set, i.e. it does not point to nullptr; false otherwise */ - bool pathFormulaIsSet() const { - return pathFormula.get() != nullptr; + bool childIsSet() const { + return child.get() != nullptr; } /*! @@ -207,7 +207,7 @@ public: private: storm::property::ComparisonType comparisonOperator; T bound; - std::shared_ptr<AbstractPathFormula<T>> pathFormula; + std::shared_ptr<AbstractPathFormula<T>> child; }; } //namespace csl diff --git a/src/modelchecker/csl/AbstractModelChecker.h b/src/modelchecker/csl/AbstractModelChecker.h index af7d28f86..3a9ff9285 100644 --- a/src/modelchecker/csl/AbstractModelChecker.h +++ b/src/modelchecker/csl/AbstractModelChecker.h @@ -174,7 +174,7 @@ public: */ virtual storm::storage::BitVector checkProbabilisticBoundOperator(storm::property::csl::ProbabilisticBoundOperator<Type> const& formula) const { // First, we need to compute the probability for satisfying the path formula for each state. - std::vector<Type> quantitativeResult = formula.getPathFormula()->check(*this, false); + std::vector<Type> quantitativeResult = formula.getChild()->check(*this, false); // Create resulting bit vector that will hold the yes/no-answer for every state. storm::storage::BitVector result(quantitativeResult.size()); diff --git a/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h b/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h index 0b4c6bd43..71213f1b8 100644 --- a/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h +++ b/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h @@ -65,7 +65,7 @@ public: } // First, we need to compute the probability for satisfying the path formula for each state. - std::vector<ValueType> quantitativeResult = formula.getPathFormula()->check(*this, false); + std::vector<ValueType> quantitativeResult = formula.getChild()->check(*this, false); //Remove the minimizing operator entry from the stack. this->minimumOperatorStack.pop(); diff --git a/src/parser/CslParser.cpp b/src/parser/CslParser.cpp index f0a51afa6..1f2f66361 100644 --- a/src/parser/CslParser.cpp +++ b/src/parser/CslParser.cpp @@ -78,27 +78,27 @@ struct CslParser::CslGrammar : qi::grammar<Iterator, std::shared_ptr<csl::CslFil //This block defines rules for "atomic" state formulas //(Propositions, probabilistic/reward formulas, and state formulas in brackets) - atomicStateFormula %= probabilisticBoundOperator | steadyStateBoundOperator | atomicProposition | qi::lit("(") >> stateFormula >> qi::lit(")"); + atomicStateFormula %= probabilisticBoundOperator | steadyStateBoundOperator | atomicProposition | (qi::lit("(") >> stateFormula >> qi::lit(")")) | (qi::lit("[") >> stateFormula >> qi::lit("]")); atomicStateFormula.name("atomic state formula"); atomicProposition = (freeIdentifierName)[qi::_val = MAKE(csl::Ap<double>, qi::_1)]; atomicProposition.name("atomic proposition"); probabilisticBoundOperator = ( - (qi::lit("P") >> comparisonType > qi::double_ > qi::lit("[") > pathFormula > qi::lit("]"))[qi::_val = + (qi::lit("P") >> comparisonType > qi::double_ > pathFormula )[qi::_val = MAKE(csl::ProbabilisticBoundOperator<double> , qi::_1, qi::_2, qi::_3)] ); probabilisticBoundOperator.name("probabilistic bound operator"); steadyStateBoundOperator = ( - (qi::lit("S") >> comparisonType > qi::double_ > qi::lit("[") > stateFormula > qi::lit("]"))[qi::_val = - MAKE(csl::SteadyStateBoundOperator<double> , qi::_1, qi::_2, qi::_3)] + (qi::lit("S") >> comparisonType > qi::double_ > stateFormula )[qi::_val = + MAKE(csl::SteadyStateBoundOperator<double> , qi::_1, qi::_2, qi::_3)] ); steadyStateBoundOperator.name("steady state bound operator"); //This block defines rules for parsing probabilistic path formulas - pathFormula = (timeBoundedEventually | eventually | globally | next | timeBoundedUntil | until); + pathFormula = (timeBoundedEventually | eventually | globally | next | timeBoundedUntil | until | (qi::lit("(") >> pathFormula >> qi::lit(")")) | (qi::lit("[") >> pathFormula >> qi::lit("]"))); pathFormula.name("path formula"); timeBoundedEventually = ( - (qi::lit("F") >> qi::lit("[") > qi::double_ > qi::lit(",") > qi::double_ > qi::lit("]") > stateFormula)[qi::_val = + (qi::lit("F") >> qi::lit("[") >> qi::double_ >> qi::lit(",") > qi::double_ > qi::lit("]") > stateFormula)[qi::_val = MAKE(csl::TimeBoundedEventually<double>, qi::_1, qi::_2, qi::_3)] | (qi::lit("F") >> (qi::lit("<=") | qi::lit("<")) > qi::double_ > stateFormula)[qi::_val = MAKE(csl::TimeBoundedEventually<double>, 0, qi::_1, qi::_2)] | @@ -116,11 +116,11 @@ struct CslParser::CslGrammar : qi::grammar<Iterator, std::shared_ptr<csl::CslFil MAKE(csl::Globally<double> , qi::_1)]; globally.name("globally"); timeBoundedUntil = ( - (stateFormula[qi::_a = qi::_1] >> qi::lit("U") >> qi::lit("[") > qi::double_ > qi::lit(",") > qi::double_ > qi::lit("]") > stateFormula) + (stateFormula[qi::_a = qi::_1] >> qi::lit("U") >> qi::lit("[") >> qi::double_ >> qi::lit(",") >> qi::double_ >> qi::lit("]") >> stateFormula) [qi::_val = MAKE(csl::TimeBoundedUntil<double>, qi::_2, qi::_3, qi::_a, qi::_4)] | - (stateFormula[qi::_a = qi::_1] >> qi::lit("U") >> (qi::lit("<=") | qi::lit("<")) > qi::double_ > stateFormula) + (stateFormula[qi::_a = qi::_1] >> qi::lit("U") >> (qi::lit("<=") | qi::lit("<")) > qi::double_ > stateFormula) [qi::_val = MAKE(csl::TimeBoundedUntil<double>, 0, qi::_2, qi::_a, qi::_3)] | - (stateFormula[qi::_a = qi::_1] >> qi::lit("U") >> (qi::lit(">=") | qi::lit(">")) > qi::double_ > stateFormula) + (stateFormula[qi::_a = qi::_1] >> qi::lit("U") >> (qi::lit(">=") | qi::lit(">")) > qi::double_ > stateFormula) [qi::_val = MAKE(csl::TimeBoundedUntil<double>, qi::_2, std::numeric_limits<double>::infinity(), qi::_a, qi::_3)] ); timeBoundedUntil.name("time bounded until"); @@ -135,14 +135,14 @@ struct CslParser::CslGrammar : qi::grammar<Iterator, std::shared_ptr<csl::CslFil noBoundOperator = (probabilisticNoBoundOperator | steadyStateNoBoundOperator); noBoundOperator.name("no bound operator"); probabilisticNoBoundOperator = - (qi::lit("P") >> qi::lit("min") >> qi::lit("=") >> qi::lit("?") >> qi::lit("[") >> pathFormula >> qi::lit("]"))[qi::_val = + (qi::lit("P") >> qi::lit("min") >> qi::lit("=") > qi::lit("?") >> pathFormula)[qi::_val = MAKE(csl::CslFilter<double>, qi::_1, storm::property::MINIMIZE)] | - (qi::lit("P") >> qi::lit("max") >> qi::lit("=") >> qi::lit("?") >> qi::lit("[") >> pathFormula >> qi::lit("]"))[qi::_val = + (qi::lit("P") >> qi::lit("max") >> qi::lit("=") > qi::lit("?") >> pathFormula)[qi::_val = MAKE(csl::CslFilter<double>, qi::_1, storm::property::MAXIMIZE)] | - (qi::lit("P") >> qi::lit("=") >> qi::lit("?") >> qi::lit("[") >> pathFormula >> qi::lit("]"))[qi::_val = + (qi::lit("P") >> qi::lit("=") > qi::lit("?") >> pathFormula)[qi::_val = MAKE(csl::CslFilter<double>, qi::_1)]; probabilisticNoBoundOperator.name("probabilistic no bound operator"); - steadyStateNoBoundOperator = (qi::lit("S") >> qi::lit("=") >> qi::lit("?") >> qi::lit("[") >> stateFormula >> qi::lit("]"))[qi::_val = + steadyStateNoBoundOperator = (qi::lit("S") >> qi::lit("=") > qi::lit("?") >> stateFormula )[qi::_val = MAKE(csl::CslFilter<double>, qi::_1, storm::property::UNDEFINED, true)]; steadyStateNoBoundOperator.name("steady state no bound operator"); @@ -176,11 +176,15 @@ struct CslParser::CslGrammar : qi::grammar<Iterator, std::shared_ptr<csl::CslFil ); sortAction.name("sort action"); - abstractAction = (boundAction | invertAction | formulaAction | rangeAction | sortAction) >> (qi::lit(";") | qi::eps); + abstractAction = (qi::lit(";") | qi::eps) >> (boundAction | invertAction | formulaAction | rangeAction | sortAction) >> (qi::lit(";") | qi::eps); abstractAction.name("filter action"); filter = (qi::lit("filter") >> qi::lit("[") >> +abstractAction >> qi::lit("]") >> qi::lit("(") >> formula >> qi::lit(")"))[qi::_val = MAKE(csl::CslFilter<double>, qi::_2, qi::_1)] | + (qi::lit("filter") >> qi::lit("[") >> qi::lit("max") > +abstractAction >> qi::lit("]") >> qi::lit("(") >> formula >> qi::lit(")"))[qi::_val = + MAKE(csl::CslFilter<double>, qi::_2, qi::_1, storm::property::MAXIMIZE)] | + (qi::lit("filter") >> qi::lit("[") >> qi::lit("min") > +abstractAction >> qi::lit("]") >> qi::lit("(") >> formula >> qi::lit(")"))[qi::_val = + MAKE(csl::CslFilter<double>, qi::_2, qi::_1, storm::property::MINIMIZE)] | (noBoundOperator)[qi::_val = qi::_1] | (formula)[qi::_val = @@ -188,7 +192,7 @@ struct CslParser::CslGrammar : qi::grammar<Iterator, std::shared_ptr<csl::CslFil filter.name("CSL formula filter"); - start = (((filter) > (comment | qi::eps))[qi::_val = qi::_1] | comment[qi::_val = nullptr] ) > qi::eoi; + start = (((filter) > (comment | qi::eps))[qi::_val = qi::_1] | comment[qi::_val = MAKE(csl::CslFilter<double>, nullptr)] ) > qi::eoi; start.name("CSL formula filter start"); } diff --git a/src/parser/PrctlParser.cpp b/src/parser/PrctlParser.cpp index b31b621bb..bd9590980 100644 --- a/src/parser/PrctlParser.cpp +++ b/src/parser/PrctlParser.cpp @@ -146,7 +146,7 @@ struct PrctlParser::PrctlGrammar : qi::grammar<Iterator, std::shared_ptr<storm:: MAKE(prctl::PrctlFilter<double>, qi::_1, storm::property::MINIMIZE)] | (qi::lit("R") >> qi::lit("max") >> qi::lit("=") > qi::lit("?") >> rewardPathFormula )[qi::_val = MAKE(prctl::PrctlFilter<double>, qi::_1, storm::property::MAXIMIZE)] | - (qi::lit("R") >> qi::lit("=") >> qi::lit("?") >> rewardPathFormula )[qi::_val = + (qi::lit("R") >> qi::lit("=") > qi::lit("?") >> rewardPathFormula )[qi::_val = MAKE(prctl::PrctlFilter<double>, qi::_1)] ); @@ -183,7 +183,7 @@ struct PrctlParser::PrctlGrammar : qi::grammar<Iterator, std::shared_ptr<storm:: ); sortAction.name("sort action"); - abstractAction = (boundAction | invertAction | formulaAction | rangeAction | sortAction) >> (qi::lit(";") | qi::eps); + abstractAction = (qi::lit(";") | qi::eps) >> (boundAction | invertAction | formulaAction | rangeAction | sortAction) >> (qi::lit(";") | qi::eps); abstractAction.name("filter action"); filter = (qi::lit("filter") >> qi::lit("[") >> +abstractAction >> qi::lit("]") > qi::lit("(") >> formula >> qi::lit(")"))[qi::_val = diff --git a/test/functional/modelchecker/FilterTest.cpp b/test/functional/modelchecker/FilterTest.cpp index 65fa50e7a..a9f3cfbe8 100644 --- a/test/functional/modelchecker/FilterTest.cpp +++ b/test/functional/modelchecker/FilterTest.cpp @@ -10,11 +10,16 @@ #include "src/models/Dtmc.h" #include "src/parser/DeterministicModelParser.h" #include "src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h" +#include "src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h" #include "src/solver/GmmxxLinearEquationSolver.h" +#include "src/solver/GmmxxNondeterministicLinearEquationSolver.h" #include "src/formula/prctl/PrctlFilter.h" #include "src/formula/csl/CslFilter.h" #include "src/formula/ltl/LtlFilter.h" #include "src/parser/PrctlParser.h" +#include "src/parser/CslParser.h" +#include "src/parser/MarkovAutomatonParser.h" +#include "src/formula/actions/InvertAction.h" #include <memory> @@ -42,12 +47,12 @@ TEST(PrctlFilterTest, generalFunctionality) { formula->check(mc); - std::string output = buffer.str(); - ASSERT_NE(std::string::npos, output.find("\t6: 1")); - // Reset cout to the original buffer. std::cout.rdbuf(sbuf); + std::string output = buffer.str(); + ASSERT_NE(std::string::npos, output.find("\t6: 1")); + // The remaining queries use evaluate directly as its easier to work with in a test environment. // Get the probability to reach a b state for all states but those that cannot reach a 'b' state or are 'b' states themselves. // Sorted by value; highest first. @@ -148,9 +153,206 @@ TEST(PrctlFilterTest, Safety) { // Make a stub formula as child. auto apFormula = std::make_shared<storm::property::prctl::Ap<double>>("a"); + // Test the filter for nullptr action handling. auto formula = std::make_shared<storm::property::prctl::PrctlFilter<double>>(apFormula, nullptr); - ASSERT_NO_THROW(formula->check(mc)); + ASSERT_EQ(0, formula->getActionCount()); + ASSERT_NO_THROW(formula->evaluate(mc)); + + // Repeat with vector containing only one action but three nullptr. + std::vector<std::shared_ptr<storm::property::action::AbstractAction<double>>> actions(4, nullptr); + actions[1] = std::make_shared<storm::property::action::InvertAction<double>>(); + + formula = std::make_shared<storm::property::prctl::PrctlFilter<double>>(apFormula, actions); + + ASSERT_EQ(1, formula->getActionCount()); + ASSERT_NO_THROW(formula->evaluate(mc)); + + // Test the filter for nullptr child formula handling. + // It sholud not write anything to the standard out and return an empty result. + formula = std::make_shared<storm::property::prctl::PrctlFilter<double>>(); + Result result; + + // To capture the output, redirect cout and test the written buffer content. + std::stringstream buffer; + std::streambuf *sbuf = std::cout.rdbuf(); + std::cout.rdbuf(buffer.rdbuf()); + + ASSERT_NO_THROW(result = formula->evaluate(mc)); + + // Reset cout to the original buffer. + std::cout.rdbuf(sbuf); + + ASSERT_EQ(0, buffer.str().length()); + + ASSERT_EQ(0, result.pathResult.size()); + ASSERT_EQ(0, result.stateResult.size()); + ASSERT_EQ(0, result.selection.size()); + ASSERT_EQ(0, result.stateMap.size()); } +TEST(CslFilterTest, generalFunctionality) { + // Test filter queries of increasing complexity. + + // Setup model and modelchecker. + storm::models::MarkovAutomaton<double> model = storm::parser::MarkovAutomatonParser::parseMarkovAutomaton(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/ma_cslFilterTest.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/ma_cslFilterTest.lab"); + storm::modelchecker::csl::SparseMarkovAutomatonCslModelChecker<double> mc(model, std::make_shared<storm::solver::GmmxxNondeterministicLinearEquationSolver<double>>()); + + // Find the best valued state to finally reach a 'r1' state. + std::string input = "filter[max; sort(value, descending); range(0,0)](F r1)"; + std::shared_ptr<storm::property::csl::CslFilter<double>> formula(nullptr); + ASSERT_NO_THROW( + formula = storm::parser::CslParser::parseCslFormula(input) + ); + + // Here we test if the check method gives the correct result. + // To capture the output, redirect cout and test the written buffer content. + std::stringstream buffer; + std::streambuf *sbuf = std::cout.rdbuf(); + std::cout.rdbuf(buffer.rdbuf()); + + formula->check(mc); + + // Reset cout to the original buffer. + std::cout.rdbuf(sbuf); + + std::string output = buffer.str(); + ASSERT_NE(std::string::npos, output.find("\t6: 1")); + + // The remaining queries use evaluate directly as its easier to work with in a test environment. + // Get the maximum probability to reach an 'r1' state for all states but those that cannot reach an 'r1' state or are 'r1' states themselves. + // Sorted by value; highest first. + input = "filter[max; formula(P<=0(F r1) | r1); invert; sort(value, desc)](F r1)"; + ASSERT_NO_THROW( + formula = storm::parser::CslParser::parseCslFormula(input) + ); + + Result result = formula->evaluate(mc); + + // Test the selection. + ASSERT_EQ(6, result.selection.getNumberOfSetBits()); + ASSERT_TRUE(result.selection[0]); + ASSERT_TRUE(result.selection[1]); + ASSERT_TRUE(result.selection[2]); + ASSERT_TRUE(result.selection[3]); + ASSERT_TRUE(result.selection[4]); + ASSERT_TRUE(result.selection[5]); + ASSERT_FALSE(result.selection[6]); + ASSERT_FALSE(result.selection[7]); + + // Test the sorting. + ASSERT_EQ(6, result.stateMap[0]); + ASSERT_EQ(5, result.stateMap[1]); + ASSERT_EQ(2, result.stateMap[2]); + ASSERT_EQ(3, result.stateMap[3]); + ASSERT_EQ(0, result.stateMap[4]); + ASSERT_EQ(4, result.stateMap[5]); + ASSERT_EQ(1, result.stateMap[6]); + ASSERT_EQ(7, result.stateMap[7]); + + // Get the minimum probability for reaching an 'err' state only for those states that have a probability to do so of at most 0.2. + // Sorted by value; lowest first. + input = "filter[min; bound(<, 0.2); sort(value, ascending)](F err)"; + ASSERT_NO_THROW( + formula = storm::parser::CslParser::parseCslFormula(input) + ); + + result = formula->evaluate(mc); + + // Test the selection. + ASSERT_EQ(5, result.selection.getNumberOfSetBits()); + ASSERT_FALSE(result.selection[0]); + ASSERT_TRUE(result.selection[1]); + ASSERT_FALSE(result.selection[2]); + ASSERT_FALSE(result.selection[3]); + ASSERT_TRUE(result.selection[4]); + ASSERT_TRUE(result.selection[5]); + ASSERT_TRUE(result.selection[6]); + ASSERT_TRUE(result.selection[7]); + + // Test the sorting. + ASSERT_EQ(6, result.stateMap[0]); + ASSERT_EQ(7, result.stateMap[1]); + ASSERT_EQ(5, result.stateMap[2]); + ASSERT_EQ(4, result.stateMap[3]); + ASSERT_EQ(1, result.stateMap[4]); + ASSERT_EQ(0, result.stateMap[5]); + ASSERT_EQ(2, result.stateMap[6]); + ASSERT_EQ(3, result.stateMap[7]); + + // Get the three highest indexed states reaching an 'r2' state with probability at most 0.3. + input = "filter[sort(value); range(5,7); sort(index, descending)](P<=0.3(F r2))"; + ASSERT_NO_THROW( + formula = storm::parser::CslParser::parseCslFormula(input) + ); + + result = formula->evaluate(mc); + + // Test the selection. + ASSERT_EQ(3, result.selection.getNumberOfSetBits()); + ASSERT_FALSE(result.selection[0]); + ASSERT_FALSE(result.selection[1]); + ASSERT_FALSE(result.selection[2]); + ASSERT_TRUE(result.selection[3]); + ASSERT_FALSE(result.selection[4]); + ASSERT_TRUE(result.selection[5]); + ASSERT_TRUE(result.selection[6]); + ASSERT_FALSE(result.selection[7]); + + // Test the sorting. + ASSERT_EQ(7, result.stateMap[0]); + ASSERT_EQ(6, result.stateMap[1]); + ASSERT_EQ(5, result.stateMap[2]); + ASSERT_EQ(4, result.stateMap[3]); + ASSERT_EQ(3, result.stateMap[4]); + ASSERT_EQ(2, result.stateMap[5]); + ASSERT_EQ(1, result.stateMap[6]); + ASSERT_EQ(0, result.stateMap[7]); +} + +TEST(CslFilterTest, Safety) { + // Setup model and modelchecker. + storm::models::MarkovAutomaton<double> model = storm::parser::MarkovAutomatonParser::parseMarkovAutomaton(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/ma_cslFilterTest.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/ma_cslFilterTest.lab"); + storm::modelchecker::csl::SparseMarkovAutomatonCslModelChecker<double> mc(model, std::make_shared<storm::solver::GmmxxNondeterministicLinearEquationSolver<double>>()); + + // Make a stub formula as child. + auto apFormula = std::make_shared<storm::property::csl::Ap<double>>("r1"); + + // Test the filter for nullptr action handling. + auto formula = std::make_shared<storm::property::csl::CslFilter<double>>(apFormula, nullptr, storm::property::MAXIMIZE); + + ASSERT_NO_THROW(formula->evaluate(mc)); + ASSERT_EQ(0, formula->getActionCount()); + + // Repeat with vector containing only one action but three nullptr. + std::vector<std::shared_ptr<storm::property::action::AbstractAction<double>>> actions(4, nullptr); + actions[1] = std::make_shared<storm::property::action::InvertAction<double>>(); + + formula = std::make_shared<storm::property::csl::CslFilter<double>>(apFormula, actions, storm::property::MAXIMIZE); + + ASSERT_EQ(1, formula->getActionCount()); + ASSERT_NO_THROW(formula->evaluate(mc)); + + // Test the filter for nullptr child formula handling. + // It sholud not write anything to the standard out and return an empty result. + formula = std::make_shared<storm::property::csl::CslFilter<double>>(); + Result result; + + // To capture the output, redirect cout and test the written buffer content. + std::stringstream buffer; + std::streambuf *sbuf = std::cout.rdbuf(); + std::cout.rdbuf(buffer.rdbuf()); + + ASSERT_NO_THROW(result = formula->evaluate(mc)); + + // Reset cout to the original buffer. + std::cout.rdbuf(sbuf); + + ASSERT_EQ(0, buffer.str().length()); + + ASSERT_EQ(0, result.pathResult.size()); + ASSERT_EQ(0, result.stateResult.size()); + ASSERT_EQ(0, result.selection.size()); + ASSERT_EQ(0, result.stateMap.size()); +} diff --git a/test/functional/parser/CslParserTest.cpp b/test/functional/parser/CslParserTest.cpp index ff0a4f4d1..4d13479e1 100644 --- a/test/functional/parser/CslParserTest.cpp +++ b/test/functional/parser/CslParserTest.cpp @@ -9,6 +9,11 @@ #include "storm-config.h" #include "src/parser/CslParser.h" #include "src/exceptions/WrongFormatException.h" +#include "src/formula/actions/FormulaAction.h" +#include "src/formula/actions/InvertAction.h" +#include "src/formula/actions/SortAction.h" +#include "src/formula/actions/RangeAction.h" +#include "src/formula/actions/BoundAction.h" namespace csl = storm::property::csl; @@ -40,6 +45,35 @@ TEST(CslParserTest, parsePropositionalFormulaTest) { ASSERT_EQ("(!(a & b) | (a & !c))", formula->toString()); } +TEST(CslParserTest, parsePathFormulaTest) { + std::string input = "X( P<0.9 (a U b))"; + std::shared_ptr<csl::CslFilter<double>> formula(nullptr); + ASSERT_NO_THROW( + formula = storm::parser::CslParser::parseCslFormula(input) + ); + + // The parser did not falsely recognize the input as a comment. + ASSERT_NE(formula, nullptr); + + // The input was parsed correctly. + ASSERT_NE(std::dynamic_pointer_cast<csl::Next<double>>(formula->getChild()).get(), nullptr); + auto nextFormula = std::dynamic_pointer_cast<csl::Next<double>>(formula->getChild()); + ASSERT_NE(std::dynamic_pointer_cast<csl::ProbabilisticBoundOperator<double>>(nextFormula->getChild()).get(), nullptr); + auto probBoundFormula = std::dynamic_pointer_cast<csl::ProbabilisticBoundOperator<double>>(nextFormula->getChild()); + ASSERT_NE(std::dynamic_pointer_cast<csl::Until<double>>(probBoundFormula->getChild()).get(), nullptr); + auto untilFormula = std::dynamic_pointer_cast<csl::Until<double>>(probBoundFormula->getChild()); + ASSERT_NE(std::dynamic_pointer_cast<csl::Ap<double>>(untilFormula->getLeft()).get(), nullptr); + ASSERT_NE(std::dynamic_pointer_cast<csl::Ap<double>>(untilFormula->getRight()).get(), nullptr); + ASSERT_EQ("a", std::dynamic_pointer_cast<csl::Ap<double>>(untilFormula->getLeft())->getAp()); + ASSERT_EQ("b", std::dynamic_pointer_cast<csl::Ap<double>>(untilFormula->getRight())->getAp()); + ASSERT_EQ(0.9, probBoundFormula->getBound()); + ASSERT_EQ(storm::property::LESS, probBoundFormula->getComparisonOperator()); + + + // The string representation is also correct. + ASSERT_EQ("P = ? (X P < 0.900000 (a U b))", formula->toString()); +} + TEST(CslParserTest, parseProbabilisticFormulaTest) { std::string input = "P > 0.5 [ F a ]"; std::shared_ptr<csl::CslFilter<double>> formula(nullptr); @@ -118,7 +152,46 @@ TEST(CslParserTest, parseComplexFormulaTest) { ASSERT_NE(formula.get(), nullptr); // The input was parsed correctly. - ASSERT_EQ("(S <= 0.500000 (P <= 0.500000 (a U c)) & (P > 0.500000 (G b) | !P < 0.400000 (G P > 0.900000 (F>=7.000000 (a & b)))))", formula->toString()); + ASSERT_EQ("S <= 0.500000 ((P <= 0.500000 (a U c) & (P > 0.500000 (G b) | !P < 0.400000 (G P > 0.900000 (F>=7.000000 (a & b))))))", formula->toString()); +} + +TEST(CslParserTest, parseCslFilterTest) { + std::string input = "filter[formula(b); invert; bound(<, 0.5); sort(value); range(0,3)](F a)"; + std::shared_ptr<csl::CslFilter<double>> formula(nullptr); + ASSERT_NO_THROW( + formula = storm::parser::CslParser::parseCslFormula(input) + ); + + // The parser did not falsely recognize the input as a comment. + ASSERT_NE(formula, nullptr); + + ASSERT_EQ(5, formula->getActionCount()); + ASSERT_NE(std::dynamic_pointer_cast<storm::property::action::FormulaAction<double>>(formula->getAction(0)).get(), nullptr); + ASSERT_NE(std::dynamic_pointer_cast<storm::property::action::InvertAction<double>>(formula->getAction(1)).get(), nullptr); + ASSERT_NE(std::dynamic_pointer_cast<storm::property::action::BoundAction<double>>(formula->getAction(2)).get(), nullptr); + ASSERT_NE(std::dynamic_pointer_cast<storm::property::action::SortAction<double>>(formula->getAction(3)).get(), nullptr); + ASSERT_NE(std::dynamic_pointer_cast<storm::property::action::RangeAction<double>>(formula->getAction(4)).get(), nullptr); + + // The input was parsed correctly. + ASSERT_EQ("filter[formula(b); invert; bound(<, 0.500000); sort(value, ascending); range(0, 3)](F a)", formula->toString()); +} + +TEST(CslParserTest, commentTest) { + std::string input = "// This is a comment. And this is a commented out formula: P = ? [ F a ]"; + std::shared_ptr<csl::CslFilter<double>> formula(nullptr); + ASSERT_NO_THROW( + formula = storm::parser::CslParser::parseCslFormula(input) + ); + + // The parser recognized the input as a comment. + ASSERT_NE(nullptr, formula.get()); + + // Test if the parser recognizes the comment at the end of a line. + input = "P = ? [ F a ] // This is a comment."; + ASSERT_NO_THROW( + formula = storm::parser::CslParser::parseCslFormula(input) + ); + ASSERT_EQ("P = ? (F a)", formula->toString()); } TEST(CslParserTest, wrongProbabilisticFormulaTest) { From 0a2a759932833e71a939774dd465eb2001129413 Mon Sep 17 00:00:00 2001 From: masawei <manuel.sascha.weiand@rwth-aachen.de> Date: Wed, 13 Aug 2014 00:06:10 +0200 Subject: [PATCH 24/30] Ltl testng. Former-commit-id: 57f486db59aa0dd43903147bcb022b03733c3916 --- src/formula/csl/CslFilter.h | 2 +- src/formula/ltl/LtlFilter.h | 62 +++++++++++----------- src/parser/LtlParser.cpp | 10 ++-- test/functional/parser/CslParserTest.cpp | 6 ++- test/functional/parser/LtlParserTest.cpp | 60 ++++++++++++++++++--- test/functional/parser/PrctlParserTest.cpp | 8 +-- 6 files changed, 98 insertions(+), 50 deletions(-) diff --git a/src/formula/csl/CslFilter.h b/src/formula/csl/CslFilter.h index d09902760..d77d38592 100644 --- a/src/formula/csl/CslFilter.h +++ b/src/formula/csl/CslFilter.h @@ -52,7 +52,7 @@ public: } virtual ~CslFilter() { - this->actions.clear(); + // Intentionally left empty. } void check(storm::modelchecker::csl::AbstractModelChecker<T> const & modelchecker) const { diff --git a/src/formula/ltl/LtlFilter.h b/src/formula/ltl/LtlFilter.h index d35b9fd46..2dd9c9a7f 100644 --- a/src/formula/ltl/LtlFilter.h +++ b/src/formula/ltl/LtlFilter.h @@ -42,7 +42,7 @@ public: } LtlFilter(std::shared_ptr<AbstractLtlFormula<T>> const & child, std::shared_ptr<action::AbstractAction<T>> const & action, OptimizingOperator opt = UNDEFINED) : AbstractFilter<T>(action, opt), child(child) { - this->actions.push_back(action); + // Intentionally left empty. } LtlFilter(std::shared_ptr<AbstractLtlFormula<T>> const & child, std::vector<std::shared_ptr<action::AbstractAction<T>>> const & actions, OptimizingOperator opt = UNDEFINED) : AbstractFilter<T>(actions, opt), child(child) { @@ -50,7 +50,7 @@ public: } virtual ~LtlFilter() { - this->actions.clear(); + // Intentionally left empty. } @@ -83,6 +83,35 @@ public: } + Result evaluate(storm::modelchecker::ltl::AbstractModelChecker<T> const & modelchecker) const { + // First, get the model checking result. + Result result; + + if(this->opt != UNDEFINED) { + // If it is specified that min/max probabilities/rewards should be computed, call the appropriate method of the model checker. + LOG4CPLUS_ERROR(logger, "Calculation of minimizing and maximizing schedulers for LTL-formula model checking is not yet implemented."); + throw storm::exceptions::NotImplementedException() << "Calculation of minimizing and maximizing schedulers for LTL-formula model checking is not yet implemented."; + } else { + result.pathResult = child->check(modelchecker); + } + + // Now apply all filter actions and return the result. + + // Init the state selection and state map vectors. + result.selection = storm::storage::BitVector(result.stateResult.size(), true); + result.stateMap = std::vector<uint_fast64_t>(result.selection.size()); + for(uint_fast64_t i = 0; i < result.selection.size(); i++) { + result.stateMap[i] = i; + } + + // Now apply all filter actions and return the result. + for(auto action : this->actions) { + result = action->evaluate(result, modelchecker); + } + + return result; + } + std::string toString() const override { std::string desc = ""; @@ -142,35 +171,6 @@ public: private: - Result evaluate(storm::modelchecker::ltl::AbstractModelChecker<T> const & modelchecker) const { - // First, get the model checking result. - Result result; - - if(this->opt != UNDEFINED) { - // If it is specified that min/max probabilities/rewards should be computed, call the appropriate method of the model checker. - LOG4CPLUS_ERROR(logger, "Calculation of minimizing and maximizing schedulers for LTL-formula model checking is not yet implemented."); - throw storm::exceptions::NotImplementedException() << "Calculation of minimizing and maximizing schedulers for LTL-formula model checking is not yet implemented."; - } else { - result.stateResult = child->check(modelchecker); - } - - // Now apply all filter actions and return the result. - - // Init the state selection and state map vectors. - result.selection = storm::storage::BitVector(result.stateResult.size(), true); - result.stateMap = std::vector<uint_fast64_t>(result.selection.size()); - for(uint_fast64_t i = 0; i < result.selection.size(); i++) { - result.stateMap[i] = i; - } - - // Now apply all filter actions and return the result. - for(auto action : this->actions) { - result = action->evaluate(result, modelchecker); - } - - return result; - } - void writeOut(Result const & result, storm::modelchecker::ltl::AbstractModelChecker<T> const & modelchecker) const { // Test for the kind of result. Values or states. diff --git a/src/parser/LtlParser.cpp b/src/parser/LtlParser.cpp index 25d62d241..74cb89944 100644 --- a/src/parser/LtlParser.cpp +++ b/src/parser/LtlParser.cpp @@ -62,13 +62,13 @@ struct LtlParser::LtlGrammar : qi::grammar<Iterator, std::shared_ptr<storm::prop (qi::lit("index"))[qi::_val = storm::property::action::SortAction<double>::INDEX] | (qi::lit("value"))[qi::_val = storm::property::action::SortAction<double>::VALUE] ); - //Comment: Empty line or line starting with "//" + // Comment: Empty line or line starting with "//" comment = (qi::lit("//") >> *(qi::char_))[qi::_val = nullptr]; freeIdentifierName = qi::lexeme[+(qi::alpha | qi::char_('_'))]; - //This block defines rules for parsing state formulas - formula %= orFormula; + // This block defines rules for parsing state formulas + formula %= orFormula | qi::lit("(") >> formula >> qi::lit(")")| qi::lit("[") >> formula >> qi::lit("]"); formula.name("LTL formula"); orFormula = andFormula[qi::_val = qi::_1] > *(qi::lit("|") > andFormula)[qi::_val = MAKE(ltl::Or<double>, qi::_val, qi::_1)]; @@ -85,7 +85,7 @@ struct LtlParser::LtlGrammar : qi::grammar<Iterator, std::shared_ptr<storm::prop //This block defines rules for "atomic" state formulas //(Propositions, probabilistic/reward formulas, and state formulas in brackets) - atomicLtlFormula %= pathFormula | atomicProposition | qi::lit("(") >> formula >> qi::lit(")"); + atomicLtlFormula %= pathFormula | atomicProposition; atomicLtlFormula.name("LTL formula"); atomicProposition = (freeIdentifierName)[qi::_val = MAKE(ltl::Ap<double>, qi::_1)]; @@ -133,7 +133,7 @@ struct LtlParser::LtlGrammar : qi::grammar<Iterator, std::shared_ptr<storm::prop ); sortAction.name("sort action"); - abstractAction = (boundAction | invertAction | rangeAction | sortAction) >> (qi::lit(";") | qi::eps); + abstractAction = (qi::lit(";") | qi::eps) >> (boundAction | invertAction | rangeAction | sortAction) >> (qi::lit(";") | qi::eps); abstractAction.name("filter action"); filter = (qi::lit("filter") >> qi::lit("[") >> +abstractAction >> qi::lit("]") > qi::lit("(") >> formula >> qi::lit(")"))[qi::_val = diff --git a/test/functional/parser/CslParserTest.cpp b/test/functional/parser/CslParserTest.cpp index 4d13479e1..e4289a2b4 100644 --- a/test/functional/parser/CslParserTest.cpp +++ b/test/functional/parser/CslParserTest.cpp @@ -156,7 +156,7 @@ TEST(CslParserTest, parseComplexFormulaTest) { } TEST(CslParserTest, parseCslFilterTest) { - std::string input = "filter[formula(b); invert; bound(<, 0.5); sort(value); range(0,3)](F a)"; + std::string input = "filter[max; formula(b); invert; bound(<, 0.5); sort(value); range(0,3)](F a)"; std::shared_ptr<csl::CslFilter<double>> formula(nullptr); ASSERT_NO_THROW( formula = storm::parser::CslParser::parseCslFormula(input) @@ -165,6 +165,8 @@ TEST(CslParserTest, parseCslFilterTest) { // The parser did not falsely recognize the input as a comment. ASSERT_NE(formula, nullptr); + ASSERT_EQ(storm::property::MAXIMIZE, formula->getOptimizingOperator()); + ASSERT_EQ(5, formula->getActionCount()); ASSERT_NE(std::dynamic_pointer_cast<storm::property::action::FormulaAction<double>>(formula->getAction(0)).get(), nullptr); ASSERT_NE(std::dynamic_pointer_cast<storm::property::action::InvertAction<double>>(formula->getAction(1)).get(), nullptr); @@ -173,7 +175,7 @@ TEST(CslParserTest, parseCslFilterTest) { ASSERT_NE(std::dynamic_pointer_cast<storm::property::action::RangeAction<double>>(formula->getAction(4)).get(), nullptr); // The input was parsed correctly. - ASSERT_EQ("filter[formula(b); invert; bound(<, 0.500000); sort(value, ascending); range(0, 3)](F a)", formula->toString()); + ASSERT_EQ("filter[max; formula(b); invert; bound(<, 0.500000); sort(value, ascending); range(0, 3)](F a)", formula->toString()); } TEST(CslParserTest, commentTest) { diff --git a/test/functional/parser/LtlParserTest.cpp b/test/functional/parser/LtlParserTest.cpp index 0ccda625a..8086bbf88 100644 --- a/test/functional/parser/LtlParserTest.cpp +++ b/test/functional/parser/LtlParserTest.cpp @@ -9,6 +9,10 @@ #include "storm-config.h" #include "src/parser/LtlParser.h" #include "src/exceptions/WrongFormatException.h" +#include "src/formula/actions/InvertAction.h" +#include "src/formula/actions/SortAction.h" +#include "src/formula/actions/RangeAction.h" +#include "src/formula/actions/BoundAction.h" namespace ltl = storm::property::ltl; @@ -20,7 +24,7 @@ TEST(LtlParserTest, parseApOnlyTest) { ); ASSERT_NE(ltlFormula.get(), nullptr); - ASSERT_EQ(ltlFormula->toString(), formula); + ASSERT_EQ(formula, ltlFormula->toString()); } TEST(LtlParserTest, parsePropositionalFormulaTest) { @@ -31,7 +35,7 @@ TEST(LtlParserTest, parsePropositionalFormulaTest) { ); ASSERT_NE(ltlFormula.get(), nullptr); - ASSERT_EQ(ltlFormula->toString(), "(!(a & b) | (a & !c))"); + ASSERT_EQ("(!(a & b) | (a & !c))", ltlFormula->toString()); } /*! @@ -46,7 +50,7 @@ TEST(LtlParserTest, parseAmbiguousFormulaTest) { ); ASSERT_NE(ltlFormula.get(), nullptr); - ASSERT_EQ(ltlFormula->toString(), "(F & b)"); + ASSERT_EQ("(F & b)", ltlFormula->toString()); } /*! @@ -61,7 +65,7 @@ TEST(LtlParserTest, parseAmbiguousFormulaTest2) { ); ASSERT_NE(ltlFormula.get(), nullptr); - ASSERT_EQ(ltlFormula->toString(), "F F"); + ASSERT_EQ("F F", ltlFormula->toString()); } TEST(LtlParserTest, parseBoundedEventuallyFormulaTest) { @@ -78,7 +82,7 @@ TEST(LtlParserTest, parseBoundedEventuallyFormulaTest) { ASSERT_EQ(static_cast<uint_fast64_t>(5), op->getBound()); - ASSERT_EQ(ltlFormula->toString(), "F<=5 a"); + ASSERT_EQ("F<=5 a", ltlFormula->toString()); } TEST(LtlParserTest, parseBoundedUntilFormulaTest) { @@ -95,7 +99,47 @@ TEST(LtlParserTest, parseBoundedUntilFormulaTest) { ASSERT_EQ(static_cast<uint_fast64_t>(3), op->getBound()); - ASSERT_EQ(ltlFormula->toString(), "(a U<=3 b)"); + ASSERT_EQ("(a U<=3 b)", ltlFormula->toString()); +} + +TEST(LtlParserTest, parseLtlFilterTest) { + std::string input = "filter[max; invert; bound(<, 0.5); sort(value); range(0,3)](X a)"; + std::shared_ptr<ltl::LtlFilter<double>> formula(nullptr); + ASSERT_NO_THROW( + formula = storm::parser::LtlParser::parseLtlFormula(input) + ); + + // The parser did not falsely recognize the input as a comment. + ASSERT_NE(formula, nullptr); + + ASSERT_EQ(storm::property::MAXIMIZE, formula->getOptimizingOperator()); + + ASSERT_EQ(4, formula->getActionCount()); + ASSERT_NE(std::dynamic_pointer_cast<storm::property::action::InvertAction<double>>(formula->getAction(0)).get(), nullptr); + ASSERT_NE(std::dynamic_pointer_cast<storm::property::action::BoundAction<double>>(formula->getAction(1)).get(), nullptr); + ASSERT_NE(std::dynamic_pointer_cast<storm::property::action::SortAction<double>>(formula->getAction(2)).get(), nullptr); + ASSERT_NE(std::dynamic_pointer_cast<storm::property::action::RangeAction<double>>(formula->getAction(3)).get(), nullptr); + + // The input was parsed correctly. + ASSERT_EQ("filter[max; invert; bound(<, 0.500000); sort(value, ascending); range(0, 3)](X a)", formula->toString()); +} + +TEST(PrctlParserTest, commentTest) { + std::string input = "// This is a comment. And this is a commented out formula: F X a"; + std::shared_ptr<ltl::LtlFilter<double>> formula(nullptr); + ASSERT_NO_THROW( + formula = storm::parser::LtlParser::parseLtlFormula(input) + ); + + // The parser recognized the input as a comment. + ASSERT_NE(nullptr, formula.get()); + + // Test if the parser recognizes the comment at the end of a line. + input = "F X a // This is a comment."; + ASSERT_NO_THROW( + formula = storm::parser::LtlParser::parseLtlFormula(input) + ); + ASSERT_EQ("F X a", formula->toString()); } TEST(LtlParserTest, parseComplexUntilTest) { @@ -106,7 +150,7 @@ TEST(LtlParserTest, parseComplexUntilTest) { ); ASSERT_NE(ltlFormula.get(), nullptr); - ASSERT_EQ(ltlFormula->toString(), "((a U b) U<=3 c)"); + ASSERT_EQ("((a U b) U<=3 c)", ltlFormula->toString()); } TEST(LtlParserTest, parseComplexFormulaTest) { @@ -117,7 +161,7 @@ TEST(LtlParserTest, parseComplexFormulaTest) { ); ASSERT_NE(ltlFormula.get(), nullptr); - ASSERT_EQ(ltlFormula->toString(), "(a U F (b | G (a & F<=3 (a U<=7 b))))"); + ASSERT_EQ("(a U F (b | G (a & F<=3 (a U<=7 b))))", ltlFormula->toString()); } TEST(LtlParserTest, wrongFormulaTest) { diff --git a/test/functional/parser/PrctlParserTest.cpp b/test/functional/parser/PrctlParserTest.cpp index ee86d92e8..dbdb508b7 100644 --- a/test/functional/parser/PrctlParserTest.cpp +++ b/test/functional/parser/PrctlParserTest.cpp @@ -159,7 +159,7 @@ TEST(PrctlParserTest, parseComplexFormulaTest) { } TEST(PrctlParserTest, parsePrctlFilterTest) { - std::string input = "filter[formula(b); invert; bound(<, 0.5); sort(value); range(0,3)](F a)"; + std::string input = "filter[max; formula(b); invert; bound(<, 0.5); sort(value); range(0,3)](F a)"; std::shared_ptr<prctl::PrctlFilter<double>> formula(nullptr); ASSERT_NO_THROW( formula = storm::parser::PrctlParser::parsePrctlFormula(input) @@ -168,6 +168,8 @@ TEST(PrctlParserTest, parsePrctlFilterTest) { // The parser did not falsely recognize the input as a comment. ASSERT_NE(formula, nullptr); + ASSERT_EQ(storm::property::MAXIMIZE, formula->getOptimizingOperator()); + ASSERT_EQ(5, formula->getActionCount()); ASSERT_NE(std::dynamic_pointer_cast<storm::property::action::FormulaAction<double>>(formula->getAction(0)).get(), nullptr); ASSERT_NE(std::dynamic_pointer_cast<storm::property::action::InvertAction<double>>(formula->getAction(1)).get(), nullptr); @@ -176,10 +178,10 @@ TEST(PrctlParserTest, parsePrctlFilterTest) { ASSERT_NE(std::dynamic_pointer_cast<storm::property::action::RangeAction<double>>(formula->getAction(4)).get(), nullptr); // The input was parsed correctly. - ASSERT_EQ("filter[formula(b); invert; bound(<, 0.500000); sort(value, ascending); range(0, 3)](F a)", formula->toString()); + ASSERT_EQ("filter[max; formula(b); invert; bound(<, 0.500000); sort(value, ascending); range(0, 3)](F a)", formula->toString()); } -TEST(PrctlParserTest, commentTest) { +TEST(LtlParserTest, commentTest) { std::string input = "// This is a comment. And this is a commented out formula: R = ? [ F a ]"; std::shared_ptr<prctl::PrctlFilter<double>> formula(nullptr); ASSERT_NO_THROW( From 27df78c2b0b1514551c7b41cac6202eb6f601a44 Mon Sep 17 00:00:00 2001 From: masawei <manuel.sascha.weiand@rwth-aachen.de> Date: Wed, 13 Aug 2014 00:40:24 +0200 Subject: [PATCH 25/30] Finished testing Ltl. - Regrettably, the LtlFilterTest could not be done, since an Ltl modechecker would be needed for that. Which, we don't have. |- So that is a TODO until such a modelchecker is implemented. - This concludes the testing for the refactured formulas. Next up: Documentation. Former-commit-id: 2d731edcd9a7a492a9792a1c82cac57c29c5c176 --- src/formula/csl/CslFilter.h | 4 +-- src/formula/ltl/LtlFilter.h | 4 +-- src/formula/ltl/Next.h | 4 +-- src/formula/prctl/PrctlFilter.h | 4 +-- src/parser/LtlParser.cpp | 30 ++++++++++----------- test/functional/modelchecker/FilterTest.cpp | 2 ++ test/functional/parser/LtlParserTest.cpp | 2 +- test/functional/parser/PrctlParserTest.cpp | 2 +- 8 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/formula/csl/CslFilter.h b/src/formula/csl/CslFilter.h index d77d38592..ef1ec5044 100644 --- a/src/formula/csl/CslFilter.h +++ b/src/formula/csl/CslFilter.h @@ -111,10 +111,10 @@ public: switch(this->opt) { case MINIMIZE: - desc += "min, "; + desc += "min; "; break; case MAXIMIZE: - desc += "max, "; + desc += "max; "; break; default: break; diff --git a/src/formula/ltl/LtlFilter.h b/src/formula/ltl/LtlFilter.h index 2dd9c9a7f..9f876bd8c 100644 --- a/src/formula/ltl/LtlFilter.h +++ b/src/formula/ltl/LtlFilter.h @@ -124,10 +124,10 @@ public: switch(this->opt) { case MINIMIZE: - desc += " min, "; + desc += "min; "; break; case MAXIMIZE: - desc += " max, "; + desc += "max; "; break; default: break; diff --git a/src/formula/ltl/Next.h b/src/formula/ltl/Next.h index ebf8edc96..0fd069135 100644 --- a/src/formula/ltl/Next.h +++ b/src/formula/ltl/Next.h @@ -112,10 +112,8 @@ public: * @returns a string representation of the formula */ virtual std::string toString() const override { - std::string result = "("; - result += " X "; + std::string result = "X "; result += child->toString(); - result += ")"; return result; } diff --git a/src/formula/prctl/PrctlFilter.h b/src/formula/prctl/PrctlFilter.h index 48967486e..6341764f9 100644 --- a/src/formula/prctl/PrctlFilter.h +++ b/src/formula/prctl/PrctlFilter.h @@ -125,10 +125,10 @@ public: switch(this->opt) { case MINIMIZE: - desc += " min, "; + desc += "min; "; break; case MAXIMIZE: - desc += " max, "; + desc += "max; "; break; default: break; diff --git a/src/parser/LtlParser.cpp b/src/parser/LtlParser.cpp index 74cb89944..bb87ab79c 100644 --- a/src/parser/LtlParser.cpp +++ b/src/parser/LtlParser.cpp @@ -68,44 +68,45 @@ struct LtlParser::LtlGrammar : qi::grammar<Iterator, std::shared_ptr<storm::prop freeIdentifierName = qi::lexeme[+(qi::alpha | qi::char_('_'))]; // This block defines rules for parsing state formulas - formula %= orFormula | qi::lit("(") >> formula >> qi::lit(")")| qi::lit("[") >> formula >> qi::lit("]"); + formula %= orFormula; formula.name("LTL formula"); orFormula = andFormula[qi::_val = qi::_1] > *(qi::lit("|") > andFormula)[qi::_val = MAKE(ltl::Or<double>, qi::_val, qi::_1)]; - orFormula.name("LTL formula"); + orFormula.name("Or"); andFormula = untilFormula[qi::_val = qi::_1] > *(qi::lit("&") > untilFormula)[qi::_val = MAKE(ltl::And<double>, qi::_val, qi::_1)]; - andFormula.name("LTL formula"); + andFormula.name("And"); untilFormula = notFormula[qi::_val = qi::_1] > *((qi::lit("U") >> qi::lit("<=") > qi::int_ > notFormula)[qi::_val = MAKE(ltl::BoundedUntil<double>, qi::_val, qi::_2, qi::_1)] | (qi::lit("U") > notFormula)[qi::_val = MAKE(ltl::Until<double>, qi::_val, qi::_1)]); + until.name("Until"); notFormula = atomicLtlFormula[qi::_val = qi::_1] | (qi::lit("!") > atomicLtlFormula)[qi::_val = MAKE(ltl::Not<double>, qi::_1)]; - notFormula.name("LTL formula"); + notFormula.name("Not"); //This block defines rules for "atomic" state formulas //(Propositions, probabilistic/reward formulas, and state formulas in brackets) - atomicLtlFormula %= pathFormula | atomicProposition; - atomicLtlFormula.name("LTL formula"); + atomicLtlFormula %= pathFormula | atomicProposition | qi::lit("(") >> formula >> qi::lit(")")| qi::lit("[") >> formula >> qi::lit("]"); + atomicLtlFormula.name("Atomic LTL formula"); atomicProposition = (freeIdentifierName)[qi::_val = MAKE(ltl::Ap<double>, qi::_1)]; - atomicProposition.name("LTL formula"); + atomicProposition.name("Atomic Proposition"); //This block defines rules for parsing probabilistic path formulas pathFormula = (boundedEventually | eventually | globally | next); - pathFormula.name("LTL formula"); + pathFormula.name("Path Formula"); boundedEventually = (qi::lit("F") >> qi::lit("<=") > qi::int_ > formula)[qi::_val = MAKE(ltl::BoundedEventually<double>, qi::_2, qi::_1)]; - boundedEventually.name("LTL formula"); + boundedEventually.name("Bounded Eventually"); eventually = (qi::lit("F") >> formula)[qi::_val = MAKE(ltl::Eventually<double>, qi::_1)]; - eventually.name("LTL formula"); + eventually.name("Eventually"); globally = (qi::lit("G") >> formula)[qi::_val = MAKE(ltl::Globally<double>, qi::_1)]; - globally.name("LTL formula"); + globally.name("Globally"); next = (qi::lit("X") >> formula)[qi::_val = MAKE(ltl::Next<double>, qi::_1)]; - next.name("LTL formula"); + next.name("Next"); // This block defines rules for parsing filter actions. boundAction = (qi::lit("bound") > qi::lit("(") >> comparisonType >> qi::lit(",") >> qi::double_ >> qi::lit(")"))[qi::_val = @@ -144,10 +145,10 @@ struct LtlParser::LtlGrammar : qi::grammar<Iterator, std::shared_ptr<storm::prop MAKE(ltl::LtlFilter<double>, qi::_2, qi::_1, storm::property::MINIMIZE)] | (formula)[qi::_val = MAKE(ltl::LtlFilter<double>, qi::_1)]; - filter.name("PRCTL formula filter"); + filter.name("LTL formula filter"); start = (((filter) > (comment | qi::eps))[qi::_val = qi::_1] | comment[qi::_val = MAKE(ltl::LtlFilter<double>, nullptr)] ) > qi::eoi; - start.name("LTL formula"); + start.name("start"); } qi::rule<Iterator, std::shared_ptr<storm::property::ltl::LtlFilter<double>>(), Skipper> start; @@ -180,7 +181,6 @@ struct LtlParser::LtlGrammar : qi::grammar<Iterator, std::shared_ptr<storm::prop qi::rule<Iterator, std::string(), Skipper> freeIdentifierName; qi::rule<Iterator, storm::property::ComparisonType(), Skipper> comparisonType; qi::rule<Iterator, storm::property::action::SortAction<double>::SortingCategory(), Skipper> sortingCategory; - }; std::shared_ptr<storm::property::ltl::LtlFilter<double>> LtlParser::parseLtlFormula(std::string formulaString) { diff --git a/test/functional/modelchecker/FilterTest.cpp b/test/functional/modelchecker/FilterTest.cpp index a9f3cfbe8..ffbd11978 100644 --- a/test/functional/modelchecker/FilterTest.cpp +++ b/test/functional/modelchecker/FilterTest.cpp @@ -356,3 +356,5 @@ TEST(CslFilterTest, Safety) { ASSERT_EQ(0, result.selection.size()); ASSERT_EQ(0, result.stateMap.size()); } + +// TODO Set up the LtlFilterTest once an Ltl modelchecker has been implemented. diff --git a/test/functional/parser/LtlParserTest.cpp b/test/functional/parser/LtlParserTest.cpp index 8086bbf88..5c55ab54a 100644 --- a/test/functional/parser/LtlParserTest.cpp +++ b/test/functional/parser/LtlParserTest.cpp @@ -124,7 +124,7 @@ TEST(LtlParserTest, parseLtlFilterTest) { ASSERT_EQ("filter[max; invert; bound(<, 0.500000); sort(value, ascending); range(0, 3)](X a)", formula->toString()); } -TEST(PrctlParserTest, commentTest) { +TEST(LtlParserTest, commentTest) { std::string input = "// This is a comment. And this is a commented out formula: F X a"; std::shared_ptr<ltl::LtlFilter<double>> formula(nullptr); ASSERT_NO_THROW( diff --git a/test/functional/parser/PrctlParserTest.cpp b/test/functional/parser/PrctlParserTest.cpp index dbdb508b7..bed83948c 100644 --- a/test/functional/parser/PrctlParserTest.cpp +++ b/test/functional/parser/PrctlParserTest.cpp @@ -181,7 +181,7 @@ TEST(PrctlParserTest, parsePrctlFilterTest) { ASSERT_EQ("filter[max; formula(b); invert; bound(<, 0.500000); sort(value, ascending); range(0, 3)](F a)", formula->toString()); } -TEST(LtlParserTest, commentTest) { +TEST(PrctlParserTest, commentTest) { std::string input = "// This is a comment. And this is a commented out formula: R = ? [ F a ]"; std::shared_ptr<prctl::PrctlFilter<double>> formula(nullptr); ASSERT_NO_THROW( From 532b0cf3ad0cdea6e5e6c3deb3ace99cc2b6becb Mon Sep 17 00:00:00 2001 From: masawei <manuel.sascha.weiand@rwth-aachen.de> Date: Thu, 14 Aug 2014 12:45:58 +0200 Subject: [PATCH 26/30] Added function to test if a formula is a probability bounded reachability formula, i.e. conforms to the pattern P[<,<=,>,>=]p ([phi U, E] psi) where phi, psi are propositional formulas (consisting only of And, Or, Not and AP). - For that implemented function that checks if a formula is a propositional logic formula to all three logics. - Added tests for the function. - Added documentation for the function. Former-commit-id: 3fcb84b990ae8ef13cdea7231691f8eae7f7a6bf --- src/formula/AbstractFormula.h | 10 ++ src/formula/PrctlFormulaChecker.h | 2 +- src/formula/csl/AbstractCslFormula.h | 43 +++++++++ src/formula/csl/And.h | 9 ++ src/formula/csl/Ap.h | 9 ++ src/formula/csl/Not.h | 9 ++ src/formula/csl/Or.h | 9 ++ src/formula/ltl/And.h | 9 ++ src/formula/ltl/Ap.h | 10 ++ src/formula/ltl/Not.h | 10 ++ src/formula/ltl/Or.h | 10 ++ src/formula/prctl/AbstractPrctlFormula.h | 42 ++++++++ src/formula/prctl/And.h | 10 ++ src/formula/prctl/Ap.h | 10 ++ src/formula/prctl/Not.h | 11 +++ src/formula/prctl/Or.h | 10 ++ test/functional/parser/CslParserTest.cpp | 45 ++++++++- test/functional/parser/LtlParserTest.cpp | 106 ++++++++++++--------- test/functional/parser/PrctlParserTest.cpp | 64 ++++++++++--- 19 files changed, 363 insertions(+), 65 deletions(-) diff --git a/src/formula/AbstractFormula.h b/src/formula/AbstractFormula.h index b1e7f262d..c790d8eae 100644 --- a/src/formula/AbstractFormula.h +++ b/src/formula/AbstractFormula.h @@ -79,6 +79,16 @@ public: * @return true iff all subtrees are valid. */ virtual bool validate(AbstractFormulaChecker<T> const & checker) const = 0; + + /*! + * Returns whether the formula is a propositional logic formula. + * That is, this formula and all its subformulas consist only of And, Or, Not and AP. + * + * @return True iff this is a propositional logic formula. + */ + virtual bool isPropositional() const { + return false; + } }; } // namespace property diff --git a/src/formula/PrctlFormulaChecker.h b/src/formula/PrctlFormulaChecker.h index 08b40f895..5ed817e09 100644 --- a/src/formula/PrctlFormulaChecker.h +++ b/src/formula/PrctlFormulaChecker.h @@ -23,7 +23,7 @@ class PrctlFormulaChecker : public AbstractFormulaChecker<T> { * Implementation of AbstractFormulaChecker::validate() using code * looking exactly like the sample code given there. */ - virtual bool validate(std::shared_ptr<storm::property::abstract::AbstractFormula<T>> const & formula) const { + virtual bool validate(std::shared_ptr<storm::property::AbstractFormula<T>> const & formula) const { // What to support: Principles of Model Checking Def. 10.76 + syntactic sugar if ( dynamic_pointer_cast<storm::property::prctl::And<T>>(formula) || diff --git a/src/formula/csl/AbstractCslFormula.h b/src/formula/csl/AbstractCslFormula.h index 7de783d96..6631a753f 100644 --- a/src/formula/csl/AbstractCslFormula.h +++ b/src/formula/csl/AbstractCslFormula.h @@ -14,6 +14,18 @@ namespace storm { namespace property { namespace csl { +template <class T> class ProbabilisticBoundOperator; +template <class T> class Eventually; +template <class T> class Until; + +} +} +} + +namespace storm { +namespace property { +namespace csl { + /*! * Abstract base class for all CSL root formulas. */ @@ -23,6 +35,37 @@ public: virtual ~AbstractCslFormula() { // Intentionally left empty } + + /*! + * Checks whether the formula is a probabilistic bound reachability formula. + * Returns true iff the formula conforms to the following pattern. + * Pattern: P[<,<=,>,>=]p ([psi U, E] phi) whith psi, phi propositional logic formulas (consisiting only of And, Or, Not and AP). + * That is, a probabilistic bound operator as root with a single until or eventually formula directly below it, whose subformulas are propositional + * (denoting some set of atomic propositions). + * + * @return True iff this is a probabilistic bound reachability formula. + */ + bool isProbEventuallyAP() const { + + if(dynamic_cast<storm::property::csl::ProbabilisticBoundOperator<T> const *>(this) == nullptr) { + return false; + } + + auto probFormula = dynamic_cast<storm::property::csl::ProbabilisticBoundOperator<T> const *>(this); + + if(std::dynamic_pointer_cast<storm::property::csl::Eventually<T>>(probFormula->getChild()).get() != nullptr) { + + auto eventuallyFormula = std::dynamic_pointer_cast<storm::property::csl::Eventually<T>>(probFormula->getChild()); + return eventuallyFormula->getChild()->isPropositional(); + } + else if(std::dynamic_pointer_cast<storm::property::csl::Until<T>>(probFormula->getChild()).get() != nullptr) { + + auto untilFormula = std::dynamic_pointer_cast<storm::property::csl::Until<T>>(probFormula->getChild()); + return untilFormula->getLeft()->isPropositional() && untilFormula->getRight()->isPropositional(); + } + + return false; + } }; } /* namespace csl */ diff --git a/src/formula/csl/And.h b/src/formula/csl/And.h index 0d10fbef6..0218edecb 100644 --- a/src/formula/csl/And.h +++ b/src/formula/csl/And.h @@ -139,6 +139,15 @@ public: return checker.validate(this->left) && checker.validate(this->right); } + /*! Returns whether the formula is a propositional logic formula. + * That is, this formula and all its subformulas consist only of And, Or, Not and AP. + * + * @return True iff this is a propositional logic formula. + */ + virtual bool isPropositional() const override { + return left->isPropositional() && right->isPropositional(); + } + /*! * Sets the left child node. * diff --git a/src/formula/csl/Ap.h b/src/formula/csl/Ap.h index 6b7f8ec56..284f94eeb 100644 --- a/src/formula/csl/Ap.h +++ b/src/formula/csl/Ap.h @@ -106,6 +106,15 @@ public: return true; } + /*! Returns whether the formula is a propositional logic formula. + * That is, this formula and all its subformulas consist only of And, Or, Not and AP. + * + * @return True iff this is a propositional logic formula. + */ + virtual bool isPropositional() const override { + return true; + } + /*! * @returns the name of the atomic proposition */ diff --git a/src/formula/csl/Not.h b/src/formula/csl/Not.h index 002adb5bf..698b92b89 100644 --- a/src/formula/csl/Not.h +++ b/src/formula/csl/Not.h @@ -125,6 +125,15 @@ public: return checker.validate(this->child); } + /*! Returns whether the formula is a propositional logic formula. + * That is, this formula and all its subformulas consist only of And, Or, Not and AP. + * + * @return True iff this is a propositional logic formula. + */ + virtual bool isPropositional() const override { + return child->isPropositional(); + } + /*! * @returns The child node */ diff --git a/src/formula/csl/Or.h b/src/formula/csl/Or.h index fa9649f61..2ecc7fab9 100644 --- a/src/formula/csl/Or.h +++ b/src/formula/csl/Or.h @@ -137,6 +137,15 @@ public: return checker.validate(this->left) && checker.validate(this->right); } + /*! Returns whether the formula is a propositional logic formula. + * That is, this formula and all its subformulas consist only of And, Or, Not and AP. + * + * @return True iff this is a propositional logic formula. + */ + virtual bool isPropositional() const override { + return left->isPropositional() && right->isPropositional(); + } + /*! * Sets the left child node. * diff --git a/src/formula/ltl/And.h b/src/formula/ltl/And.h index ffc5848de..48c4350cb 100644 --- a/src/formula/ltl/And.h +++ b/src/formula/ltl/And.h @@ -138,6 +138,15 @@ public: return checker.validate(this->left) && checker.validate(this->right); } + /*! + * Returns whether the formula is a propositional logic formula. + * That is, this formula and all its subformulas consist only of And, Or, Not and AP. + * + * @return True iff this is a propositional logic formula. + */ + virtual bool isPropositional() const override { + return left->isPropositional() && right->isPropositional(); + } /*! * Sets the left child node. diff --git a/src/formula/ltl/Ap.h b/src/formula/ltl/Ap.h index b84aff340..c7845604f 100644 --- a/src/formula/ltl/Ap.h +++ b/src/formula/ltl/Ap.h @@ -118,6 +118,16 @@ public: return true; } + /*! + * Returns whether the formula is a propositional logic formula. + * That is, this formula and all its subformulas consist only of And, Or, Not and AP. + * + * @return True iff this is a propositional logic formula. + */ + virtual bool isPropositional() const override { + return true; + } + /*! * @returns the name of the atomic proposition */ diff --git a/src/formula/ltl/Not.h b/src/formula/ltl/Not.h index ebc742800..99a90736c 100644 --- a/src/formula/ltl/Not.h +++ b/src/formula/ltl/Not.h @@ -123,6 +123,16 @@ public: return checker.validate(this->child); } + /*! + * Returns whether the formula is a propositional logic formula. + * That is, this formula and all its subformulas consist only of And, Or, Not and AP. + * + * @return True iff this is a propositional logic formula. + */ + virtual bool isPropositional() const override { + return child->isPropositional(); + } + /*! * @returns The child node */ diff --git a/src/formula/ltl/Or.h b/src/formula/ltl/Or.h index d2ee4a4f5..336da397b 100644 --- a/src/formula/ltl/Or.h +++ b/src/formula/ltl/Or.h @@ -135,6 +135,16 @@ public: return checker.validate(this->left) && checker.validate(this->right); } + /*! + * Returns whether the formula is a propositional logic formula. + * That is, this formula and all its subformulas consist only of And, Or, Not and AP. + * + * @return True iff this is a propositional logic formula. + */ + virtual bool isPropositional() const override { + return left->isPropositional() && right->isPropositional(); + } + /*! * Sets the left child node. * diff --git a/src/formula/prctl/AbstractPrctlFormula.h b/src/formula/prctl/AbstractPrctlFormula.h index 3beddb206..044996b9c 100644 --- a/src/formula/prctl/AbstractPrctlFormula.h +++ b/src/formula/prctl/AbstractPrctlFormula.h @@ -14,6 +14,18 @@ namespace storm { namespace property { namespace prctl { +template <class T> class ProbabilisticBoundOperator; +template <class T> class Eventually; +template <class T> class Until; + +} +} +} + +namespace storm { +namespace property { +namespace prctl { + /*! * Interface class for all PRCTL root formulas. */ @@ -23,6 +35,36 @@ public: virtual ~AbstractPrctlFormula() { // Intentionally left empty } + + /*! Returns whether the formula is a probabilistic bound reachability formula. + * Returns true iff the formula conforms to the following pattern. + * Pattern: P[<,<=,>,>=]p ([psi U, E] phi) whith psi, phi propositional logic formulas (consisiting only of And, Or, Not and AP). + * That is, a probabilistic bound operator as root with a single until or eventually formula directly below it, whose subformulas are propositional + * (denoting some set of atomic propositions). + * + * @return True iff this is a probabilistic bound reachability formula. + */ + bool isProbEventuallyAP() const { + + if(dynamic_cast<storm::property::prctl::ProbabilisticBoundOperator<T> const *>(this) == nullptr) { + return false; + } + + auto probFormula = dynamic_cast<storm::property::prctl::ProbabilisticBoundOperator<T> const *>(this); + + if(std::dynamic_pointer_cast<storm::property::prctl::Eventually<T>>(probFormula->getChild()).get() != nullptr) { + + auto eventuallyFormula = std::dynamic_pointer_cast<storm::property::prctl::Eventually<T>>(probFormula->getChild()); + return eventuallyFormula->getChild()->isPropositional(); + } + else if(std::dynamic_pointer_cast<storm::property::prctl::Until<T>>(probFormula->getChild()).get() != nullptr) { + + auto untilFormula = std::dynamic_pointer_cast<storm::property::prctl::Until<T>>(probFormula->getChild()); + return untilFormula->getLeft()->isPropositional() && untilFormula->getRight()->isPropositional(); + } + + return false; + } }; } /* namespace prctl */ diff --git a/src/formula/prctl/And.h b/src/formula/prctl/And.h index f821f08d4..80a9cffd3 100644 --- a/src/formula/prctl/And.h +++ b/src/formula/prctl/And.h @@ -139,6 +139,16 @@ public: return checker.validate(this->left) && checker.validate(this->right); } + /*! + * Returns whether the formula is a propositional logic formula. + * That is, this formula and all its subformulas consist only of And, Or, Not and AP. + * + * @return True iff this is a propositional logic formula. + */ + virtual bool isPropositional() const override { + return left->isPropositional() && right->isPropositional(); + } + /*! * Sets the left child node. * diff --git a/src/formula/prctl/Ap.h b/src/formula/prctl/Ap.h index 906158ac9..ef6d77b12 100644 --- a/src/formula/prctl/Ap.h +++ b/src/formula/prctl/Ap.h @@ -106,6 +106,16 @@ public: return true; } + /*! + * Returns whether the formula is a propositional logic formula. + * That is, this formula and all its subformulas consist only of And, Or, Not and AP. + * + * @return True iff this is a propositional logic formula. + */ + virtual bool isPropositional() const override { + return true; + } + /*! * @returns the name of the atomic proposition */ diff --git a/src/formula/prctl/Not.h b/src/formula/prctl/Not.h index 49660f1af..7531989f6 100644 --- a/src/formula/prctl/Not.h +++ b/src/formula/prctl/Not.h @@ -124,6 +124,17 @@ public: return checker.validate(this->child); } + + /*! + * Returns whether the formula is a propositional logic formula. + * That is, this formula and all its subformulas consist only of And, Or, Not and AP. + * + * @return True iff this is a propositional logic formula. + */ + virtual bool isPropositional() const override { + return child->isPropositional(); + } + /*! * @returns The child node */ diff --git a/src/formula/prctl/Or.h b/src/formula/prctl/Or.h index 004b633c7..7bbc0e045 100644 --- a/src/formula/prctl/Or.h +++ b/src/formula/prctl/Or.h @@ -136,6 +136,16 @@ public: return checker.validate(this->left) && checker.validate(this->right); } + /*! + * Returns whether the formula is a propositional logic formula. + * That is, this formula and all its subformulas consist only of And, Or, Not and AP. + * + * @return True iff this is a propositional logic formula. + */ + virtual bool isPropositional() const override { + return left->isPropositional() && right->isPropositional(); + } + /*! * Sets the left child node. * diff --git a/test/functional/parser/CslParserTest.cpp b/test/functional/parser/CslParserTest.cpp index e4289a2b4..ecff80e4d 100644 --- a/test/functional/parser/CslParserTest.cpp +++ b/test/functional/parser/CslParserTest.cpp @@ -27,6 +27,9 @@ TEST(CslParserTest, parseApOnlyTest) { // The parser did not falsely recognize the input as a comment. ASSERT_NE(formula.get(), nullptr); + ASSERT_TRUE(formula->getChild()->isPropositional()); + ASSERT_FALSE(formula->getChild()->isProbEventuallyAP()); + // The input was parsed correctly. ASSERT_EQ(input, formula->toString()); } @@ -41,6 +44,9 @@ TEST(CslParserTest, parsePropositionalFormulaTest) { // The parser did not falsely recognize the input as a comment. ASSERT_NE(formula.get(), nullptr); + ASSERT_TRUE(formula->getChild()->isPropositional()); + ASSERT_FALSE(formula->getChild()->isProbEventuallyAP()); + // The input was parsed correctly. ASSERT_EQ("(!(a & b) | (a & !c))", formula->toString()); } @@ -58,16 +64,25 @@ TEST(CslParserTest, parsePathFormulaTest) { // The input was parsed correctly. ASSERT_NE(std::dynamic_pointer_cast<csl::Next<double>>(formula->getChild()).get(), nullptr); auto nextFormula = std::dynamic_pointer_cast<csl::Next<double>>(formula->getChild()); + ASSERT_FALSE(nextFormula->isPropositional()); + ASSERT_FALSE(nextFormula->isProbEventuallyAP()); + ASSERT_NE(std::dynamic_pointer_cast<csl::ProbabilisticBoundOperator<double>>(nextFormula->getChild()).get(), nullptr); auto probBoundFormula = std::dynamic_pointer_cast<csl::ProbabilisticBoundOperator<double>>(nextFormula->getChild()); + ASSERT_EQ(0.9, probBoundFormula->getBound()); + ASSERT_EQ(storm::property::LESS, probBoundFormula->getComparisonOperator()); + ASSERT_FALSE(probBoundFormula->isPropositional()); + ASSERT_TRUE(probBoundFormula->isProbEventuallyAP()); + ASSERT_NE(std::dynamic_pointer_cast<csl::Until<double>>(probBoundFormula->getChild()).get(), nullptr); auto untilFormula = std::dynamic_pointer_cast<csl::Until<double>>(probBoundFormula->getChild()); + ASSERT_FALSE(untilFormula->isPropositional()); + ASSERT_FALSE(untilFormula->isProbEventuallyAP()); + ASSERT_NE(std::dynamic_pointer_cast<csl::Ap<double>>(untilFormula->getLeft()).get(), nullptr); ASSERT_NE(std::dynamic_pointer_cast<csl::Ap<double>>(untilFormula->getRight()).get(), nullptr); ASSERT_EQ("a", std::dynamic_pointer_cast<csl::Ap<double>>(untilFormula->getLeft())->getAp()); ASSERT_EQ("b", std::dynamic_pointer_cast<csl::Ap<double>>(untilFormula->getRight())->getAp()); - ASSERT_EQ(0.9, probBoundFormula->getBound()); - ASSERT_EQ(storm::property::LESS, probBoundFormula->getComparisonOperator()); // The string representation is also correct. @@ -88,6 +103,8 @@ TEST(CslParserTest, parseProbabilisticFormulaTest) { ASSERT_NE(op.get(), nullptr); ASSERT_EQ(storm::property::GREATER, op->getComparisonOperator()); ASSERT_EQ(0.5, op->getBound()); + ASSERT_FALSE(op->isPropositional()); + ASSERT_TRUE(op->isProbEventuallyAP()); // Test the string representation for the parsed formula. ASSERT_EQ("P > 0.500000 (F a)", formula->toString()); @@ -107,6 +124,8 @@ TEST(CslParserTest, parseSteadyStateBoundFormulaTest) { ASSERT_NE(op.get(), nullptr); ASSERT_EQ(storm::property::GREATER_EQUAL, op->getComparisonOperator()); ASSERT_EQ(15.0, op->getBound()); + ASSERT_FALSE(op->isPropositional()); + ASSERT_FALSE(op->isProbEventuallyAP()); // Test the string representation for the parsed formula. ASSERT_EQ("S >= 15.000000 (P < 0.200000 (a U[0.000000,3.000000] b))", formula->toString()); @@ -122,6 +141,9 @@ TEST(CslParserTest, parseSteadyStateNoBoundFormulaTest) { // The parser did not falsely recognize the input as a comment. ASSERT_NE(formula.get(), nullptr); + ASSERT_FALSE(formula->getChild()->isPropositional()); + ASSERT_FALSE(formula->getChild()->isProbEventuallyAP()); + // The input was parsed correctly. ASSERT_EQ("S = ? (P <= 0.500000 (F[0.000000,3.000000] a))", formula->toString()); } @@ -136,6 +158,9 @@ TEST(CslParserTest, parseProbabilisticNoBoundFormulaTest) { // The parser did not falsely recognize the input as a comment. ASSERT_NE(formula.get(), nullptr); + ASSERT_FALSE(formula->getChild()->isPropositional()); + ASSERT_FALSE(formula->getChild()->isProbEventuallyAP()); + // The input was parsed correctly. ASSERT_EQ("P = ? (a U[3.000000,4.000000] (b & !c))", formula->toString()); } @@ -151,6 +176,9 @@ TEST(CslParserTest, parseComplexFormulaTest) { // The parser did not falsely recognize the input as a comment. ASSERT_NE(formula.get(), nullptr); + ASSERT_FALSE(formula->getChild()->isPropositional()); + ASSERT_FALSE(formula->getChild()->isProbEventuallyAP()); + // The input was parsed correctly. ASSERT_EQ("S <= 0.500000 ((P <= 0.500000 (a U c) & (P > 0.500000 (G b) | !P < 0.400000 (G P > 0.900000 (F>=7.000000 (a & b))))))", formula->toString()); } @@ -174,12 +202,15 @@ TEST(CslParserTest, parseCslFilterTest) { ASSERT_NE(std::dynamic_pointer_cast<storm::property::action::SortAction<double>>(formula->getAction(3)).get(), nullptr); ASSERT_NE(std::dynamic_pointer_cast<storm::property::action::RangeAction<double>>(formula->getAction(4)).get(), nullptr); + ASSERT_FALSE(formula->getChild()->isPropositional()); + ASSERT_FALSE(formula->getChild()->isProbEventuallyAP()); + // The input was parsed correctly. ASSERT_EQ("filter[max; formula(b); invert; bound(<, 0.500000); sort(value, ascending); range(0, 3)](F a)", formula->toString()); } TEST(CslParserTest, commentTest) { - std::string input = "// This is a comment. And this is a commented out formula: P = ? [ F a ]"; + std::string input = "// This is a comment. And this is a commented out formula: P<=0.5 [ X a ]"; std::shared_ptr<csl::CslFilter<double>> formula(nullptr); ASSERT_NO_THROW( formula = storm::parser::CslParser::parseCslFormula(input) @@ -189,11 +220,15 @@ TEST(CslParserTest, commentTest) { ASSERT_NE(nullptr, formula.get()); // Test if the parser recognizes the comment at the end of a line. - input = "P = ? [ F a ] // This is a comment."; + input = "P<=0.5 [ X a ] // This is a comment."; ASSERT_NO_THROW( formula = storm::parser::CslParser::parseCslFormula(input) ); - ASSERT_EQ("P = ? (F a)", formula->toString()); + + ASSERT_FALSE(formula->getChild()->isPropositional()); + ASSERT_FALSE(formula->getChild()->isProbEventuallyAP()); + + ASSERT_EQ("P <= 0.500000 (X a)", formula->toString()); } TEST(CslParserTest, wrongProbabilisticFormulaTest) { diff --git a/test/functional/parser/LtlParserTest.cpp b/test/functional/parser/LtlParserTest.cpp index 5c55ab54a..e44f84f0e 100644 --- a/test/functional/parser/LtlParserTest.cpp +++ b/test/functional/parser/LtlParserTest.cpp @@ -17,25 +17,29 @@ namespace ltl = storm::property::ltl; TEST(LtlParserTest, parseApOnlyTest) { - std::string formula = "ap"; - std::shared_ptr<storm::property::ltl::LtlFilter<double>> ltlFormula(nullptr); + std::string input = "ap"; + std::shared_ptr<storm::property::ltl::LtlFilter<double>> formula(nullptr); ASSERT_NO_THROW( - ltlFormula = storm::parser::LtlParser::parseLtlFormula(formula); + formula = storm::parser::LtlParser::parseLtlFormula(input); ); - ASSERT_NE(ltlFormula.get(), nullptr); - ASSERT_EQ(formula, ltlFormula->toString()); + ASSERT_TRUE(formula->getChild()->isPropositional()); + + ASSERT_NE(formula.get(), nullptr); + ASSERT_EQ(input, formula->toString()); } TEST(LtlParserTest, parsePropositionalFormulaTest) { - std::string formula = "!(a & b) | a & ! c"; - std::shared_ptr<ltl::LtlFilter<double>> ltlFormula(nullptr); + std::string input = "!(a & b) | a & ! c"; + std::shared_ptr<ltl::LtlFilter<double>> formula(nullptr); ASSERT_NO_THROW( - ltlFormula = storm::parser::LtlParser::parseLtlFormula(formula); + formula = storm::parser::LtlParser::parseLtlFormula(input); ); - ASSERT_NE(ltlFormula.get(), nullptr); - ASSERT_EQ("(!(a & b) | (a & !c))", ltlFormula->toString()); + ASSERT_TRUE(formula->getChild()->isPropositional()); + + ASSERT_NE(formula.get(), nullptr); + ASSERT_EQ("(!(a & b) | (a & !c))", formula->toString()); } /*! @@ -43,14 +47,16 @@ TEST(LtlParserTest, parsePropositionalFormulaTest) { * "Eventually" operator. */ TEST(LtlParserTest, parseAmbiguousFormulaTest) { - std::string formula = "F & b"; - std::shared_ptr<ltl::LtlFilter<double>> ltlFormula(nullptr); + std::string input = "F & b"; + std::shared_ptr<ltl::LtlFilter<double>> formula(nullptr); ASSERT_NO_THROW( - ltlFormula = storm::parser::LtlParser::parseLtlFormula(formula); + formula = storm::parser::LtlParser::parseLtlFormula(input); ); - ASSERT_NE(ltlFormula.get(), nullptr); - ASSERT_EQ("(F & b)", ltlFormula->toString()); + ASSERT_TRUE(formula->getChild()->isPropositional()); + + ASSERT_NE(formula.get(), nullptr); + ASSERT_EQ("(F & b)", formula->toString()); } /*! @@ -58,48 +64,54 @@ TEST(LtlParserTest, parseAmbiguousFormulaTest) { * depending where it occurs. */ TEST(LtlParserTest, parseAmbiguousFormulaTest2) { - std::string formula = "F F"; - std::shared_ptr<ltl::LtlFilter<double>> ltlFormula(nullptr); + std::string input = "F F"; + std::shared_ptr<ltl::LtlFilter<double>> formula(nullptr); ASSERT_NO_THROW( - ltlFormula = storm::parser::LtlParser::parseLtlFormula(formula); + formula = storm::parser::LtlParser::parseLtlFormula(input); ); - ASSERT_NE(ltlFormula.get(), nullptr); - ASSERT_EQ("F F", ltlFormula->toString()); + ASSERT_FALSE(formula->getChild()->isPropositional()); + + ASSERT_NE(formula.get(), nullptr); + ASSERT_EQ("F F", formula->toString()); } TEST(LtlParserTest, parseBoundedEventuallyFormulaTest) { - std::string formula = "F<=5 a"; - std::shared_ptr<ltl::LtlFilter<double>> ltlFormula(nullptr); + std::string input = "F<=5 a"; + std::shared_ptr<ltl::LtlFilter<double>> formula(nullptr); ASSERT_NO_THROW( - ltlFormula = storm::parser::LtlParser::parseLtlFormula(formula); + formula = storm::parser::LtlParser::parseLtlFormula(input); ); - ASSERT_NE(ltlFormula.get(), nullptr); + ASSERT_NE(formula.get(), nullptr); - std::shared_ptr<storm::property::ltl::BoundedEventually<double>> op = std::dynamic_pointer_cast<storm::property::ltl::BoundedEventually<double>>(ltlFormula->getChild()); + ASSERT_FALSE(formula->getChild()->isPropositional()); + + std::shared_ptr<storm::property::ltl::BoundedEventually<double>> op = std::dynamic_pointer_cast<storm::property::ltl::BoundedEventually<double>>(formula->getChild()); ASSERT_NE(op.get(), nullptr); ASSERT_EQ(static_cast<uint_fast64_t>(5), op->getBound()); - ASSERT_EQ("F<=5 a", ltlFormula->toString()); + ASSERT_EQ("F<=5 a", formula->toString()); } TEST(LtlParserTest, parseBoundedUntilFormulaTest) { - std::string formula = "a U<=3 b"; - std::shared_ptr<ltl::LtlFilter<double>> ltlFormula(nullptr); + std::string input = "a U<=3 b"; + std::shared_ptr<ltl::LtlFilter<double>> formula(nullptr); ASSERT_NO_THROW( - ltlFormula = storm::parser::LtlParser::parseLtlFormula(formula); + formula = storm::parser::LtlParser::parseLtlFormula(input); ); - ASSERT_NE(ltlFormula.get(), nullptr); + ASSERT_NE(formula.get(), nullptr); - std::shared_ptr<storm::property::ltl::BoundedUntil<double>> op = std::dynamic_pointer_cast<storm::property::ltl::BoundedUntil<double>>(ltlFormula->getChild()); + ASSERT_FALSE(formula->getChild()->isPropositional()); + + std::shared_ptr<storm::property::ltl::BoundedUntil<double>> op = std::dynamic_pointer_cast<storm::property::ltl::BoundedUntil<double>>(formula->getChild()); ASSERT_NE(op.get(), nullptr); ASSERT_EQ(static_cast<uint_fast64_t>(3), op->getBound()); - ASSERT_EQ("(a U<=3 b)", ltlFormula->toString()); + ASSERT_EQ("(a U<=3 b)", formula->toString()); } TEST(LtlParserTest, parseLtlFilterTest) { @@ -112,6 +124,8 @@ TEST(LtlParserTest, parseLtlFilterTest) { // The parser did not falsely recognize the input as a comment. ASSERT_NE(formula, nullptr); + ASSERT_FALSE(formula->getChild()->isPropositional()); + ASSERT_EQ(storm::property::MAXIMIZE, formula->getOptimizingOperator()); ASSERT_EQ(4, formula->getActionCount()); @@ -133,41 +147,45 @@ TEST(LtlParserTest, commentTest) { // The parser recognized the input as a comment. ASSERT_NE(nullptr, formula.get()); + ASSERT_EQ(nullptr, formula->getChild().get()); // Test if the parser recognizes the comment at the end of a line. input = "F X a // This is a comment."; ASSERT_NO_THROW( formula = storm::parser::LtlParser::parseLtlFormula(input) ); + + ASSERT_FALSE(formula->getChild()->isPropositional()); + ASSERT_EQ("F X a", formula->toString()); } TEST(LtlParserTest, parseComplexUntilTest) { - std::string formula = "a U b U<=3 c"; - std::shared_ptr<ltl::LtlFilter<double>> ltlFormula(nullptr); + std::string input = "a U b U<=3 c"; + std::shared_ptr<ltl::LtlFilter<double>> formula(nullptr); ASSERT_NO_THROW( - ltlFormula = storm::parser::LtlParser::parseLtlFormula(formula); + formula = storm::parser::LtlParser::parseLtlFormula(input); ); - ASSERT_NE(ltlFormula.get(), nullptr); - ASSERT_EQ("((a U b) U<=3 c)", ltlFormula->toString()); + ASSERT_NE(formula.get(), nullptr); + ASSERT_EQ("((a U b) U<=3 c)", formula->toString()); } TEST(LtlParserTest, parseComplexFormulaTest) { - std::string formula = "a U F b | G a & F<=3 a U<=7 b // and a comment"; - std::shared_ptr<ltl::LtlFilter<double>> ltlFormula(nullptr); + std::string input = "a U F b | G a & F<=3 a U<=7 b // and a comment"; + std::shared_ptr<ltl::LtlFilter<double>> formula(nullptr); ASSERT_NO_THROW( - ltlFormula = storm::parser::LtlParser::parseLtlFormula(formula); + formula = storm::parser::LtlParser::parseLtlFormula(input); ); - ASSERT_NE(ltlFormula.get(), nullptr); - ASSERT_EQ("(a U F (b | G (a & F<=3 (a U<=7 b))))", ltlFormula->toString()); + ASSERT_NE(formula.get(), nullptr); + ASSERT_EQ("(a U F (b | G (a & F<=3 (a U<=7 b))))", formula->toString()); } TEST(LtlParserTest, wrongFormulaTest) { - std::string formula = "(a | c) & +"; + std::string input = "(a | c) & +"; ASSERT_THROW( - storm::parser::LtlParser::parseLtlFormula(formula), + storm::parser::LtlParser::parseLtlFormula(input), storm::exceptions::WrongFormatException ); } diff --git a/test/functional/parser/PrctlParserTest.cpp b/test/functional/parser/PrctlParserTest.cpp index bed83948c..1a63495d0 100644 --- a/test/functional/parser/PrctlParserTest.cpp +++ b/test/functional/parser/PrctlParserTest.cpp @@ -26,7 +26,10 @@ TEST(PrctlParserTest, parseApOnlyTest) { ); // The parser did not falsely recognize the input as a comment. - ASSERT_NE(formula, nullptr); + ASSERT_NE(formula.get(), nullptr); + + ASSERT_TRUE(formula->getChild()->isPropositional()); + ASSERT_FALSE(formula->getChild()->isProbEventuallyAP()); // The input was parsed correctly. ASSERT_EQ(input, formula->toString()); @@ -40,7 +43,10 @@ TEST(PrctlParserTest, parsePropositionalFormulaTest) { ); // The parser did not falsely recognize the input as a comment. - ASSERT_NE(formula, nullptr); + ASSERT_NE(formula.get(), nullptr); + + ASSERT_TRUE(formula->getChild()->isPropositional()); + ASSERT_FALSE(formula->getChild()->isProbEventuallyAP()); // The input was parsed correctly. ASSERT_EQ("(!(a & b) | (a & !c))", formula->toString()); @@ -54,22 +60,30 @@ TEST(PrctlParserTest, parsePathFormulaTest) { ); // The parser did not falsely recognize the input as a comment. - ASSERT_NE(formula, nullptr); + ASSERT_NE(formula.get(), nullptr); // The input was parsed correctly. ASSERT_NE(std::dynamic_pointer_cast<prctl::Next<double>>(formula->getChild()).get(), nullptr); auto nextFormula = std::dynamic_pointer_cast<prctl::Next<double>>(formula->getChild()); + ASSERT_FALSE(nextFormula->isPropositional()); + ASSERT_FALSE(nextFormula->isProbEventuallyAP()); + ASSERT_NE(std::dynamic_pointer_cast<prctl::ProbabilisticBoundOperator<double>>(nextFormula->getChild()).get(), nullptr); auto probBoundFormula = std::dynamic_pointer_cast<prctl::ProbabilisticBoundOperator<double>>(nextFormula->getChild()); + ASSERT_EQ(0.9, probBoundFormula->getBound()); + ASSERT_EQ(storm::property::LESS, probBoundFormula->getComparisonOperator()); + ASSERT_FALSE(probBoundFormula->isPropositional()); + ASSERT_TRUE(probBoundFormula->isProbEventuallyAP()); + ASSERT_NE(std::dynamic_pointer_cast<prctl::Until<double>>(probBoundFormula->getChild()).get(), nullptr); auto untilFormula = std::dynamic_pointer_cast<prctl::Until<double>>(probBoundFormula->getChild()); + ASSERT_FALSE(untilFormula->isPropositional()); + ASSERT_FALSE(untilFormula->isProbEventuallyAP()); + ASSERT_NE(std::dynamic_pointer_cast<prctl::Ap<double>>(untilFormula->getLeft()).get(), nullptr); ASSERT_NE(std::dynamic_pointer_cast<prctl::Ap<double>>(untilFormula->getRight()).get(), nullptr); ASSERT_EQ("a", std::dynamic_pointer_cast<prctl::Ap<double>>(untilFormula->getLeft())->getAp()); ASSERT_EQ("b", std::dynamic_pointer_cast<prctl::Ap<double>>(untilFormula->getRight())->getAp()); - ASSERT_EQ(0.9, probBoundFormula->getBound()); - ASSERT_EQ(storm::property::LESS, probBoundFormula->getComparisonOperator()); - // The string representation is also correct. ASSERT_EQ("P = ? (X P < 0.900000 (a U b))", formula->toString()); @@ -83,7 +97,7 @@ TEST(PrctlParserTest, parseProbabilisticFormulaTest) { ); // The parser did not falsely recognize the input as a comment. - ASSERT_NE(formula, nullptr); + ASSERT_NE(formula.get(), nullptr); ASSERT_NE(std::dynamic_pointer_cast<prctl::ProbabilisticBoundOperator<double>>(formula->getChild()).get(), nullptr); @@ -91,6 +105,8 @@ TEST(PrctlParserTest, parseProbabilisticFormulaTest) { ASSERT_EQ(storm::property::GREATER, op->getComparisonOperator()); ASSERT_EQ(0.5, op->getBound()); + ASSERT_FALSE(op->isPropositional()); + ASSERT_TRUE(op->isProbEventuallyAP()); // Test the string representation for the parsed formula. ASSERT_EQ("P > 0.500000 (F a)", formula->toString()); @@ -104,13 +120,15 @@ TEST(PrctlParserTest, parseRewardFormulaTest) { ); // The parser did not falsely recognize the input as a comment. - ASSERT_NE(formula, nullptr); + ASSERT_NE(formula.get(), nullptr); ASSERT_NE(std::dynamic_pointer_cast<prctl::RewardBoundOperator<double>>(formula->getChild()).get(), nullptr); std::shared_ptr<prctl::RewardBoundOperator<double>> op = std::static_pointer_cast<prctl::RewardBoundOperator<double>>(formula->getChild()); ASSERT_EQ(storm::property::GREATER_EQUAL, op->getComparisonOperator()); ASSERT_EQ(15.0, op->getBound()); + ASSERT_FALSE(op->isPropositional()); + ASSERT_FALSE(op->isProbEventuallyAP()); // Test the string representation for the parsed formula. ASSERT_EQ("R >= 15.000000 (I=5)", formula->toString()); @@ -124,7 +142,10 @@ TEST(PrctlParserTest, parseRewardNoBoundFormulaTest) { ); // The parser did not falsely recognize the input as a comment. - ASSERT_NE(formula, nullptr); + ASSERT_NE(formula.get(), nullptr); + + ASSERT_FALSE(formula->getChild()->isPropositional()); + ASSERT_FALSE(formula->getChild()->isProbEventuallyAP()); // The input was parsed correctly. ASSERT_EQ("R = ? (F a)", formula->toString()); @@ -138,7 +159,10 @@ TEST(PrctlParserTest, parseProbabilisticNoBoundFormulaTest) { ); // The parser did not falsely recognize the input as a comment. - ASSERT_NE(formula, nullptr); + ASSERT_NE(formula.get(), nullptr); + + ASSERT_FALSE(formula->getChild()->isPropositional()); + ASSERT_FALSE(formula->getChild()->isProbEventuallyAP()); // The input was parsed correctly. ASSERT_EQ("P = ? (a U<=4 (b & !c))", formula->toString()); @@ -152,7 +176,10 @@ TEST(PrctlParserTest, parseComplexFormulaTest) { ); // The parser did not falsely recognize the input as a comment. - ASSERT_NE(formula, nullptr); + ASSERT_NE(formula.get(), nullptr); + + ASSERT_FALSE(formula->getChild()->isPropositional()); + ASSERT_FALSE(formula->getChild()->isProbEventuallyAP()); // The input was parsed correctly. ASSERT_EQ("(R <= 0.500000 (S) & (R > 15.000000 (C <= 0.500000) | !P < 0.400000 (G P > 0.900000 (F<=7 (a & b)))))", formula->toString()); @@ -166,7 +193,7 @@ TEST(PrctlParserTest, parsePrctlFilterTest) { ); // The parser did not falsely recognize the input as a comment. - ASSERT_NE(formula, nullptr); + ASSERT_NE(formula.get(), nullptr); ASSERT_EQ(storm::property::MAXIMIZE, formula->getOptimizingOperator()); @@ -177,12 +204,15 @@ TEST(PrctlParserTest, parsePrctlFilterTest) { ASSERT_NE(std::dynamic_pointer_cast<storm::property::action::SortAction<double>>(formula->getAction(3)).get(), nullptr); ASSERT_NE(std::dynamic_pointer_cast<storm::property::action::RangeAction<double>>(formula->getAction(4)).get(), nullptr); + ASSERT_FALSE(formula->getChild()->isPropositional()); + ASSERT_FALSE(formula->getChild()->isProbEventuallyAP()); + // The input was parsed correctly. ASSERT_EQ("filter[max; formula(b); invert; bound(<, 0.500000); sort(value, ascending); range(0, 3)](F a)", formula->toString()); } TEST(PrctlParserTest, commentTest) { - std::string input = "// This is a comment. And this is a commented out formula: R = ? [ F a ]"; + std::string input = "// This is a comment. And this is a commented out formula: P<=0.5 [ X a ]"; std::shared_ptr<prctl::PrctlFilter<double>> formula(nullptr); ASSERT_NO_THROW( formula = storm::parser::PrctlParser::parsePrctlFormula(input) @@ -192,11 +222,15 @@ TEST(PrctlParserTest, commentTest) { ASSERT_NE(nullptr, formula.get()); // Test if the parser recognizes the comment at the end of a line. - input = "R = ? [ F a ] // This is a comment."; + input = "P<=0.5 [ X a ] // This is a comment."; ASSERT_NO_THROW( formula = storm::parser::PrctlParser::parsePrctlFormula(input) ); - ASSERT_EQ("R = ? (F a)", formula->toString()); + + ASSERT_FALSE(formula->getChild()->isPropositional()); + ASSERT_FALSE(formula->getChild()->isProbEventuallyAP()); + + ASSERT_EQ("P <= 0.500000 (X a)", formula->toString()); } From 7f15f358c1994e4222bc822512908fddbb9e7e16 Mon Sep 17 00:00:00 2001 From: masawei <manuel.sascha.weiand@rwth-aachen.de> Date: Thu, 14 Aug 2014 13:17:11 +0200 Subject: [PATCH 27/30] Removed the FormulaCheckers. Former-commit-id: 24910974c628020bbf89d0754f0957ff3e3e02ad --- src/formula/AbstractFormula.h | 19 +---- src/formula/AbstractFormulaChecker.h | 74 ------------------- src/formula/PrctlFormulaChecker.h | 49 ------------ src/formula/csl/AbstractCslFormula.h | 4 + src/formula/csl/And.h | 11 --- src/formula/csl/Ap.h | 13 ---- src/formula/csl/Eventually.h | 10 --- src/formula/csl/Globally.h | 11 --- src/formula/csl/Next.h | 11 --- src/formula/csl/Not.h | 11 --- src/formula/csl/Or.h | 11 --- src/formula/csl/ProbabilisticBoundOperator.h | 10 --- src/formula/csl/SteadyStateBoundOperator.h | 11 --- src/formula/csl/TimeBoundedEventually.h | 10 --- src/formula/csl/TimeBoundedUntil.h | 10 --- src/formula/csl/Until.h | 11 --- src/formula/ltl/And.h | 11 --- src/formula/ltl/Ap.h | 12 --- src/formula/ltl/BoundedEventually.h | 11 --- src/formula/ltl/BoundedUntil.h | 10 --- src/formula/ltl/Eventually.h | 10 --- src/formula/ltl/Globally.h | 11 --- src/formula/ltl/Next.h | 11 --- src/formula/ltl/Not.h | 11 --- src/formula/ltl/Or.h | 10 --- src/formula/ltl/Until.h | 11 --- src/formula/prctl/AbstractPrctlFormula.h | 4 + src/formula/prctl/And.h | 11 --- src/formula/prctl/Ap.h | 13 ---- src/formula/prctl/BoundedEventually.h | 11 --- src/formula/prctl/BoundedNaryUntil.h | 14 ---- src/formula/prctl/BoundedUntil.h | 10 --- src/formula/prctl/CumulativeReward.h | 13 ---- src/formula/prctl/Eventually.h | 10 --- src/formula/prctl/Globally.h | 11 --- src/formula/prctl/InstantaneousReward.h | 13 ---- src/formula/prctl/Next.h | 11 --- src/formula/prctl/Not.h | 12 --- src/formula/prctl/Or.h | 11 --- .../prctl/ProbabilisticBoundOperator.h | 10 --- src/formula/prctl/ReachabilityReward.h | 11 --- src/formula/prctl/RewardBoundOperator.h | 10 --- src/formula/prctl/SteadyStateReward.h | 13 ---- src/formula/prctl/Until.h | 11 --- 44 files changed, 9 insertions(+), 574 deletions(-) delete mode 100644 src/formula/AbstractFormulaChecker.h delete mode 100644 src/formula/PrctlFormulaChecker.h diff --git a/src/formula/AbstractFormula.h b/src/formula/AbstractFormula.h index c790d8eae..8ab2fd130 100644 --- a/src/formula/AbstractFormula.h +++ b/src/formula/AbstractFormula.h @@ -9,6 +9,7 @@ #define STORM_FORMULA_ABSTRACTFORMULA_H_ #include <string> +#include <memory> namespace storm { namespace property { @@ -16,8 +17,6 @@ template <class T> class AbstractFormula; } //namespace property } //namespace storm -#include "src/formula/AbstractFormulaChecker.h" - namespace storm { namespace property { @@ -64,22 +63,6 @@ public: */ virtual std::string toString() const = 0; - /*! - * @brief Checks if all subtrees are valid in some logic. - * - * @note Every subclass must implement this method. - * - * This method is given a checker object that knows which formula - * classes are allowed within the logic the checker represents. Every - * subclass is supposed to call checker.validate() for all child - * formulas and return true if and only if all those calls returned - * true. - * - * @param checker Checker object. - * @return true iff all subtrees are valid. - */ - virtual bool validate(AbstractFormulaChecker<T> const & checker) const = 0; - /*! * Returns whether the formula is a propositional logic formula. * That is, this formula and all its subformulas consist only of And, Or, Not and AP. diff --git a/src/formula/AbstractFormulaChecker.h b/src/formula/AbstractFormulaChecker.h deleted file mode 100644 index 97c0446ee..000000000 --- a/src/formula/AbstractFormulaChecker.h +++ /dev/null @@ -1,74 +0,0 @@ -#ifndef STORM_FORMULA_ABSTRACTFORMULACHECKER_H_ -#define STORM_FORMULA_ABSTRACTFORMULACHECKER_H_ - -namespace storm { -namespace property { - -template <class T> class AbstractFormulaChecker; - -} //namespace property -} //namespace storm - - -#include "src/formula/AbstractFormula.h" -#include <memory> - -namespace storm { -namespace property { - -/*! - * @brief Base class for all formula checkers. - * - * A formula checker is used to check if a given formula is valid in some - * logic. Hence, this pure virtual base class should be subclassed for - * every logic we support. - * - * Every subclass must implement validate(). It gets a pointer to an - * AbstractFormula object and should return if the subtree represented by - * this formula is valid in the logic. - * - * Usually, this will be implemented like this: - * @code - * if ( - * dynamic_cast<const And<T>*>(formula) || - * dynamic_cast<const Not<T>*>(formula) || - * dynamic_cast<const Or<T>*>(formula) - * ) { - * return formula->validate(*this); - * } else return false; - * @endcode - * - * Every formula class implements a validate() method itself which calls - * validate() on the given checker for every child in the formula tree. - * - * If the formula structure is not an actual tree, but an directed acyclic - * graph, the shared subtrees will be checked twice. If we have directed - * cycles, we will have infinite recursions. - */ -template <class T> -class AbstractFormulaChecker { - public: - /*! - * Virtual destructor - * To ensure that the right destructor is called - */ - virtual ~AbstractFormulaChecker() { - //intentionally left empty - } - - /*! - * @brief Checks if the given formula is valid in some logic. - * - * Every subclass must implement this method and check, if the - * formula object is valid in the logic of the subclass. - * - * @param formula A pointer to some formula object. - * @return true iff the formula is valid. - */ - virtual bool validate(std::shared_ptr<AbstractFormula<T>> const & formula) const = 0; -}; - -} // namespace property -} // namespace storm - -#endif diff --git a/src/formula/PrctlFormulaChecker.h b/src/formula/PrctlFormulaChecker.h deleted file mode 100644 index 5ed817e09..000000000 --- a/src/formula/PrctlFormulaChecker.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef STORM_FORMULA_PRCTLFORMULACHECKER_H_ -#define STORM_FORMULA_PRCTLFORMULACHECKER_H_ - -#include "src/formula/AbstractFormulaChecker.h" -#include "src/formula/Prctl.h" - -#include <iostream> -#include <memory> - -namespace storm { -namespace property { - -/*! - * @brief Checks formulas if they are within PRCTL. - * - * This class implements AbstractFormulaChecker to check if a given formula - * is part of PRCTL logic. - */ -template <class T> -class PrctlFormulaChecker : public AbstractFormulaChecker<T> { - public: - /*! - * Implementation of AbstractFormulaChecker::validate() using code - * looking exactly like the sample code given there. - */ - virtual bool validate(std::shared_ptr<storm::property::AbstractFormula<T>> const & formula) const { - // What to support: Principles of Model Checking Def. 10.76 + syntactic sugar - if ( - dynamic_pointer_cast<storm::property::prctl::And<T>>(formula) || - dynamic_pointer_cast<storm::property::prctl::Ap<T>>(formula) || - dynamic_pointer_cast<storm::property::prctl::BoundedUntil<T>>(formula) || - dynamic_pointer_cast<storm::property::prctl::Eventually<T>>(formula) || - dynamic_pointer_cast<storm::property::prctl::Globally<T>>(formula) || - dynamic_pointer_cast<storm::property::prctl::Next<T>>(formula) || - dynamic_pointer_cast<storm::property::prctl::Not<T>>(formula) || - dynamic_pointer_cast<storm::property::prctl::Or<T>>(formula) || - dynamic_pointer_cast<storm::property::prctl::ProbabilisticBoundOperator<T>>(formula) || - dynamic_pointer_cast<storm::property::prctl::Until<T>>(formula) - ) { - return formula->validate(*this); - } - return false; - } -}; - -} // namespace property -} // namespace storm - -#endif diff --git a/src/formula/csl/AbstractCslFormula.h b/src/formula/csl/AbstractCslFormula.h index 6631a753f..73d4f3dcd 100644 --- a/src/formula/csl/AbstractCslFormula.h +++ b/src/formula/csl/AbstractCslFormula.h @@ -47,19 +47,23 @@ public: */ bool isProbEventuallyAP() const { + // Test if a probabilistic bound operator is at the root. if(dynamic_cast<storm::property::csl::ProbabilisticBoundOperator<T> const *>(this) == nullptr) { return false; } auto probFormula = dynamic_cast<storm::property::csl::ProbabilisticBoundOperator<T> const *>(this); + // Check if the direct subformula of the probabilistic bound operator is an eventually or until formula. if(std::dynamic_pointer_cast<storm::property::csl::Eventually<T>>(probFormula->getChild()).get() != nullptr) { + // Get the subformula and check if its subformulas are propositional. auto eventuallyFormula = std::dynamic_pointer_cast<storm::property::csl::Eventually<T>>(probFormula->getChild()); return eventuallyFormula->getChild()->isPropositional(); } else if(std::dynamic_pointer_cast<storm::property::csl::Until<T>>(probFormula->getChild()).get() != nullptr) { + // Get the subformula and check if its subformulas are propositional. auto untilFormula = std::dynamic_pointer_cast<storm::property::csl::Until<T>>(probFormula->getChild()); return untilFormula->getLeft()->isPropositional() && untilFormula->getRight()->isPropositional(); } diff --git a/src/formula/csl/And.h b/src/formula/csl/And.h index 0218edecb..afb78ceeb 100644 --- a/src/formula/csl/And.h +++ b/src/formula/csl/And.h @@ -9,7 +9,6 @@ #define STORM_FORMULA_CSL_AND_H_ #include "src/formula/csl/AbstractStateFormula.h" -#include "src/formula/AbstractFormulaChecker.h" #include "src/modelchecker/csl/ForwardDeclarations.h" #include <string> @@ -129,16 +128,6 @@ public: return result; } - /*! - * @brief Checks if all subtrees conform to some logic. - * - * @param checker Formula checker object. - * @return true iff all subtrees conform to some logic. - */ - virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { - return checker.validate(this->left) && checker.validate(this->right); - } - /*! Returns whether the formula is a propositional logic formula. * That is, this formula and all its subformulas consist only of And, Or, Not and AP. * diff --git a/src/formula/csl/Ap.h b/src/formula/csl/Ap.h index 284f94eeb..a80f8fdfe 100644 --- a/src/formula/csl/Ap.h +++ b/src/formula/csl/Ap.h @@ -9,7 +9,6 @@ #define STORM_FORMULA_CSL_AP_H_ #include "src/formula/csl/AbstractStateFormula.h" -#include "src/formula/AbstractFormulaChecker.h" #include "src/modelchecker/csl/ForwardDeclarations.h" namespace storm { @@ -94,18 +93,6 @@ public: return modelChecker.template as<IApModelChecker>()->checkAp(*this); } - /*! - * @brief Checks if all subtrees conform to some logic. - * - * As atomic propositions have no subformulas, we return true here. - * - * @param checker Formula checker object. - * @return true - */ - virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { - return true; - } - /*! Returns whether the formula is a propositional logic formula. * That is, this formula and all its subformulas consist only of And, Or, Not and AP. * diff --git a/src/formula/csl/Eventually.h b/src/formula/csl/Eventually.h index 8428d5f00..21bdd71b4 100644 --- a/src/formula/csl/Eventually.h +++ b/src/formula/csl/Eventually.h @@ -119,16 +119,6 @@ public: return result; } - /*! - * @brief Checks if the subtree conforms to some logic. - * - * @param checker Formula checker object. - * @return true iff the subtree conforms to some logic. - */ - virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { - return checker.validate(this->child); - } - /*! * @returns the child node */ diff --git a/src/formula/csl/Globally.h b/src/formula/csl/Globally.h index 211532efb..e93baeca5 100644 --- a/src/formula/csl/Globally.h +++ b/src/formula/csl/Globally.h @@ -10,7 +10,6 @@ #include "src/formula/csl/AbstractPathFormula.h" #include "src/formula/csl/AbstractStateFormula.h" -#include "src/formula/AbstractFormulaChecker.h" #include "src/modelchecker/csl/ForwardDeclarations.h" namespace storm { @@ -120,16 +119,6 @@ public: return result; } - /*! - * @brief Checks if the subtree conforms to some logic. - * - * @param checker Formula checker object. - * @return true iff the subtree conforms to some logic. - */ - virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { - return checker.validate(this->child); - } - /*! * @returns the child node */ diff --git a/src/formula/csl/Next.h b/src/formula/csl/Next.h index 3148377a6..8c86095b8 100644 --- a/src/formula/csl/Next.h +++ b/src/formula/csl/Next.h @@ -10,7 +10,6 @@ #include "src/formula/csl/AbstractPathFormula.h" #include "src/formula/csl/AbstractStateFormula.h" -#include "src/formula/AbstractFormulaChecker.h" namespace storm { namespace property { @@ -119,16 +118,6 @@ public: return result; } - /*! - * @brief Checks if the subtree conforms to some logic. - * - * @param checker Formula checker object. - * @return true iff the subtree conforms to some logic. - */ - virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { - return checker.validate(this->child); - } - /*! * @returns the child node */ diff --git a/src/formula/csl/Not.h b/src/formula/csl/Not.h index 698b92b89..9c23323ce 100644 --- a/src/formula/csl/Not.h +++ b/src/formula/csl/Not.h @@ -9,7 +9,6 @@ #define STORM_FORMULA_CSL_NOT_H_ #include "src/formula/csl/AbstractStateFormula.h" -#include "src/formula/AbstractFormulaChecker.h" #include "src/modelchecker/csl/ForwardDeclarations.h" namespace storm { @@ -115,16 +114,6 @@ public: return result; } - /*! - * @brief Checks if the subtree conforms to some logic. - * - * @param checker Formula checker object. - * @return true iff the subtree conforms to some logic. - */ - virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { - return checker.validate(this->child); - } - /*! Returns whether the formula is a propositional logic formula. * That is, this formula and all its subformulas consist only of And, Or, Not and AP. * diff --git a/src/formula/csl/Or.h b/src/formula/csl/Or.h index 2ecc7fab9..b6017d4be 100644 --- a/src/formula/csl/Or.h +++ b/src/formula/csl/Or.h @@ -9,7 +9,6 @@ #define STORM_FORMULA_CSL_OR_H_ #include "src/formula/csl/AbstractStateFormula.h" -#include "src/formula/AbstractFormulaChecker.h" namespace storm { namespace property { @@ -127,16 +126,6 @@ public: return result; } - /*! - * @brief Checks if all subtrees conform to some logic. - * - * @param checker Formula checker object. - * @return true iff all subtrees conform to some logic. - */ - virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { - return checker.validate(this->left) && checker.validate(this->right); - } - /*! Returns whether the formula is a propositional logic formula. * That is, this formula and all its subformulas consist only of And, Or, Not and AP. * diff --git a/src/formula/csl/ProbabilisticBoundOperator.h b/src/formula/csl/ProbabilisticBoundOperator.h index 6d0e0d6a3..f0c51af72 100644 --- a/src/formula/csl/ProbabilisticBoundOperator.h +++ b/src/formula/csl/ProbabilisticBoundOperator.h @@ -114,16 +114,6 @@ public: return modelChecker.template as<IProbabilisticBoundOperatorModelChecker>()->checkProbabilisticBoundOperator(*this); } - /*! - * @brief Checks if the subtree conforms to some logic. - * - * @param checker Formula checker object. - * @return true iff the subtree conforms to some logic. - */ - virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { - return checker.validate(this->child); - } - /*! * @returns a string representation of the formula */ diff --git a/src/formula/csl/SteadyStateBoundOperator.h b/src/formula/csl/SteadyStateBoundOperator.h index c53823639..3c664f05a 100644 --- a/src/formula/csl/SteadyStateBoundOperator.h +++ b/src/formula/csl/SteadyStateBoundOperator.h @@ -9,7 +9,6 @@ #define STORM_FORMULA_CSL_STEADYSTATEOPERATOR_H_ #include "AbstractStateFormula.h" -#include "src/formula/AbstractFormulaChecker.h" #include "src/formula/ComparisonType.h" namespace storm { @@ -111,16 +110,6 @@ public: return modelChecker.template as<ISteadyStateBoundOperatorModelChecker>()->checkSteadyStateBoundOperator(*this); } - /*! - * @brief Checks if the subtree conforms to some logic. - * - * @param checker Formula checker object. - * @return true iff the subtree conforms to some logic. - */ - virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { - return checker.validate(this->stateFormula); - } - /*! * @returns a string representation of the formula */ diff --git a/src/formula/csl/TimeBoundedEventually.h b/src/formula/csl/TimeBoundedEventually.h index 8564a0db3..e4c6aa483 100644 --- a/src/formula/csl/TimeBoundedEventually.h +++ b/src/formula/csl/TimeBoundedEventually.h @@ -86,16 +86,6 @@ public: return modelChecker.template as<ITimeBoundedEventuallyModelChecker>()->checkTimeBoundedEventually(*this, qualitative); } - /*! - * @brief Checks if the subtree conforms to some logic. - * - * @param checker Formula checker object. - * @return true iff the subtree conforms to some logic. - */ - virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { - return checker.validate(this->child); - } - /*! * @returns a string representation of the formula */ diff --git a/src/formula/csl/TimeBoundedUntil.h b/src/formula/csl/TimeBoundedUntil.h index 1bdf2f0aa..170ddf54a 100644 --- a/src/formula/csl/TimeBoundedUntil.h +++ b/src/formula/csl/TimeBoundedUntil.h @@ -101,16 +101,6 @@ public: return modelChecker.template as<ITimeBoundedUntilModelChecker>()->checkTimeBoundedUntil(*this, qualitative); } - /*! - * @brief Checks if the subtree conforms to some logic. - * - * @param checker Formula checker object. - * @return true iff the subtree conforms to some logic. - */ - virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { - return checker.validate(this->left) && checker.validate(this->right); - } - /*! * @returns a string representation of the formula */ diff --git a/src/formula/csl/Until.h b/src/formula/csl/Until.h index ea0209053..8d2446489 100644 --- a/src/formula/csl/Until.h +++ b/src/formula/csl/Until.h @@ -10,7 +10,6 @@ #include "src/formula/csl/AbstractPathFormula.h" #include "src/formula/csl/AbstractStateFormula.h" -#include "src/formula/AbstractFormulaChecker.h" namespace storm { namespace property { @@ -124,16 +123,6 @@ public: return result; } - /*! - * @brief Checks if all subtrees conform to some logic. - * - * @param checker Formula checker object. - * @return true iff all subtrees conform to some logic. - */ - virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { - return checker.validate(this->left) && checker.validate(this->right); - } - /*! * Sets the left child node. * diff --git a/src/formula/ltl/And.h b/src/formula/ltl/And.h index 48c4350cb..06fc83cae 100644 --- a/src/formula/ltl/And.h +++ b/src/formula/ltl/And.h @@ -9,7 +9,6 @@ #define STORM_FORMULA_LTL_AND_H_ #include "AbstractLtlFormula.h" -#include "src/formula/AbstractFormulaChecker.h" #include "src/modelchecker/ltl/ForwardDeclarations.h" #include <string> @@ -128,16 +127,6 @@ public: return result; } - /*! - * @brief Checks if all subtrees conform to some logic. - * - * @param checker Formula checker object. - * @return true iff all subtrees conform to some logic. - */ - virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { - return checker.validate(this->left) && checker.validate(this->right); - } - /*! * Returns whether the formula is a propositional logic formula. * That is, this formula and all its subformulas consist only of And, Or, Not and AP. diff --git a/src/formula/ltl/Ap.h b/src/formula/ltl/Ap.h index c7845604f..451dadb99 100644 --- a/src/formula/ltl/Ap.h +++ b/src/formula/ltl/Ap.h @@ -106,18 +106,6 @@ public: return getAp(); } - /*! - * @brief Checks if all subtrees conform to some logic. - * - * As atomic propositions have no subformulas, we return true here. - * - * @param checker Formula checker object. - * @return true - */ - virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { - return true; - } - /*! * Returns whether the formula is a propositional logic formula. * That is, this formula and all its subformulas consist only of And, Or, Not and AP. diff --git a/src/formula/ltl/BoundedEventually.h b/src/formula/ltl/BoundedEventually.h index 40cdb4038..630e0bbae 100644 --- a/src/formula/ltl/BoundedEventually.h +++ b/src/formula/ltl/BoundedEventually.h @@ -9,7 +9,6 @@ #define STORM_FORMULA_LTL_BOUNDEDEVENTUALLY_H_ #include "AbstractLtlFormula.h" -#include "src/formula/AbstractFormulaChecker.h" #include <cstdint> #include <string> #include "src/modelchecker/ltl/ForwardDeclarations.h" @@ -126,16 +125,6 @@ public: return result; } - /*! - * @brief Checks if the subtree conforms to some logic. - * - * @param checker Formula checker object. - * @return true iff the subtree conforms to some logic. - */ - virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { - return checker.validate(this->child); - } - /*! * @returns the child node */ diff --git a/src/formula/ltl/BoundedUntil.h b/src/formula/ltl/BoundedUntil.h index b17b901f4..87e0a7a2d 100644 --- a/src/formula/ltl/BoundedUntil.h +++ b/src/formula/ltl/BoundedUntil.h @@ -135,16 +135,6 @@ public: return result; } - /*! - * @brief Checks if all subtrees conform to some logic. - * - * @param checker Formula checker object. - * @return true iff all subtrees conform to some logic. - */ - virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { - return checker.validate(this->left) && checker.validate(this->right); - } - /*! * Sets the left child node. * diff --git a/src/formula/ltl/Eventually.h b/src/formula/ltl/Eventually.h index b8662cd69..328fd993b 100644 --- a/src/formula/ltl/Eventually.h +++ b/src/formula/ltl/Eventually.h @@ -117,16 +117,6 @@ public: return result; } - /*! - * @brief Checks if the subtree conforms to some logic. - * - * @param checker Formula checker object. - * @return true iff the subtree conforms to some logic. - */ - virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { - return checker.validate(this->child); - } - /*! * @returns the child node */ diff --git a/src/formula/ltl/Globally.h b/src/formula/ltl/Globally.h index 50d977ee8..060b5bba2 100644 --- a/src/formula/ltl/Globally.h +++ b/src/formula/ltl/Globally.h @@ -9,7 +9,6 @@ #define STORM_FORMULA_LTL_GLOBALLY_H_ #include "AbstractLtlFormula.h" -#include "src/formula/AbstractFormulaChecker.h" #include "src/modelchecker/ltl/ForwardDeclarations.h" namespace storm { @@ -118,16 +117,6 @@ public: return result; } - /*! - * @brief Checks if the subtree conforms to some logic. - * - * @param checker Formula checker object. - * @return true iff the subtree conforms to some logic. - */ - virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { - return checker.validate(this->child); - } - /*! * @returns the child node */ diff --git a/src/formula/ltl/Next.h b/src/formula/ltl/Next.h index 0fd069135..a038252c2 100644 --- a/src/formula/ltl/Next.h +++ b/src/formula/ltl/Next.h @@ -9,7 +9,6 @@ #define STORM_FORMULA_LTL_NEXT_H_ #include "AbstractLtlFormula.h" -#include "src/formula/AbstractFormulaChecker.h" namespace storm { namespace property { @@ -117,16 +116,6 @@ public: return result; } - /*! - * @brief Checks if the subtree conforms to some logic. - * - * @param checker Formula checker object. - * @return true iff the subtree conforms to some logic. - */ - virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { - return checker.validate(this->child); - } - /*! * @returns the child node */ diff --git a/src/formula/ltl/Not.h b/src/formula/ltl/Not.h index 99a90736c..2538298a4 100644 --- a/src/formula/ltl/Not.h +++ b/src/formula/ltl/Not.h @@ -9,7 +9,6 @@ #define STORM_FORMULA_LTL_NOT_H_ #include "AbstractLtlFormula.h" -#include "src/formula/AbstractFormulaChecker.h" namespace storm { namespace property { @@ -113,16 +112,6 @@ public: return result; } - /*! - * @brief Checks if the subtree conforms to some logic. - * - * @param checker Formula checker object. - * @return true iff the subtree conforms to some logic. - */ - virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { - return checker.validate(this->child); - } - /*! * Returns whether the formula is a propositional logic formula. * That is, this formula and all its subformulas consist only of And, Or, Not and AP. diff --git a/src/formula/ltl/Or.h b/src/formula/ltl/Or.h index 336da397b..42296766f 100644 --- a/src/formula/ltl/Or.h +++ b/src/formula/ltl/Or.h @@ -125,16 +125,6 @@ public: return result; } - /*! - * @brief Checks if all subtrees conform to some logic. - * - * @param checker Formula checker object. - * @return true iff all subtrees conform to some logic. - */ - virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { - return checker.validate(this->left) && checker.validate(this->right); - } - /*! * Returns whether the formula is a propositional logic formula. * That is, this formula and all its subformulas consist only of And, Or, Not and AP. diff --git a/src/formula/ltl/Until.h b/src/formula/ltl/Until.h index 95c999e39..92a6e4ed1 100644 --- a/src/formula/ltl/Until.h +++ b/src/formula/ltl/Until.h @@ -9,7 +9,6 @@ #define STORM_FORMULA_LTL_UNTIL_H_ #include "AbstractLtlFormula.h" -#include "src/formula/AbstractFormulaChecker.h" namespace storm { namespace property { @@ -146,16 +145,6 @@ public: return result; } - /*! - * @brief Checks if all subtrees conform to some logic. - * - * @param checker Formula checker object. - * @return true iff all subtrees conform to some logic. - */ - virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { - return checker.validate(this->left) && checker.validate(this->right); - } - /*! * Sets the left child node. * diff --git a/src/formula/prctl/AbstractPrctlFormula.h b/src/formula/prctl/AbstractPrctlFormula.h index 044996b9c..f728110fe 100644 --- a/src/formula/prctl/AbstractPrctlFormula.h +++ b/src/formula/prctl/AbstractPrctlFormula.h @@ -46,19 +46,23 @@ public: */ bool isProbEventuallyAP() const { + // Test if a probabilistic bound operator is at the root. if(dynamic_cast<storm::property::prctl::ProbabilisticBoundOperator<T> const *>(this) == nullptr) { return false; } auto probFormula = dynamic_cast<storm::property::prctl::ProbabilisticBoundOperator<T> const *>(this); + // Check if the direct subformula of the probabilistic bound operator is an eventually or until formula. if(std::dynamic_pointer_cast<storm::property::prctl::Eventually<T>>(probFormula->getChild()).get() != nullptr) { + // Get the subformula and check if its subformulas are propositional. auto eventuallyFormula = std::dynamic_pointer_cast<storm::property::prctl::Eventually<T>>(probFormula->getChild()); return eventuallyFormula->getChild()->isPropositional(); } else if(std::dynamic_pointer_cast<storm::property::prctl::Until<T>>(probFormula->getChild()).get() != nullptr) { + // Get the subformula and check if its subformulas are propositional. auto untilFormula = std::dynamic_pointer_cast<storm::property::prctl::Until<T>>(probFormula->getChild()); return untilFormula->getLeft()->isPropositional() && untilFormula->getRight()->isPropositional(); } diff --git a/src/formula/prctl/And.h b/src/formula/prctl/And.h index 80a9cffd3..81b33ad28 100644 --- a/src/formula/prctl/And.h +++ b/src/formula/prctl/And.h @@ -9,7 +9,6 @@ #define STORM_FORMULA_PRCTL_AND_H_ #include "src/formula/prctl/AbstractStateFormula.h" -#include "src/formula/AbstractFormulaChecker.h" #include "src/modelchecker/prctl/ForwardDeclarations.h" #include <string> @@ -129,16 +128,6 @@ public: return result; } - /*! - * @brief Checks if all subtrees conform to some logic. - * - * @param checker Formula checker object. - * @return true iff all subtrees conform to some logic. - */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { - return checker.validate(this->left) && checker.validate(this->right); - } - /*! * Returns whether the formula is a propositional logic formula. * That is, this formula and all its subformulas consist only of And, Or, Not and AP. diff --git a/src/formula/prctl/Ap.h b/src/formula/prctl/Ap.h index ef6d77b12..7df3cabd8 100644 --- a/src/formula/prctl/Ap.h +++ b/src/formula/prctl/Ap.h @@ -9,7 +9,6 @@ #define STORM_FORMULA_PRCTL_AP_H_ #include "src/formula/prctl/AbstractStateFormula.h" -#include "src/formula/AbstractFormulaChecker.h" #include "src/modelchecker/prctl/ForwardDeclarations.h" namespace storm { @@ -94,18 +93,6 @@ public: return modelChecker.template as<IApModelChecker>()->checkAp(*this); } - /*! - * @brief Checks if all subtrees conform to some logic. - * - * As atomic propositions have no subformulas, we return true here. - * - * @param checker Formula checker object. - * @return true - */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { - return true; - } - /*! * Returns whether the formula is a propositional logic formula. * That is, this formula and all its subformulas consist only of And, Or, Not and AP. diff --git a/src/formula/prctl/BoundedEventually.h b/src/formula/prctl/BoundedEventually.h index 70e10020d..16b7df1d8 100644 --- a/src/formula/prctl/BoundedEventually.h +++ b/src/formula/prctl/BoundedEventually.h @@ -10,7 +10,6 @@ #include "src/formula/prctl/AbstractPathFormula.h" #include "src/formula/prctl/AbstractStateFormula.h" -#include "src/formula/AbstractFormulaChecker.h" #include <cstdint> #include <string> #include "src/modelchecker/prctl/ForwardDeclarations.h" @@ -126,16 +125,6 @@ public: return result; } - /*! - * @brief Checks if the subtree conforms to some logic. - * - * @param checker Formula checker object. - * @return true iff the subtree conforms to some logic. - */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { - return checker.validate(this->child); - } - /*! * @returns the child node */ diff --git a/src/formula/prctl/BoundedNaryUntil.h b/src/formula/prctl/BoundedNaryUntil.h index 0cf02d4f4..1c9863ac7 100644 --- a/src/formula/prctl/BoundedNaryUntil.h +++ b/src/formula/prctl/BoundedNaryUntil.h @@ -142,20 +142,6 @@ public: return result.str(); } - /*! - * @brief Checks if all subtrees conform to some logic. - * - * @param checker Formula checker object. - * @return true iff all subtrees conform to some logic. - */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { - bool res = checker.validate(left); - for (auto it = right->begin(); it != right->end(); ++it) { - res &= checker.validate(std::get<0>(*it)); - } - return res; - } - /*! * Sets the left child node. * diff --git a/src/formula/prctl/BoundedUntil.h b/src/formula/prctl/BoundedUntil.h index d018567eb..92d119583 100644 --- a/src/formula/prctl/BoundedUntil.h +++ b/src/formula/prctl/BoundedUntil.h @@ -130,16 +130,6 @@ public: return result; } - /*! - * @brief Checks if all subtrees conform to some logic. - * - * @param checker Formula checker object. - * @return true iff all subtrees conform to some logic. - */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { - return checker.validate(this->left) && checker.validate(this->right); - } - /*! * Sets the left child node. * diff --git a/src/formula/prctl/CumulativeReward.h b/src/formula/prctl/CumulativeReward.h index 84861ed91..4a94c021b 100644 --- a/src/formula/prctl/CumulativeReward.h +++ b/src/formula/prctl/CumulativeReward.h @@ -9,7 +9,6 @@ #define STORM_FORMULA_PRCTL_CUMULATIVEREWARD_H_ #include "AbstractRewardPathFormula.h" -#include "src/formula/AbstractFormulaChecker.h" #include <string> namespace storm { @@ -108,18 +107,6 @@ public: return result; } - /*! - * @brief Checks if all subtrees conform to some logic. - * - * As CumulativeReward objects have no subformulas, we return true here. - * - * @param checker Formula checker object. - * @return true - */ - virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { - return true; - } - /*! * @returns the time instance for the instantaneous reward operator */ diff --git a/src/formula/prctl/Eventually.h b/src/formula/prctl/Eventually.h index 321ac872f..77dcb3c73 100644 --- a/src/formula/prctl/Eventually.h +++ b/src/formula/prctl/Eventually.h @@ -118,16 +118,6 @@ public: return result; } - /*! - * @brief Checks if the subtree conforms to some logic. - * - * @param checker Formula checker object. - * @return true iff the subtree conforms to some logic. - */ - virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { - return checker.validate(child); - } - /*! * @returns the child node */ diff --git a/src/formula/prctl/Globally.h b/src/formula/prctl/Globally.h index 7296a9534..8f0b9c910 100644 --- a/src/formula/prctl/Globally.h +++ b/src/formula/prctl/Globally.h @@ -10,7 +10,6 @@ #include "src/formula/prctl/AbstractPathFormula.h" #include "src/formula/prctl/AbstractStateFormula.h" -#include "src/formula/AbstractFormulaChecker.h" #include "src/modelchecker/prctl/ForwardDeclarations.h" namespace storm { @@ -119,16 +118,6 @@ public: return result; } - /*! - * @brief Checks if the subtree conforms to some logic. - * - * @param checker Formula checker object. - * @return true iff the subtree conforms to some logic. - */ - virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { - return checker.validate(child); - } - /*! * @returns the child node */ diff --git a/src/formula/prctl/InstantaneousReward.h b/src/formula/prctl/InstantaneousReward.h index 3a65583a6..18cf7eeae 100644 --- a/src/formula/prctl/InstantaneousReward.h +++ b/src/formula/prctl/InstantaneousReward.h @@ -9,7 +9,6 @@ #define STORM_FORMULA_PRCTL_INSTANTANEOUSREWARD_H_ #include "AbstractRewardPathFormula.h" -#include "src/formula/AbstractFormulaChecker.h" #include <cstdint> #include <string> @@ -110,18 +109,6 @@ public: return result; } - /*! - * @brief Checks if all subtrees conform to some logic. - * - * As InstantaneousReward formulas have no subformulas, we return true here. - * - * @param checker Formula checker object. - * @return true - */ - virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { - return true; - } - /*! * @returns the time instance for the instantaneous reward operator */ diff --git a/src/formula/prctl/Next.h b/src/formula/prctl/Next.h index 49b66c062..052adf9ca 100644 --- a/src/formula/prctl/Next.h +++ b/src/formula/prctl/Next.h @@ -10,7 +10,6 @@ #include "src/formula/prctl/AbstractPathFormula.h" #include "src/formula/prctl/AbstractStateFormula.h" -#include "src/formula/AbstractFormulaChecker.h" namespace storm { namespace property { @@ -118,16 +117,6 @@ public: return result; } - /*! - * @brief Checks if the subtree conforms to some logic. - * - * @param checker Formula checker object. - * @return true iff the subtree conforms to some logic. - */ - virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { - return checker.validate(this->child); - } - /*! * @returns the child node */ diff --git a/src/formula/prctl/Not.h b/src/formula/prctl/Not.h index 7531989f6..a58c5d3f4 100644 --- a/src/formula/prctl/Not.h +++ b/src/formula/prctl/Not.h @@ -9,7 +9,6 @@ #define STORM_FORMULA_PRCTL_NOT_H_ #include "AbstractStateFormula.h" -#include "src/formula/AbstractFormulaChecker.h" #include "src/modelchecker/prctl/ForwardDeclarations.h" namespace storm { @@ -114,17 +113,6 @@ public: return result; } - /*! - * @brief Checks if the subtree conforms to some logic. - * - * @param checker Formula checker object. - * @return true iff the subtree conforms to some logic. - */ - virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { - return checker.validate(this->child); - } - - /*! * Returns whether the formula is a propositional logic formula. * That is, this formula and all its subformulas consist only of And, Or, Not and AP. diff --git a/src/formula/prctl/Or.h b/src/formula/prctl/Or.h index 7bbc0e045..646b5735c 100644 --- a/src/formula/prctl/Or.h +++ b/src/formula/prctl/Or.h @@ -9,7 +9,6 @@ #define STORM_FORMULA_PRCTL_OR_H_ #include "src/formula/prctl/AbstractStateFormula.h" -#include "src/formula/AbstractFormulaChecker.h" namespace storm { namespace property { @@ -126,16 +125,6 @@ public: return result; } - /*! - * @brief Checks if all subtrees conform to some logic. - * - * @param checker Formula checker object. - * @return true iff all subtrees conform to some logic. - */ - virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { - return checker.validate(this->left) && checker.validate(this->right); - } - /*! * Returns whether the formula is a propositional logic formula. * That is, this formula and all its subformulas consist only of And, Or, Not and AP. diff --git a/src/formula/prctl/ProbabilisticBoundOperator.h b/src/formula/prctl/ProbabilisticBoundOperator.h index e1557ce04..6905d9069 100644 --- a/src/formula/prctl/ProbabilisticBoundOperator.h +++ b/src/formula/prctl/ProbabilisticBoundOperator.h @@ -113,16 +113,6 @@ public: return modelChecker.template as<IProbabilisticBoundOperatorModelChecker>()->checkProbabilisticBoundOperator(*this); } - /*! - * @brief Checks if the subtree conforms to some logic. - * - * @param checker Formula checker object. - * @return true iff the subtree conforms to some logic. - */ - virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { - return checker.validate(child); - } - /*! * @returns a string representation of the formula */ diff --git a/src/formula/prctl/ReachabilityReward.h b/src/formula/prctl/ReachabilityReward.h index eacc49e3e..0fe5f5792 100644 --- a/src/formula/prctl/ReachabilityReward.h +++ b/src/formula/prctl/ReachabilityReward.h @@ -10,7 +10,6 @@ #include "AbstractRewardPathFormula.h" #include "AbstractStateFormula.h" -#include "src/formula/AbstractFormulaChecker.h" namespace storm { namespace property { @@ -114,16 +113,6 @@ public: return result; } - /*! - * @brief Checks if the subtree conforms to some logic. - * - * @param checker Formula checker object. - * @return true iff the subtree conforms to some logic. - */ - virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { - return checker.validate(this->child); - } - /*! * @returns the child node */ diff --git a/src/formula/prctl/RewardBoundOperator.h b/src/formula/prctl/RewardBoundOperator.h index cfebea0d6..12900c58c 100644 --- a/src/formula/prctl/RewardBoundOperator.h +++ b/src/formula/prctl/RewardBoundOperator.h @@ -111,16 +111,6 @@ public: return modelChecker.template as<IRewardBoundOperatorModelChecker>()->checkRewardBoundOperator(*this); } - /*! - * @brief Checks if the subtree conforms to some logic. - * - * @param checker Formula checker object. - * @return true iff the subtree conforms to some logic. - */ - virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { - return checker.validate(this->child); - } - /*! * @returns a string representation of the formula */ diff --git a/src/formula/prctl/SteadyStateReward.h b/src/formula/prctl/SteadyStateReward.h index d7dfc5416..84774998f 100644 --- a/src/formula/prctl/SteadyStateReward.h +++ b/src/formula/prctl/SteadyStateReward.h @@ -9,7 +9,6 @@ #define STORM_FORMULA_PRCTL_STEADYSTATEREWARD_H_ #include "AbstractRewardPathFormula.h" -#include "src/formula/AbstractFormulaChecker.h" #include <string> namespace storm { @@ -88,18 +87,6 @@ public: virtual std::string toString() const override { return "S"; } - - /*! - * @brief Checks if all subtrees conform to some logic. - * - * As SteadyStateReward objects have no subformulas, we return true here. - * - * @param checker Formula checker object. - * @return true - */ - virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { - return true; - } }; } //namespace prctl diff --git a/src/formula/prctl/Until.h b/src/formula/prctl/Until.h index 3d8a5f4e2..eb939b54f 100644 --- a/src/formula/prctl/Until.h +++ b/src/formula/prctl/Until.h @@ -10,7 +10,6 @@ #include "AbstractPathFormula.h" #include "AbstractStateFormula.h" -#include "src/formula/AbstractFormulaChecker.h" namespace storm { namespace property { @@ -124,16 +123,6 @@ public: return result; } - /*! - * @brief Checks if all subtrees conform to some logic. - * - * @param checker Formula checker object. - * @return true iff all subtrees conform to some logic. - */ - virtual bool validate(AbstractFormulaChecker<T> const & checker) const override { - return checker.validate(left) && checker.validate(right); - } - /*! * Sets the left child node. * From 6b2b1e4d7b57afc5bfcb567e343d4da4e1a3122a Mon Sep 17 00:00:00 2001 From: masawei <manuel.sascha.weiand@rwth-aachen.de> Date: Fri, 29 Aug 2014 05:08:59 +0200 Subject: [PATCH 28/30] Finished the documentation of the formulas. - Also removed one superflous class (IOptimizingOperator). - Killed all warnings concerning missing virtual destructor in the interfaced for the modelchecker. - A whole lot of little things I can't quite remember. Next up: Remerge Former-commit-id: 28fedd036c992809e700bf355dd2ca578446b9f5 --- src/formula/AbstractFilter.h | 100 ++++++++++-- src/formula/AbstractFormula.h | 36 ++--- src/formula/ComparisonType.h | 5 + src/formula/IOptimizingOperator.h | 43 ----- src/formula/actions/AbstractAction.h | 70 ++++++-- src/formula/actions/BoundAction.h | 45 +++++- src/formula/actions/FormulaAction.h | 41 ++++- src/formula/actions/InvertAction.h | 34 +++- src/formula/actions/RangeAction.h | 49 +++++- src/formula/actions/SortAction.h | 71 +++++++- src/formula/csl/AbstractCslFormula.h | 19 ++- src/formula/csl/AbstractPathFormula.h | 28 +--- src/formula/csl/AbstractStateFormula.h | 14 +- src/formula/csl/And.h | 106 ++++++------ src/formula/csl/Ap.h | 68 ++++---- src/formula/csl/CslFilter.h | 136 +++++++++++++--- src/formula/csl/Eventually.h | 77 +++++---- src/formula/csl/Globally.h | 76 +++++---- src/formula/csl/Next.h | 74 +++++---- src/formula/csl/Not.h | 73 +++++---- src/formula/csl/Or.h | 140 +++++++++------- src/formula/csl/ProbabilisticBoundOperator.h | 100 ++++++++---- src/formula/csl/SteadyStateBoundOperator.h | 118 +++++++++----- src/formula/csl/TimeBoundedEventually.h | 118 +++++++++----- src/formula/csl/TimeBoundedUntil.h | 151 +++++++++++------- src/formula/csl/Until.h | 108 ++++++++----- src/formula/ltl/AbstractLtlFormula.h | 30 ++-- src/formula/ltl/And.h | 100 +++++++----- src/formula/ltl/Ap.h | 75 ++++----- src/formula/ltl/BoundedEventually.h | 84 ++++++---- src/formula/ltl/BoundedUntil.h | 121 ++++++++------ src/formula/ltl/Eventually.h | 74 +++++---- src/formula/ltl/Globally.h | 80 ++++++---- src/formula/ltl/LtlFilter.h | 107 ++++++++++--- src/formula/ltl/Next.h | 74 +++++---- src/formula/ltl/Not.h | 73 +++++---- src/formula/ltl/Or.h | 106 ++++++------ src/formula/ltl/Until.h | 123 +++++++------- src/formula/prctl/AbstractPathFormula.h | 16 +- src/formula/prctl/AbstractPrctlFormula.h | 26 ++- src/formula/prctl/AbstractRewardPathFormula.h | 14 +- src/formula/prctl/AbstractStateFormula.h | 14 +- src/formula/prctl/And.h | 108 +++++++------ src/formula/prctl/Ap.h | 70 ++++---- src/formula/prctl/BoundedEventually.h | 87 ++++++---- src/formula/prctl/BoundedNaryUntil.h | 119 ++++++++------ src/formula/prctl/BoundedUntil.h | 118 ++++++++------ src/formula/prctl/CumulativeReward.h | 64 +++++--- src/formula/prctl/Eventually.h | 77 +++++---- src/formula/prctl/Globally.h | 77 +++++---- src/formula/prctl/InstantaneousReward.h | 67 ++++---- src/formula/prctl/Next.h | 71 ++++---- src/formula/prctl/Not.h | 68 +++++--- src/formula/prctl/Or.h | 105 +++++++----- src/formula/prctl/PrctlFilter.h | 141 +++++++++++++--- .../prctl/ProbabilisticBoundOperator.h | 102 ++++++++---- src/formula/prctl/ReachabilityReward.h | 81 ++++++---- src/formula/prctl/RewardBoundOperator.h | 101 ++++++++---- src/formula/prctl/SteadyStateReward.h | 51 ++++-- src/formula/prctl/Until.h | 112 +++++++------ src/parser/CslParser.h | 10 +- src/parser/LtlFileParser.h | 4 +- src/parser/LtlParser.h | 5 +- src/parser/PrctlFileParser.h | 4 +- src/parser/PrctlParser.h | 4 +- 65 files changed, 2986 insertions(+), 1677 deletions(-) delete mode 100644 src/formula/IOptimizingOperator.h diff --git a/src/formula/AbstractFilter.h b/src/formula/AbstractFilter.h index f1e7017f7..3824817fe 100644 --- a/src/formula/AbstractFilter.h +++ b/src/formula/AbstractFilter.h @@ -17,25 +17,72 @@ namespace storm { namespace property { /*! - * + * This enum contains value indicating which kind of scheduler is to be used + * for path formulas, i.e. probability or reward queries on nondeterministic models. */ enum OptimizingOperator {MINIMIZE, MAXIMIZE, UNDEFINED}; +/*! + * This is the base class for the logic specific filter classes. + * It provides the logic independent functionality concerning the organization of actions and the optimization operator. + * + * The general role of the filter is to twofold. + * + * On the one hand it is meant to be the interface between the control and the formulas and modelchecker. + * It sits one level above the root of the formula tree which is represented by it. + * This gives a distinct class that can be moved through the control functions, thus encapsulating the formula tree and all its classes. + * + * On the other hand, as all modelchecking is initiated through its interface it opens up the opportunity to manipulate the output generated by the modelchecker. + * The manipulation is done by a series of filter actions which are evaluated after the modelchecker has finished. + * Each action has a distinct function that ranges from state selection to sorting. + * The input for the first filter action consists mainly of the modelckecking result. + * Thereafter, the result of each filter action is used as input for the next filter action until all actions have been executed. + * The final result is then used to generate the output. + */ template <class T> class AbstractFilter { public: + /*! + * Constructs an empty AbstractFilter. + * If a value for the optimization operator is given it will be set accordingly. + * Otherwise, it will be undefined. The undefined value is intended for deterministic + * models, as the do not need a scheduler resolving the nondeterminism. + * + * @note If a query is executed on a nondeterministic model using an undefined optimization operator + * the modelchecker will throw an exception. + * + * @param opt The value of the optimization operator. + */ AbstractFilter(OptimizingOperator opt = UNDEFINED) : opt(opt) { // Intentionally left empty. } + /*! + * Constructs an AbstractFilter containing only the specified action. + * + * @note If the shared_ptr to the action is empty (contains a nullptr) the Abstract filter will be created empty. + * + * @param action The action to be executed during evaluation. + * @param opt The value of the optimization operator. + */ AbstractFilter(std::shared_ptr<action::AbstractAction<T>> const & action, OptimizingOperator opt = UNDEFINED) : opt(opt) { if(action.get() != nullptr) { actions.push_back(action); } } + /*! + * Constructs an AbstractFilter containing the given vector of actions as action list. + * The actions will be executed in ascending order of index. + * + * @note Any vector entry containing an empty shared_ptr will be ignored. Thus, giving a + * vector of five actions with two empty shared_ptr will result in a AbstractFilter containing three actions. + * + * @param actions A vector of shared_ptr to the actions to be executed during evaluation. + * @param opt The value of the optimization operator. + */ AbstractFilter(std::vector<std::shared_ptr<action::AbstractAction<T>>> const & actions, OptimizingOperator opt = UNDEFINED) { // Filter out all nullptr actions. // First detect that there is at least one. @@ -64,10 +111,18 @@ public: this->opt = opt; } + /*! + * The virtual destructor. + */ virtual ~AbstractFilter() { // Intentionally left empty. } + /*! + * Returns a string representation of the filter. + * + * @returns A string representing the filter. + */ virtual std::string toString() const { std::string desc = "filter("; @@ -87,25 +142,32 @@ public: return desc; } - virtual std::string toPrettyString() const { - std::string desc = "Filter: "; - desc += "\nActions:"; - for(auto action : actions) { - desc += "\n\t" + action->toString(); - } - return desc; - } - + /*! + * Appends the given action to the list of actions to be executed during evaluation. + * + * @note If the argument is an empty shared_ptr nothing will happen. + * + * @param action A shared pointer to the action to be appended. + */ void addAction(std::shared_ptr<action::AbstractAction<T>> const & action) { if(action.get() != nullptr) { actions.push_back(action); } } + /*! + * Removes the last action. + */ void removeAction() { actions.pop_back(); } + /*! + * Returns the action at the specified position. + * + * @param position The position of the action to be returned within the action list. + * @returns A shared pointer to the specified action. + */ std::shared_ptr<action::AbstractAction<T>> getAction(uint_fast64_t position) { // Make sure the chosen position is not beyond the end of the vector. // If it is so return the last element. @@ -116,22 +178,40 @@ public: } } + /*! + * Returns the number of actions to be executed during evaluation. + * + * @returns The number of actions in the action list. + */ uint_fast64_t getActionCount() const { return actions.size(); } + /*! + * Sets whether a minimizing or a maximizing scheduler is to be used for + * modelchecking of path formulas, i.e. probability and reward queries. + * + * @param opt The new operator specifying the scheduler to be used for path formulas. + */ void setOptimizingOperator(OptimizingOperator opt) { this->opt = opt; } + /*! + * Returns the current optimization operator. + * + * @return The optimization operator. + */ OptimizingOperator getOptimizingOperator() const { return opt; } protected: + //! The vector containing the actions to be executed during evaluation. std::vector<std::shared_ptr<action::AbstractAction<T>>> actions; + //! The optimization operator specifying if and which kind of scheduler is to be used during modelchecking of path formulas on nondeterministic models. OptimizingOperator opt; }; diff --git a/src/formula/AbstractFormula.h b/src/formula/AbstractFormula.h index 8ab2fd130..9b009f208 100644 --- a/src/formula/AbstractFormula.h +++ b/src/formula/AbstractFormula.h @@ -20,44 +20,36 @@ template <class T> class AbstractFormula; namespace storm { namespace property { -//abstract +// do properties + /*! - * @brief Abstract base class for logic Abstract formulas in general. - * - * The namespace storm::property::abstract contains versions of the formula classes which are logic abstract, and contain - * the implementation which is not directly dependent on the logics. - * The classes for the subtrees are referenced by the template parameter FormulaType, which is typically instantiated in - * the derived classes of concrete logics. - * - * The instantiation of FormulaType should be a subclass of AbstractFormula, as the functions "toString" and "validate" - * of the subformulas are needed. + * This is the abstract base class for every formula class in every logic. * - * @note - * Even though the namespace is called "abstract", its classes may be completely implemented; abstract here denotes - * the abstraction from a concrete logic. + * There are currently three implemented logics Ltl, Csl and Pctl. + * The implementation of these logics can be found in the namespaces storm::property::<logic> + * where <logic> is one of ltl, pctl and csl. * - * @attention This class is abstract. - * @note Formula classes do not have copy constructors. The parameters of the constructors are usually the subtrees, so - * the syntax conflicts with copy constructors for unary operators. To produce an identical object, the classes - * AbstractFormula and AbstractFormula offer the method clone(). - * - * This is the base class for every formula class in every logic. + * @note While formula classes do have copy constructors using a copy constructor + * will yield a formula objects whose formula subtree consists of the same objects + * as the original formula. The ownership of the formula tree will be shared between + * the original and the copy. */ template <class T> class AbstractFormula { public: + /*! - * Virtual destructor. + * The virtual destructor. */ virtual ~AbstractFormula() { // Intentionally left empty. } /*! - * @brief Return string representation of this formula. + * Return string representation of this formula. * - * @note every subclass must implement this method. + * @note Every subclass must implement this method. * * @returns a string representation of the formula */ diff --git a/src/formula/ComparisonType.h b/src/formula/ComparisonType.h index 98ee80373..bb6ea82ee 100644 --- a/src/formula/ComparisonType.h +++ b/src/formula/ComparisonType.h @@ -11,6 +11,11 @@ namespace storm { namespace property { +/*! + * An enum representing the greater- and less-than operators in both + * the strict (<, >) and the non strict (<=, >=) variant. + * It is mainly used to represent upper and lower bounds. + */ enum ComparisonType { LESS, LESS_EQUAL, GREATER, GREATER_EQUAL }; } diff --git a/src/formula/IOptimizingOperator.h b/src/formula/IOptimizingOperator.h deleted file mode 100644 index f89419d91..000000000 --- a/src/formula/IOptimizingOperator.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * IOptimizingOperator.h - * - * Created on: 17.04.2013 - * Author: thomas - */ - -#ifndef STORM_FORMULA_IOPTIMIZINGOPERATOR_H_ -#define STORM_FORMULA_IOPTIMIZINGOPERATOR_H_ - -namespace storm { -namespace property { - -/*! - * @brief Interface for optimizing operators - * - * Needed to link abstract classes in concrete logics with the logic-abstract implementation. - */ -class IOptimizingOperator { -public: - - virtual ~IOptimizingOperator() { - // Intentionally left empty - } - - /*! - * Retrieves whether the operator is to be interpreted as an optimizing (i.e. min/max) operator. - * @returns True if the operator is an optimizing operator. - */ - virtual bool isOptimalityOperator() const = 0; - - /*! - * Retrieves whether the operator is a minimizing operator given that it is an optimality - * operator. - * @returns True if the operator is an optimizing operator and it is a minimizing operator and - * false otherwise, i.e. if it is either not an optimizing operator or not a minimizing operator. - */ - virtual bool isMinimumOperator() const = 0; -}; - -} /* namespace property */ -} /* namespace storm */ -#endif /* STORM_FORMULA_IOPTIMIZINGOPERATOR_H_ */ diff --git a/src/formula/actions/AbstractAction.h b/src/formula/actions/AbstractAction.h index 77d2089ea..0912751fd 100644 --- a/src/formula/actions/AbstractAction.h +++ b/src/formula/actions/AbstractAction.h @@ -19,78 +19,122 @@ namespace storm { namespace property { namespace action { +/*! + * This is the abstract base class for all filter actions. + * + * Each action implements a distinct function which executed each time evaluate() is called. + * The input and output for each action is an instance of the Result struct. + * Thus the action is able to manipulate both the selection of output states and the order in which they are returned. + */ template <class T> class AbstractAction { public: + /*! + * This is the struct used by all actions to pass along information. + * + * It contains fields for the two possible data structures containing the modelchecking results. + * A value vector for path formulas and a bit vector for state formulas. + * The two other fields are used to describe a selection as well as an ordering of states within the modelchecking results. + * + * @note For each formula the modelchecker will return either a BitVector or a std::vector. + * Thus, either the state- or the pathResult should be set to be empty. + * If both contain a value for at least one state the pathResult will be used. + * + * @note The four vectors should always have the same number of entries. + */ struct Result { /*! - * + * Constructs an empty Result. */ Result() : selection(), stateMap(), pathResult(), stateResult(){ // Intentionally left empty. } /*! + * Copy constructs a Result. * + * @param other The Result from which the fields are copied. */ Result(Result const & other) : selection(other.selection), stateMap(other.stateMap), pathResult(other.pathResult), stateResult(other.stateResult) { // Intentionally left empty. } /*! + * Constructs a Result using values for each field. * + * @param selection A BitVector describing which states are currently selected. + * @param stateMap A vector representing an ordering on the states within the modelchecking results. + * @param pathResult The modelchecking result for a path formula. + * @param stateResult The modelchecking result for a state formula. */ Result(storm::storage::BitVector const & selection, std::vector<uint_fast64_t> const & stateMap, std::vector<T> const & pathResult, storm::storage::BitVector const & stateResult) : selection(selection), stateMap(stateMap), pathResult(pathResult), stateResult(stateResult) { // Intentionally left empty. } - //! + //! A BitVector describing which states are currently selected. + //! For state i the i-th bit is true iff state i is selected. storm::storage::BitVector selection; - //! + //! A vector representing an ordering on the states within the modelchecking results. + //! The first value of the vector is the index of the state to be returned first. + //! Thus, stateMap[i] is the index of the state that is to be returned at position i. std::vector<uint_fast64_t> stateMap; - //! + //! The modelchecking result for a path formula. std::vector<T> pathResult; - //! + //! The modelchecking result for a state formula. storm::storage::BitVector stateResult; }; /*! - * Virtual destructor - * To ensure that the right destructor is called + * The virtual destructor. + * To ensure that the right destructor is called. */ virtual ~AbstractAction() { //Intentionally left empty } - /* + /*! + * Evaluate the action for a Prctl formula. * + * @param result The Result struct on which the action is to be evaluated. + * @param mc The Prctl modelchecker that computed the path- or stateResult contained in the Result struct. + * @returns A Result struct containing the output of the action. */ - virtual Result evaluate(Result const & filterResult, storm::modelchecker::prctl::AbstractModelChecker<T> const & mc) const { + virtual Result evaluate(Result const & result, storm::modelchecker::prctl::AbstractModelChecker<T> const & mc) const { return Result(); } - /* + /*! + * Evaluate the action for a Csl formula. * + * @param result The Result struct on which the action is to be evaluated. + * @param mc The Csl modelchecker that computed the path- or stateResult contained in the Result struct. + * @returns A Result struct containing the output of the action. */ - virtual Result evaluate(Result const & filterResult, storm::modelchecker::csl::AbstractModelChecker<T> const & mc) const { + virtual Result evaluate(Result const & result, storm::modelchecker::csl::AbstractModelChecker<T> const & mc) const { return Result(); } - /* + /*! + * Evaluate the action for an Ltl formula. * + * @param result The Result struct on which the action is to be evaluated. + * @param mc The Ltl modelchecker that computed the path- or stateResult contained in the Result struct. + * @returns A Result struct containing the output of the action. */ - virtual Result evaluate(Result const & filterResult, storm::modelchecker::ltl::AbstractModelChecker<T> const & mc) const { + virtual Result evaluate(Result const & result, storm::modelchecker::ltl::AbstractModelChecker<T> const & mc) const { return Result(); } /*! + * Returns a string representation of the action. * + * @returns A string representing the action. */ virtual std::string toString() const = 0; diff --git a/src/formula/actions/BoundAction.h b/src/formula/actions/BoundAction.h index f90107742..1603c3308 100644 --- a/src/formula/actions/BoundAction.h +++ b/src/formula/actions/BoundAction.h @@ -16,52 +16,83 @@ namespace storm { namespace property { namespace action { +/*! + * The bound action deselects all states whose modelchecking values do not satisfy the given bound. + * + * Strict and non strict upper and lower bounds can be represented. + * For modelchecking results of state formulas the value is taken to be 1 iff true and 0 otherwise. + */ template <class T> class BoundAction : public AbstractAction<T> { + // Convenience typedef to make the code more readable. typedef typename AbstractAction<T>::Result Result; public: + /*! + * Constructs an empty BoundAction. + * The bound is set to >= 0. Thus, all states will be selected by the action. + */ BoundAction() : comparisonOperator(storm::property::GREATER_EQUAL), bound(0) { //Intentionally left empty. } + /*! + * Constructs a BoundAction using the given values for the comparison operator and the bound. + * + * @param comparisonOperator The operator used to make the comparison between the bound and the modelchecking values for each state. + * @param bound The bound to compare the modelchecking values against. + */ BoundAction(storm::property::ComparisonType comparisonOperator, T bound) : comparisonOperator(comparisonOperator), bound(bound) { //Intentionally left empty. } /*! - * Virtual destructor - * To ensure that the right destructor is called + * The virtual destructor. + * To ensure that the right destructor is called. */ virtual ~BoundAction() { //Intentionally left empty } /*! + * Evaluate the action for an Prctl formula. * + * @param result The Result struct on which the action is to be evaluated. + * @param mc The Prctl modelchecker that computed the path- or stateResult contained in the Result struct. + * @returns A Result struct containing the output of the action. */ virtual Result evaluate(Result const & result, storm::modelchecker::prctl::AbstractModelChecker<T> const & mc) const override { return evaluate(result); } /*! + * Evaluate the action for an Csl formula. * + * @param result The Result struct on which the action is to be evaluated. + * @param mc The Csl modelchecker that computed the path- or stateResult contained in the Result struct. + * @returns A Result struct containing the output of the action. */ virtual Result evaluate(Result const & result, storm::modelchecker::csl::AbstractModelChecker<T> const & mc) const override { return evaluate(result); } /*! + * Evaluate the action for an Ltl formula. * + * @param result The Result struct on which the action is to be evaluated. + * @param mc The Ltl modelchecker that computed the path- or stateResult contained in the Result struct. + * @returns A Result struct containing the output of the action. */ virtual Result evaluate(Result const & result, storm::modelchecker::ltl::AbstractModelChecker<T> const & mc) const override { return evaluate(result); } /*! + * Returns a string representation of this action. * + * @returns A string representing this action. */ virtual std::string toString() const override { std::string out = "bound("; @@ -92,7 +123,14 @@ public: private: /*! + * Evaluate the action. * + * As the BoundAction does not depend on the model or the formula for which the modelchecking result was computed, + * it does not depend on the modelchecker at all. This internal version of the evaluate method therefore only needs the + * modelchecking result as input. + * + * @param result The Result struct on which the action is to be evaluated. + * @returns A Result struct containing the output of the action. */ virtual Result evaluate(Result const & result) const { @@ -159,7 +197,10 @@ private: return Result(out, result.stateMap, result.pathResult, result.stateResult); } + // The operator used to make the comparison between the bound and the modelchecking values for each state at time of evaluation. storm::property::ComparisonType comparisonOperator; + + // The bound to compare the modelchecking values against during evaluation. T bound; }; diff --git a/src/formula/actions/FormulaAction.h b/src/formula/actions/FormulaAction.h index 9ac3ad861..5028253fe 100644 --- a/src/formula/actions/FormulaAction.h +++ b/src/formula/actions/FormulaAction.h @@ -19,35 +19,62 @@ namespace storm { namespace property { namespace action { +/*! + * The Formula action deselects all states that do not satisfy the given state formula. + * + * @note Since there is no modelchecker implemented for Ltl formulas (except the abstract base class) + * the formula action currently only supports Prctl and Csl state formulas. + */ template <class T> class FormulaAction : public AbstractAction<T> { + // Convenience typedef to make the code more readable. typedef typename AbstractAction<T>::Result Result; public: + + /*! + * Constructs an empty FormulaAction. + * + * The evaluation will do nothing and return the Result as it was put in. + */ FormulaAction() : prctlFormula(nullptr), cslFormula(nullptr) { //Intentionally left empty. } + /*! + * Constructs a FormulaAction using the given Prctl formula. + * + * @param prctlFormula The Prctl state formula used to filter the selection during evaluation. + */ FormulaAction(std::shared_ptr<storm::property::prctl::AbstractStateFormula<T>> const & prctlFormula) : prctlFormula(prctlFormula), cslFormula(nullptr) { //Intentionally left empty. } + /*! + * Constructs a FormulaAction using the given Csl formula. + * + * @param cslFormula The Csl state formula used to filter the selection during evaluation. + */ FormulaAction(std::shared_ptr<storm::property::csl::AbstractStateFormula<T>> const & cslFormula) : prctlFormula(nullptr), cslFormula(cslFormula) { //Intentionally left empty. } /*! - * Virtual destructor - * To ensure that the right destructor is called + * The virtual destructor. + * To ensure that the right destructor is called. */ virtual ~FormulaAction() { // Intentionally left empty. } /*! + * Evaluate the action for an Prctl formula. * + * @param result The Result struct on which the action is to be evaluated. + * @param mc The Prctl modelchecker that computed the path- or stateResult contained in the Result struct. + * @returns A Result struct containing the output of the action. */ virtual Result evaluate(Result const & result, storm::modelchecker::prctl::AbstractModelChecker<T> const & mc) const override { @@ -62,7 +89,11 @@ public: } /*! + * Evaluate the action for an Csl formula. * + * @param result The Result struct on which the action is to be evaluated. + * @param mc The Csl modelchecker that computed the path- or stateResult contained in the Result struct. + * @returns A Result struct containing the output of the action. */ virtual Result evaluate(Result const & result, storm::modelchecker::csl::AbstractModelChecker<T> const & mc) const override { @@ -77,7 +108,9 @@ public: } /*! + * Returns a string representation of this action. * + * @returns A string representing this action. */ virtual std::string toString() const override { std::string out = "formula("; @@ -91,7 +124,11 @@ public: } private: + + // The Prctl state formula used during evaluation. std::shared_ptr<storm::property::prctl::AbstractStateFormula<T>> prctlFormula; + + // The Csl state formula used during evaluation. std::shared_ptr<storm::property::csl::AbstractStateFormula<T>> cslFormula; }; diff --git a/src/formula/actions/InvertAction.h b/src/formula/actions/InvertAction.h index 5492e4644..7084d52e2 100644 --- a/src/formula/actions/InvertAction.h +++ b/src/formula/actions/InvertAction.h @@ -14,48 +14,71 @@ namespace storm { namespace property { namespace action { +/*! + * The InvertAction inverts the selection, selecting precisely the unselected states. + */ template <class T> class InvertAction : public AbstractAction<T> { + // Convenience typedef to make the code more readable. typedef typename AbstractAction<T>::Result Result; public: + /*! + * Constructs an InvertAction. + * + * As the simple inversion of the selection does not need any parameters, the empty constructor is the only one needed. + */ InvertAction() { //Intentionally left empty. } /*! - * Virtual destructor - * To ensure that the right destructor is called + * The virtual destructor. + * To ensure that the right destructor is called. */ virtual ~InvertAction() { //Intentionally left empty } /*! + * Evaluate the action for a Prctl formula. * + * @param result The Result struct on which the action is to be evaluated. + * @param mc The Prctl modelchecker that computed the path- or stateResult contained in the Result struct. + * @returns A Result struct containing the output of the action. */ virtual Result evaluate(Result const & result, storm::modelchecker::prctl::AbstractModelChecker<T> const & mc) const override { return evaluate(result); } /*! + * Evaluate the action for a Csl formula. * + * @param result The Result struct on which the action is to be evaluated. + * @param mc The Csl modelchecker that computed the path- or stateResult contained in the Result struct. + * @returns A Result struct containing the output of the action. */ virtual Result evaluate(Result const & result, storm::modelchecker::csl::AbstractModelChecker<T> const & mc) const override { return evaluate(result); } /*! + * Evaluate the action for a Ltl formula. * + * @param result The Result struct on which the action is to be evaluated. + * @param mc The Ltl modelchecker that computed the path- or stateResult contained in the Result struct. + * @returns A Result struct containing the output of the action. */ virtual Result evaluate(Result const & result, storm::modelchecker::ltl::AbstractModelChecker<T> const & mc) const override { return evaluate(result); } /*! + * Returns a string representation of this action. * + * @returns A string representing this action. */ virtual std::string toString() const override { return "invert"; @@ -64,7 +87,14 @@ public: private: /*! + * Evaluate the action. + * + * As the InvertAction does not depend on the model or the formula for which the modelchecking result was computed, + * it does not depend on the modelchecker at all. This internal version of the evaluate method therefore only needs the + * modelchecking result as input. * + * @param result The Result struct on which the action is to be evaluated. + * @returns A Result struct containing the output of the action. */ virtual Result evaluate(Result const & result) const { storm::storage::BitVector out(result.selection); diff --git a/src/formula/actions/RangeAction.h b/src/formula/actions/RangeAction.h index 382492d49..8136715b2 100644 --- a/src/formula/actions/RangeAction.h +++ b/src/formula/actions/RangeAction.h @@ -14,57 +14,80 @@ namespace storm { namespace property { namespace action { +/*! + * The RangeAction deselects all states that are not within the given range. + * + * The bounds of the range given are indices in the result ordering. + * Thus, if the lower bound is 0 and the upper bound is 5 then all states that are not + * at index 0 through 5 (including) in the state ordering will be deselected. + * This action is thought to be used in connection with the SortAction. + */ template <class T> class RangeAction : public AbstractAction<T> { + // Convenience typedef to make the code more readable. typedef typename AbstractAction<T>::Result Result; public: - RangeAction() : from(0), to(0) { - //Intentionally left empty. - } - /*! - * Including the state with position to. + * Construct a RangeAction using the given values. + * + * If no values are given they default to [0,UINT_FAST64_MAX] thus deselecting no state at evaluation. + * + * @note The interval bounds are included in the interval. */ - RangeAction(uint_fast64_t from, uint_fast64_t to) : from(from), to(to) { + RangeAction(uint_fast64_t from = 0, uint_fast64_t to = UINT_FAST64_MAX) : from(from), to(to) { if(from > to) { throw storm::exceptions::IllegalArgumentValueException() << "The end of the range is lower than its beginning"; } } /*! - * Virtual destructor - * To ensure that the right destructor is called + * The virtual destructor. + * To ensure that the right destructor is called. */ virtual ~RangeAction() { //Intentionally left empty } /*! + * Evaluate the action for a Prctl formula. * + * @param result The Result struct on which the action is to be evaluated. + * @param mc The Prctl modelchecker that computed the path- or stateResult contained in the Result struct. + * @returns A Result struct containing the output of the action. */ virtual Result evaluate(Result const & result, storm::modelchecker::prctl::AbstractModelChecker<T> const & mc) const override { return evaluate(result); } /*! + * Evaluate the action for a Csl formula. * + * @param result The Result struct on which the action is to be evaluated. + * @param mc The Csl modelchecker that computed the path- or stateResult contained in the Result struct. + * @returns A Result struct containing the output of the action. */ virtual Result evaluate(Result const & result, storm::modelchecker::csl::AbstractModelChecker<T> const & mc) const override { return evaluate(result); } /*! + * Evaluate the action for a Ltl formula. * + * @param result The Result struct on which the action is to be evaluated. + * @param mc The Ltl modelchecker that computed the path- or stateResult contained in the Result struct. + * @returns A Result struct containing the output of the action. */ virtual Result evaluate(Result const & result, storm::modelchecker::ltl::AbstractModelChecker<T> const & mc) const override { return evaluate(result); } /*! + * Returns a string representation of this action. * + * @returns A string representing this action. */ virtual std::string toString() const override { std::string out = "range("; @@ -78,7 +101,14 @@ public: private: /*! + * Evaluate the action. * + * As the RangeAction does not depend on the model or the formula for which the modelchecking result was computed, + * it does not depend on the modelchecker at all. This internal version of the evaluate method therefore only needs the + * modelchecking result as input. + * + * @param result The Result struct on which the action is to be evaluated. + * @returns A Result struct containing the output of the action. */ virtual Result evaluate(Result const & result) const { //Initialize the output vector. @@ -110,7 +140,10 @@ private: return Result(out, result.stateMap, result.pathResult, result.stateResult); } + // The lower bound of the interval of states not deselected. uint_fast64_t from; + + // The upper bound of the interval of states not deselected. uint_fast64_t to; }; diff --git a/src/formula/actions/SortAction.h b/src/formula/actions/SortAction.h index ea676dfd4..289426f6f 100644 --- a/src/formula/actions/SortAction.h +++ b/src/formula/actions/SortAction.h @@ -15,54 +15,81 @@ namespace storm { namespace property { namespace action { +/*! + * This action manipulates the state ordering by sorting the states by some category. + * + * Currently the states can be sorted either by index or by value; ascending or descending. + * This is done using the standard libraries sort function, thus the action evaluates in O(n*log n) where n is the number of states. + */ template <class T> class SortAction : public AbstractAction<T> { + // Convenience typedef to make the code more readable. typedef typename AbstractAction<T>::Result Result; public: + //! Enum defining the categories in relation to which the states can be sorted. enum SortingCategory {INDEX, VALUE}; - SortAction() : category(INDEX), ascending(true) { - //Intentionally left empty. - } - - SortAction(SortingCategory category, bool ascending = true) : category(category), ascending(ascending) { + /*! + * Construct a SortAction using the given values. + * + * If no values are given the action will sort by ascending state index. + * + * @param category An enum value identifying the category by which the states are to be ordered. + * @param ascending Determines whether the values are to be sorted in ascending or descending order. + * The parameter is to be set to true iff the values are to be sorted in ascending order. + */ + SortAction(SortingCategory category = INDEX, bool ascending = true) : category(category), ascending(ascending) { //Intentionally left empty. } /*! - * Virtual destructor - * To ensure that the right destructor is called + * The virtual destructor. + * To ensure that the right destructor is called. */ virtual ~SortAction() { //Intentionally left empty } /*! + * Evaluate the action for a Prctl formula. * + * @param result The Result struct on which the action is to be evaluated. + * @param mc The Prctl modelchecker that computed the path- or stateResult contained in the Result struct. + * @returns A Result struct containing the output of the action. */ virtual Result evaluate(Result const & result, storm::modelchecker::prctl::AbstractModelChecker<T> const & mc) const override { return evaluate(result); } /*! + * Evaluate the action for a Csl formula. * + * @param result The Result struct on which the action is to be evaluated. + * @param mc The Csl modelchecker that computed the path- or stateResult contained in the Result struct. + * @returns A Result struct containing the output of the action. */ virtual Result evaluate(Result const & result, storm::modelchecker::csl::AbstractModelChecker<T> const & mc) const override { return evaluate(result); } /*! + * Evaluate the action for a Ltl formula. * + * @param result The Result struct on which the action is to be evaluated. + * @param mc The Ltl modelchecker that computed the path- or stateResult contained in the Result struct. + * @returns A Result struct containing the output of the action. */ virtual Result evaluate(Result const & result, storm::modelchecker::ltl::AbstractModelChecker<T> const & mc) const override { return evaluate(result); } /*! + * Returns a string representation of this action. * + * @returns A string representing this action. */ virtual std::string toString() const override { std::string out = "sort("; @@ -87,7 +114,14 @@ public: private: /*! + * Evaluate the action. + * + * As the SortAction does not depend on the model or the formula for which the modelchecking result was computed, + * it does not depend on the modelchecker at all. This internal version of the evaluate method therefore only needs the + * modelchecking result as input. * + * @param result The Result struct on which the action is to be evaluated. + * @returns A Result struct containing the output of the action. */ Result evaluate(Result const & result) const { @@ -106,7 +140,11 @@ private: } /*! + * This method returns a vector of the given length filled with the numbers 0 to length-1 in ascending or descending order, + * depending on the value of the member variable ascending. Thus it sorts by state index. * + * @param length The length of the generated vector. + * @returns A vector of unsigned integers from 0 to length-1 in ascending or descending order. */ std::vector<uint_fast64_t> sort(uint_fast64_t length) const { @@ -128,7 +166,15 @@ private: } /*! + * Sort the stateMap vector representing the current state ordering by the values in the values vector. * + * Here the entries in the values vector are assumed to be the modelchecking results of a path formula. + * Hence, the value at index i is associated with state i, i.e the value i in the stateMap. + * The ordering direction (ascending/decending) is given by the member variable ascending, set in the constructor. + * + * @param stateMap A vector representing the current state ordering. + * @param values A vector containing the values by which the stateMap is to be ordered. + * @returns A vector containing the reordered entries of the stateMap. */ std::vector<uint_fast64_t> sort(std::vector<uint_fast64_t> const & stateMap, std::vector<T> const & values) const { @@ -146,7 +192,15 @@ private: } /*! + * Sort the stateMap vector representing the current state ordering by the values in the values vector. + * + * Here the entries in the values vector are assumed to be the modelchecking results of a state formula. + * Hence, the value at index i is associated with state i, i.e the value i in the stateMap. + * The ordering direction (ascending/decending) is given by the member variable ascending, set in the constructor. * + * @param stateMap A vector representing the current state ordering. + * @param values A vector containing the values by which the stateMap is to be ordered. + * @returns A vector containing the reordered entries of the stateMap. */ std::vector<uint_fast64_t> sort(std::vector<uint_fast64_t> const & stateMap, storm::storage::BitVector const & values) const { @@ -163,7 +217,10 @@ private: return outMap; } + // The category by which the states are to be ordered. SortingCategory category; + + // Determines whether the values are to be sorted in ascending or descending order. bool ascending; }; diff --git a/src/formula/csl/AbstractCslFormula.h b/src/formula/csl/AbstractCslFormula.h index 73d4f3dcd..360b5d411 100644 --- a/src/formula/csl/AbstractCslFormula.h +++ b/src/formula/csl/AbstractCslFormula.h @@ -5,8 +5,8 @@ * Author: Thomas Heinemann */ -#ifndef ABSTRACTCSLFORMULA_H_ -#define ABSTRACTCSLFORMULA_H_ +#ifndef STORM_FORMULA_CSL_ABSTRACTCSLFORMULA_H_ +#define STORM_FORMULA_CSL_ABSTRACTCSLFORMULA_H_ #include "src/formula/AbstractFormula.h" @@ -14,6 +14,8 @@ namespace storm { namespace property { namespace csl { +// Forward declarations. + template <class T> class ProbabilisticBoundOperator; template <class T> class Eventually; template <class T> class Until; @@ -27,11 +29,20 @@ namespace property { namespace csl { /*! - * Abstract base class for all CSL root formulas. + * This is the abstract base class for all Csl formulas. + * + * @note While formula classes do have copy constructors using a copy constructor + * will yield a formula objects whose formula subtree consists of the same objects + * as the original formula. The ownership of the formula tree will be shared between + * the original and the copy. */ template <class T> class AbstractCslFormula : public virtual storm::property::AbstractFormula<T>{ public: + + /*! + * The virtual destructor. + */ virtual ~AbstractCslFormula() { // Intentionally left empty } @@ -75,4 +86,4 @@ public: } /* namespace csl */ } /* namespace property */ } /* namespace storm */ -#endif /* ABSTRACTCSLFORMULA_H_ */ +#endif /* STORM_FORMULA_CSL_ABSTRACTCSLFORMULA_H_ */ diff --git a/src/formula/csl/AbstractPathFormula.h b/src/formula/csl/AbstractPathFormula.h index 6de58a14d..a8d415616 100644 --- a/src/formula/csl/AbstractPathFormula.h +++ b/src/formula/csl/AbstractPathFormula.h @@ -8,14 +8,6 @@ #ifndef STORM_FORMULA_CSL_ABSTRACTPATHFORMULA_H_ #define STORM_FORMULA_CSL_ABSTRACTPATHFORMULA_H_ -namespace storm { -namespace property { -namespace csl { -template<class T> class AbstractPathFormula; -} //namespace csl -} //namespace property -} //namespace storm - #include "src/formula/csl/AbstractCslFormula.h" #include "src/modelchecker/csl/ForwardDeclarations.h" @@ -28,23 +20,18 @@ namespace property { namespace csl { /*! - * @brief - * Abstract base class for Abstract path formulas. - * - * @attention This class is abstract. - * @note Formula classes do not have copy constructors. The parameters of the constructors are usually the subtrees, so - * the syntax conflicts with copy constructors for unary operators. To produce an identical object, use the method - * clone(). + * Abstract base class for Csl path formulas. * - * @note - * This class is intentionally not derived from AbstractCslFormula, as a path formula is not a complete CSL formula. + * @note Differing from the formal definitions of PRCTL a path formula may be the root of a PRCTL formula. + * The result of a modelchecking process on such a formula is a vector representing the satisfaction probabilities for each state of the model. */ template <class T> class AbstractPathFormula : public virtual storm::property::csl::AbstractCslFormula<T> { public: + /*! - * empty destructor + * The virtual destructor. */ virtual ~AbstractPathFormula() { // Intentionally left empty @@ -53,10 +40,11 @@ public: /*! * Clones the called object. * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones + * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones. * * @note This function is not implemented in this class. - * @returns a new AND-object that is identical the called object. + * + * @returns A deep copy of the called object. */ virtual std::shared_ptr<AbstractPathFormula<T>> clone() const = 0; diff --git a/src/formula/csl/AbstractStateFormula.h b/src/formula/csl/AbstractStateFormula.h index 4a50c21b2..dec96eb45 100644 --- a/src/formula/csl/AbstractStateFormula.h +++ b/src/formula/csl/AbstractStateFormula.h @@ -17,20 +17,15 @@ namespace property { namespace csl { /*! - * @brief - * Abstract base class for Abstract state formulas. - * - * @attention This class is abstract. - * @note Formula classes do not have copy constructors. The parameters of the constructors are usually the subtrees, so - * the syntax conflicts with copy constructors for unary operators. To produce an identical object, use the method - * clone(). + * Abstract base class for Csl state formulas. */ template <class T> class AbstractStateFormula : public storm::property::csl::AbstractCslFormula<T> { public: + /*! - * empty destructor + * Empty virtual destructor. */ virtual ~AbstractStateFormula() { // Intentionally left empty @@ -42,7 +37,8 @@ public: * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones * * @note This function is not implemented in this class. - * @returns a new AND-object that is identical the called object. + * + * @returns A deep copy of the called object. */ virtual std::shared_ptr<AbstractStateFormula<T>> clone() const = 0; diff --git a/src/formula/csl/And.h b/src/formula/csl/And.h index afb78ceeb..a5ebaffb2 100644 --- a/src/formula/csl/And.h +++ b/src/formula/csl/And.h @@ -16,37 +16,45 @@ namespace storm { namespace property { namespace csl { +// Forward declaration for the interface class. template <class T> class And; /*! - * @brief Interface class for model checkers that support And. + * Interface class for model checkers that support And. * - * All model checkers that support the formula class And must inherit - * this pure virtual class. + * All model checkers that support the formula class And must inherit + * this pure virtual class. */ template <class T> class IAndModelChecker { public: + + /*! + * Empty virtual destructor. + */ + virtual ~IAndModelChecker() { + // Intentionally left empty + } + /*! - * @brief Evaluates And formula within a model checker. + * Evaluates an And formula within a model checker. * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. + * @param obj Formula object with subformulas. + * @return The modelchecking result of the formula for every state. */ virtual storm::storage::BitVector checkAnd(const And<T>& obj) const = 0; }; /*! - * @brief - * Class for an abstract formula tree with AND node as root. + * Class for a Csl formula tree with an And node as root. * - * Has two Abstract state formulas as sub formulas/trees. + * Has two Csl state formulas as sub formulas/trees. * - * As AND is commutative, the order is \e theoretically not important, but will influence the order in which + * As And is commutative, the order is \e theoretically not important, but will influence the order in which * the model checker works. * - * The subtrees are seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) + * The object has shared ownership of its subtrees. If this object is deleted and no other object has a shared + * ownership of the subtrees they will be deleted as well. * * @see AbstractStateFormula * @see AbstractCslFormula @@ -57,29 +65,25 @@ class And : public AbstractStateFormula<T> { public: /*! - * Empty constructor. - * Will create an AND-node without subnotes. Will not represent a complete formula! + * Creates an And node without subnodes. + * The resulting object will not represent a complete formula! */ And() : left(nullptr), right(nullptr){ // Intentionally left empty. } /*! - * Constructor. - * Creates an AND note with the parameters as subtrees. + * Creates an And node with the parameters as subtrees. * - * @param left The left sub formula - * @param right The right sub formula + * @param left The left sub formula. + * @param right The right sub formula. */ And(std::shared_ptr<AbstractStateFormula<T>> const & left, std::shared_ptr<AbstractStateFormula<T>> const & right) : left(left), right(right) { // Intentionally left empty. } /*! - * Destructor. - * - * The subtrees are deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) + * Empty virtual destructor. */ virtual ~And() { // Intentionally left empty. @@ -88,16 +92,16 @@ public: /*! * Clones the called object. * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones + * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones. * - * @returns a new AND-object that is identical the called object. + * @returns A new And object that is a deep copy of the called object. */ virtual std::shared_ptr<AbstractStateFormula<T>> clone() const override { std::shared_ptr<And<T>> result(new And()); - if (this->leftIsSet()) { + if (this->isLeftSet()) { result->setLeft(left->clone()); } - if (this->rightIsSet()) { + if (this->isRightSet()) { result->setRight(right->clone()); } return result; @@ -117,7 +121,9 @@ public: } /*! - * @returns a string representation of the formula + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. */ virtual std::string toString() const override { std::string result = "("; @@ -138,55 +144,65 @@ public: } /*! - * Sets the left child node. + * Gets the left child node. * - * @param newLeft the new left child. + * @returns The left child node. */ - void setLeft(std::shared_ptr<AbstractStateFormula<T>> const & newLeft) { - left = newLeft; + std::shared_ptr<AbstractStateFormula<T>> const & getLeft() const { + return left; } /*! - * Sets the right child node. + * Gets the right child node. * - * @param newRight the new right child. + * @returns The right child node. */ - void setRight(std::shared_ptr<AbstractStateFormula<T>> const & newRight) { - right = newRight; + std::shared_ptr<AbstractStateFormula<T>> const & getRight() const { + return right; } /*! - * @returns a pointer to the left child node + * Sets the left child node. + * + * @param newLeft The new left child. */ - std::shared_ptr<AbstractStateFormula<T>> const & getLeft() const { - return left; + void setLeft(std::shared_ptr<AbstractStateFormula<T>> const & newLeft) { + left = newLeft; } /*! - * @returns a pointer to the right child node + * Sets the right child node. + * + * @param newRight The new right child. */ - std::shared_ptr<AbstractStateFormula<T>> const & getRight() const { - return right; + void setRight(std::shared_ptr<AbstractStateFormula<T>> const & newRight) { + right = newRight; } /*! + * Checks if the left child is set, i.e. it does not point to null. * - * @return True if the left child is set, i.e. it does not point to nullptr; false otherwise + * @return True iff the left child is set. */ - bool leftIsSet() const { + bool isLeftSet() const { return left.get() != nullptr; } /*! + * Checks if the right child is set, i.e. it does not point to null. * - * @return True if the right child is set, i.e. it does not point to nullptr; false otherwise + * @return True iff the right child is set. */ - bool rightIsSet() const { + bool isRightSet() const { return right.get() != nullptr; } private: + + // The left child node. std::shared_ptr<AbstractStateFormula<T>> left; + + // The right child node. std::shared_ptr<AbstractStateFormula<T>> right; }; diff --git a/src/formula/csl/Ap.h b/src/formula/csl/Ap.h index a80f8fdfe..8ab7600fe 100644 --- a/src/formula/csl/Ap.h +++ b/src/formula/csl/Ap.h @@ -15,29 +15,37 @@ namespace storm { namespace property { namespace csl { +// Forward declaration for the interface class. template <class T> class Ap; /*! - * @brief Interface class for model checkers that support Ap. + * Interface class for model checkers that support Ap. * - * All model checkers that support the formula class Ap must inherit - * this pure virtual class. + * All model checkers that support the formula class Ap must inherit + * this pure virtual class. */ template <class T> class IApModelChecker { public: + + /*! + * Empty virtual destructor. + */ + virtual ~IApModelChecker() { + // Intentionally left empty + } + /*! - * @brief Evaluates Ap formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ + * Evaluates an Ap formula within a model checker. + * + * @param obj Formula object with subformulas. + * @return The modelchecking result of the formula for every state. + */ virtual storm::storage::BitVector checkAp(const Ap<T>& obj) const = 0; }; /*! - * @brief - * Class for an abstract formula tree with atomic proposition as root. + * Class for a Csl formula tree with an atomic proposition as root. * * This class represents the leaves in the formula tree. * @@ -50,19 +58,16 @@ class Ap : public AbstractStateFormula<T> { public: /*! - * Constructor + * Creates a new atomic proposition leaf, with the given label. * - * Creates a new atomic proposition leaf, with the label Ap - * - * @param ap The string representing the atomic proposition + * @param ap A string representing the atomic proposition. */ - Ap(std::string ap) { - this->ap = ap; + Ap(std::string ap) : ap(ap) { + // Intentionally left empty. } /*! - * Destructor. - * At this time, empty... + * Empty virtual destructor. */ virtual ~Ap() { // Intentionally left empty @@ -71,9 +76,9 @@ public: /*! * Clones the called object. * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones + * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones. * - * @returns a new AND-object that is identical the called object. + * @returns A new Ap object that is a deep copy of the called object. */ virtual std::shared_ptr<AbstractStateFormula<T>> clone() const override { std::shared_ptr<AbstractStateFormula<T>> result(new Ap(this->getAp())); @@ -93,6 +98,15 @@ public: return modelChecker.template as<IApModelChecker>()->checkAp(*this); } + /*! + * A string representing the atomic proposition. + * + * @returns A string representing the leaf. + */ + virtual std::string toString() const override { + return getAp(); + } + /*! Returns whether the formula is a propositional logic formula. * That is, this formula and all its subformulas consist only of And, Or, Not and AP. * @@ -103,21 +117,17 @@ public: } /*! - * @returns the name of the atomic proposition + * Gets the name of the atomic proposition. + * + * @returns The name of the atomic proposition. */ std::string const & getAp() const { return ap; } - /*! - * @returns a string representation of the leaf. - * - */ - virtual std::string toString() const override { - return getAp(); - } - private: + + // The atomic proposition referenced by this leaf. std::string ap; }; diff --git a/src/formula/csl/CslFilter.h b/src/formula/csl/CslFilter.h index ef1ec5044..4d92829e5 100644 --- a/src/formula/csl/CslFilter.h +++ b/src/formula/csl/CslFilter.h @@ -16,45 +16,88 @@ #include "src/formula/actions/AbstractAction.h" -namespace storm { -namespace property { -namespace action { - template <typename T> class AbstractAction; -} -} -} - namespace storm { namespace property { namespace csl { +/*! + * This is the Csl specific filter. + * + * It maintains a Csl formula which can be checked against a given model by either calling evaluate() or check(). + * Additionally it maintains a list of filter actions that are used to further manipulate the modelchecking results and prepare them for output. + */ template <class T> class CslFilter : public storm::property::AbstractFilter<T> { + // Convenience typedef to make the code more readable. typedef typename storm::property::action::AbstractAction<T>::Result Result; public: + /*! + * Creates an empty CslFilter, maintaining no Csl formula. + * + * Calling check or evaluate will return an empty result. + */ CslFilter() : AbstractFilter<T>(UNDEFINED), child(nullptr), steadyStateQuery(false) { // Intentionally left empty. } + /*! + * Creates a CslFilter maintaining a Csl formula but containing no actions. + * + * The modelchecking result will be returned or printed as is. + * + * @param child The Csl formula to be maintained. + * @param opt An enum value indicating which kind of scheduler shall be used for path formulas on nondeterministic models. + * @param steadyStateQuery A flag indicating whether this is a steady state query. + */ CslFilter(std::shared_ptr<AbstractCslFormula<T>> const & child, OptimizingOperator opt = UNDEFINED, bool steadyStateQuery = false) : AbstractFilter<T>(opt), child(child), steadyStateQuery(steadyStateQuery) { // Intentionally left empty. } + /*! + * Creates a CslFilter maintaining a Csl formula and containing a single action. + * + * The given action will be applied to the modelchecking result during evaluation. + * Further actions can be added later. + * + * @param child The Csl formula to be maintained. + * @param action The single action to be executed during evaluation. + * @param opt An enum value indicating which kind of scheduler shall be used for path formulas on nondeterministic models. + * @param steadyStateQuery A flag indicating whether this is a steady state query. + */ CslFilter(std::shared_ptr<AbstractCslFormula<T>> const & child, std::shared_ptr<action::AbstractAction<T>> const & action, OptimizingOperator opt = UNDEFINED, bool steadyStateQuery = false) : AbstractFilter<T>(action, opt), child(child), steadyStateQuery(steadyStateQuery) { // Intentionally left empty } + /*! + * Creates a CslFilter using the given parameters. + * + * The given actions will be applied to the modelchecking result in ascending index order during evaluation. + * Further actions can be added later. + * + * @param child The Csl formula to be maintained. + * @param actions A vector conatining the actions that are to be executed during evaluation. + * @param opt An enum value indicating which kind of scheduler shall be used for path formulas on nondeterministic models. + * @param steadyStateQuery A flag indicating whether this is a steady state query. + */ CslFilter(std::shared_ptr<AbstractCslFormula<T>> const & child, std::vector<std::shared_ptr<action::AbstractAction<T>>> const & actions, OptimizingOperator opt = UNDEFINED, bool steadyStateQuery = false) : AbstractFilter<T>(actions, opt), child(child), steadyStateQuery(steadyStateQuery) { // Intentionally left empty. } + /*! + * Empty virtual destructor. + */ virtual ~CslFilter() { // Intentionally left empty. } + /*! + * Calls the modelchecker, retrieves the modelchecking result, applies the filter action one by one and prints out the result. + * + * @param modelchecker The modelchecker to be called. + */ void check(storm::modelchecker::csl::AbstractModelChecker<T> const & modelchecker) const { // Write out the formula to be checked. @@ -66,6 +109,12 @@ public: } + /*! + * Calls the modelchecker, retrieves the modelchecking result, applies the filter action one by one and returns the result. + * + * @param modelchecker The modelchecker to be called. + * @returns The result of the sequential application of the filter actions to the modelchecking result. + */ Result evaluate(storm::modelchecker::csl::AbstractModelChecker<T> const & modelchecker) const { Result result; @@ -83,6 +132,13 @@ public: return result; } + /*! + * Returns a textual representation of the filter. + * + * That includes the actions as well as the maintained formula. + * + * @returns A string representing the filter. + */ virtual std::string toString() const override { std::string desc = ""; @@ -170,30 +226,50 @@ public: return desc; } - virtual std::string toPrettyString() const override{ - std::string desc = "Filter: "; - desc += "\nActions:"; - for(auto action : this->actions) { - desc += "\n\t" + action->toString(); - } - desc += "\nFormula:\n\t" + child->toString(); - return desc; + /*! + * Gets the child node. + * + * @returns The child node. + */ + std::shared_ptr<AbstractCslFormula<T>> const & getChild() const { + return child; } + /*! + * Sets the subtree. + * + * @param child The new child. + */ void setChild(std::shared_ptr<AbstractCslFormula<T>> const & child) { this->child = child; } - std::shared_ptr<AbstractCslFormula<T>> const & getChild() const { - return child; + /*! + * Checks if the child is set, i.e. it does not point to null. + * + * @return True iff the child is set. + */ + bool isChildSet() const { + return child.get() != nullptr; } private: + /*! + * Calls the modelchecker for a state formula, retrieves the modelchecking result, applies the filter action one by one and returns the result. + * + * This an internal version of the evaluate method overloading it for the different Csl formula types. + * + * @param modelchecker The modelchecker to be called. + * @param formula The state formula for which the modelchecker will be called. + * @returns The result of the sequential application of the filter actions to the modelchecking result. + */ Result evaluate(storm::modelchecker::csl::AbstractModelChecker<T> const & modelchecker, std::shared_ptr<AbstractStateFormula<T>> const & formula) const { // First, get the model checking result. Result result; + //TODO: Once a modelchecker supporting steady state formulas is implemented, call it here in case steadyStateQuery is set. + if(this->opt != UNDEFINED) { // If there is an action specifying that min/max probabilities should be computed, call the appropriate method of the model checker. result.stateResult = modelchecker.checkMinMaxOperator(*formula, this->opt == MINIMIZE ? true : false); @@ -206,6 +282,15 @@ private: return evaluateActions(result, modelchecker); } + /*! + * Calls the modelchecker for a path formula, retrieves the modelchecking result, applies the filter action one by one and returns the result. + * + * This an internal version of the evaluate method overloading it for the different Csl formula types. + * + * @param modelchecker The modelchecker to be called. + * @param formula The path formula for which the modelchecker will be called. + * @returns The result of the sequential application of the filter actions to the modelchecking result. + */ Result evaluate(storm::modelchecker::csl::AbstractModelChecker<T> const & modelchecker, std::shared_ptr<AbstractPathFormula<T>> const & formula) const { // First, get the model checking result. Result result; @@ -221,6 +306,13 @@ private: return evaluateActions(result, modelchecker); } + /*! + * Evaluates the filter actions by calling them one by one using the output of each action as the input for the next one. + * + * @param input The modelchecking result in form of a Result struct. + * @param modelchecker The modelchecker that was called to generate the modelchecking result. Needed by some actions. + * @returns The result of the sequential application of the filter actions to the modelchecking result. + */ Result evaluateActions(Result result, storm::modelchecker::csl::AbstractModelChecker<T> const & modelchecker) const { // Init the state selection and state map vectors. @@ -238,6 +330,12 @@ private: return result; } + /*! + * Writes out the given result. + * + * @param result The result of the sequential application of the filter actions to a modelchecking result. + * @param modelchecker The modelchecker that was called to generate the modelchecking result. Needed for legacy support. + */ void writeOut(Result const & result, storm::modelchecker::csl::AbstractModelChecker<T> const & modelchecker) const { // Test if there is anything to write out. @@ -302,8 +400,10 @@ private: std::cout << std::endl << "-------------------------------------------" << std::endl; } + // The Csl formula maintained by this filter. std::shared_ptr<AbstractCslFormula<T>> child; + // A flag indicating whether this is a steady state query. bool steadyStateQuery; }; diff --git a/src/formula/csl/Eventually.h b/src/formula/csl/Eventually.h index 21bdd71b4..6c27dfa75 100644 --- a/src/formula/csl/Eventually.h +++ b/src/formula/csl/Eventually.h @@ -1,5 +1,5 @@ /* - * Next.h + * Globally.h * * Created on: 26.12.2012 * Author: Christian Dehnert @@ -16,37 +16,48 @@ namespace storm { namespace property { namespace csl { +// Forward declaration for the interface class. template <class T> class Eventually; /*! - * @brief Interface class for model checkers that support Eventually. + * Interface class for model checkers that support Eventually. * - * All model checkers that support the formula class Eventually must inherit - * this pure virtual class. + * All model checkers that support the formula class Eventually must inherit + * this pure virtual class. */ template <class T> class IEventuallyModelChecker { public: + /*! - * @brief Evaluates Eventually formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ + * Empty virtual destructor. + */ + virtual ~IEventuallyModelChecker() { + // Intentionally left empty. + } + + /*! + * Evaluates an Eventually formula within a model checker. + * + * @param obj Formula object with subformulas. + * @param qualitative A flag indicating whether the formula only needs to be evaluated qualitatively, i.e. if the + * results are only compared against the bounds 0 and 1. + * @return The modelchecking result of the formula for every state. + */ virtual std::vector<T> checkEventually(const Eventually<T>& obj, bool qualitative) const = 0; }; /*! * @brief - * Class for an abstract (path) formula tree with an Eventually node as root. + * Class for a Csl (path) formula tree with an Eventually node as root. * - * Has one Abstract state formula as sub formula/tree. + * Has one Csl state formula as sub formula/tree. * * @par Semantics - * The formula holds iff eventually \e child holds. + * The formula holds iff eventually formula \e child holds. * - * The subtree is seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to nullptr before deletion) + * The object has shared ownership of its subtree. If this object is deleted and no other object has a shared + * ownership of the subtree it will be deleted as well. * * @see AbstractPathFormula * @see AbstractCslFormula @@ -57,26 +68,24 @@ class Eventually : public AbstractPathFormula<T> { public: /*! - * Empty constructor + * Creates an Eventually node without a subnode. + * The resulting object will not represent a complete formula! */ Eventually() : child(nullptr) { // Intentionally left empty. } /*! - * Constructor + * Creates an Eventually node using the given parameter. * - * @param child The child node + * @param child The child formula subtree. */ Eventually(std::shared_ptr<AbstractStateFormula<T>> const & child) : child(child){ // Intentionally left empty. } /*! - * Constructor. - * - * Also deletes the subtree. - * (this behaviour can be prevented by setting the subtrees to nullptr before deletion) + * Empty virtual destructor. */ virtual ~Eventually() { // Intentionally left empty. @@ -85,13 +94,13 @@ public: /*! * Clones the called object. * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. * - * @returns a new Eventually-object that is identical the called object. + * @returns A new Eventually object that is a deep copy of the called object. */ virtual std::shared_ptr<AbstractPathFormula<T>> clone() const override { std::shared_ptr<Eventually<T>> result(new Eventually<T>()); - if (this->childIsSet()) { + if (this->isChildSet()) { result->setChild(child->clone()); } return result; @@ -111,7 +120,9 @@ public: } /*! - * @returns a string representation of the formula + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. */ virtual std::string toString() const override { std::string result = "F "; @@ -120,29 +131,35 @@ public: } /*! - * @returns the child node + * Gets the child node. + * + * @returns The child node. */ std::shared_ptr<AbstractStateFormula<T>> const & getChild() const { return child; } /*! - * Sets the subtree - * @param child the new child node + * Sets the subtree. + * + * @param child The new child. */ void setChild(std::shared_ptr<AbstractStateFormula<T>> const & child) { this->child = child; } /*! + * Checks if the child is set, i.e. it does not point to null. * - * @return True if the child node is set, i.e. it does not point to nullptr; false otherwise + * @return True iff the child is set. */ - bool childIsSet() const { + bool isChildSet() const { return child.get() != nullptr; } private: + + // The child node. std::shared_ptr<AbstractStateFormula<T>> child; }; diff --git a/src/formula/csl/Globally.h b/src/formula/csl/Globally.h index e93baeca5..421d9e354 100644 --- a/src/formula/csl/Globally.h +++ b/src/formula/csl/Globally.h @@ -1,5 +1,5 @@ /* - * Next.h + * Globally.h * * Created on: 26.12.2012 * Author: Christian Dehnert @@ -16,37 +16,47 @@ namespace storm { namespace property { namespace csl { +// Forward declaration for the interface class. template <class T> class Globally; /*! - * @brief Interface class for model checkers that support Globally. + * Interface class for model checkers that support Globally. * - * All model checkers that support the formula class Globally must inherit - * this pure virtual class. + * All model checkers that support the formula class Globally must inherit + * this pure virtual class. */ template <class T> class IGloballyModelChecker { public: + /*! - * @brief Evaluates Globally formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ + * Empty virtual destructor. + */ + virtual ~IGloballyModelChecker() { + // Intentionally left empty + } + + /*! + * Evaluates a Globally formula within a model checker. + * + * @param obj Formula object with subformulas. + * @param qualitative A flag indicating whether the formula only needs to be evaluated qualitatively, i.e. if the + * results are only compared against the bounds 0 and 1. + * @return The modelchecking result of the formula for every state. + */ virtual std::vector<T> checkGlobally(const Globally<T>& obj, bool qualitative) const = 0; }; /*! - * @brief - * Class for an abstract (path) formula tree with a Globally node as root. + * Class for a Csl (path) formula tree with a Globally node as root. * - * Has one Abstract state formula as sub formula/tree. + * Has one Csl state formula as sub formula/tree. * * @par Semantics * The formula holds iff globally \e child holds. * - * The subtree is seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to nullptr before deletion) + * The object has shared ownership of its subtree. If this object is deleted and no other object has a shared + * ownership of the subtree it will be deleted as well. * * @see AbstractPathFormula * @see AbstractCslFormula @@ -57,26 +67,24 @@ class Globally : public AbstractPathFormula<T> { public: /*! - * Empty constructor + * Creates a Globally node without a subnode. + * The resulting object will not represent a complete formula! */ Globally() : child(nullptr){ // Intentionally left empty. } /*! - * Constructor + * Creates a Globally node using the given parameter. * - * @param child The child node + * @param child The child formula subtree. */ Globally(std::shared_ptr<AbstractStateFormula<T>> const & child) : child(child){ // Intentionally left empty. } /*! - * Constructor. - * - * Also deletes the subtree. - * (this behaviour can be prevented by setting the subtrees to nullptr before deletion) + * Empty virtual destructor. */ virtual ~Globally() { // Intentionally left empty. @@ -85,13 +93,13 @@ public: /*! * Clones the called object. * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. * - * @returns a new Globally-object that is identical the called object. + * @returns A new Globally object that is a deep copy of the called object. */ virtual std::shared_ptr<AbstractPathFormula<T>> clone() const override { std::shared_ptr<Globally<T>> result(new Globally<T>()); - if (this->childIsSet()) { + if (this->isChildSet()) { result->setChild(child->clone()); } return result; @@ -111,7 +119,9 @@ public: } /*! - * @returns a string representation of the formula + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. */ virtual std::string toString() const override { std::string result = "G "; @@ -120,29 +130,35 @@ public: } /*! - * @returns the child node + * Gets the child node. + * + * @returns The child node. */ AbstractStateFormula<T> const & getChild() const { return child; } /*! - * Sets the subtree - * @param child the new child node + * Sets the subtree. + * + * @param child The new child. */ void setChild(std::shared_ptr<AbstractStateFormula<T>> const & child) { this->child = child; } /*! + * Checks if the child is set, i.e. it does not point to null. * - * @return True if the child node is set, i.e. it does not point to nullptr; false otherwise + * @return True iff the child is set. */ - bool childIsSet() const { + bool isChildSet() const { return child.get() != nullptr; } private: + + // The child node. std::shared_ptr<AbstractStateFormula<T>> child; }; diff --git a/src/formula/csl/Next.h b/src/formula/csl/Next.h index 8c86095b8..478247de6 100644 --- a/src/formula/csl/Next.h +++ b/src/formula/csl/Next.h @@ -15,37 +15,47 @@ namespace storm { namespace property { namespace csl { +// Forward declaration for the interface class. template <class T> class Next; /*! - * @brief Interface class for model checkers that support Next. + * Interface class for model checkers that support Next. * - * All model checkers that support the formula class Next must inherit - * this pure virtual class. + * All model checkers that support the formula class Next must inherit + * this pure virtual class. */ template <class T> class INextModelChecker { public: + /*! - * @brief Evaluates Next formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ + * Empty virtual destructor. + */ + virtual ~INextModelChecker() { + // Intentionally left empty + } + + /*! + * Evaluates Next formula within a model checker. + * + * @param obj Formula object with subformulas. + * @param qualitative A flag indicating whether the formula only needs to be evaluated qualitatively, i.e. if the + * results are only compared against the bounds 0 and 1. + * @return Result of the formula for every node. + */ virtual std::vector<T> checkNext(const Next<T>& obj, bool qualitative) const = 0; }; /*! - * @brief - * Class for an abstract (path) formula tree with a Next node as root. + * Class for a Csl (path) formula tree with a Next node as root. * - * Has two Abstract state formulas as sub formulas/trees. + * Has two Csl state formulas as sub formulas/trees. * * @par Semantics * The formula holds iff in the next step, \e child holds * - * The subtree is seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) + * The object has shared ownership of its subtree. If this object is deleted and no other object has a shared + * ownership of the subtree it will be deleted as well. * * @see AbstractPathFormula * @see AbstractCslFormula @@ -56,26 +66,24 @@ class Next : public AbstractPathFormula<T> { public: /*! - * Empty constructor + * Creates a Next node without a subnode. + * The resulting object will not represent a complete formula! */ Next() : child(nullptr){ // Intentionally left empty. } /*! - * Constructor + * Creates a Next node using the given parameter. * - * @param child The child node + * @param child The child formula subtree. */ Next(std::shared_ptr<AbstractStateFormula<T>> const & child) : child(child) { // Intentionally left empty. } /*! - * Constructor. - * - * Also deletes the subtree. - * (this behavior can be prevented by setting the subtrees to NULL before deletion) + * Empty virtual destructor. */ virtual ~Next() { // Intetionally left empty. @@ -84,13 +92,13 @@ public: /*! * Clones the called object. * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. * - * @returns a new BoundedUntil-object that is identical the called object. + * @returns A new Next object that is a deep copy of the called object. */ virtual std::shared_ptr<AbstractPathFormula<T>> clone() const override { std::shared_ptr<Next<T>> result(new Next<T>()); - if (this->childIsSet()) { + if (this->isChildSet()) { result->setChild(child->clone()); } return result; @@ -110,7 +118,9 @@ public: } /*! - * @returns a string representation of the formula + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. */ virtual std::string toString() const override { std::string result = "X "; @@ -119,29 +129,35 @@ public: } /*! - * @returns the child node + * Gets the child node. + * + * @returns The child node. */ std::shared_ptr<AbstractStateFormula<T>> const & getChild() const { return child; } /*! - * Sets the subtree - * @param child the new child node + * Sets the subtree. + * + * @param child The new child. */ void setChild(std::shared_ptr<AbstractStateFormula<T>> const & child) { this->child = child; } /*! + * Checks if the child is set, i.e. it does not point to null. * - * @return True if the child node is set, i.e. it does not point to nullptr; false otherwise + * @return True iff the child is set. */ - bool childIsSet() const { + bool isChildSet() const { return child.get() != nullptr; } private: + + // The child node. std::shared_ptr<AbstractStateFormula<T>> child; }; diff --git a/src/formula/csl/Not.h b/src/formula/csl/Not.h index 9c23323ce..5e382893d 100644 --- a/src/formula/csl/Not.h +++ b/src/formula/csl/Not.h @@ -15,34 +15,42 @@ namespace storm { namespace property { namespace csl { +// Forward declaration for the interface class. template <class T> class Not; /*! - * @brief Interface class for model checkers that support Not. + * Interface class for model checkers that support Not. * - * All model checkers that support the formula class Not must inherit - * this pure virtual class. + * All model checkers that support the formula class Not must inherit + * this pure virtual class. */ template <class T> class INotModelChecker { public: + /*! - * @brief Evaluates Not formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ + * Empty virtual destructor. + */ + virtual ~INotModelChecker() { + // Intentionally left empty + } + + /*! + * Evaluates Not formulas within a model checker. + * + * @param obj Formula object with subformulas. + * @return Result of the formula for every node. + */ virtual storm::storage::BitVector checkNot(const Not<T>& obj) const = 0; }; /*! - * @brief - * Class for an abstract formula tree with NOT node as root. + * Class for a Csl formula tree with Not node as root. * - * Has one Abstract state formula as sub formula/tree. + * Has one Csl state formula as sub formula/tree. * - * The subtree is seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) + * The object has shared ownership of its subtree. If this object is deleted and no other object has a shared + * ownership of the subtree it will be deleted as well. * * @see AbstractStateFormula * @see AbstractCslFormula @@ -53,25 +61,24 @@ class Not : public AbstractStateFormula<T> { public: /*! - * Empty constructor + * Creates a Not node without a subnode. + * The resulting object will not represent a complete formula! */ Not() : child(nullptr) { // Intentionally left empty. } /*! - * Constructor - * @param child The child node + * Creates a Not node using the given parameter. + * + * @param child The child formula subtree. */ Not(std::shared_ptr<AbstractStateFormula<T>> const & child) : child(child) { // Intentionally left empty. } /*! - * Destructor - * - * Also deletes the subtree - * (this behavior can be prevented by setting them to NULL before deletion) + * Empty virtual destructor. */ virtual ~Not() { // Intentionally left empty. @@ -80,13 +87,13 @@ public: /*! * Clones the called object. * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. * - * @returns a new AND-object that is identical the called object. + * @returns A new Not object that is a deep copy of the called object. */ virtual std::shared_ptr<AbstractStateFormula<T>> clone() const override { std::shared_ptr<Not<T>> result(new Not<T>()); - if (this->childIsSet()) { + if (this->isChildSet()) { result->setChild(child->clone()); } return result; @@ -106,7 +113,9 @@ public: } /*! - * @returns a string representation of the formula + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. */ virtual std::string toString() const override { std::string result = "!"; @@ -124,29 +133,35 @@ public: } /*! - * @returns The child node + * Gets the child node. + * + * @returns The child node. */ std::shared_ptr<AbstractStateFormula<T>> const & getChild() const { return child; } /*! - * Sets the subtree - * @param child the new child node + * Sets the subtree. + * + * @param child The new child. */ void setChild(std::shared_ptr<AbstractStateFormula<T>> const & child) { this->child = child; } /*! + * Checks if the child is set, i.e. it does not point to null. * - * @return True if the child node is set, i.e. it does not point to nullptr; false otherwise + * @return True iff the child is set. */ - bool childIsSet() const { + bool isChildSet() const { return child.get() != nullptr; } private: + + // The child node. std::shared_ptr<AbstractStateFormula<T>> child; }; diff --git a/src/formula/csl/Or.h b/src/formula/csl/Or.h index b6017d4be..d1c1a795c 100644 --- a/src/formula/csl/Or.h +++ b/src/formula/csl/Or.h @@ -14,37 +14,45 @@ namespace storm { namespace property { namespace csl { +// Forward declaration for the interface class. template <class T> class Or; /*! - * @brief Interface class for model checkers that support Or. + * Interface class for model checkers that support Or. * - * All model checkers that support the formula class Or must inherit - * this pure virtual class. + * All model checkers that support the formula class Or must inherit + * this pure virtual class. */ template <class T> class IOrModelChecker { public: + /*! - * @brief Evaluates Or formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ + * Empty virtual destructor. + */ + virtual ~IOrModelChecker() { + // Intentionally left empty + } + + /*! + * Evaluates Or formula within a model checker. + * + * @param obj Formula object with subformulas. + * @return Result of the formula for every node. + */ virtual storm::storage::BitVector checkOr(const Or<T>& obj) const = 0; }; /*! - * @brief - * Class for an abstract formula tree with OR node as root. + * Class for an Csl formula tree with an Or node as root. * - * Has two Abstract state formulas as sub formulas/trees. + * Has two state formulas as sub formulas/trees. * - * As OR is commutative, the order is \e theoretically not important, but will influence the order in which + * As Or is commutative, the order is \e theoretically not important, but will influence the order in which * the model checker works. * - * The subtrees are seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) + * The object has shared ownership of its subtrees. If this object is deleted and no other object has a shared + * ownership of the subtrees they will be deleted as well. * * @see AbstractStateFormula * @see AbstractCslFormula @@ -55,47 +63,43 @@ class Or : public AbstractStateFormula<T> { public: /*! - * Empty constructor. - * Will create an OR-node without subnotes. Will not represent a complete formula! - */ - Or() : left(nullptr), right(nullptr) { - // Intentionally left empty. - } + * Creates an Or node without subnodes. + * The resulting object will not represent a complete formula! + */ + Or() : left(nullptr), right(nullptr) { + // Intentionally left empty. + } - /*! - * Constructor. - * Creates an OR note with the parameters as subtrees. - * - * @param left The left sub formula - * @param right The right sub formula - */ - Or(std::shared_ptr<AbstractStateFormula<T>> const & left, std::shared_ptr<AbstractStateFormula<T>> const & right) : left(left), right(right) { - // Intentionally left empty. - } + /*! + * Creates an Or node with the parameters as subtrees. + * + * @param left The left sub formula. + * @param right The right sub formula. + */ + Or(std::shared_ptr<AbstractStateFormula<T>> const & left, std::shared_ptr<AbstractStateFormula<T>> const & right) : left(left), right(right) { + // Intentionally left empty. + } - /*! - * Destructor. - * - * The subtrees are deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - */ - virtual ~Or() { - // Intentionally left empty. - } + /*! + * Empty virtual destructor. + */ + virtual ~Or() { + // Intentionally left empty. + } /*! * Clones the called object. * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones + * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones. * - * @returns a new AND-object that is identical the called object. + * @returns A new Or object that is a deep copy of the called object. */ virtual std::shared_ptr<AbstractStateFormula<T>> clone() const override { std::shared_ptr<Or<T>> result(new Or()); - if (this->leftIsSet()) { + if (this->isLeftSet()) { result->setLeft(left->clone()); } - if (this->rightIsSet()) { + if (this->isRightSet()) { result->setRight(right->clone()); } return result; @@ -115,7 +119,9 @@ public: } /*! - * @returns a string representation of the formula + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. */ virtual std::string toString() const override { std::string result = "("; @@ -136,55 +142,65 @@ public: } /*! - * Sets the left child node. + * Gets the left child node. * - * @param newLeft the new left child. + * @returns The left child node. */ - void setLeft(std::shared_ptr<AbstractStateFormula<T>> const & newLeft) { - left = newLeft; + std::shared_ptr<AbstractStateFormula<T>> const & getLeft() const { + return left; } /*! - * Sets the right child node. + * Gets the right child node. * - * @param newRight the new right child. + * @returns The right child node. */ - void setRight(std::shared_ptr<AbstractStateFormula<T>> const & newRight) { - right = newRight; + std::shared_ptr<AbstractStateFormula<T>> const & getRight() const { + return right; } /*! - * @returns a pointer to the left child node + * Sets the left child node. + * + * @param newLeft The new left child. */ - std::shared_ptr<AbstractStateFormula<T>> const & getLeft() const { - return left; + void setLeft(std::shared_ptr<AbstractStateFormula<T>> const & newLeft) { + left = newLeft; } /*! - * @returns a pointer to the right child node + * Sets the right child node. + * + * @param newRight The new right child. */ - std::shared_ptr<AbstractStateFormula<T>> const & getRight() const { - return right; + void setRight(std::shared_ptr<AbstractStateFormula<T>> const & newRight) { + right = newRight; } /*! + * Checks if the left child is set, i.e. it does not point to null. * - * @return True if the left child is set, i.e. it does not point to nullptr; false otherwise + * @return True iff the left child is set. */ - bool leftIsSet() const { + bool isLeftSet() const { return left.get() != nullptr; } /*! + * Checks if the right child is set, i.e. it does not point to null. * - * @return True if the right child is set, i.e. it does not point to nullptr; false otherwise + * @return True iff the left right is set. */ - bool rightIsSet() const { + bool isRightSet() const { return right.get() != nullptr; } private: + + // The left child node. std::shared_ptr<AbstractStateFormula<T>> left; + + // The right child node. std::shared_ptr<AbstractStateFormula<T>> right; }; diff --git a/src/formula/csl/ProbabilisticBoundOperator.h b/src/formula/csl/ProbabilisticBoundOperator.h index f0c51af72..a9adc4d6b 100644 --- a/src/formula/csl/ProbabilisticBoundOperator.h +++ b/src/formula/csl/ProbabilisticBoundOperator.h @@ -17,39 +17,49 @@ namespace storm { namespace property { namespace csl { +// Forward declaration for the interface class. template <class T> class ProbabilisticBoundOperator; /*! - * @brief Interface class for model checkers that support ProbabilisticBoundOperator. + * Interface class for model checkers that support ProbabilisticBoundOperator. * - * All model checkers that support the formula class PathBoundOperator must inherit - * this pure virtual class. + * All model checkers that support the formula class PathBoundOperator must inherit + * this pure virtual class. */ template <class T> class IProbabilisticBoundOperatorModelChecker { public: + + /*! + * Empty virtual destructor. + */ + virtual ~IProbabilisticBoundOperatorModelChecker() { + // Intentionally left empty + } + + /*! + * Evaluates a ProbabilisticBoundOperator within a model checker. + * + * @param obj Formula object with subformulas. + * @return The modelchecking result of the formula for every state. + */ virtual storm::storage::BitVector checkProbabilisticBoundOperator(const ProbabilisticBoundOperator<T>& obj) const = 0; }; /*! - * @brief - * Class for an abstract formula tree with a P (probablistic) operator node over a probability interval - * as root. + * Class for a Csl formula tree with a P (probablistic) bound operator node as root. * - * Has one Abstract path formula as sub formula/tree. + * Has one path formula as sub formula/tree. * * @par Semantics - * The formula holds iff the probability that the path formula holds is inside the bounds + * The formula holds iff the probability that the path formula holds meets the bound * specified in this operator * - * The subtree is seen as part of the object and deleted with it - * (this behavior can be prevented by setting them to NULL before deletion) - * + * The object has shared ownership of its subtree. If this object is deleted and no other object has a shared + * ownership of the subtree it will be deleted as well. * * @see AbstractStateFormula * @see AbstractPathFormula - * @see ProbabilisticOperator - * @see ProbabilisticNoBoundsOperator * @see AbstractCslFormula */ template<class T> @@ -58,18 +68,19 @@ class ProbabilisticBoundOperator : public AbstractStateFormula<T> { public: /*! - * Empty constructor + * Creates a ProbabilisticBoundOperator node without a subnode. + * The resulting object will not represent a complete formula! */ ProbabilisticBoundOperator() : comparisonOperator(LESS), bound(0), child(nullptr) { // Intentionally left empty. } /*! - * Constructor for non-optimizing operator. + * Creates a ProbabilisticBoundOperator node using the given parameters. * * @param comparisonOperator The relation for the bound. - * @param bound The bound for the probability - * @param child The child node + * @param bound The bound for the probability. + * @param child The child formula subtree. */ ProbabilisticBoundOperator(storm::property::ComparisonType comparisonOperator, T bound, std::shared_ptr<AbstractPathFormula<T>> const & child) : comparisonOperator(comparisonOperator), bound(bound), child(child) { @@ -77,10 +88,7 @@ public: } /*! - * Destructor - * - * The subtree is deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) + * Empty virtual destructor. */ virtual ~ProbabilisticBoundOperator() { // Intentionally left empty. @@ -89,9 +97,9 @@ public: /*! * Clones the called object. * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. * - * @returns a new AND-object that is identical the called object. + * @returns A new ProbabilisticBoundOperator object that is a deep copy of the called object. */ virtual std::shared_ptr<AbstractStateFormula<T>> clone() const override { std::shared_ptr<ProbabilisticBoundOperator<T>> result(new ProbabilisticBoundOperator<T>()); @@ -115,7 +123,9 @@ public: } /*! - * @returns a string representation of the formula + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. */ virtual std::string toString() const override { std::string result = "P "; @@ -134,56 +144,74 @@ public: } /*! - * @returns the child node (representation of a formula) + * Gets the child node. + * + * @returns The child node. */ std::shared_ptr<AbstractPathFormula<T>> const & getChild () const { return child; } /*! - * Sets the child node + * Sets the subtree. * - * @param child the path formula that becomes the new child node + * @param child The new child. */ void setChild(std::shared_ptr<AbstractPathFormula<T>> const & child) { this->child = child; } /*! + * Checks if the child is set, i.e. it does not point to null. * - * @return True if the path formula is set, i.e. it does not point to nullptr; false otherwise + * @return True iff the child is set. */ - bool childIsSet() const { + bool isChildSet() const { return child.get() != nullptr; } /*! - * @returns the comparison relation + * Gets the comparison operator. + * + * @returns An enum value representing the comparison relation. */ storm::property::ComparisonType const getComparisonOperator() const { return comparisonOperator; } + /*! + * Sets the comparison operator. + * + * @param comparisonOperator An enum value representing the new comparison relation. + */ void setComparisonOperator(storm::property::ComparisonType comparisonOperator) { this->comparisonOperator = comparisonOperator; } /*! - * @returns the bound for the measure + * Gets the bound which the probability that the path formula holds has to obey. + * + * @returns The probability bound. */ T const & getBound() const { return bound; } /*! - * Sets the interval in which the probability that the path formula holds may lie in. + * Sets the bound which the probability that the path formula holds has to obey. * - * @param bound The bound for the measure + * @param bound The new probability bound. */ void setBound(T const & bound) { this->bound = bound; } + /*! + * Checks if the bound is met by the given value. + * + * @param value The value to test against the bound. + * @returns True iff value <comparisonOperator> bound holds. + */ bool meetsBound(T const & value) const { switch (comparisonOperator) { case LESS: return value < bound; break; @@ -195,8 +223,14 @@ public: } private: + + // The operator used to indicate the kind of bound that is to be met. storm::property::ComparisonType comparisonOperator; + + // The probability bound. T bound; + + // The path formula for which the probability to be satisfied has to meet the bound. std::shared_ptr<AbstractPathFormula<T>> child; }; diff --git a/src/formula/csl/SteadyStateBoundOperator.h b/src/formula/csl/SteadyStateBoundOperator.h index 3c664f05a..4ca8a2cba 100644 --- a/src/formula/csl/SteadyStateBoundOperator.h +++ b/src/formula/csl/SteadyStateBoundOperator.h @@ -15,37 +15,45 @@ namespace storm { namespace property { namespace csl { +// Forward declaration for the interface class. template <class T> class SteadyStateBoundOperator; /*! - * @brief Interface class for model checkers that support SteadyStateOperator. + * Interface class for model checkers that support SteadyStateOperator. * - * All model checkers that support the formula class SteadyStateOperator must inherit - * this pure virtual class. + * All model checkers that support the formula class SteadyStateOperator must inherit + * this pure virtual class. */ template <class T> class ISteadyStateBoundOperatorModelChecker { public: + /*! - * @brief Evaluates SteadyStateOperator formula within a model checker. + * Empty virtual destructor. + */ + virtual ~ISteadyStateBoundOperatorModelChecker() { + // Intentionally left empty + } + + /*! + * Evaluates a SteadyStateOperator formula within a model checker. * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. + * @param obj Formula object with subformulas. + * @return The modelchecking result of the formula for every state. */ virtual storm::storage::BitVector checkSteadyStateBoundOperator(const SteadyStateBoundOperator<T>& obj) const = 0; }; /*! - * @brief - * Class for an Abstract (path) formula tree with a SteadyStateOperator node as root. + * Class for a Csl formula tree with a SteadyStateOperator node as root. * - * Has two Abstract state formulas as sub formulas/trees. + * Has two state formulas as sub formulas/trees. * * @par Semantics - * The formula holds iff \e child holds SteadyStateOperator step, \e child holds + * The formula holds iff the long-run probability of being in a state satisfying \e child meets the \e bound specified in this operator. * - * The subtree is seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) + * The object has shared ownership of its subtree. If this object is deleted and no other object has a shared + * ownership of the subtree it will be deleted as well. * * @see AbstractPathFormula * @see AbstractCslFormula @@ -56,29 +64,27 @@ class SteadyStateBoundOperator : public AbstractStateFormula<T> { public: /*! - * Empty constructor + * Creates a SteadyStateBoundOperator node without a subnode. + * The resulting object will not represent a complete formula! */ - SteadyStateBoundOperator() : comparisonOperator(LESS), bound(storm::utility::constantZero<T>()), stateFormula(nullptr) { + SteadyStateBoundOperator() : comparisonOperator(LESS), bound(storm::utility::constantZero<T>()), child(nullptr) { // Intentionally left empty } /*! - * Constructor + * Creates a SteadyStateBoundOperator node using the given parameters. * * @param comparisonOperator The relation for the bound. - * @param bound The bound for the probability - * @param stateFormula The child node + * @param bound The bound for the probability. + * @param child The child formula subtree. */ - SteadyStateBoundOperator(storm::property::ComparisonType comparisonOperator, T bound, std::shared_ptr<AbstractStateFormula<T>> const & stateFormula) - : comparisonOperator(comparisonOperator), bound(bound), stateFormula(stateFormula) { + SteadyStateBoundOperator(storm::property::ComparisonType comparisonOperator, T bound, std::shared_ptr<AbstractStateFormula<T>> const & child) + : comparisonOperator(comparisonOperator), bound(bound), child(child) { // Intentionally left empty } /*! - * Destructor - * - * The subtree is deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) + * Empty virtual destructor. */ virtual ~SteadyStateBoundOperator() { // Intentionally left empty. @@ -87,13 +93,13 @@ public: /*! * Clones the called object. * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. * - * @returns a new BoundedUntil-object that is identical the called object. + * @returns A new SteadyStateBoundOperator object that is a deep copy of the called object. */ virtual std::shared_ptr<AbstractStateFormula<T>> clone() const override { std::shared_ptr<SteadyStateBoundOperator<T>> result(new SteadyStateBoundOperator<T>()); - result->setStateFormula(stateFormula->clone()); + result->setChild(child->clone()); return result; } @@ -111,7 +117,9 @@ public: } /*! - * @returns a string representation of the formula + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. */ virtual std::string toString() const override { std::string result = "S "; @@ -123,62 +131,80 @@ public: } result += std::to_string(bound); result += " ("; - result += stateFormula->toString(); + result += child->toString(); result += ")"; return result; } /*! - * @returns the child node (representation of a formula) + * Gets the child node. + * + * @returns The child node. */ - std::shared_ptr<AbstractStateFormula<T>> const & getStateFormula () const { - return stateFormula; + std::shared_ptr<AbstractStateFormula<T>> const & getChild () const { + return child; } /*! - * Sets the child node + * Sets the subtree. * - * @param stateFormula the state formula that becomes the new child node + * @param child The new child. */ - void setStateFormula(std::shared_ptr<AbstractStateFormula<T>> const & stateFormula) { - this->stateFormula = stateFormula; + void setChild(std::shared_ptr<AbstractStateFormula<T>> const & child) { + this->child = child; } /*! + * Checks if the child is set, i.e. it does not point to null. * - * @return True if the state formula is set, i.e. it does not point to nullptr; false otherwise + * @return True iff the child is set. */ - bool stateFormulaIsSet() const { - return stateFormula.get() != nullptr; + bool isChildSet() const { + return child.get() != nullptr; } /*! - * @returns the comparison relation + * Gets the comparison operator. + * + * @returns An enum value representing the comparison relation. */ ComparisonType const getComparisonOperator() const { return comparisonOperator; } + /*! + * Sets the comparison operator. + * + * @param comparisonOperator An enum value representing the new comparison relation. + */ void setComparisonOperator(ComparisonType comparisonOperator) { this->comparisonOperator = comparisonOperator; } /*! - * @returns the bound for the measure + * Gets the bound which the steady state probability has to obey. + * + * @returns The probability bound. */ T const & getBound() const { return bound; } /*! - * Sets the interval in which the probability that the path formula holds may lie in. + * Sets the bound which the steady state probability has to obey. * - * @param bound The bound for the measure + * @param bound The new probability bound. */ void setBound(T const & bound) { this->bound = bound; } + /*! + * Checks if the bound is met by the given value. + * + * @param value The value to test against the bound. + * @returns True iff value <comparisonOperator> bound holds. + */ bool meetsBound(T value) const { switch (comparisonOperator) { case LESS: return value < bound; break; @@ -190,9 +216,15 @@ public: } private: + + // The operator used to indicate the kind of bound that is to be met. ComparisonType comparisonOperator; + + // The probability bound. T bound; - std::shared_ptr<AbstractStateFormula<T>> stateFormula; + + // The state formula for whose state the long-run probability has to meet the bound. + std::shared_ptr<AbstractStateFormula<T>> child; }; } //namespace csl diff --git a/src/formula/csl/TimeBoundedEventually.h b/src/formula/csl/TimeBoundedEventually.h index e4c6aa483..785a1677a 100644 --- a/src/formula/csl/TimeBoundedEventually.h +++ b/src/formula/csl/TimeBoundedEventually.h @@ -15,45 +15,77 @@ namespace storm { namespace property { namespace csl { +// Forward declaration for the interface class. template<class T> class TimeBoundedEventually; /*! - * @brief Interface class for model checkers that support TimeBoundedEventually. + * Interface class for model checkers that support TimeBoundedEventually. * - * All model checkers that support the formula class BoundedEventually must inherit - * this pure virtual class. + * All model checkers that support the formula class TimeBoundedEventually must inherit + * this pure virtual class. */ template <class T> class ITimeBoundedEventuallyModelChecker { public: + + /*! + * Empty virtual destructor. + */ + virtual ~ITimeBoundedEventuallyModelChecker() { + // Intentionally left empty + } + /*! - * @brief Evaluates TimeBoundedUntil formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ + * Evaluates a TimeBoundedEventually formula within a model checker. + * + * @param obj Formula object with subformulas. + * @param qualitative A flag indicating whether the formula only needs to be evaluated qualitatively, i.e. if the + * results are only compared against the bounds 0 and 1. + * @return The modelchecking result of the formula for every state. + */ virtual std::vector<T> checkTimeBoundedEventually(const TimeBoundedEventually<T>& obj, bool qualitative) const = 0; }; - +/*! + * Class for a Csl (path) formula tree with a TimeBoundedEventually node as root. + * + * Has one state formula as subformula/tree. + * + * @par Semantics + * The formula holds iff formula \e child holds within the given time interval [lowerBound, upperBound]. + * + * The object has shared ownership of its subtree. If this object is deleted and no other object has a shared + * ownership of the subtree it will be deleted as well. + * + * @see AbstractPathFormula + * @see AbstractCslFormula + */ template<class T> class TimeBoundedEventually: public AbstractPathFormula<T> { public: - /** - * Simple constructor: Only sets the bounds - * - * @param lowerBound - * @param upperBound + /*! + * Creates a TimeBoundedEventually node without a subnode. + * The resulting object will not represent a complete formula! */ - TimeBoundedEventually(T lowerBound, T upperBound) : child(nullptr) { - setInterval(lowerBound, upperBound); + TimeBoundedEventually() : lowerBound(0), upperBound(0), child(nullptr) { + // Intentionally left empty. } + /*! + * Creates a TimeBoundedEventually node using the given parameters. + * + * @param lowerBound The lower bound of the admissable time interval. + * @param upperBound The upper bound of the admissable time interval. + * @param child The child formula subtree. + */ TimeBoundedEventually(T lowerBound, T upperBound, std::shared_ptr<AbstractStateFormula<T>> const & child) : child(child) { setInterval(lowerBound, upperBound); } + /*! + * Empty virtual destructor. + */ virtual ~TimeBoundedEventually() { // Intentionally left empty. } @@ -61,13 +93,13 @@ public: /*! * Clones the called object. * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. * - * @returns a new BoundedUntil-object that is identical the called object. + * @returns A new TimeBoundedEventually object that is a deep copy of the called object. */ virtual std::shared_ptr<AbstractPathFormula<T>> clone() const override { std::shared_ptr<TimeBoundedEventually<T>> result(new TimeBoundedEventually<T>(lowerBound, upperBound)); - if (this->childIsSet()) { + if (this->isChildSet()) { result->setChild(child->clone()); } return result; @@ -87,7 +119,9 @@ public: } /*! - * @returns a string representation of the formula + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. */ virtual std::string toString() const override { std::string result = "F"; @@ -106,50 +140,55 @@ public: } /*! - * @returns the child node + * Gets the child node. + * + * @returns The child node. */ std::shared_ptr<AbstractStateFormula<T>> const & getChild() const { return child; } /*! - * Sets the subtree - * @param child the new child node + * Sets the subtree. + * + * @param child The new child. */ void setChild(std::shared_ptr<AbstractStateFormula<T>> const & child) { this->child = child; } /*! + * Checks if the child is set, i.e. it does not point to null. * - * @return True if the child is set, i.e. it does not point to nullptr; false otherwise + * @return True iff the child is set. */ - bool childIsSet() const { + bool isChildSet() const { return child.get() != nullptr; } - /** - * Getter for lowerBound attribute + /*! + * Get the lower time bound. * - * @return lower bound of the operator. + * @return The lower time bound. */ T const & getLowerBound() const { return lowerBound; } - /** - * Getter for upperBound attribute - * @return upper bound of the operator. + /*! + * Get the upper time bound. + * + * @return The upper time bound. */ T const & getUpperBound() const { return upperBound; } - /** - * Set the time interval for the time bounded operator + /*! + * Set the time interval for the time bounded operator. * - * @param lowerBound - * @param upperBound + * @param lowerBound The new lower time bound. + * @param upperBound The new upper time bound. * @throw InvalidArgumentException if the lower bound is larger than the upper bound. */ void setInterval(T lowerBound, T upperBound) { @@ -161,8 +200,15 @@ public: } private: + + // The child node. std::shared_ptr<AbstractStateFormula<T>> child; - T lowerBound, upperBound; + + // The lower time bound. + T lowerBound; + + // The upper time bound. + T upperBound; }; } /* namespace csl */ diff --git a/src/formula/csl/TimeBoundedUntil.h b/src/formula/csl/TimeBoundedUntil.h index 170ddf54a..5e27edd37 100644 --- a/src/formula/csl/TimeBoundedUntil.h +++ b/src/formula/csl/TimeBoundedUntil.h @@ -15,55 +15,78 @@ namespace storm { namespace property { namespace csl { +// Forward declaration for the interface class. template <class T> class TimeBoundedUntil; /*! - * @brief Interface class for model checkers that support TimeBoundedUntil. + * Interface class for model checkers that support TimeBoundedUntil. * - * All model checkers that support the formula class BoundedEventually must inherit - * this pure virtual class. + * All model checkers that support the formula class TimeBoundedUntil must inherit + * this pure virtual class. */ template <class T> class ITimeBoundedUntilModelChecker { public: + + /*! + * Empty virtual destructor. + */ + virtual ~ITimeBoundedUntilModelChecker() { + // Intentionally left empty + } + /*! - * @brief Evaluates TimeBoundedUntil formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ + * Evaluates a TimeBoundedUntil formula within a model checker. + * + * @param obj Formula object with subformulas. + * @param qualitative A flag indicating whether the formula only needs to be evaluated qualitatively, i.e. if the + * results are only compared against the bounds 0 and 1. + * @return The modelchecking result of the formula for every state. + */ virtual std::vector<T> checkTimeBoundedUntil(const TimeBoundedUntil<T>& obj, bool qualitative) const = 0; }; + +/*! + * Class for a Csl (path) formula tree with a TimeBoundedUntil node as root. + * + * Has two state formulas as subformulas/trees. + * + * @par Semantics + * The formula holds iff formula \e right holds within the given time interval [lowerBound, upperBound] and \e left holds + * in each point in time before that. + * + * The object has shared ownership of its subtree. If this object is deleted and no other object has a shared + * ownership of the subtree it will be deleted as well. + * + * @see AbstractPathFormula + * @see AbstractCslFormula + */ template <class T> class TimeBoundedUntil: public AbstractPathFormula<T> { public: - /** - * Constructor providing bounds only; - * Sub formulas are set to null. - * - * @param lowerBound - * @param upperBound + /*! + * Creates a TimeBoundedUntil node without a subnode. + * The resulting object will not represent a complete formula! */ - TimeBoundedUntil(T lowerBound, T upperBound) : left(nullptr), right(nullptr) { + TimeBoundedUntil() : lowerBound(0), upperBound(0), left(nullptr), right(nullptr) { setInterval(lowerBound, upperBound); } - - /** - * Full constructor - * @param lowerBound - * @param upperBound - * @param left - * @param right + /*! + * Creates a TimeBoundedUntil node using the given parameters. + * + * @param lowerBound The lower bound of the admissable time interval. + * @param upperBound The upper bound of the admissable time interval. + * @param child The child formula subtree. */ TimeBoundedUntil(T lowerBound, T upperBound, std::shared_ptr<AbstractStateFormula<T>> const & left, std::shared_ptr<AbstractStateFormula<T>> const & right) : left(left), right(right) { setInterval(lowerBound, upperBound); } /*! - * Destructor + * Empty virtual destructor. */ virtual ~TimeBoundedUntil() { // Intentionally left empty. @@ -72,16 +95,16 @@ public: /*! * Clones the called object. * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. * - * @returns a new BoundedUntil-object that is identical the called object. + * @returns A new TimeBoundedUntil object that is a deep copy of the called object. */ virtual std::shared_ptr<AbstractPathFormula<T>> clone() const override { std::shared_ptr<TimeBoundedUntil<T>> result(new TimeBoundedUntil<T>(lowerBound, upperBound)); - if (this->leftIsSet()) { + if (this->isLeftSet()) { result->setLeft(left->clone()); } - if (this->rightIsSet()) { + if (this->isRightSet()) { result->setRight(right->clone()); } return result; @@ -102,7 +125,9 @@ public: } /*! - * @returns a string representation of the formula + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. */ virtual std::string toString() const override { std::string result = left->toString(); @@ -122,65 +147,72 @@ public: } /*! - * Sets the left child node. + * Gets the left child node. * - * @param newLeft the new left child. + * @returns The left child node. */ - void setLeft(std::shared_ptr<AbstractStateFormula<T>> const & newLeft) { - left = newLeft; + std::shared_ptr<AbstractStateFormula<T>> const & getLeft() const { + return left; } /*! - * Sets the right child node. + * Gets the right child node. * - * @param newRight the new right child. + * @returns The right child node. */ - void setRight(std::shared_ptr<AbstractStateFormula<T>> const & newRight) { - right = newRight; + std::shared_ptr<AbstractStateFormula<T>> const & getRight() const { + return right; } /*! - * @returns a pointer to the left child node + * Sets the left child node. + * + * @param newLeft The new left child. */ - std::shared_ptr<AbstractStateFormula<T>> const & getLeft() const { - return left; + void setLeft(std::shared_ptr<AbstractStateFormula<T>> const & newLeft) { + left = newLeft; } /*! - * @returns a pointer to the right child node + * Sets the right child node. + * + * @param newRight The new right child. */ - std::shared_ptr<AbstractStateFormula<T>> const & getRight() const { - return right; + void setRight(std::shared_ptr<AbstractStateFormula<T>> const & newRight) { + right = newRight; } /*! + * Checks if the left child is set, i.e. it does not point to null. * - * @return True if the left child is set, i.e. it does not point to nullptr; false otherwise + * @return True iff the left child is set. */ - bool leftIsSet() const { + bool isLeftSet() const { return left.get() != nullptr; } /*! + * Checks if the right child is set, i.e. it does not point to null. * - * @return True if the right child is set, i.e. it does not point to nullptr; false otherwise + * @return True iff the right child is set. */ - bool rightIsSet() const { + bool isRightSet() const { return right.get() != nullptr; } - /** - * Getter for lowerBound attribute + /*! + * Get the lower time bound. * - * @return lower bound of the operator. + * @return The lower time bound. */ T const & getLowerBound() const { return lowerBound; } - /** - * Getter for upperBound attribute - * @return upper bound of the operator. + /*! + * Get the upper time bound. + * + * @return The upper time bound. */ T const & getUpperBound() const { return upperBound; @@ -189,8 +221,8 @@ public: /** * Set the time interval for the time bounded operator * - * @param lowerBound - * @param upperBound + * @param lowerBound The new lower time bound. + * @param upperBound The new upper time bound. * @throw InvalidArgumentException if the lower bound is larger than the upper bound. */ void setInterval(T lowerBound, T upperBound) { @@ -202,9 +234,18 @@ public: } private: + + // The left child node. std::shared_ptr<AbstractStateFormula<T>> left; + + // The right child node. std::shared_ptr<AbstractStateFormula<T>> right; - T lowerBound, upperBound; + + // The lower time bound. + T lowerBound; + + // The upper time bound. + T upperBound; }; } /* namespace csl */ diff --git a/src/formula/csl/Until.h b/src/formula/csl/Until.h index 8d2446489..8db1fa7d6 100644 --- a/src/formula/csl/Until.h +++ b/src/formula/csl/Until.h @@ -15,38 +15,49 @@ namespace storm { namespace property { namespace csl { +// Forward declaration for the interface class. template <class T> class Until; /*! - * @brief Interface class for model checkers that support Until. + * Interface class for model checkers that support Until. * - * All model checkers that support the formula class Until must inherit - * this pure virtual class. + * All model checkers that support the formula class Until must inherit + * this pure virtual class. */ template <class T> class IUntilModelChecker { public: + + /*! + * Empty virtual destructor. + */ + virtual ~IUntilModelChecker() { + // Intentionally left empty + } + /*! - * @brief Evaluates Until formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ + * Evaluates an Until formula within a model checker. + * + * @param obj Formula object with subformulas. + * @param qualitative A flag indicating whether the formula only needs to be evaluated qualitatively, i.e. if the + * results are only compared against the bounds 0 and 1. + * @return The modelchecking result of the formula for every state. + */ virtual std::vector<T> checkUntil(const Until<T>& obj, bool qualitative) const = 0; }; /*! * @brief - * Class for an abstract (path) formula tree with an Until node as root. + * Class for a Csl (path) formula tree with an Until node as root. * - * Has two Abstract state formulas as sub formulas/trees. + * Has two state formulas as sub formulas/trees. * * @par Semantics * The formula holds iff eventually, formula \e right (the right subtree) holds, and before, * \e left holds always. * - * The subtrees are seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) + * The object has shared ownership of its subtrees. If this object is deleted and no other object has a shared + * ownership of the subtrees they will be deleted as well. * * @see AbstractPathFormula * @see AbstractCslFormula @@ -55,28 +66,27 @@ template <class T> class Until : public AbstractPathFormula<T> { public: + /*! - * Empty constructor + * Creates an Until node without subnodes. + * The resulting object will not represent a complete formula! */ Until() : left(nullptr), right(nullptr){ // Intentionally left empty. } /*! - * Constructor + * Creates an Until node using the given parameters. * - * @param left The left formula subtree - * @param right The left formula subtree + * @param left The left formula subtree. + * @param right The right formula subtree. */ Until(std::shared_ptr<AbstractStateFormula<T>> const & left, std::shared_ptr<AbstractStateFormula<T>> const & right) : left(left), right(right){ // Intentionally left empty. } /*! - * Destructor. - * - * Also deletes the subtrees. - * (this behaviour can be prevented by setting the subtrees to NULL before deletion) + * Empty virtual destructor. */ virtual ~Until() { // Intentionally left empty. @@ -85,16 +95,16 @@ public: /*! * Clones the called object. * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. * - * @returns a new BoundedUntil-object that is identical the called object. + * @returns A new Until object that is a deep copy of the called object. */ virtual std::shared_ptr<AbstractPathFormula<T>> clone() const override { std::shared_ptr<Until<T>> result(new Until()); - if (this->leftIsSet()) { + if (this->isLeftSet()) { result->setLeft(left->clone()); } - if (this->rightIsSet()) { + if (this->isRightSet()) { result->setRight(left->clone()); } return result; @@ -114,7 +124,9 @@ public: } /*! - * @returns a string representation of the formula + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. */ virtual std::string toString() const override { std::string result = left->toString(); @@ -124,55 +136,65 @@ public: } /*! - * Sets the left child node. + * Gets the left child node. * - * @param newLeft the new left child. + * @returns The left child node. */ - void setLeft(std::shared_ptr<AbstractStateFormula<T>> const & newLeft) { - left = newLeft; + std::shared_ptr<AbstractStateFormula<T>> const & getLeft() const { + return left; } /*! - * Sets the right child node. + * Gets the right child node. * - * @param newRight the new right child. + * @returns The right child node. */ - void setRight(std::shared_ptr<AbstractStateFormula<T>> const & newRight) { - right = newRight; + std::shared_ptr<AbstractStateFormula<T>> const & getRight() const { + return right; } /*! - * @returns a pointer to the left child node + * Sets the left child node. + * + * @param newLeft The new left child. */ - std::shared_ptr<AbstractStateFormula<T>> const & getLeft() const { - return left; + void setLeft(std::shared_ptr<AbstractStateFormula<T>> const & newLeft) { + left = newLeft; } /*! - * @returns a pointer to the right child node + * Sets the right child node. + * + * @param newRight The new right child. */ - std::shared_ptr<AbstractStateFormula<T>> const & getRight() const { - return right; + void setRight(std::shared_ptr<AbstractStateFormula<T>> const & newRight) { + right = newRight; } /*! + * Checks if the left child is set, i.e. it does not point to null. * - * @return True if the left child is set, i.e. it does not point to nullptr; false otherwise + * @return True iff the left child is set. */ - bool leftIsSet() const { + bool isLeftSet() const { return left.get() != nullptr; } /*! + * Checks if the right child is set, i.e. it does not point to null. * - * @return True if the right child is set, i.e. it does not point to nullptr; false otherwise + * @return True iff the right child is set. */ - bool rightIsSet() const { + bool isRightSet() const { return right.get() != nullptr; } private: + + // The left child node. std::shared_ptr<AbstractStateFormula<T>> left; + + // The right child node. std::shared_ptr<AbstractStateFormula<T>> right; }; diff --git a/src/formula/ltl/AbstractLtlFormula.h b/src/formula/ltl/AbstractLtlFormula.h index 1c4ef1403..3605779be 100644 --- a/src/formula/ltl/AbstractLtlFormula.h +++ b/src/formula/ltl/AbstractLtlFormula.h @@ -17,18 +17,33 @@ namespace property { namespace ltl { /*! - * Interface class for all LTL root formulas. + * This is the abstract base class for all Ltl formulas. + * + * @note While formula classes do have copy constructors using a copy constructor + * will yield a formula objects whose formula subtree consists of the same objects + * as the original formula. The ownership of the formula tree will be shared between + * the original and the copy. */ template <class T> class AbstractLtlFormula : public virtual storm::property::AbstractFormula<T> { public: - /** - * Empty destructor + + /*! + * The virtual destructor. */ virtual ~AbstractLtlFormula() { // Intentionally left empty } + /*! + * Clones the called object. + * + * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones + * + * @returns A deep copy of the called object. + */ + virtual std::shared_ptr<AbstractLtlFormula<T>> clone() const = 0; + /*! * Calls the model checker to check this formula. * Needed to infer the correct type of formula class. @@ -41,15 +56,6 @@ public: * @returns A vector indicating the probability that the formula holds for each state. */ virtual std::vector<T> check(const storm::modelchecker::ltl::AbstractModelChecker<T>& modelChecker) const = 0; - - /*! - * Clones the called object. - * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones - * - * @returns a new AND-object that is identical the called object. - */ - virtual std::shared_ptr<AbstractLtlFormula<T>> clone() const = 0; }; } /* namespace ltl */ diff --git a/src/formula/ltl/And.h b/src/formula/ltl/And.h index 06fc83cae..67656ef9b 100644 --- a/src/formula/ltl/And.h +++ b/src/formula/ltl/And.h @@ -16,17 +16,26 @@ namespace storm { namespace property { namespace ltl { +// Forward declaration for the interface class. template <class T> class And; /*! - * @brief Interface class for model checkers that support And. + * Interface class for model checkers that support And. * - * All model checkers that support the formula class And must inherit - * this pure virtual class. + * All model checkers that support the formula class And must inherit + * this pure virtual class. */ template <class T> class IAndModelChecker { public: + + /*! + * Empty virtual destructor. + */ + virtual ~IAndModelChecker() { + // Intentionally left empty + } + /*! * @brief Evaluates And formula within a model checker. * @@ -37,16 +46,15 @@ class IAndModelChecker { }; /*! - * @brief - * Class for an abstract formula tree with AND node as root. + * Class for an Ltl formula tree with And node as root. * - * Has two Abstract LTL formulas as sub formulas/trees. + * Has two Ltl formulas as sub formulas/trees. * - * As AND is commutative, the order is \e theoretically not important, but will influence the order in which + * As And is commutative, the order is \e theoretically not important, but will influence the order in which * the model checker works. * - * The subtrees are seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) + * The object has shared ownership of its subtrees. If this object is deleted and no other object has a shared + * ownership of the subtrees they will be deleted as well. * * @see AbstractLtlFormula */ @@ -56,29 +64,25 @@ class And : public AbstractLtlFormula<T> { public: /*! - * Empty constructor. - * Will create an AND-node without subnotes. Will not represent a complete formula! + * Creates an And node without subnodes. + * The resulting object will not represent a complete formula! */ And() : left(nullptr), right(nullptr){ // Intentionally left empty. } /*! - * Constructor. - * Creates an AND note with the parameters as subtrees. + * Creates an And node with the parameters as subtrees. * - * @param left The left sub formula - * @param right The right sub formula + * @param left The left sub formula. + * @param right The right sub formula. */ And(std::shared_ptr<AbstractLtlFormula<T>> left, std::shared_ptr<AbstractLtlFormula<T>> right) : left(left), right(right) { // Intentionally left empty. } /*! - * Destructor. - * - * The subtrees are deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) + * Empty virtual destructor. */ virtual ~And() { // Intentionally left empty. @@ -87,16 +91,16 @@ public: /*! * Clones the called object. * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones + * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones. * - * @returns a new AND-object that is identical the called object. + * @returns A new And object that is a deep copy of the called object. */ virtual std::shared_ptr<AbstractLtlFormula<T>> clone() const override { std::shared_ptr<And<T>> result(new And()); - if (this->leftIsSet()) { + if (this->isLeftSet()) { result->setLeft(left->clone()); } - if (this->rightIsSet()) { + if (this->isRightSet()) { result->setRight(right->clone()); } return result; @@ -116,7 +120,9 @@ public: } /*! - * @returns a string representation of the formula + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. */ virtual std::string toString() const override { std::string result = "("; @@ -138,55 +144,65 @@ public: } /*! - * Sets the left child node. + * Gets the left child node. * - * @param newLeft the new left child. + * @returns The left child node. */ - void setLeft(std::shared_ptr<AbstractLtlFormula<T>> const & newLeft) { - left = newLeft; + std::shared_ptr<AbstractLtlFormula<T>> const & getLeft() const { + return left; } /*! - * Sets the right child node. + * Gets the right child node. * - * @param newRight the new right child. + * @returns The right child node. */ - void setRight(std::shared_ptr<AbstractLtlFormula<T>> const & newRight) { - right = newRight; + std::shared_ptr<AbstractLtlFormula<T>> const & getRight() const { + return right; } /*! - * @returns a pointer to the left child node + * Sets the left child node. + * + * @param newLeft The new left child. */ - std::shared_ptr<AbstractLtlFormula<T>> const & getLeft() const { - return left; + void setLeft(std::shared_ptr<AbstractLtlFormula<T>> const & newLeft) { + left = newLeft; } /*! - * @returns a pointer to the right child node + * Sets the right child node. + * + * @param newRight The new right child. */ - std::shared_ptr<AbstractLtlFormula<T>> const & getRight() const { - return right; + void setRight(std::shared_ptr<AbstractLtlFormula<T>> const & newRight) { + right = newRight; } /*! + * Checks if the left child is set, i.e. it does not point to null. * - * @return True if the left child is set, i.e. it does not point to nullptr; false otherwise + * @return True iff the left child is set. */ - bool leftIsSet() const { + bool isLeftSet() const { return left.get() != nullptr; } /*! + * Checks if the right child is set, i.e. it does not point to null. * - * @return True if the right child is set, i.e. it does not point to nullptr; false otherwise + * @return True iff the right child is set. */ - bool rightIsSet() const { + bool isRightSet() const { return right.get() != nullptr; } private: + + // The left child node. std::shared_ptr<AbstractLtlFormula<T>> left; + + // The right child node. std::shared_ptr<AbstractLtlFormula<T>> right; }; diff --git a/src/formula/ltl/Ap.h b/src/formula/ltl/Ap.h index 451dadb99..544d84ed5 100644 --- a/src/formula/ltl/Ap.h +++ b/src/formula/ltl/Ap.h @@ -14,29 +14,37 @@ namespace storm { namespace property { namespace ltl { +// Forward declaration for the interface class. template <class T> class Ap; /*! - * @brief Interface class for model checkers that support And. + * Interface class for model checkers that support Ap. * - * All model checkers that support the formula class And must inherit - * this pure virtual class. + * All model checkers that support the formula class Ap must inherit + * this pure virtual class. */ template <class T> class IApModelChecker { public: + + /*! + * Empty virtual destructor. + */ + virtual ~IApModelChecker() { + // Intentionally left empty + } + /*! - * @brief Evaluates And formula within a model checker. + * Evaluates an Ap formula within a model checker. * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. + * @param obj Formula object with subformulas. + * @return The modelchecking result of the formula for every state. */ virtual std::vector<T> checkAp(const Ap<T>& obj) const = 0; }; /*! - * @brief - * Class for an abstract formula tree with atomic proposition as root. + * Class for an Ltl formula tree with an atomic proposition as root. * * This class represents the leaves in the formula tree. * @@ -44,33 +52,37 @@ class IApModelChecker { */ template <class T> class Ap: public storm::property::ltl::AbstractLtlFormula<T> { + public: - /*! - * Empty constructor - */ - Ap() { - // Intentionally left empty - } /*! - * Constructor - * - * Creates a new atomic proposition leaf, with the label Ap + * Creates a new atomic proposition leaf, with the given label. * - * @param ap The string representing the atomic proposition + * @param ap A string representing the atomic proposition. */ Ap(std::string ap) : ap(ap) { // Intentionally left empty. } /*! - * Destructor - * At this time, empty... + * Empty virtual destructor. */ virtual ~Ap() { // Intentionally left empty } + /*! + * Clones the called object. + * + * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones. + * + * @returns A new Ap object that is a deep copy of the called object. + */ + virtual std::shared_ptr<AbstractLtlFormula<T>> clone() const override { + auto result = std::make_shared<Ap<T>>(this->getAp()); + return result; + } + /*! * Calls the model checker to check this formula. * Needed to infer the correct type of formula class. @@ -78,8 +90,6 @@ public: * @note This function should only be called in a generic check function of a model checker class. For other uses, * the methods of the model checker should be used. * - * @note This function is not implemented in this class. - * * @returns A vector indicating the probability that the formula holds for each state. */ virtual std::vector<T> check(const storm::modelchecker::ltl::AbstractModelChecker<T>& modelChecker) const override { @@ -87,20 +97,9 @@ public: } /*! - * Clones the called object. - * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones - * - * @returns a new AND-object that is identical the called object. - */ - virtual std::shared_ptr<AbstractLtlFormula<T>> clone() const override { - std::shared_ptr<AbstractLtlFormula<T>> result(new Ap(this->getAp())); - return result; - } - - /*! - * @returns a string representation of the leaf. + * A string representing the atomic proposition. * + * @returns A string representing the leaf. */ virtual std::string toString() const override { return getAp(); @@ -117,13 +116,17 @@ public: } /*! - * @returns the name of the atomic proposition + * Gets the name of the atomic proposition. + * + * @returns The name of the atomic proposition. */ std::string const & getAp() const { return ap; } private: + + // The atomic proposition referenced by this leaf. std::string ap; }; diff --git a/src/formula/ltl/BoundedEventually.h b/src/formula/ltl/BoundedEventually.h index 630e0bbae..57027cea3 100644 --- a/src/formula/ltl/BoundedEventually.h +++ b/src/formula/ltl/BoundedEventually.h @@ -17,37 +17,45 @@ namespace storm { namespace property { namespace ltl { +// Forward declaration for the interface class. template <class T> class BoundedEventually; /*! - * @brief Interface class for model checkers that support BoundedEventually. + * Interface class for model checkers that support BoundedEventually. * - * All model checkers that support the formula class BoundedEventually must inherit - * this pure virtual class. + * All model checkers that support the formula class BoundedEventually must inherit + * this pure virtual class. */ template <class T> class IBoundedEventuallyModelChecker { public: + + /*! + * Empty virtual destructor. + */ + virtual ~IBoundedEventuallyModelChecker() { + // Intentionally left empty + } + /*! - * @brief Evaluates BoundedEventually formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ + * Evaluates a BoundedEventually formula within a model checker. + * + * @param obj Formula object with subformulas. + * @return The modelchecking result of the formula for every state. + */ virtual std::vector<T> checkBoundedEventually(const BoundedEventually<T>& obj) const = 0; }; /*! - * @brief - * Class for an abstract (path) formula tree with a BoundedEventually node as root. + * Class for a Ltl formula tree with a BoundedEventually node as root. * - * Has one Abstract LTL formulas as sub formula/tree. + * Has one Ltl formula as subformula/tree. * * @par Semantics * The formula holds iff in at most \e bound steps, formula \e child holds. * - * The subtrees are seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) + * The object has shared ownership of its subtree. If this object is deleted and no other object has a shared + * ownership of the subtree it will be deleted as well. * * @see AbstractLtlFormula */ @@ -57,27 +65,25 @@ class BoundedEventually : public AbstractLtlFormula<T> { public: /*! - * Empty constructor + * Creates a BoundedEventually node without a subnode. + * The resulting object will not represent a complete formula! */ BoundedEventually() : child(nullptr), bound(0) { // Intentionally left empty. } /*! - * Constructor + * Creates a BoundedEventually node using the given parameters. * - * @param child The child formula subtree - * @param bound The maximal number of steps + * @param child The child formula subtree. + * @param bound The maximal number of steps within which the subformula must hold. */ BoundedEventually(std::shared_ptr<AbstractLtlFormula<T>> child, uint_fast64_t bound) : child(child), bound(bound) { // Intentionally left empty. } /*! - * Destructor. - * - * Also deletes the subtrees. - * (this behaviour can be prevented by setting the subtrees to NULL before deletion) + * Empty virtual destructor. */ virtual ~BoundedEventually() { // Intentionally left empty. @@ -87,14 +93,14 @@ public: /*! * Clones the called object. * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. * - * @returns a new BoundedUntil-object that is identical the called object. + * @returns A new BoundedEventually object that is a deep copy of the called object. */ virtual std::shared_ptr<AbstractLtlFormula<T>> clone() const override { std::shared_ptr<BoundedEventually<T>> result(new BoundedEventually<T>()); result->setBound(bound); - if (this->childIsSet()) { + if (this->isChildSet()) { result->setChild(child->clone()); } return result; @@ -115,7 +121,9 @@ public: } /*! - * @returns a string representation of the formula + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. */ virtual std::string toString() const override { std::string result = "F<="; @@ -126,39 +134,45 @@ public: } /*! - * @returns the child node + * Gets the child node. + * + * @returns The child node. */ std::shared_ptr<AbstractLtlFormula<T>> const & getChild() const { return child; } /*! - * Sets the subtree - * @param child the new child node + * Sets the subtree. + * + * @param child The new child. */ void setChild(std::shared_ptr<AbstractLtlFormula<T>> const & child) { this->child = child; } /*! + * Checks if the child is set, i.e. it does not point to null. * - * @return True if the child is set, i.e. it does not point to nullptr; false otherwise + * @return True iff the child is set. */ - bool childIsSet() const { + bool isChildSet() const { return child.get() != nullptr; } /*! - * @returns the maximally allowed number of steps for the bounded until operator + * Gets the maximally allowed number of steps for the bounded eventually operator. + * + * @returns The bound. */ uint_fast64_t getBound() const { return bound; } /*! - * Sets the maximally allowed number of steps for the bounded until operator + * Sets the maximally allowed number of steps for the bounded eventually operator. * - * @param bound the new bound. + * @param bound The new bound. */ void setBound(uint_fast64_t bound) { this->bound = bound; @@ -166,7 +180,11 @@ public: private: + + // The child node. std::shared_ptr<AbstractLtlFormula<T>> child; + + // The maximal number of steps within which the subformula must hold. uint_fast64_t bound; }; diff --git a/src/formula/ltl/BoundedUntil.h b/src/formula/ltl/BoundedUntil.h index 87e0a7a2d..748e3ae0e 100644 --- a/src/formula/ltl/BoundedUntil.h +++ b/src/formula/ltl/BoundedUntil.h @@ -17,38 +17,46 @@ namespace storm { namespace property { namespace ltl { +// Forward declaration for the interface class. template <class T> class BoundedUntil; /*! - * @brief Interface class for model checkers that support BoundedUntil. + * Interface class for model checkers that support BoundedUntil. * - * All model checkers that support the formula class BoundedUntil must inherit - * this pure virtual class. + * All model checkers that support the formula class BoundedUntil must inherit + * this pure virtual class. */ template <class T> class IBoundedUntilModelChecker { public: + + /*! + * Empty virtual destructor. + */ + virtual ~IBoundedUntilModelChecker() { + // Intentionally left empty + } + /*! - * @brief Evaluates BoundedUntil formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ + * Evaluates a BoundedUntil formula within a model checker. + * + * @param obj Formula object with subformulas. + * @return The modelchecking result of the formula for every state. + */ virtual std::vector<T> checkBoundedUntil(const BoundedUntil<T>& obj) const = 0; }; /*! - * @brief - * Class for an abstract (path) formula tree with a BoundedUntil node as root. + * Class for an Ltl formula tree with a BoundedUntil node as root. * - * Has two Abstract LTL formulas as sub formulas/trees. + * Has two Ltl formulas as sub formulas/trees. * * @par Semantics * The formula holds iff in at most \e bound steps, formula \e right (the right subtree) holds, and before, * \e left holds. * - * The subtrees are seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) + * The object has shared ownership of its subtrees. If this object is deleted and no other object has a shared + * ownership of the subtrees they will be deleted as well. * * @see AbstractLtlFormula */ @@ -58,28 +66,26 @@ class BoundedUntil : public AbstractLtlFormula<T> { public: /*! - * Empty constructor + * Creates a BoundedUntil node without subnodes. + * The resulting object will not represent a complete formula! */ BoundedUntil() : left(nullptr), right(nullptr), bound(0) { // Intentionally left empty. } /*! - * Constructor + * Creates a BoundedUntil node using the given parameters. * - * @param left The left formula subtree - * @param right The left formula subtree - * @param bound The maximal number of steps + * @param left The left formula subtree. + * @param right The right formula subtree. + * @param bound The maximal number of steps within which the right subformula must hold. */ BoundedUntil(std::shared_ptr<AbstractLtlFormula<T>> const & left, std::shared_ptr<AbstractLtlFormula<T>> const & right, uint_fast64_t bound) : left(left), right(right), bound(bound) { // Intentionally left empty. } /*! - * Destructor. - * - * Also deletes the subtrees. - * (this behaviour can be prevented by setting the subtrees to NULL before deletion) + * Empty virtual destructor. */ virtual ~BoundedUntil() { // Intentionally left empty. @@ -88,17 +94,17 @@ public: /*! * Clones the called object. * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. * - * @returns a new BoundedUntil-object that is identical the called object. + * @returns A new BoundedUntil object that is a deep copy of the called object. */ virtual std::shared_ptr<AbstractLtlFormula<T>> clone() const override { std::shared_ptr<BoundedUntil<T>> result(new BoundedUntil<T>()); result->setBound(bound); - if (this->leftIsSet()) { + if (this->isLeftSet()) { result->setLeft(left->clone()); } - if (this->rightIsSet()) { + if (this->isRightSet()) { result->setRight(right->clone()); } return result; @@ -119,12 +125,9 @@ public: } /*! - * @brief Return string representation of this formula. - * - * In LTL, brackets are needed around the until, as Until may appear nested (in other logics, Until always is the - * root of a path formula); hence this function is overwritten in this class. + * Returns a textual representation of the formula tree with this node as root. * - * @return A string representation of the formula. + * @returns A string representing the formula tree. */ virtual std::string toString() const override { std::string result = "(" + left->toString(); @@ -136,72 +139,86 @@ public: } /*! - * Sets the left child node. + * Gets the left child node. * - * @param newLeft the new left child. + * @returns The left child node. */ - void setLeft(std::shared_ptr<AbstractLtlFormula<T>> const & newLeft) { - left = newLeft; + std::shared_ptr<AbstractLtlFormula<T>> const & getLeft() const { + return left; } /*! - * Sets the right child node. + * Gets the right child node. * - * @param newRight the new right child. + * @returns The right child node. */ - void setRight(std::shared_ptr<AbstractLtlFormula<T>> const & newRight) { - right = newRight; + std::shared_ptr<AbstractLtlFormula<T>> const & getRight() const { + return right; } /*! - * @returns a pointer to the left child node + * Sets the left child node. + * + * @param newLeft The new left child. */ - std::shared_ptr<AbstractLtlFormula<T>> const & getLeft() const { - return left; + void setLeft(std::shared_ptr<AbstractLtlFormula<T>> const & newLeft) { + left = newLeft; } /*! - * @returns a pointer to the right child node + * Sets the right child node. + * + * @param newRight The new right child. */ - std::shared_ptr<AbstractLtlFormula<T>> const & getRight() const { - return right; + void setRight(std::shared_ptr<AbstractLtlFormula<T>> const & newRight) { + right = newRight; } /*! + * Checks if the left child is set, i.e. it does not point to null. * - * @return True if the left child is set, i.e. it does not point to nullptr; false otherwise + * @return True iff the left child is set. */ - bool leftIsSet() const { + bool isLeftSet() const { return left.get() != nullptr; } /*! + * Checks if the right child is set, i.e. it does not point to null. * - * @return True if the right child is set, i.e. it does not point to nullptr; false otherwise + * @return True iff the right child is set. */ - bool rightIsSet() const { + bool isRightSet() const { return right.get() != nullptr; } /*! - * @returns the maximally allowed number of steps for the bounded until operator + * Gets the maximally allowed number of steps for the bounded until operator. + * + * @returns The bound. */ uint_fast64_t getBound() const { return bound; } /*! - * Sets the maximally allowed number of steps for the bounded until operator + * Sets the maximally allowed number of steps for the bounded until operator. * - * @param bound the new bound. + * @param bound The new bound. */ void setBound(uint_fast64_t bound) { this->bound = bound; } private: + + // The left child node. std::shared_ptr<AbstractLtlFormula<T>> left; + + // The right child node. std::shared_ptr<AbstractLtlFormula<T>> right; + + // The maximal number of steps within which the subformulas must hold. uint_fast64_t bound; }; diff --git a/src/formula/ltl/Eventually.h b/src/formula/ltl/Eventually.h index 328fd993b..9af8ad9b2 100644 --- a/src/formula/ltl/Eventually.h +++ b/src/formula/ltl/Eventually.h @@ -1,5 +1,5 @@ /* - * Next.h + * Eventually.h * * Created on: 26.12.2012 * Author: Christian Dehnert @@ -15,37 +15,45 @@ namespace storm { namespace property { namespace ltl { +// Forward declaration for the interface class. template <class T> class Eventually; /*! - * @brief Interface class for model checkers that support Eventually. + * Interface class for model checkers that support Eventually. * - * All model checkers that support the formula class Eventually must inherit - * this pure virtual class. + * All model checkers that support the formula class Eventually must inherit + * this pure virtual class. */ template <class T> class IEventuallyModelChecker { public: + /*! - * @brief Evaluates Eventually formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ + * Empty virtual destructor. + */ + virtual ~IEventuallyModelChecker() { + // Intentionally left empty. + } + + /*! + * Evaluates an Eventually formula within a model checker. + * + * @param obj Formula object with subformulas. + * @return The modelchecking result of the formula for every state. + */ virtual std::vector<T> checkEventually(const Eventually<T>& obj) const = 0; }; /*! - * @brief - * Class for an abstract (path) formula tree with an Eventually node as root. + * Class for an Ltl formula tree with an Eventually node as root. * - * Has one Abstract LTL formula as sub formula/tree. + * Has one Abstract Ltl formula as sub formula/tree. * * @par Semantics * The formula holds iff eventually \e child holds. * - * The subtree is seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to nullptr before deletion) + * The object has shared ownership of its subtree. If this object is deleted and no other object has a shared + * ownership of the subtree it will be deleted as well. * * @see AbstractLtlFormula */ @@ -55,26 +63,24 @@ class Eventually : public AbstractLtlFormula<T> { public: /*! - * Empty constructor + * Creates an Eventually node without a subnode. + * The resulting object will not represent a complete formula! */ Eventually() : child(nullptr) { // Intentionally left empty. } /*! - * Constructor + * Creates an Eventually node using the given parameter. * - * @param child The child node + * @param child The child formula subtree. */ Eventually(std::shared_ptr<AbstractLtlFormula<T>> const & child) : child(child) { // Intentionally left empty. } /*! - * Constructor. - * - * Also deletes the subtree. - * (this behaviour can be prevented by setting the subtrees to nullptr before deletion) + * Empty virtual destructor. */ virtual ~Eventually() { // Intentionally left empty. @@ -83,13 +89,13 @@ public: /*! * Clones the called object. * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. * - * @returns a new Eventually-object that is identical the called object. + * @returns A new Eventually object that is a deep copy of the called object. */ virtual std::shared_ptr<AbstractLtlFormula<T>> clone() const override { std::shared_ptr<Eventually<T>> result(new Eventually<T>()); - if (this->childIsSet()) { + if (this->isChildSet()) { result->setChild(child->clone()); } return result; @@ -109,7 +115,9 @@ public: } /*! - * @returns a string representation of the formula + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. */ virtual std::string toString() const override { std::string result = "F "; @@ -118,29 +126,35 @@ public: } /*! - * @returns the child node + * Gets the child node. + * + * @returns The child node. */ std::shared_ptr<AbstractLtlFormula<T>> const & getChild() const { return child; } /*! - * Sets the subtree - * @param child the new child node + * Sets the subtree. + * + * @param child The new child. */ void setChild(std::shared_ptr<AbstractLtlFormula<T>> const & child) { this->child = child; } /*! + * Checks if the child is set, i.e. it does not point to null. * - * @return True if the child node is set, i.e. it does not point to nullptr; false otherwise + * @return True iff the child is set. */ - bool childIsSet() const { + bool isChildSet() const { return child.get() != nullptr; } private: + + // The child node. std::shared_ptr<AbstractLtlFormula<T>> child; }; diff --git a/src/formula/ltl/Globally.h b/src/formula/ltl/Globally.h index 060b5bba2..0e0af887a 100644 --- a/src/formula/ltl/Globally.h +++ b/src/formula/ltl/Globally.h @@ -1,5 +1,5 @@ /* - * Next.h + * Globally.h * * Created on: 26.12.2012 * Author: Christian Dehnert @@ -15,37 +15,45 @@ namespace storm { namespace property { namespace ltl { +// Forward declaration for the interface class. template <class T> class Globally; /*! - * @brief Interface class for model checkers that support Globally. + * Interface class for model checkers that support Globally. * - * All model checkers that support the formula class Globally must inherit - * this pure virtual class. + * All model checkers that support the formula class Globally must inherit + * this pure virtual class. */ template <class T> class IGloballyModelChecker { public: + /*! - * @brief Evaluates Globally formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ + * Empty virtual destructor. + */ + virtual ~IGloballyModelChecker() { + // Intentionally left empty + } + + /*! + * Evaluates a Globally formula within a model checker. + * + * @param obj Formula object with subformulas. + * @return The modelchecking result of the formula for every state. + */ virtual std::vector<T> checkGlobally(const Globally<T>& obj) const = 0; }; /*! - * @brief - * Class for an abstract (path) formula tree with a Globally node as root. + * Class for an Ltl formula tree with a Globally node as root. * - * Has one Abstract LTL formula as sub formula/tree. + * Has one Ltl formula as sub formula/tree. * * @par Semantics - * The formula holds iff globally \e child holds. + * The formula holds iff always formula \e child holds. * - * The subtree is seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to nullptr before deletion) + * The object has shared ownership of its subtree. If this object is deleted and no other object has a shared + * ownership of the subtree it will be deleted as well. * * @see AbstractLtlFormula */ @@ -55,26 +63,24 @@ class Globally : public AbstractLtlFormula<T> { public: /*! - * Empty constructor + * Creates a Globally node without a subnode. + * The resulting object will not represent a complete formula! */ Globally() : child(nullptr) { // Intentionally left empty. } /*! - * Constructor + * Creates a Globally node using the given parameter. * - * @param child The child node + * @param child The child formula subtree. */ Globally(std::shared_ptr<AbstractLtlFormula<T>> const & child) : child(child) { // Intentionally left empty. } /*! - * Constructor. - * - * Also deletes the subtree. - * (this behaviour can be prevented by setting the subtrees to nullptr before deletion) + * Empty virtual destructor. */ virtual ~Globally() { // Intentionally left empty. @@ -83,13 +89,13 @@ public: /*! * Clones the called object. * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. * - * @returns a new Globally-object that is identical the called object. + * @returns A new Globally object that is a deep copy of the called object. */ virtual std::shared_ptr<AbstractLtlFormula<T>> clone() const override { std::shared_ptr<Globally<T>> result(new Globally<T>()); - if (this->childIsSet()) { + if (this->isChildSet()) { result->setChild(child->clone()); } return result; @@ -109,7 +115,9 @@ public: } /*! - * @returns a string representation of the formula + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. */ virtual std::string toString() const override { std::string result = "G "; @@ -118,30 +126,36 @@ public: } /*! - * @returns the child node + * Gets the child node. + * + * @returns The child node. */ std::shared_ptr<AbstractLtlFormula<T>> const & getChild() const { return *child; } /*! - * Sets the subtree - * @param child the new child node + * Sets the subtree. + * + * @param child The new child. */ void setChild(std::shared_ptr<AbstractLtlFormula<T>> const & child) { this->child = child; } /*! + * Checks if the child is set, i.e. it does not point to null. * - * @return True if the child node is set, i.e. it does not point to nullptr; false otherwise + * @return True iff the child is set. */ - bool childIsSet() const { + bool isChildSet() const { return child.get() != nullptr; } - private: - std::shared_ptr<AbstractLtlFormula<T>> child; +private: + + // The child node. + std::shared_ptr<AbstractLtlFormula<T>> child; }; } //namespace ltl diff --git a/src/formula/ltl/LtlFilter.h b/src/formula/ltl/LtlFilter.h index 9f876bd8c..4b7704b10 100644 --- a/src/formula/ltl/LtlFilter.h +++ b/src/formula/ltl/LtlFilter.h @@ -14,51 +14,85 @@ #include "src/formula/actions/AbstractAction.h" #include "src/exceptions/NotImplementedException.h" -namespace storm { -namespace property { -namespace action { - template <typename T> class AbstractAction; -} -} -} - namespace storm { namespace property { namespace ltl { +/*! + * This is the Ltl specific filter. + * + * It maintains a Ltl formula which can be checked against a given model by either calling evaluate() or check(). + * Additionally it maintains a list of filter actions that are used to further manipulate the modelchecking results and prepare them for output. + */ template <class T> class LtlFilter : public storm::property::AbstractFilter<T> { + // Convenience typedef to make the code more readable. typedef typename storm::property::action::AbstractAction<T>::Result Result; public: + /*! + * Creates an empty LtlFilter, maintaining no Ltl formula. + * + * Calling check or evaluate will return an empty result. + */ LtlFilter() : AbstractFilter<T>(UNDEFINED), child(nullptr) { // Intentionally left empty. } + /*! + * Creates an LtlFilter maintaining an Ltl formula but containing no actions. + * + * The modelchecking result will be returned or printed as is. + * + * @param child The Ltl formula to be maintained. + * @param opt An enum value indicating which kind of scheduler shall be used for path formulas on nondeterministic models. + */ LtlFilter(std::shared_ptr<AbstractLtlFormula<T>> const & child, OptimizingOperator opt = UNDEFINED) : AbstractFilter<T>(opt), child(child) { // Intentionally left empty. } + /*! + * Creates an LtlFilter maintaining a Ltl formula and containing a single action. + * + * The given action will be applied to the modelchecking result during evaluation. + * Further actions can be added later. + * + * @param child The Ltl formula to be maintained. + * @param action The single action to be executed during evaluation. + * @param opt An enum value indicating which kind of scheduler shall be used for path formulas on nondeterministic models. + */ LtlFilter(std::shared_ptr<AbstractLtlFormula<T>> const & child, std::shared_ptr<action::AbstractAction<T>> const & action, OptimizingOperator opt = UNDEFINED) : AbstractFilter<T>(action, opt), child(child) { // Intentionally left empty. } + /*! + * Creates an LtlFilter using the given parameters. + * + * The given actions will be applied to the modelchecking result in ascending index order during evaluation. + * Further actions can be added later. + * + * @param child The Ltl formula to be maintained. + * @param actions A vector conatining the actions that are to be executed during evaluation. + * @param opt An enum value indicating which kind of scheduler shall be used for path formulas on nondeterministic models. + */ LtlFilter(std::shared_ptr<AbstractLtlFormula<T>> const & child, std::vector<std::shared_ptr<action::AbstractAction<T>>> const & actions, OptimizingOperator opt = UNDEFINED) : AbstractFilter<T>(actions, opt), child(child) { // Intentionally left empty. } + /*! + * Empty virtual destructor. + */ virtual ~LtlFilter() { // Intentionally left empty. } - /*!Description copied from the MC. - * Checks the given state formula on the model and prints the result (true/false) for all initial states, i.e. - * states that carry the atomic proposition "init". + /*! + * Calls the modelchecker, retrieves the modelchecking result, applies the filter action one by one and prints out the result. * - * @param stateFormula The formula to be checked. + * @param modelchecker The modelchecker to be called. */ void check(storm::modelchecker::ltl::AbstractModelChecker<T> const & modelchecker) const { @@ -83,6 +117,12 @@ public: } + /*! + * Calls the modelchecker, retrieves the modelchecking result, applies the filter action one by one and returns the result. + * + * @param modelchecker The modelchecker to be called. + * @returns The result of the sequential application of the filter actions to the modelchecking result. + */ Result evaluate(storm::modelchecker::ltl::AbstractModelChecker<T> const & modelchecker) const { // First, get the model checking result. Result result; @@ -112,6 +152,13 @@ public: return result; } + /*! + * Returns a textual representation of the filter. + * + * That includes the actions as well as the maintained formula. + * + * @returns A string representing the filter. + */ std::string toString() const override { std::string desc = ""; @@ -151,26 +198,41 @@ public: return desc; } - virtual std::string toPrettyString() const override { - std::string desc = "Filter: "; - desc += "\nActions:"; - for(auto action : this->actions) { - desc += "\n\t" + action->toString(); - } - desc += "\nFormula:\n\t" + child->toString(); - return desc; + /*! + * Gets the child node. + * + * @returns The child node. + */ + std::shared_ptr<AbstractLtlFormula<T>> const & getChild() const { + return child; } + /*! + * Sets the subtree. + * + * @param child The new child. + */ void setChild(std::shared_ptr<AbstractLtlFormula<T>> const & child) { this->child = child; } - std::shared_ptr<AbstractLtlFormula<T>> const & getChild() const { - return child; + /*! + * Checks if the child is set, i.e. it does not point to null. + * + * @return True iff the child is set. + */ + bool isChildSet() const { + return child.get() != nullptr; } private: + /*! + * Writes out the given result. + * + * @param result The result of the sequential application of the filter actions to a modelchecking result. + * @param modelchecker The modelchecker that was called to generate the modelchecking result. Needed for legacy support. + */ void writeOut(Result const & result, storm::modelchecker::ltl::AbstractModelChecker<T> const & modelchecker) const { // Test for the kind of result. Values or states. @@ -207,6 +269,7 @@ private: std::cout << std::endl << "-------------------------------------------" << std::endl; } + // The Ltl formula maintained by this filter. std::shared_ptr<AbstractLtlFormula<T>> child; }; diff --git a/src/formula/ltl/Next.h b/src/formula/ltl/Next.h index a038252c2..0eb64a2ed 100644 --- a/src/formula/ltl/Next.h +++ b/src/formula/ltl/Next.h @@ -14,37 +14,45 @@ namespace storm { namespace property { namespace ltl { +// Forward declaration for the interface class. template <class T> class Next; /*! - * @brief Interface class for model checkers that support Next. + * Interface class for model checkers that support Next. * - * All model checkers that support the formula class Next must inherit - * this pure virtual class. + * All model checkers that support the formula class Next must inherit + * this pure virtual class. */ template <class T> class INextModelChecker { public: + /*! - * @brief Evaluates Next formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ + * Empty virtual destructor. + */ + virtual ~INextModelChecker() { + // Intentionally left empty + } + + /*! + * Evaluates Next formula within a model checker. + * + * @param obj Formula object with subformulas. + * @return Result of the formula for every node. + */ virtual std::vector<T> checkNext(const Next<T>& obj) const = 0; }; /*! - * @brief - * Class for an abstract (path) formula tree with a Next node as root. + * Class for an Ltl formula tree with a Next node as root. * - * Has two Abstract LTL formulas as sub formulas/trees. + * Has two LTL formulas as sub formulas/trees. * * @par Semantics - * The formula holds iff in the next step, \e child holds + * The formula holds iff in the next step, formula \e child holds * - * The subtree is seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) + * The object has shared ownership of its subtree. If this object is deleted and no other object has a shared + * ownership of the subtree it will be deleted as well. * * @see AbstractLtlFormula */ @@ -54,26 +62,24 @@ class Next : public AbstractLtlFormula<T> { public: /*! - * Empty constructor + * Creates a Next node without a subnode. + * The resulting object will not represent a complete formula! */ Next() : child(nullptr) { // Intentionally left empty. } /*! - * Constructor + * Creates a Next node using the given parameter. * - * @param child The child node + * @param child The child formula subtree. */ Next(std::shared_ptr<AbstractLtlFormula<T>> const & child) : child(child) { // Intentionally left empty. } /*! - * Constructor. - * - * Also deletes the subtree. - * (this behaviour can be prevented by setting the subtrees to NULL before deletion) + * Empty virtual destructor. */ virtual ~Next() { // Intentionally left empty. @@ -82,13 +88,13 @@ public: /*! * Clones the called object. * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. * - * @returns a new BoundedUntil-object that is identical the called object. + * @returns A new Next object that is a deep copy of the called object. */ virtual std::shared_ptr<AbstractLtlFormula<T>> clone() const override { std::shared_ptr<Next<T>> result(new Next<T>()); - if (this->childIsSet()) { + if (this->isChildSet()) { result->setChild(child->clone()); } return result; @@ -108,7 +114,9 @@ public: } /*! - * @returns a string representation of the formula + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. */ virtual std::string toString() const override { std::string result = "X "; @@ -117,29 +125,35 @@ public: } /*! - * @returns the child node + * Gets the child node. + * + * @returns The child node. */ std::shared_ptr<AbstractLtlFormula<T>> const & getChild() const { return child; } /*! - * Sets the subtree - * @param child the new child node + * Sets the subtree. + * + * @param child The new child. */ void setChild(std::shared_ptr<AbstractLtlFormula<T>> const & child) { this->child = child; } /*! + * Checks if the child is set, i.e. it does not point to null. * - * @return True if the child node is set, i.e. it does not point to nullptr; false otherwise + * @return True iff the child is set. */ - bool childIsSet() const { + bool isChildSet() const { return child.get() != nullptr; } private: + + // The child node. std::shared_ptr<AbstractLtlFormula<T>> child; }; diff --git a/src/formula/ltl/Not.h b/src/formula/ltl/Not.h index 2538298a4..cd1edd251 100644 --- a/src/formula/ltl/Not.h +++ b/src/formula/ltl/Not.h @@ -14,34 +14,42 @@ namespace storm { namespace property { namespace ltl { +// Forward declaration for the interface class. template <class T> class Not; /*! - * @brief Interface class for model checkers that support Not. + * Interface class for model checkers that support Not. * - * All model checkers that support the formula class Not must inherit - * this pure virtual class. + * All model checkers that support the formula class Not must inherit + * this pure virtual class. */ template <class T> class INotModelChecker { public: + /*! - * @brief Evaluates Not formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ + * Empty virtual destructor. + */ + virtual ~INotModelChecker() { + // Intentionally left empty + } + + /*! + * Evaluates Not formula within a model checker. + * + * @param obj Formula object with subformulas. + * @return Result of the formula for every node. + */ virtual std::vector<T> checkNot(const Not<T>& obj) const = 0; }; /*! - * @brief - * Class for an abstract formula tree with NOT node as root. + * Class for an Ltl formula tree with a Not node as root. * - * Has one Abstract LTL formula as sub formula/tree. + * Has one Ltl formula as sub formula/tree. * - * The subtree is seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) + * The object has shared ownership of its subtree. If this object is deleted and no other object has a shared + * ownership of the subtree it will be deleted as well. * * @see AbstractLtlFormula */ @@ -51,25 +59,24 @@ class Not : public AbstractLtlFormula<T> { public: /*! - * Empty constructor + * Creates a Not node without a subnode. + * The resulting object will not represent a complete formula! */ Not() : child(nullptr) { // Intentionally left empty. } /*! - * Constructor - * @param child The child node + * Creates a Not node using the given parameter. + * + * @param child The child formula subtree. */ Not(std::shared_ptr<AbstractLtlFormula<T>> const & child) : child(child) { // Intentionally left empty. } /*! - * Destructor - * - * Also deletes the subtree - * (this behavior can be prevented by setting them to NULL before deletion) + * Empty virtual destructor. */ virtual ~Not() { // Intentionally left empty. @@ -78,13 +85,13 @@ public: /*! * Clones the called object. * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. * - * @returns a new AND-object that is identical the called object. + * @returns A new Not object that is a deep copy of the called object. */ virtual std::shared_ptr<AbstractLtlFormula<T>> clone() const override { std::shared_ptr<Not<T>> result(new Not<T>()); - if (this->childIsSet()) { + if (this->isChildSet()) { result->setChild(child->clone()); } return result; @@ -104,7 +111,9 @@ public: } /*! - * @returns a string representation of the formula + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. */ virtual std::string toString() const override { std::string result = "!"; @@ -123,29 +132,35 @@ public: } /*! - * @returns The child node + * Gets the child node. + * + * @returns The child node. */ std::shared_ptr<AbstractLtlFormula<T>> const & getChild() const { return child; } /*! - * Sets the subtree - * @param child the new child node + * Sets the subtree. + * + * @param child The new child. */ void setChild(std::shared_ptr<AbstractLtlFormula<T>> const & child) { this->child = child; } /*! + * Checks if the child is set, i.e. it does not point to null. * - * @return True if the child node is set, i.e. it does not point to nullptr; false otherwise + * @return True iff the child is set. */ - bool childIsSet() const { + bool isChildSet() const { return child.get() != nullptr; } private: + + // The child node. std::shared_ptr<AbstractLtlFormula<T>> child; }; diff --git a/src/formula/ltl/Or.h b/src/formula/ltl/Or.h index 42296766f..a7c73a1f1 100644 --- a/src/formula/ltl/Or.h +++ b/src/formula/ltl/Or.h @@ -14,37 +14,45 @@ namespace storm { namespace property { namespace ltl { +// Forward declaration for the interface class. template <class T> class Or; /*! - * @brief Interface class for model checkers that support And. + * Interface class for model checkers that support Or. * - * All model checkers that support the formula class And must inherit - * this pure virtual class. + * All model checkers that support the formula class Or must inherit + * this pure virtual class. */ template <class T> class IOrModelChecker { public: + + /*! + * Empty virtual destructor. + */ + virtual ~IOrModelChecker() { + // Intentionally left empty + } + /*! - * @brief Evaluates And formula within a model checker. + * Evaluates Or formula within a model checker. * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. + * @param obj Formula object with subformulas. + * @return Result of the formula for every node. */ virtual std::vector<T> checkOr(const Or<T>& obj) const = 0; }; /*! - * @brief - * Class for an abstract formula tree with OR node as root. + * Class for an abstract formula tree with an Or node as root. * - * Has two LTL formulas as sub formulas/trees. + * Has two Ltl formulas as sub formulas/trees. * - * As OR is commutative, the order is \e theoretically not important, but will influence the order in which + * As Or is commutative, the order is \e theoretically not important, but will influence the order in which * the model checker works. * - * The subtrees are seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) + * The object has shared ownership of its subtrees. If this object is deleted and no other object has a shared + * ownership of the subtrees they will be deleted as well. * * @see AbstractLtlFormula */ @@ -54,29 +62,25 @@ class Or: public storm::property::ltl::AbstractLtlFormula<T> { public: /*! - * Empty constructor. - * Will create an AND-node without subnotes. Will not represent a complete formula! + * Creates an Or node without subnodes. + * The resulting object will not represent a complete formula! */ Or() : left(nullptr), right(nullptr) { // Intentionally left empty. } /*! - * Constructor. - * Creates an AND note with the parameters as subtrees. + * Creates an Or node with the parameters as subtrees. * - * @param left The left sub formula - * @param right The right sub formula + * @param left The left sub formula. + * @param right The right sub formula. */ Or(std::shared_ptr<AbstractLtlFormula<T>> const & left, std::shared_ptr<AbstractLtlFormula<T>> const & right) : left(left), right(right) { // Intentionally left empty. } /*! - * Destructor. - * - * The subtrees are deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) + * Empty virtual destructor. */ virtual ~Or() { // Intentionally left empty. @@ -85,16 +89,16 @@ public: /*! * Clones the called object. * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones + * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones. * - * @returns a new AND-object that is identical the called object. + * @returns A new Or object that is a deep copy of the called object. */ virtual std::shared_ptr<AbstractLtlFormula<T>> clone() const override { std::shared_ptr<Or<T>> result(new Or<T>()); - if (this->leftIsSet()) { + if (this->isLeftSet()) { result->setLeft(left->clone()); } - if (this->rightIsSet()) { + if (this->isRightSet()) { result->setRight(right->clone()); } return result; @@ -114,7 +118,9 @@ public: } /*! - * @returns a string representation of the formula + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. */ virtual std::string toString() const override { std::string result = "("; @@ -136,55 +142,65 @@ public: } /*! - * Sets the left child node. + * Gets the left child node. * - * @param newLeft the new left child. + * @returns The left child node. */ - void setLeft(std::shared_ptr<AbstractLtlFormula<T>> const & newLeft) { - left = newLeft; + std::shared_ptr<AbstractLtlFormula<T>> const & getLeft() const { + return left; } /*! - * Sets the right child node. + * Gets the right child node. * - * @param newRight the new right child. + * @returns The right child node. */ - void setRight(std::shared_ptr<AbstractLtlFormula<T>> const & newRight) { - right = newRight; + std::shared_ptr<AbstractLtlFormula<T>> const & getRight() const { + return right; } /*! - * @returns a pointer to the left child node + * Sets the left child node. + * + * @param newLeft The new left child. */ - std::shared_ptr<AbstractLtlFormula<T>> const & getLeft() const { - return left; + void setLeft(std::shared_ptr<AbstractLtlFormula<T>> const & newLeft) { + left = newLeft; } /*! - * @returns a pointer to the right child node + * Sets the right child node. + * + * @param newRight The new right child. */ - std::shared_ptr<AbstractLtlFormula<T>> const & getRight() const { - return right; + void setRight(std::shared_ptr<AbstractLtlFormula<T>> const & newRight) { + right = newRight; } /*! + * Checks if the left child is set, i.e. it does not point to null. * - * @return True if the left child is set, i.e. it does not point to nullptr; false otherwise + * @return True iff the left child is set. */ - bool leftIsSet() const { + bool isLeftSet() const { return left.get() != nullptr; } /*! + * Checks if the right child is set, i.e. it does not point to null. * - * @return True if the right child is set, i.e. it does not point to nullptr; false otherwise + * @return True iff the left right is set. */ - bool rightIsSet() const { + bool isRightSet() const { return right.get() != nullptr; } private: + + // The left child node. std::shared_ptr<AbstractLtlFormula<T>> left; + + // The right child node. std::shared_ptr<AbstractLtlFormula<T>> right; }; diff --git a/src/formula/ltl/Until.h b/src/formula/ltl/Until.h index 92a6e4ed1..56301c0f4 100644 --- a/src/formula/ltl/Until.h +++ b/src/formula/ltl/Until.h @@ -14,56 +14,46 @@ namespace storm { namespace property { namespace ltl { +// Forward declaration for the interface class. template <class T> class Until; /*! - * @brief Interface class for model checkers that support Until. + * Interface class for model checkers that support Until. * - * All model checkers that support the formula class Until must inherit - * this pure virtual class. + * All model checkers that support the formula class Until must inherit + * this pure virtual class. */ template <class T> class IUntilModelChecker { public: + /*! - * @brief Evaluates Until formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual std::vector<T> checkUntil(const Until<T>& obj) const = 0; -}; + * Empty virtual destructor. + */ + virtual ~IUntilModelChecker() { + // Intentionally left empty + } -/*! - * @brief Interface class for visitors that support Until. - * - * All visitors that support the formula class Until must inherit - * this pure virtual class. - */ -template <class T> -class IUntilVisitor { - public: /*! - * @brief Visits Until formula. + * Evaluates an Until formula within a model checker. * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. + * @param obj Formula object with subformulas. + * @return The modelchecking result of the formula for every state. */ - virtual void visitUntil(const Until<T>& obj) = 0; + virtual std::vector<T> checkUntil(const Until<T>& obj) const = 0; }; /*! - * @brief - * Class for an abstract (path) formula tree with an Until node as root. + * Class for an Ltl formula tree with an Until node as root. * - * Has two Abstract LTL formulas as sub formulas/trees. + * Has two Ltl formulas as sub formulas/trees. * * @par Semantics * The formula holds iff eventually, formula \e right (the right subtree) holds, and before, * \e left holds always. * - * The subtrees are seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) + * The object has shared ownership of its subtrees. If this object is deleted and no other object has a shared + * ownership of the subtrees they will be deleted as well. * * @see AbstractLtlFormula */ @@ -73,27 +63,25 @@ class Until : public AbstractLtlFormula<T> { public: /*! - * Empty constructor + * Creates an Until node without subnodes. + * The resulting object will not represent a complete formula! */ - Until() : left(left), right(right) { + Until() : left(nullptr), right(nullptr) { // Intentionally left empty. } /*! - * Constructor + * Creates an Until node using the given parameters. * - * @param left The left formula subtree - * @param right The left formula subtree + * @param left The left formula subtree. + * @param right The right formula subtree. */ Until(std::shared_ptr<AbstractLtlFormula<T>> const & left, std::shared_ptr<AbstractLtlFormula<T>> const & right) : left(left), right(right) { // Intentionally left empty. } /*! - * Destructor. - * - * Also deletes the subtrees. - * (this behaviour can be prevented by setting the subtrees to NULL before deletion) + * Empty virtual destructor. */ virtual ~Until() { // Intentionally left empty. @@ -102,16 +90,16 @@ public: /*! * Clones the called object. * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. * - * @returns a new BoundedUntil-object that is identical the called object. + * @returns A new Until object that is a deep copy of the called object. */ virtual std::shared_ptr<AbstractLtlFormula<T>> clone() const override { std::shared_ptr<Until<T>> result(new Until<T>()); - if (this->leftIsSet()) { + if (this->isLeftSet()) { result->setLeft(left->clone()); } - if (this->rightIsSet()) { + if (this->isRightSet()) { result->setRight(right->clone()); } return result; @@ -131,12 +119,9 @@ public: } /*! - * @brief Return string representation of this formula. - * - * In LTL, brackets are needed around the until, as Until may appear nested (in other logics, Until always is the - * root of a path formula); hence this function is overwritten in this class. + * Returns a textual representation of the formula tree with this node as root. * - * @return A string representation of the formula. + * @returns A string representing the formula tree. */ virtual std::string toString() const { std::string result = "(" + left->toString(); @@ -146,55 +131,65 @@ public: } /*! - * Sets the left child node. + * Gets the left child node. * - * @param newLeft the new left child. + * @returns The left child node. */ - void setLeft(std::shared_ptr<AbstractLtlFormula<T>> const & newLeft) { - left = newLeft; + std::shared_ptr<AbstractLtlFormula<T>> const & getLeft() const { + return left; } /*! - * Sets the right child node. + * Gets the right child node. * - * @param newRight the new right child. + * @returns The right child node. */ - void setRight(std::shared_ptr<AbstractLtlFormula<T>> const & newRight) { - right = newRight; + std::shared_ptr<AbstractLtlFormula<T>> const & getRight() const { + return right; } /*! - * @returns a pointer to the left child node + * Sets the left child node. + * + * @param newLeft The new left child. */ - std::shared_ptr<AbstractLtlFormula<T>> const & getLeft() const { - return left; + void setLeft(std::shared_ptr<AbstractLtlFormula<T>> const & newLeft) { + left = newLeft; } /*! - * @returns a pointer to the right child node + * Sets the right child node. + * + * @param newRight The new right child. */ - std::shared_ptr<AbstractLtlFormula<T>> const & getRight() const { - return right; + void setRight(std::shared_ptr<AbstractLtlFormula<T>> const & newRight) { + right = newRight; } /*! + * Checks if the left child is set, i.e. it does not point to null. * - * @return True if the left child is set, i.e. it does not point to nullptr; false otherwise + * @return True iff the left child is set. */ - bool leftIsSet() const { + bool isLeftSet() const { return left.get() != nullptr; } /*! + * Checks if the right child is set, i.e. it does not point to null. * - * @return True if the right child is set, i.e. it does not point to nullptr; false otherwise + * @return True iff the right child is set. */ - bool rightIsSet() const { + bool isRightSet() const { return right.get() != nullptr; } private: + + // The left child node. std::shared_ptr<AbstractLtlFormula<T>> left; + + // The right child node. std::shared_ptr<AbstractLtlFormula<T>> right; }; diff --git a/src/formula/prctl/AbstractPathFormula.h b/src/formula/prctl/AbstractPathFormula.h index f8cb686b6..1caf60297 100644 --- a/src/formula/prctl/AbstractPathFormula.h +++ b/src/formula/prctl/AbstractPathFormula.h @@ -20,13 +20,7 @@ namespace property { namespace prctl { /*! - * @brief - * Abstract base class for Abstract path formulas. - * - * @attention This class is abstract. - * @note Formula classes do not have copy constructors. The parameters of the constructors are usually the subtrees, so - * the syntax conflicts with copy constructors for unary operators. To produce an identical object, use the method - * clone(). + * Abstract base class for Prctl path formulas. * * @note Differing from the formal definitions of PRCTL a path formula may be the root of a PRCTL formula. * The result of a modelchecking process on such a formula is a vector representing the satisfaction probabilities for each state of the model. @@ -35,8 +29,9 @@ template <class T> class AbstractPathFormula : public virtual storm::property::prctl::AbstractPrctlFormula<T> { public: + /*! - * empty destructor + * The virtual destructor. */ virtual ~AbstractPathFormula() { // Intentionally left empty @@ -45,10 +40,11 @@ public: /*! * Clones the called object. * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones + * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones. * * @note This function is not implemented in this class. - * @returns a new AND-object that is identical the called object. + * + * @returns A deep copy of the called object. */ virtual std::shared_ptr<AbstractPathFormula<T>> clone() const = 0; diff --git a/src/formula/prctl/AbstractPrctlFormula.h b/src/formula/prctl/AbstractPrctlFormula.h index f728110fe..e7b165afa 100644 --- a/src/formula/prctl/AbstractPrctlFormula.h +++ b/src/formula/prctl/AbstractPrctlFormula.h @@ -14,6 +14,8 @@ namespace storm { namespace property { namespace prctl { +// Forward declarations. + template <class T> class ProbabilisticBoundOperator; template <class T> class Eventually; template <class T> class Until; @@ -27,22 +29,32 @@ namespace property { namespace prctl { /*! - * Interface class for all PRCTL root formulas. + * This is the abstract base class for all Prctl formulas. + * + * @note While formula classes do have copy constructors using a copy constructor + * will yield a formula objects whose formula subtree consists of the same objects + * as the original formula. The ownership of the formula tree will be shared between + * the original and the copy. */ template<class T> class AbstractPrctlFormula : public virtual storm::property::AbstractFormula<T> { public: + + /*! + * The virtual destructor. + */ virtual ~AbstractPrctlFormula() { // Intentionally left empty } - /*! Returns whether the formula is a probabilistic bound reachability formula. - * Returns true iff the formula conforms to the following pattern. - * Pattern: P[<,<=,>,>=]p ([psi U, E] phi) whith psi, phi propositional logic formulas (consisiting only of And, Or, Not and AP). - * That is, a probabilistic bound operator as root with a single until or eventually formula directly below it, whose subformulas are propositional - * (denoting some set of atomic propositions). + /*! + * Checks whether the formula is a probabilistic bound reachability formula. + * Returns true iff the formula conforms to the following pattern. + * Pattern: P[<,<=,>,>=]p ([psi U, E] phi) whith psi, phi propositional logic formulas (consisiting only of And, Or, Not and AP). + * That is, a probabilistic bound operator as root with a single until or eventually formula directly below it, whose subformulas are propositional + * (denoting some set of atomic propositions). * - * @return True iff this is a probabilistic bound reachability formula. + * @return True iff this is a probabilistic bound reachability formula. */ bool isProbEventuallyAP() const { diff --git a/src/formula/prctl/AbstractRewardPathFormula.h b/src/formula/prctl/AbstractRewardPathFormula.h index 949ecc422..09d0dcbf2 100644 --- a/src/formula/prctl/AbstractRewardPathFormula.h +++ b/src/formula/prctl/AbstractRewardPathFormula.h @@ -14,16 +14,21 @@ namespace storm { namespace property { namespace prctl { -/*! Base class for reward path formulas. +/*! + * Abstract base class for Prctl reward path formulas. * - * Reward path formulas are subformulas of reward bound operators. - * They may not be subformulas of a probabilitic bound operator. + * Reward path formulas may not be subformulas of a probabilitic bound operator, as they describe rewards along paths not probabilities. * + * @note Differing from the formal definitions of PRCTL a reward path formula may be the root of a PRCTL formula. + * The result of a modelchecking process on such a formula is a vector representing the rewards for each state of the model. + * + * @see AbstractPrctlFormula */ template <class T> class AbstractRewardPathFormula : public virtual storm::property::prctl::AbstractPrctlFormula<T> { public: + /*! * Empty virtual destructor. */ @@ -37,7 +42,8 @@ public: * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones * * @note This function is not implemented in this class. - * @returns a new AND-object that is identical the called object. + * + * @returns A deep copy of the called object. */ virtual std::shared_ptr<AbstractRewardPathFormula<T>> clone() const = 0; diff --git a/src/formula/prctl/AbstractStateFormula.h b/src/formula/prctl/AbstractStateFormula.h index d07c169a8..2da8c093b 100644 --- a/src/formula/prctl/AbstractStateFormula.h +++ b/src/formula/prctl/AbstractStateFormula.h @@ -17,20 +17,15 @@ namespace property { namespace prctl { /*! - * @brief - * Abstract base class for Abstract state formulas. - * - * @attention This class is abstract. - * @note Formula classes do not have copy constructors. The parameters of the constructors are usually the subtrees, so - * the syntax conflicts with copy constructors for unary operators. To produce an identical object, use the method - * clone(). + * Abstract base class for Prctl state formulas. */ template <class T> class AbstractStateFormula : public storm::property::prctl::AbstractPrctlFormula<T> { public: + /*! - * empty destructor + * Empty virtual destructor. */ virtual ~AbstractStateFormula() { // Intentionally left empty @@ -42,7 +37,8 @@ public: * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones * * @note This function is not implemented in this class. - * @returns a new AND-object that is identical the called object. + * + * @returns A deep copy of the called object. */ virtual std::shared_ptr<AbstractStateFormula<T>> clone() const = 0; diff --git a/src/formula/prctl/And.h b/src/formula/prctl/And.h index 81b33ad28..c312f30c5 100644 --- a/src/formula/prctl/And.h +++ b/src/formula/prctl/And.h @@ -16,37 +16,45 @@ namespace storm { namespace property { namespace prctl { +// Forward declaration for the interface class. template <class T> class And; /*! - * @brief Interface class for model checkers that support And. + * Interface class for model checkers that support And. * - * All model checkers that support the formula class And must inherit - * this pure virtual class. + * All model checkers that support the formula class And must inherit + * this pure virtual class. */ template <class T> class IAndModelChecker { public: + + /*! + * Empty virtual destructor. + */ + virtual ~IAndModelChecker() { + // Intentionally left empty + } + /*! - * @brief Evaluates And formula within a model checker. + * Evaluates an And formula within a model checker. * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. + * @param obj Formula object with subformulas. + * @return The modelchecking result of the formula for every state. */ virtual storm::storage::BitVector checkAnd(const And<T>& obj) const = 0; }; /*! - * @brief - * Class for an abstract formula tree with AND node as root. + * Class for a Prctl formula tree with an And node as root. * - * Has two Abstract state formulas as sub formulas/trees. + * It has two state formulas as sub formulas/trees. * - * As AND is commutative, the order is \e theoretically not important, but will influence the order in which + * As And is commutative, the order is \e theoretically not important, but will influence the order in which * the model checker works. * - * The subtrees are seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) + * The object has shared ownership of its subtrees. If this object is deleted and no other object has a shared + * ownership of the subtrees they will be deleted as well. * * @see AbstractStateFormula * @see AbstractPrctlFormula @@ -57,29 +65,25 @@ class And : public AbstractStateFormula<T> { public: /*! - * Empty constructor. - * Will create an AND-node without subnotes. Will not represent a complete formula! + * Creates an And node without subnodes. + * The resulting object will not represent a complete formula! */ - And() { + And() : left(nullptr), right(nullptr) { // Intentionally left empty. } /*! - * Constructor. - * Creates an AND note with the parameters as subtrees. + * Creates an And node with the parameters as subtrees. * - * @param left The left sub formula - * @param right The right sub formula + * @param left The left sub formula. + * @param right The right sub formula. */ And(std::shared_ptr<AbstractStateFormula<T>> const & left, std::shared_ptr<AbstractStateFormula<T>> const & right) : left(left), right(right) { // Intentionally left empty. } /*! - * Destructor. - * - * The subtrees are deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) + * Empty virtual destructor. */ virtual ~And() { // Intentionally left empty. @@ -88,16 +92,16 @@ public: /*! * Clones the called object. * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones + * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones. * - * @returns a new AND-object that is identical the called object. + * @returns A new And object that is a deep copy of the called object. */ virtual std::shared_ptr<AbstractStateFormula<T>> clone() const override { std::shared_ptr<And<T>> result(new And()); - if (this->leftIsSet()) { + if (this->isLeftSet()) { result->setLeft(left->clone()); } - if (this->rightIsSet()) { + if (this->isRightSet()) { result->setRight(right->clone()); } return result; @@ -117,7 +121,9 @@ public: } /*! - * @returns a string representation of the formula + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. */ virtual std::string toString() const override { std::string result = "("; @@ -139,55 +145,65 @@ public: } /*! - * Sets the left child node. + * Gets the left child node. * - * @param newLeft the new left child. + * @returns The left child node. */ - void setLeft(std::shared_ptr<AbstractStateFormula<T>> const & newLeft) { - left = newLeft; + std::shared_ptr<AbstractStateFormula<T>> const & getLeft() const { + return left; } /*! - * Sets the right child node. + * Gets the right child node. * - * @param newRight the new right child. + * @returns The right child node. */ - void setRight(std::shared_ptr<AbstractStateFormula<T>> const & newRight) { - right = newRight; + std::shared_ptr<AbstractStateFormula<T>> const & getRight() const { + return right; } /*! - * @returns a reference to the left child node + * Sets the left child node. + * + * @param newLeft The new left child. */ - std::shared_ptr<AbstractStateFormula<T>> const & getLeft() const { - return left; + void setLeft(std::shared_ptr<AbstractStateFormula<T>> const & newLeft) { + left = newLeft; } /*! - * @returns a reference to the right child node + * Sets the right child node. + * + * @param newRight The new right child. */ - std::shared_ptr<AbstractStateFormula<T>> const & getRight() const { - return right; + void setRight(std::shared_ptr<AbstractStateFormula<T>> const & newRight) { + right = newRight; } /*! + * Checks if the left child is set, i.e. it does not point to null. * - * @return True if the left child is set, i.e. it does not point to nullptr; false otherwise + * @return True iff the left child is set. */ - bool leftIsSet() const { + bool isLeftSet() const { return left.get() != nullptr; } /*! + * Checks if the right child is set, i.e. it does not point to null. * - * @return True if the right child is set, i.e. it does not point to nullptr; false otherwise + * @return True iff the right child is set. */ - bool rightIsSet() const { + bool isRightSet() const { return right.get() != nullptr; } private: + + // The left child node. std::shared_ptr<AbstractStateFormula<T>> left; + + // The right child node. std::shared_ptr<AbstractStateFormula<T>> right; }; diff --git a/src/formula/prctl/Ap.h b/src/formula/prctl/Ap.h index 7df3cabd8..15bd442ca 100644 --- a/src/formula/prctl/Ap.h +++ b/src/formula/prctl/Ap.h @@ -15,31 +15,39 @@ namespace storm { namespace property { namespace prctl { +// Forward declaration for the interface class. template <class T> class Ap; /*! - * @brief Interface class for model checkers that support Ap. + * Interface class for model checkers that support Ap. * - * All model checkers that support the formula class Ap must inherit - * this pure virtual class. + * All model checkers that support the formula class Ap must inherit + * this pure virtual class. */ template <class T> class IApModelChecker { public: + + /*! + * Empty virtual destructor. + */ + virtual ~IApModelChecker() { + // Intentionally left empty + } + /*! - * @brief Evaluates Ap formula within a model checker. + * Evaluates an Ap formula within a model checker. * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. + * @param obj Formula object with subformulas. + * @return The modelchecking result of the formula for every state. */ virtual storm::storage::BitVector checkAp(const Ap<T>& obj) const = 0; }; /*! - * @brief - * Class for an abstract formula tree with atomic proposition as root. + * Class for a Prctl formula tree with an atomic proposition as root. * - * This class represents the leaves in the formula tree. + * This class represents leaves in the formula tree. * * @see AbstractPrctlFormula * @see AbstractStateFormula @@ -50,19 +58,16 @@ class Ap : public AbstractStateFormula<T> { public: /*! - * Constructor + * Creates a new atomic proposition leaf, with the given label. * - * Creates a new atomic proposition leaf, with the label Ap - * - * @param ap The string representing the atomic proposition + * @param ap A string representing the atomic proposition. */ - Ap(std::string ap) { - this->ap = ap; + Ap(std::string ap) : ap(ap) { + // Intentionally left empty. } /*! - * Destructor. - * At this time, empty... + * Empty virtual destructor. */ virtual ~Ap() { // Intentionally left empty @@ -71,12 +76,12 @@ public: /*! * Clones the called object. * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones + * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones. * - * @returns a new AND-object that is identical the called object. + * @returns A new Ap object that is a deep copy of the called object. */ virtual std::shared_ptr<AbstractStateFormula<T>> clone() const override { - std::shared_ptr<AbstractStateFormula<T>> result(new Ap(this->getAp())); + auto result = std::make_shared<Ap<T>>(this->getAp()); return result; } @@ -93,6 +98,15 @@ public: return modelChecker.template as<IApModelChecker>()->checkAp(*this); } + /*! + * A string representing the atomic proposition. + * + * @returns A string representing the leaf. + */ + virtual std::string toString() const override { + return getAp(); + } + /*! * Returns whether the formula is a propositional logic formula. * That is, this formula and all its subformulas consist only of And, Or, Not and AP. @@ -104,21 +118,17 @@ public: } /*! - * @returns the name of the atomic proposition - */ - const std::string& getAp() const { - return ap; - } - - /*! - * @returns a string representation of the leaf. + * Gets the name of the atomic proposition. * + * @returns The name of the atomic proposition. */ - virtual std::string toString() const override { - return getAp(); + std::string const & getAp() const { + return ap; } private: + + // The atomic proposition referenced by this leaf. std::string ap; }; diff --git a/src/formula/prctl/BoundedEventually.h b/src/formula/prctl/BoundedEventually.h index 16b7df1d8..920a6a073 100644 --- a/src/formula/prctl/BoundedEventually.h +++ b/src/formula/prctl/BoundedEventually.h @@ -18,37 +18,47 @@ namespace storm { namespace property { namespace prctl{ +// Forward declaration for the interface class. template <class T> class BoundedEventually; /*! - * @brief Interface class for model checkers that support BoundedEventually. + * Interface class for model checkers that support BoundedEventually. * - * All model checkers that support the formula class BoundedEventually must inherit - * this pure virtual class. + * All model checkers that support the formula class BoundedEventually must inherit + * this pure virtual class. */ template <class T> class IBoundedEventuallyModelChecker { public: + + /*! + * Empty virtual destructor. + */ + virtual ~IBoundedEventuallyModelChecker() { + // Intentionally left empty + } + /*! - * @brief Evaluates BoundedEventually formula within a model checker. + * Evaluates a BoundedEventually formula within a model checker. * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. + * @param obj Formula object with subformulas. + * @param qualitative A flag indicating whether the formula only needs to be evaluated qualitatively, i.e. if the + * results are only compared against the bounds 0 and 1. + * @return The modelchecking result of the formula for every state. */ virtual std::vector<T> checkBoundedEventually(const BoundedEventually<T>& obj, bool qualitative) const = 0; }; /*! - * @brief - * Class for an abstract (path) formula tree with a BoundedEventually node as root. + * Class for a Prctl (path) formula tree with a BoundedEventually node as root. * - * Has one Abstract state formulas as sub formula/tree. + * Has one state formula as subformula/tree. * * @par Semantics * The formula holds iff in at most \e bound steps, formula \e child holds. * - * The subtrees are seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) + * The object has shared ownership of its subtree. If this object is deleted and no other object has a shared + * ownership of the subtree it will be deleted as well. * * @see AbstractPathFormula * @see AbstractPrctlFormula @@ -57,28 +67,27 @@ template <class T> class BoundedEventually : public AbstractPathFormula<T> { public: + /*! - * Empty constructor + * Creates a BoundedEventually node without a subnode. + * The resulting object will not represent a complete formula! */ - BoundedEventually() : child(nullptr), bound(0){ + BoundedEventually() : child(nullptr), bound(0) { // Intentionally left empty. } /*! - * Constructor + * Creates a BoundedEventually node using the given parameters. * - * @param child The child formula subtree - * @param bound The maximal number of steps + * @param child The child formula subtree. + * @param bound The maximal number of steps within which the subformula must hold. */ - BoundedEventually(std::shared_ptr<AbstractStateFormula<T>> child, uint_fast64_t bound) : child(child), bound(bound){ + BoundedEventually(std::shared_ptr<AbstractStateFormula<T>> child, uint_fast64_t bound) : child(child), bound(bound) { // Intentionally left empty. } /*! - * Destructor. - * - * Also deletes the subtrees. - * (this behaviour can be prevented by setting the subtrees to NULL before deletion) + * Empty virtual destructor. */ virtual ~BoundedEventually() { // Intentionally left empty. @@ -87,14 +96,14 @@ public: /*! * Clones the called object. * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. * - * @returns a new BoundedUntil-object that is identical the called object. + * @returns A new BoundedEventually object that is a deep copy of the called object. */ virtual std::shared_ptr<AbstractPathFormula<T>> clone() const override { std::shared_ptr<BoundedEventually<T>> result(new BoundedEventually<T>()); result->setBound(bound); - if (this->childIsSet()) { + if (this->isChildSet()) { result->setChild(child->clone()); } return result; @@ -115,7 +124,9 @@ public: } /*! - * @returns a string representation of the formula + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. */ virtual std::string toString() const override { std::string result = "F<="; @@ -126,46 +137,56 @@ public: } /*! - * @returns the child node + * Gets the child node. + * + * @returns The child node. */ std::shared_ptr<AbstractStateFormula<T>> const & getChild() const { return child; } /*! - * Sets the subtree - * @param child the new child node + * Sets the subtree. + * + * @param child The new child. */ void setChild(std::shared_ptr<AbstractStateFormula<T>> const & child) { this->child = child; } /*! + * Checks if the child is set, i.e. it does not point to null. * - * @return True if the child is set, i.e. it does not point to nullptr; false otherwise + * @return True iff the child is set. */ - bool childIsSet() const { + bool isChildSet() const { return child.get() != nullptr; } /*! - * @returns the maximally allowed number of steps for the bounded until operator + * Gets the maximally allowed number of steps for the bounded eventually operator. + * + * @returns The bound. */ uint_fast64_t getBound() const { return bound; } /*! - * Sets the maximally allowed number of steps for the bounded until operator + * Sets the maximally allowed number of steps for the bounded eventually operator. * - * @param bound the new bound. + * @param bound The new bound. */ void setBound(uint_fast64_t bound) { this->bound = bound; } private: + + // The child node. std::shared_ptr<AbstractStateFormula<T>> child; + + // The maximal number of steps within which the subformula must hold. uint_fast64_t bound; }; diff --git a/src/formula/prctl/BoundedNaryUntil.h b/src/formula/prctl/BoundedNaryUntil.h index 1c9863ac7..c6e4092e9 100644 --- a/src/formula/prctl/BoundedNaryUntil.h +++ b/src/formula/prctl/BoundedNaryUntil.h @@ -21,33 +21,42 @@ namespace storm { namespace property { namespace prctl { - +// Forward declaration for the interface class. template <class T> class BoundedNaryUntil; /*! - * @brief Interface class for model checkers that support BoundedNaryUntil. + * Interface class for model checkers that support BoundedNaryUntil. * - * All model checkers that support the formula class BoundedNaryUntil must inherit - * this pure virtual class. + * All model checkers that support the formula class BoundedNaryUntil must inherit + * this pure virtual class. */ template <class T> class IBoundedNaryUntilModelChecker { public: + + /*! + * Empty virtual destructor. + */ + virtual ~IBoundedNaryUntilModelChecker() { + // Intentionally left empty + } + /*! - * @brief Evaluates BoundedNaryUntil formula within a model checker. + * Evaluates BoundedNaryUntil formula within a model checker. * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. + * @param obj Formula object with subformulas. + * @param qualitative A flag indicating whether the formula only needs to be evaluated qualitatively, i.e. if the + * results are only compared against the bounds 0 and 1. + * @return Result of the formula for every state. */ virtual std::vector<T> checkBoundedNaryUntil(const BoundedNaryUntil<T>& obj, bool qualitative) const = 0; }; /*! - * @brief - * Class for an abstract (path) formula tree with a BoundedNaryUntil node as root. + * Class for a Prctl (path) formula tree with a BoundedNaryUntil node as root. * - * Has at least two Abstract state formulas as sub formulas and an interval - * associated with all but the first sub formula. We'll call the first one + * Has at least two state formulas as sub formulas and an interval + * associated with all but the first sub formula. We will call the first one * \e left and all other one \e right. * * @par Semantics @@ -55,8 +64,8 @@ class IBoundedNaryUntilModelChecker { * formulas holds after a number of steps contained in the interval * associated with this formula. * - * The subtrees are seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) + * The object has shared ownership of its subtrees. If this object is deleted and no other object has a shared + * ownership of the subtrees they will be deleted as well. * * @see AbstractPathFormula * @see AbstractPrctlFormula @@ -67,27 +76,25 @@ class BoundedNaryUntil : public AbstractPathFormula<T> { public: /*! - * Empty constructor + * Creates a BoundedNaryUntil node without subnodes. + * The resulting object will not represent a complete formula! */ BoundedNaryUntil() : left(nullptr), right() { // Intentionally left empty. } /*! - * Constructor + * Creates a BoundedNaryUntil node with the parameters as subtrees. * - * @param left The left formula subtree - * @param right The left formula subtree + * @param left The left formula subtree. + * @param right The right formula subtrees with their associated intervals. */ BoundedNaryUntil(std::shared_ptr<AbstractStateFormula<T>> const & left, std::vector<std::tuple<std::shared_ptr<AbstractStateFormula<T>>,T,T>> const & right) : left(left), right(right) { // Intentionally left empty. } /*! - * Destructor. - * - * Also deletes the subtrees. - * (this behaviour can be prevented by setting the subtrees to NULL before deletion) + * Empty virtual destructor. */ virtual ~BoundedNaryUntil() { // Intentionally left empty. @@ -96,16 +103,16 @@ public: /*! * Clones the called object. * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones + * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones. * - * @returns a new BoundedNaryUntil-object that is identical the called object. + * @returns A new BoundedNaryUntil object that is a deep copy of the called object. */ virtual std::shared_ptr<AbstractPathFormula<T>> clone() const override { std::shared_ptr<BoundedNaryUntil<T>> result(new BoundedNaryUntil<T>()); - if (this->leftIsSet()) { + if (this->isLeftSet()) { result->setLeft(left->clone()); } - if (this->rightIsSet()) { + if (this->isRightSet()) { std::vector<std::tuple<std::shared_ptr<AbstractStateFormula<T>>,T,T>> newright; for (auto it = right->begin(); it != right->end(); ++it) { newright.push_back(std::tuple<std::shared_ptr<AbstractStateFormula<T>>,T,T>(std::get<0>(*it)->clone(), std::get<1>(*it), std::get<2>(*it))); @@ -130,7 +137,9 @@ public: } /*! - * @returns a string representation of the formula + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. */ virtual std::string toString() const override { std::stringstream result; @@ -143,60 +152,76 @@ public: } /*! - * Sets the left child node. + * Gets the left child node. * - * @param newLeft the new left child. + * @returns The left child node. */ - void setLeft(std::shared_ptr<AbstractStateFormula<T>> const & newLeft) { - left = newLeft; + std::shared_ptr<AbstractStateFormula<T>> const & getLeft() const { + return left; } - void setRight(std::vector<std::tuple<std::shared_ptr<AbstractStateFormula<T>>,T,T>> const & newRight) { - right = newRight; + /*! + * Gets the right child nodes and their associated intervals. + * + * @returns A vector containing the right children as well as the associated intervals. + */ + std::vector<std::tuple<std::shared_ptr<AbstractStateFormula<T>>,T,T>> const & getRight() const { + return right; } /*! + * Sets the left child node. * - * @return True if the left child is set, i.e. it does not point to nullptr; false otherwise + * @param newLeft The new left child. */ - bool leftIsSet() const { - return left != nullptr; + void setLeft(std::shared_ptr<AbstractStateFormula<T>> const & newLeft) { + left = newLeft; } /*! + * Sets the right child nodes. * - * @return True if the right child is set, i.e. it is not empty; false otherwise + * @param newRight A vector containing the new right children as well as the associated intervals. */ - bool rightIsSet() const { - return !(right.empty()); + void setRight(std::vector<std::tuple<std::shared_ptr<AbstractStateFormula<T>>,T,T>> const & newRight) { + right = newRight; } /*! - * Sets the right child node. + * Adds a new rightmost child node. * - * @param newRight the new right child. + * @param newRight The new child. + * @param upperBound The upper bound of the associated interval. + * @param lowerBound The lower bound of the associated interval. */ void addRight(std::shared_ptr<AbstractStateFormula<T>> const & newRight, T upperBound, T lowerBound) { right.push_back(std::tuple<std::shared_ptr<AbstractStateFormula<T>>,T,T>(newRight, upperBound, lowerBound)); } /*! - * @returns a pointer to the left child node + * Checks if the left child is set, i.e. it does not point to null. + * + * @return True iff the left child is set. */ - std::shared_ptr<AbstractStateFormula<T>> const & getLeft() const { - return left; + bool isLeftSet() const { + return left != nullptr; } /*! - * @returns a pointer to the right child nodes. + * Checks if the right child is set, i.e. it contains at least one entry. + * + * @return True iff the right child is set. */ - std::vector<std::tuple<std::shared_ptr<AbstractStateFormula<T>>,T,T>> const & getRight() const { - return right; + bool isRightSet() const { + return !(right.empty()); } - private: + + // The left formula subtree. std::shared_ptr<AbstractStateFormula<T>> left; + + // The right formula subtrees with their associated intervals. std::vector<std::tuple<std::shared_ptr<AbstractStateFormula<T>>,T,T>> right; }; diff --git a/src/formula/prctl/BoundedUntil.h b/src/formula/prctl/BoundedUntil.h index 92d119583..ec0b59f51 100644 --- a/src/formula/prctl/BoundedUntil.h +++ b/src/formula/prctl/BoundedUntil.h @@ -18,38 +18,48 @@ namespace storm { namespace property { namespace prctl { +// Forward declaration for the interface class. template <class T> class BoundedUntil; /*! - * @brief Interface class for model checkers that support BoundedUntil. + * Interface class for model checkers that support BoundedUntil. * - * All model checkers that support the formula class BoundedUntil must inherit - * this pure virtual class. + * All model checkers that support the formula class BoundedUntil must inherit + * this pure virtual class. */ template <class T> class IBoundedUntilModelChecker { public: + /*! - * @brief Evaluates BoundedUntil formula within a model checker. + * Empty virtual destructor. + */ + virtual ~IBoundedUntilModelChecker() { + // Intentionally left empty + } + + /*! + * Evaluates a BoundedUntil formula within a model checker. * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. + * @param obj Formula object with subformulas. + * @param qualitative A flag indicating whether the formula only needs to be evaluated qualitatively, i.e. if the + * results are only compared against the bounds 0 and 1. + * @return The modelchecking result of the formula for every state. */ virtual std::vector<T> checkBoundedUntil(const BoundedUntil<T>& obj, bool qualitative) const = 0; }; /*! - * @brief - * Class for an abstract (path) formula tree with a BoundedUntil node as root. + * Class for a Prctl (path) formula tree with a BoundedUntil node as root. * - * Has two Abstract state formulas as sub formulas/trees. + * Has two Prctl state formulas as sub formulas/trees. * * @par Semantics * The formula holds iff in at most \e bound steps, formula \e right (the right subtree) holds, and before, * \e left holds. * - * The subtrees are seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) + * The object has shared ownership of its subtrees. If this object is deleted and no other object has a shared + * ownership of the subtrees they will be deleted as well. * * @see AbstractPathFormula * @see AbstractPrctlFormula @@ -60,26 +70,26 @@ class BoundedUntil : public AbstractPathFormula<T> { public: /*! - * Empty constructor + * Creates a BoundedUntil node without subnodes. + * The resulting object will not represent a complete formula! */ - BoundedUntil() : left(nullptr), right(nullptr), bound(0){ + BoundedUntil() : left(nullptr), right(nullptr), bound(0) { // Intentionally left empty. } /*! - * Constructor + * Creates a BoundedUntil node using the given parameters. * - * @param left The left formula subtree - * @param right The left formula subtree - * @param bound The maximal number of steps + * @param left The left formula subtree. + * @param right The right formula subtree. + * @param bound The maximal number of steps within which the right subformula must hold. */ BoundedUntil(std::shared_ptr<AbstractStateFormula<T>> const & left, std::shared_ptr<AbstractStateFormula<T>> const & right, uint_fast64_t bound) : left(left), right(right), bound(bound) { // Intentionally left empty. } + /*! - * Destructor. - * - * Deletes the subtrees iff this object is the only owner of them. + * Empty virtual destructor. */ virtual ~BoundedUntil() { // Intentionally left empty. @@ -88,17 +98,17 @@ public: /*! * Clones the called object. * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. * - * @returns a new BoundedUntil-object that is identical the called object. + * @returns A new BoundedUntil object that is a deep copy of the called object. */ virtual std::shared_ptr<AbstractPathFormula<T>> clone() const override { std::shared_ptr<BoundedUntil<T>> result(new BoundedUntil<T>()); result->setBound(bound); - if (this->leftIsSet()) { + if (this->isLeftSet()) { result->setLeft(left->clone()); } - if (this->rightIsSet()) { + if (this->isRightSet()) { result->setRight(right->clone()); } return result; @@ -119,7 +129,9 @@ public: } /*! - * @returns a string representation of the formula + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. */ virtual std::string toString() const override { std::string result = left->toString(); @@ -131,72 +143,86 @@ public: } /*! - * Sets the left child node. + * Gets the left child node. * - * @param newLeft the new left child. + * @returns The left child node. */ - void setLeft(std::shared_ptr<AbstractStateFormula<T>> const & newLeft) { - left = newLeft; + std::shared_ptr<AbstractStateFormula<T>> const & getLeft() const { + return left; } /*! - * Sets the right child node. + * Gets the right child node. * - * @param newRight the new right child. + * @returns The right child node. */ - void setRight(std::shared_ptr<AbstractStateFormula<T>> const & newRight) { - right = newRight; + std::shared_ptr<AbstractStateFormula<T>> const & getRight() const { + return right; } /*! - * @returns a pointer to the left child node + * Sets the left child node. + * + * @param newLeft The new left child. */ - std::shared_ptr<AbstractStateFormula<T>> const & getLeft() const { - return left; + void setLeft(std::shared_ptr<AbstractStateFormula<T>> const & newLeft) { + left = newLeft; } /*! - * @returns a pointer to the right child node + * Sets the right child node. + * + * @param newRight The new right child. */ - std::shared_ptr<AbstractStateFormula<T>> const & getRight() const { - return right; + void setRight(std::shared_ptr<AbstractStateFormula<T>> const & newRight) { + right = newRight; } /*! + * Checks if the left child is set, i.e. it does not point to null. * - * @return True if the left child is set, i.e. it does not point to nullptr; false otherwise + * @return True iff the left child is set. */ - bool leftIsSet() const { + bool isLeftSet() const { return left.get() != nullptr; } /*! + * Checks if the right child is set, i.e. it does not point to null. * - * @return True if the right child is set, i.e. it does not point to nullptr; false otherwise + * @return True iff the right child is set. */ - bool rightIsSet() const { + bool isRightSet() const { return right.get() != nullptr; } /*! - * @returns the maximally allowed number of steps for the bounded until operator + * Gets the maximally allowed number of steps for the bounded until operator. + * + * @returns The bound. */ uint_fast64_t getBound() const { return bound; } /*! - * Sets the maximally allowed number of steps for the bounded until operator + * Sets the maximally allowed number of steps for the bounded until operator. * - * @param bound the new bound. + * @param bound The new bound. */ void setBound(uint_fast64_t bound) { this->bound = bound; } private: + + // The left child node. std::shared_ptr<AbstractStateFormula<T>> left; + + // The right child node. std::shared_ptr<AbstractStateFormula<T>> right; + + // The maximal number of steps within which the subformulas must hold. uint_fast64_t bound; }; diff --git a/src/formula/prctl/CumulativeReward.h b/src/formula/prctl/CumulativeReward.h index 4a94c021b..fd51db72c 100644 --- a/src/formula/prctl/CumulativeReward.h +++ b/src/formula/prctl/CumulativeReward.h @@ -15,32 +15,44 @@ namespace storm { namespace property { namespace prctl { +// Forward declaration for the interface class. template <class T> class CumulativeReward; /*! - * @brief Interface class for model checkers that support CumulativeReward. + * Interface class for model checkers that support CumulativeReward. * - * All model checkers that support the formula class CumulativeReward must inherit - * this pure virtual class. + * All model checkers that support the formula class CumulativeReward must inherit + * this pure virtual class. */ template <class T> class ICumulativeRewardModelChecker { public: + + /*! + * Empty virtual destructor. + */ + virtual ~ICumulativeRewardModelChecker() { + // Intentionally left empty + } + /*! - * @brief Evaluates CumulativeReward formula within a model checker. + * Evaluates CumulativeReward formula within a model checker. * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. + * @param obj Formula object with subformulas. + * @param qualitative A flag indicating whether the formula only needs to be evaluated qualitatively, i.e. if the + * results are only compared against the bounds 0 and 1. + * @return Result of the formula for every node. */ virtual std::vector<T> checkCumulativeReward(const CumulativeReward<T>& obj, bool qualitative) const = 0; }; /*! - * @brief - * Class for an abstract (path) formula tree with a Cumulative Reward node as root. + * Class for a Prctl (reward path) formula tree with a Cumulative Reward node as root. * - * The subtrees are seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) + * Given a path of finite length. + * The sum of all rewards received upon entering each state of the path is the cumulative reward of the path. + * The cumulative reward for a state s at time \e bound is the expected cumulative reward of a path of length \e bound starting in s. + * In the continuous case all paths that need at most time \e bound are considered. * * @see AbstractPathFormula * @see AbstractPrctlFormula @@ -49,19 +61,15 @@ template <class T> class CumulativeReward : public AbstractRewardPathFormula<T> { public: - /*! - * Empty constructor - */ - CumulativeReward() : bound(0){ - // Intentionally left empty. - } /*! - * Constructor + * Creates a CumulativeReward node with the given bound. + * + * If no bound is given it defaults to 0, referencing the state reward received upon entering the state s itself. * - * @param bound The time bound of the reward formula + * @param bound The time instance of the reward formula. */ - CumulativeReward(T bound) : bound(bound){ + CumulativeReward(T bound = 0) : bound(bound){ // Intentionally left empty. } @@ -75,9 +83,9 @@ public: /*! * Clones the called object. * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. * - * @returns a new CumulativeReward-object that is identical the called object. + * @returns A new CumulativeReward object that is a deep copy of the called object. */ virtual std::shared_ptr<AbstractRewardPathFormula<T>> clone() const override { std::shared_ptr<CumulativeReward<T>> result(new CumulativeReward(this->getBound())); @@ -99,7 +107,9 @@ public: } /*! - * @returns a string representation of the formula + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. */ virtual std::string toString() const override { std::string result = "C <= "; @@ -108,22 +118,26 @@ public: } /*! - * @returns the time instance for the instantaneous reward operator + * Gets the time bound for the paths considered. + * + * @returns The time bound for the paths considered. */ T getBound() const { return bound; } /*! - * Sets the the time instance for the instantaneous reward operator + * Sets the time bound for the paths considered. * - * @param bound the new bound. + * @param bound The new bound. */ void setBound(T bound) { this->bound = bound; } private: + + // The time bound for the paths considered. T bound; }; diff --git a/src/formula/prctl/Eventually.h b/src/formula/prctl/Eventually.h index 77dcb3c73..6d22e1dd4 100644 --- a/src/formula/prctl/Eventually.h +++ b/src/formula/prctl/Eventually.h @@ -1,5 +1,5 @@ /* - * Next.h + * Eventually.h * * Created on: 26.12.2012 * Author: Christian Dehnert @@ -16,37 +16,47 @@ namespace storm { namespace property { namespace prctl { +// Forward declaration for the interface class. template <class T> class Eventually; /*! - * @brief Interface class for model checkers that support Eventually. + * Interface class for model checkers that support Eventually. * - * All model checkers that support the formula class Eventually must inherit - * this pure virtual class. + * All model checkers that support the formula class Eventually must inherit + * this pure virtual class. */ template <class T> class IEventuallyModelChecker { public: + /*! - * @brief Evaluates Eventually formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ + * Empty virtual destructor. + */ + virtual ~IEventuallyModelChecker() { + // Intentionally left empty. + } + + /*! + * Evaluates an Eventually formula within a model checker. + * + * @param obj Formula object with subformulas. + * @param qualitative A flag indicating whether the formula only needs to be evaluated qualitatively, i.e. if the + * results are only compared against the bounds 0 and 1. + * @return The modelchecking result of the formula for every state. + */ virtual std::vector<T> checkEventually(const Eventually<T>& obj, bool qualitative) const = 0; }; /*! - * @brief - * Class for an abstract (path) formula tree with an Eventually node as root. + * Class for a Prctl (path) formula tree with an Eventually node as root. * - * Has one Abstract state formula as sub formula/tree. + * Has one state formula as sub formula/tree. * * @par Semantics - * The formula holds iff eventually \e child holds. + * The formula holds iff eventually formula \e child holds. * - * The subtree is seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to nullptr before deletion) + * The object has shared ownership of its subtree. If this object is deleted and no other object has a shared + * ownership of the subtree it will be deleted as well. * * @see AbstractPathFormula * @see AbstractPrctlFormula @@ -57,25 +67,24 @@ class Eventually : public AbstractPathFormula<T> { public: /*! - * Empty constructor + * Creates an Eventually node without a subnode. + * The resulting object will not represent a complete formula! */ Eventually() : child(nullptr) { // Intentionally left empty. } /*! - * Constructor + * Creates an Eventually node using the given parameter. * - * @param child The child node + * @param child The child formula subtree. */ Eventually(std::shared_ptr<AbstractStateFormula<T>> const & child) : child(child){ // Intentionally left empty. } /*! - * Constructor. - * - * Deletes the subtree iff this object is the last remaining owner of the subtree. + * Empty virtual destructor. */ virtual ~Eventually() { // Intentionally left empty. @@ -84,13 +93,13 @@ public: /*! * Clones the called object. * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. * - * @returns a new Eventually-object that is identical the called object. + * @returns A new Eventually object that is a deep copy of the called object. */ virtual std::shared_ptr<AbstractPathFormula<T>> clone() const override { std::shared_ptr<Eventually<T>> result(new Eventually<T>()); - if (this->childIsSet()) { + if (this->isChildSet()) { result->setChild(child->clone()); } return result; @@ -110,7 +119,9 @@ public: } /*! - * @returns a string representation of the formula + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. */ virtual std::string toString() const override { std::string result = "F "; @@ -119,29 +130,35 @@ public: } /*! - * @returns the child node + * Gets the child node. + * + * @returns The child node. */ std::shared_ptr<AbstractStateFormula<T>> const & getChild() const { return child; } /*! - * Sets the subtree - * @param child the new child node + * Sets the subtree. + * + * @param child The new child. */ void setChild(std::shared_ptr<AbstractStateFormula<T>> const & child) { this->child = child; } /*! + * Checks if the child is set, i.e. it does not point to null. * - * @return True if the child node is set, i.e. it does not point to nullptr; false otherwise + * @return True iff the child is set. */ - bool childIsSet() const { + bool isChildSet() const { return child.get() != nullptr; } private: + + // The child node. std::shared_ptr<AbstractStateFormula<T>> child; }; diff --git a/src/formula/prctl/Globally.h b/src/formula/prctl/Globally.h index 8f0b9c910..12f29f19d 100644 --- a/src/formula/prctl/Globally.h +++ b/src/formula/prctl/Globally.h @@ -1,5 +1,5 @@ /* - * Next.h + * Globally.h * * Created on: 26.12.2012 * Author: Christian Dehnert @@ -16,37 +16,47 @@ namespace storm { namespace property { namespace prctl { +// Forward declaration for the interface class. template <class T> class Globally; /*! - * @brief Interface class for model checkers that support Globally. + * Interface class for model checkers that support Globally. * - * All model checkers that support the formula class Globally must inherit - * this pure virtual class. + * All model checkers that support the formula class Globally must inherit + * this pure virtual class. */ template <class T> class IGloballyModelChecker { public: + /*! - * @brief Evaluates Globally formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ + * Empty virtual destructor. + */ + virtual ~IGloballyModelChecker() { + // Intentionally left empty + } + + /*! + * Evaluates a Globally formula within a model checker. + * + * @param obj Formula object with subformulas. + * @param qualitative A flag indicating whether the formula only needs to be evaluated qualitatively, i.e. if the + * results are only compared against the bounds 0 and 1. + * @return The modelchecking result of the formula for every state. + */ virtual std::vector<T> checkGlobally(const Globally<T>& obj, bool qualitative) const = 0; }; /*! - * @brief - * Class for an abstract (path) formula tree with a Globally node as root. + * Class for an Prctl (path) formula tree with a Globally node as root. * - * Has one Abstract state formula as sub formula/tree. + * Has one state formula as sub formula/tree. * * @par Semantics - * The formula holds iff globally \e child holds. + * The formula holds iff globally formula \e child holds. * - * The subtree is seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to nullptr before deletion) + * The object has shared ownership of its subtree. If this object is deleted and no other object has a shared + * ownership of the subtree it will be deleted as well. * * @see AbstractPathFormula * @see AbstractPrctlFormula @@ -57,25 +67,24 @@ class Globally : public AbstractPathFormula<T> { public: /*! - * Empty constructor + * Creates a Globally node without a subnode. + * The resulting object will not represent a complete formula! */ Globally() : child(nullptr){ // Intentionally left empty. } /*! - * Constructor + * Creates a Globally node using the given parameter. * - * @param child The child node + * @param child The child formula subtree. */ Globally(std::shared_ptr<AbstractStateFormula<T>> const & child) : child(child){ // Intentionally left empty. } /*! - * Destructor. - * - * Deletes the subtree iff this object is the last remaining owner of the subtree. + * Empty virtual destructor. */ virtual ~Globally() { // Intentionally left empty. @@ -84,13 +93,13 @@ public: /*! * Clones the called object. * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. * - * @returns a new Globally-object that is identical the called object. + * @returns A new Globally object that is a deep copy of the called object. */ virtual std::shared_ptr<AbstractPathFormula<T>> clone() const override { std::shared_ptr<Globally<T>> result(new Globally<T>()); - if (this->childIsSet()) { + if (this->isChildSet()) { result->setChild(child->clone()); } return result; @@ -110,7 +119,9 @@ public: } /*! - * @returns a string representation of the formula + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. */ virtual std::string toString() const override { std::string result = "G "; @@ -119,29 +130,35 @@ public: } /*! - * @returns the child node + * Gets the child node. + * + * @returns The child node. */ std::shared_ptr<AbstractStateFormula<T>> const & getChild() const { return child; } /*! - * Sets the subtree - * @param child the new child node + * Sets the subtree. + * + * @param child The new child. */ void setChild(std::shared_ptr<AbstractStateFormula<T>> const & child) { this->child = child; } /*! + * Checks if the child is set, i.e. it does not point to null. * - * @return True if the child node is set, i.e. it does not point to nullptr; false otherwise + * @return True iff the child is set. */ - bool childIsSet() const { + bool isChildSet() const { return child.get() != nullptr; } private: + + // The child node. std::shared_ptr<AbstractStateFormula<T>> child; }; diff --git a/src/formula/prctl/InstantaneousReward.h b/src/formula/prctl/InstantaneousReward.h index 18cf7eeae..c8f61b120 100644 --- a/src/formula/prctl/InstantaneousReward.h +++ b/src/formula/prctl/InstantaneousReward.h @@ -16,32 +16,44 @@ namespace storm { namespace property { namespace prctl { +// Forward declaration for the interface class. template <class T> class InstantaneousReward; /*! - * @brief Interface class for model checkers that support InstantaneousReward. + * Interface class for model checkers that support InstantaneousReward. * - * All model checkers that support the formula class InstantaneousReward must inherit - * this pure virtual class. + * All model checkers that support the formula class InstantaneousReward must inherit + * this pure virtual class. */ template <class T> class IInstantaneousRewardModelChecker { public: + + /*! + * Empty virtual destructor. + */ + virtual ~IInstantaneousRewardModelChecker() { + // Intentionally left empty + } + /*! - * @brief Evaluates InstantaneousReward formula within a model checker. + * Evaluates an InstantaneousReward formula within a model checker. * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. + * @param obj Formula object with subformulas. + * @param qualitative A flag indicating whether the formula only needs to be evaluated qualitatively, i.e. if the + * results are only compared against the bounds 0 and 1. + * @return The modelchecking result of the formula for every state. */ virtual std::vector<T> checkInstantaneousReward(const InstantaneousReward<T>& obj, bool qualitative) const = 0; }; /*! - * @brief - * Class for an abstract (path) formula tree with a Instantaneous Reward node as root. + * Class for an Instantaneous Reward formula. + * This class represents a possible leaf in a reward formula tree. * - * The subtrees are seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) + * Given a path of finite length. + * The reward received upon entering the last state of the path is the instantaneous reward of the path. + * The instantaneous reward for a state s at time \e bound is the expected instantaneous reward of a path of length \e bound starting in s. * * @see AbstractPathFormula * @see AbstractPrctlFormula @@ -52,23 +64,18 @@ class InstantaneousReward : public AbstractRewardPathFormula<T> { public: /*! - * Empty constructor - */ - InstantaneousReward() : bound(0) { - // Intentionally left empty. - } - - /*! - * Constructor + * Creates an InstantaneousReward node with the given bound. + * + * If no bound is given it defaults to 0, referencing the state reward received upon entering the state s itself. * - * @param bound The time instance of the reward formula + * @param bound The time instance of the reward formula. */ - InstantaneousReward(uint_fast64_t bound) : bound(bound) { + InstantaneousReward(uint_fast64_t bound = 0) : bound(bound) { // Intentionally left empty. } /*! - * Empty destructor. + * Empty virtual destructor. */ virtual ~InstantaneousReward() { // Intentionally left empty. @@ -77,9 +84,9 @@ public: /*! * Clones the called object. * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. * - * @returns a new InstantaneousReward-object that is identical the called object. + * @returns A new InstantaneousReward object that is a deep copy of the called object. */ virtual std::shared_ptr<AbstractRewardPathFormula<T>> clone() const override { std::shared_ptr<InstantaneousReward<T>> result(new InstantaneousReward(bound)); @@ -101,7 +108,9 @@ public: } /*! - * @returns a string representation of the formula + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. */ virtual std::string toString() const override { std::string result = "I="; @@ -110,22 +119,26 @@ public: } /*! - * @returns the time instance for the instantaneous reward operator + * Gets the time instance for the instantaneous reward operator. + * + * @returns The time instance for the instantaneous reward operator. */ uint_fast64_t getBound() const { return bound; } /*! - * Sets the the time instance for the instantaneous reward operator + * Sets the the time instance for the instantaneous reward operator. * - * @param bound the new bound. + * @param bound The new time instance. */ void setBound(uint_fast64_t bound) { this->bound = bound; } private: + + // The time instance of the reward formula. uint_fast64_t bound; }; diff --git a/src/formula/prctl/Next.h b/src/formula/prctl/Next.h index 052adf9ca..a83ff1690 100644 --- a/src/formula/prctl/Next.h +++ b/src/formula/prctl/Next.h @@ -15,37 +15,47 @@ namespace storm { namespace property { namespace prctl { +// Forward declaration for the interface class. template <class T> class Next; /*! - * @brief Interface class for model checkers that support Next. + * Interface class for model checkers that support Next. * - * All model checkers that support the formula class Next must inherit - * this pure virtual class. + * All model checkers that support the formula class Next must inherit + * this pure virtual class. */ template <class T> class INextModelChecker { public: + /*! - * @brief Evaluates Next formula within a model checker. + * Empty virtual destructor. + */ + virtual ~INextModelChecker() { + // Intentionally left empty + } + + /*! + * Evaluates Next formula within a model checker. * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. + * @param obj Formula object with subformulas. + * @param qualitative A flag indicating whether the formula only needs to be evaluated qualitatively, i.e. if the + * results are only compared against the bounds 0 and 1. + * @return Result of the formula for every node. */ virtual std::vector<T> checkNext(const Next<T>& obj, bool qualitative) const = 0; }; /*! - * @brief - * Class for an abstract (path) formula tree with a Next node as root. + * Class for a Prctl (path) formula tree with a Next node as root. * - * Has two Abstract state formulas as sub formulas/trees. + * Has two Prctl state formulas as sub formulas/trees. * * @par Semantics - * The formula holds iff in the next step, \e child holds + * The formula holds iff in the next step, formula \e child holds * - * The subtree is seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) + * The object has shared ownership of its subtree. If this object is deleted and no other object has a shared + * ownership of the subtree it will be deleted as well. * * @see AbstractPathFormula * @see AbstractPrctlFormula @@ -56,25 +66,24 @@ class Next : public AbstractPathFormula<T> { public: /*! - * Empty constructor + * Creates a Next node without a subnode. + * The resulting object will not represent a complete formula! */ Next() : child(nullptr){ // Intentionally left empty. } /*! - * Constructor + * Creates a Next node using the given parameter. * - * @param child The child node + * @param child The child formula subtree. */ Next(std::shared_ptr<AbstractStateFormula<T>> const & child) : child(child){ // Intentionally left empty. } /*! - * Constructor. - * - * Deletes the subtree iff this object is the last remaining owner of the subtree. + * Empty virtual destructor. */ virtual ~Next() { // Intentionally left empty. @@ -83,13 +92,13 @@ public: /*! * Clones the called object. * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. * - * @returns a new BoundedUntil-object that is identical the called object. + * @returns A new Next object that is a deep copy of the called object. */ virtual std::shared_ptr<AbstractPathFormula<T>> clone() const override { std::shared_ptr<Next<T>> result(new Next<T>()); - if (this->childIsSet()) { + if (this->isChildSet()) { result->setChild(child->clone()); } return result; @@ -109,7 +118,9 @@ public: } /*! - * @returns a string representation of the formula + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. */ virtual std::string toString() const override { std::string result = "X "; @@ -118,29 +129,35 @@ public: } /*! - * @returns the child node + * Gets the child node. + * + * @returns The child node. */ std::shared_ptr<AbstractStateFormula<T>> const & getChild() const { return child; } /*! - * Sets the subtree - * @param child the new child node + * Sets the subtree. + * + * @param child The new child. */ void setChild(std::shared_ptr<AbstractStateFormula<T>> const & child) { this->child = child; } /*! + * Checks if the child is set, i.e. it does not point to null. * - * @return True if the child node is set, i.e. it does not point to nullptr; false otherwise + * @return True iff the child is set. */ - bool childIsSet() const { + bool isChildSet() const { return child.get() != nullptr; } private: + + // The child node. std::shared_ptr<AbstractStateFormula<T>> child; }; diff --git a/src/formula/prctl/Not.h b/src/formula/prctl/Not.h index a58c5d3f4..83af85e53 100644 --- a/src/formula/prctl/Not.h +++ b/src/formula/prctl/Not.h @@ -15,34 +15,42 @@ namespace storm { namespace property { namespace prctl { +// Forward declaration for the interface class. template <class T> class Not; /*! - * @brief Interface class for model checkers that support Not. + * Interface class for model checkers that support Not. * - * All model checkers that support the formula class Not must inherit - * this pure virtual class. + * All model checkers that support the formula class Not must inherit + * this pure virtual class. */ template <class T> class INotModelChecker { public: + /*! - * @brief Evaluates Not formula within a model checker. + * Empty virtual destructor. + */ + virtual ~INotModelChecker() { + // Intentionally left empty + } + + /*! + * Evaluates Not formulas within a model checker. * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. + * @param obj Formula object with subformulas. + * @return Result of the formula for every node. */ virtual storm::storage::BitVector checkNot(const Not<T>& obj) const = 0; }; /*! - * @brief - * Class for an abstract formula tree with NOT node as root. + * Class for an Prctl formula tree with Not node as root. * - * Has one Abstract state formula as sub formula/tree. + * Has one state formula as sub formula/tree. * - * The subtree is seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) + * The object has shared ownership of its subtree. If this object is deleted and no other object has a shared + * ownership of the subtree it will be deleted as well. * * @see AbstractStateFormula * @see AbstractPrctlFormula @@ -53,24 +61,24 @@ class Not : public AbstractStateFormula<T> { public: /*! - * Empty constructor + * Creates a Not node without a subnode. + * The resulting object will not represent a complete formula! */ Not() : child(nullptr) { // Intentionally left empty. } /*! - * Constructor - * @param child The child node + * Creates a Not node using the given parameter. + * + * @param child The child formula subtree. */ Not(std::shared_ptr<AbstractStateFormula<T>> child) : child(child) { // Intentionally left empty. } /*! - * Destructor - * - * Deletes the subtree iff this object is the last remaining owner of the subtree. + * Empty virtual destructor. */ virtual ~Not() { // Intentionally left empty. @@ -79,13 +87,13 @@ public: /*! * Clones the called object. * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. * - * @returns a new AND-object that is identical the called object. + * @returns A new Not object that is a deep copy of the called object. */ virtual std::shared_ptr<AbstractStateFormula<T>> clone() const override { std::shared_ptr<Not<T>> result(new Not<T>()); - if (this->childIsSet()) { + if (this->isChildSet()) { result->setChild(child->clone()); } return result; @@ -105,7 +113,9 @@ public: } /*! - * @returns a string representation of the formula + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. */ virtual std::string toString() const override { std::string result = "!"; @@ -124,29 +134,35 @@ public: } /*! - * @returns The child node + * Gets the child node. + * + * @returns The child node. */ std::shared_ptr<AbstractStateFormula<T>> const & getChild() const { return child; } /*! - * Sets the subtree - * @param child the new child node + * Sets the subtree. + * + * @param child The new child. */ void setChild(std::shared_ptr<AbstractStateFormula<T>> const & child) { this->child = child; } /*! + * Checks if the child is set, i.e. it does not point to null. * - * @return True if the child node is set, i.e. it does not point to nullptr; false otherwise + * @return True iff the child is set. */ - bool childIsSet() const { + bool isChildSet() const { return child.get() != nullptr; } private: + + // The child node. std::shared_ptr<AbstractStateFormula<T>> child; }; diff --git a/src/formula/prctl/Or.h b/src/formula/prctl/Or.h index 646b5735c..3044ce3e7 100644 --- a/src/formula/prctl/Or.h +++ b/src/formula/prctl/Or.h @@ -14,37 +14,45 @@ namespace storm { namespace property { namespace prctl { +// Forward declaration for the interface class. template <class T> class Or; /*! - * @brief Interface class for model checkers that support Or. + * Interface class for model checkers that support Or. * - * All model checkers that support the formula class Or must inherit - * this pure virtual class. + * All model checkers that support the formula class Or must inherit + * this pure virtual class. */ template <class T> class IOrModelChecker { public: + + /*! + * Empty virtual destructor. + */ + virtual ~IOrModelChecker() { + // Intentionally left empty + } + /*! - * @brief Evaluates Or formula within a model checker. + * Evaluates Or formula within a model checker. * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. + * @param obj Formula object with subformulas. + * @return Result of the formula for every node. */ virtual storm::storage::BitVector checkOr(const Or<T>& obj) const = 0; }; /*! - * @brief - * Class for an abstract formula tree with OR node as root. + * Class for a Prctl formula tree with an Or node as root. * - * Has two Abstract state formulas as sub formulas/trees. + * Has two state formulas as sub formulas/trees. * - * As OR is commutative, the order is \e theoretically not important, but will influence the order in which + * As Or is commutative, the order is \e theoretically not important, but will influence the order in which * the model checker works. * - * The subtrees are seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) + * The object has shared ownership of its subtrees. If this object is deleted and no other object has a shared + * ownership of the subtrees they will be deleted as well. * * @see AbstractStateFormula * @see AbstractPrctlFormula @@ -55,28 +63,25 @@ class Or : public AbstractStateFormula<T> { public: /*! - * Empty constructor. - * Will create an OR-node without subnotes. Will not represent a complete formula! + * Creates an Or node without subnodes. + * The resulting object will not represent a complete formula! */ Or() : left(nullptr), right(nullptr) { // Intentionally left empty. } /*! - * Constructor. - * Creates an OR note with the parameters as subtrees. + * Creates an Or node with the parameters as subtrees. * - * @param left The left sub formula - * @param right The right sub formula + * @param left The left sub formula. + * @param right The right sub formula. */ Or(std::shared_ptr<AbstractStateFormula<T>> left, std::shared_ptr<AbstractStateFormula<T>> right) : left(left), right(right) { // Intentionally left empty. } /*! - * Destructor. - * - * Deletes the subtree iff this object is the last remaining owner of the subtree. + * Empty virtual destructor. */ virtual ~Or() { // Intentionally left empty. @@ -85,16 +90,16 @@ public: /*! * Clones the called object. * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones + * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones. * - * @returns a new AND-object that is identical the called object. + * @returns A new Or object that is a deep copy of the called object. */ virtual std::shared_ptr<AbstractStateFormula<T>> clone() const override { std::shared_ptr<Or<T>> result(new Or()); - if (this->leftIsSet()) { + if (this->isLeftSet()) { result->setLeft(left->clone()); } - if (this->rightIsSet()) { + if (this->isRightSet()) { result->setRight(right->clone()); } return result; @@ -114,7 +119,9 @@ public: } /*! - * @returns a string representation of the formula + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. */ virtual std::string toString() const override { std::string result = "("; @@ -136,55 +143,65 @@ public: } /*! - * Sets the left child node. + * Gets the left child node. * - * @param newLeft the new left child. + * @returns The left child node. */ - void setLeft(std::shared_ptr<AbstractStateFormula<T>> const & newLeft) { - left = newLeft; + std::shared_ptr<AbstractStateFormula<T>> const & getLeft() const { + return left; } /*! - * Sets the right child node. + * Gets the right child node. * - * @param newRight the new right child. + * @returns The right child node. */ - void setRight(std::shared_ptr<AbstractStateFormula<T>> const & newRight) { - right = newRight; + std::shared_ptr<AbstractStateFormula<T>> const & getRight() const { + return right; } /*! - * @returns a pointer to the left child node + * Sets the left child node. + * + * @param newLeft The new left child. */ - std::shared_ptr<AbstractStateFormula<T>> const & getLeft() const { - return left; + void setLeft(std::shared_ptr<AbstractStateFormula<T>> const & newLeft) { + left = newLeft; } /*! - * @returns a pointer to the right child node + * Sets the right child node. + * + * @param newRight The new right child. */ - std::shared_ptr<AbstractStateFormula<T>> const & getRight() const { - return right; + void setRight(std::shared_ptr<AbstractStateFormula<T>> const & newRight) { + right = newRight; } /*! + * Checks if the left child is set, i.e. it does not point to null. * - * @return True if the left child is set, i.e. it does not point to nullptr; false otherwise + * @return True iff the left child is set. */ - bool leftIsSet() const { + bool isLeftSet() const { return left.get() != nullptr; } /*! + * Checks if the right child is set, i.e. it does not point to null. * - * @return True if the right child is set, i.e. it does not point to nullptr; false otherwise + * @return True iff the left right is set. */ - bool rightIsSet() const { + bool isRightSet() const { return right.get() != nullptr; } private: + + // The left child node. std::shared_ptr<AbstractStateFormula<T>> left; + + // The right child node. std::shared_ptr<AbstractStateFormula<T>> right; }; diff --git a/src/formula/prctl/PrctlFilter.h b/src/formula/prctl/PrctlFilter.h index 6341764f9..02ffa5c5a 100644 --- a/src/formula/prctl/PrctlFilter.h +++ b/src/formula/prctl/PrctlFilter.h @@ -15,15 +15,6 @@ #include "src/modelchecker/prctl/AbstractModelChecker.h" #include "src/formula/actions/AbstractAction.h" -// TODO: Test if this can be can be ommitted. -namespace storm { -namespace property { -namespace action { - template <typename T> class AbstractAction; -} -} -} - #include <algorithm> #include <memory> @@ -31,33 +22,81 @@ namespace storm { namespace property { namespace prctl { +/*! + * This is the Prctl specific filter. + * + * It maintains a Prctl formula which can be checked against a given model by either calling evaluate() or check(). + * Additionally it maintains a list of filter actions that are used to further manipulate the modelchecking results and prepare them for output. + */ template <class T> class PrctlFilter : public storm::property::AbstractFilter<T> { + // Convenience typedef to make the code more readable. typedef typename storm::property::action::AbstractAction<T>::Result Result; public: + /*! + * Creates an empty PrctlFilter, maintaining no Prctl formula. + * + * Calling check or evaluate will return an empty result. + */ PrctlFilter() : AbstractFilter<T>(UNDEFINED), child(nullptr) { // Intentionally left empty. } + /*! + * Creates a PrctlFilter maintaining a Prctl formula but containing no actions. + * + * The modelchecking result will be returned or printed as is. + * + * @param child The Prctl formula to be maintained. + * @param opt An enum value indicating which kind of scheduler shall be used for path formulas on nondeterministic models. + */ PrctlFilter(std::shared_ptr<AbstractPrctlFormula<T>> const & child, OptimizingOperator opt = UNDEFINED) : AbstractFilter<T>(opt), child(child) { // Intentionally left empty. } + /*! + * Creates a PrctlFilter maintaining a Prctl formula and containing a single action. + * + * The given action will be applied to the modelchecking result during evaluation. + * Further actions can be added later. + * + * @param child The Prctl formula to be maintained. + * @param action The single action to be executed during evaluation. + * @param opt An enum value indicating which kind of scheduler shall be used for path formulas on nondeterministic models. + */ PrctlFilter(std::shared_ptr<AbstractPrctlFormula<T>> const & child, std::shared_ptr<action::AbstractAction<T>> const & action, OptimizingOperator opt = UNDEFINED) : AbstractFilter<T>(action, opt), child(child) { // Intentionally left empty. } + /*! + * Creates a PrctlFilter using the given parameters. + * + * The given actions will be applied to the modelchecking result in ascending index order during evaluation. + * Further actions can be added later. + * + * @param child The Prctl formula to be maintained. + * @param actions A vector conatining the actions that are to be executed during evaluation. + * @param opt An enum value indicating which kind of scheduler shall be used for path formulas on nondeterministic models. + */ PrctlFilter(std::shared_ptr<AbstractPrctlFormula<T>> const & child, std::vector<std::shared_ptr<action::AbstractAction<T>>> const & actions, OptimizingOperator opt = UNDEFINED) : AbstractFilter<T>(actions, opt), child(child) { // Intentionally left empty. } + /*! + * Empty virtual destructor. + */ virtual ~PrctlFilter() { // Intentionally left empty. } + /*! + * Calls the modelchecker, retrieves the modelchecking result, applies the filter action one by one and prints out the result. + * + * @param modelchecker The modelchecker to be called. + */ void check(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelchecker) const { // Write out the formula to be checked. @@ -68,6 +107,12 @@ public: writeOut(evaluate(modelchecker), modelchecker); } + /*! + * Calls the modelchecker, retrieves the modelchecking result, applies the filter action one by one and returns the result. + * + * @param modelchecker The modelchecker to be called. + * @returns The result of the sequential application of the filter actions to the modelchecking result. + */ Result evaluate(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelchecker) const { Result result; @@ -88,6 +133,13 @@ public: return result; } + /*! + * Returns a textual representation of the filter. + * + * That includes the actions as well as the maintained formula. + * + * @returns A string representing the filter. + */ virtual std::string toString() const override { std::string desc = ""; @@ -175,26 +227,44 @@ public: return desc; } - virtual std::string toPrettyString() const override { - std::string desc = "Filter: "; - desc += "\nActions:"; - for(auto action : this->actions) { - desc += "\n\t" + action->toString(); - } - desc += "\nFormula:\n\t" + child->toString(); - return desc; + /*! + * Gets the child node. + * + * @returns The child node. + */ + std::shared_ptr<AbstractPrctlFormula<T>> const & getChild() const { + return child; } + /*! + * Sets the subtree. + * + * @param child The new child. + */ void setChild(std::shared_ptr<AbstractPrctlFormula<T>> const & child) { this->child = child; } - std::shared_ptr<AbstractPrctlFormula<T>> const & getChild() const { - return child; + /*! + * Checks if the child is set, i.e. it does not point to null. + * + * @return True iff the child is set. + */ + bool isChildSet() const { + return child.get() != nullptr; } private: + /*! + * Calls the modelchecker for a state formula, retrieves the modelchecking result, applies the filter action one by one and returns the result. + * + * This an internal version of the evaluate method overloading it for the different Prctl formula types. + * + * @param modelchecker The modelchecker to be called. + * @param formula The state formula for which the modelchecker will be called. + * @returns The result of the sequential application of the filter actions to the modelchecking result. + */ Result evaluate(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelchecker, std::shared_ptr<AbstractStateFormula<T>> const & formula) const { // First, get the model checking result. Result result; @@ -210,6 +280,15 @@ private: return evaluateActions(result, modelchecker); } + /*! + * Calls the modelchecker for a path formula, retrieves the modelchecking result, applies the filter action one by one and returns the result. + * + * This an internal version of the evaluate method overloading it for the different Prctl formula types. + * + * @param modelchecker The modelchecker to be called. + * @param formula The path formula for which the modelchecker will be called. + * @returns The result of the sequential application of the filter actions to the modelchecking result. + */ Result evaluate(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelchecker, std::shared_ptr<AbstractPathFormula<T>> const & formula) const { // First, get the model checking result. Result result; @@ -225,6 +304,15 @@ private: return evaluateActions(result, modelchecker); } + /*! + * Calls the modelchecker for a reward formula, retrieves the modelchecking result, applies the filter action one by one and returns the result. + * + * This an internal version of the evaluate method overloading it for the different Prctl formula types. + * + * @param modelchecker The modelchecker to be called. + * @param formula The reward formula for which the modelchecker will be called. + * @returns The result of the sequential application of the filter actions to the modelchecking result. + */ Result evaluate(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelchecker, std::shared_ptr<AbstractRewardPathFormula<T>> const & formula) const { // First, get the model checking result. Result result; @@ -240,6 +328,13 @@ private: return evaluateActions(result, modelchecker); } + /*! + * Evaluates the filter actions by calling them one by one using the output of each action as the input for the next one. + * + * @param input The modelchecking result in form of a Result struct. + * @param modelchecker The modelchecker that was called to generate the modelchecking result. Needed by some actions. + * @returns The result of the sequential application of the filter actions to the modelchecking result. + */ Result evaluateActions(Result const & input, storm::modelchecker::prctl::AbstractModelChecker<T> const & modelchecker) const { // Init the state selection and state map vectors. @@ -258,7 +353,12 @@ private: return result; } - + /*! + * Writes out the given result. + * + * @param result The result of the sequential application of the filter actions to a modelchecking result. + * @param modelchecker The modelchecker that was called to generate the modelchecking result. Needed for legacy support. + */ void writeOut(Result const & result, storm::modelchecker::prctl::AbstractModelChecker<T> const & modelchecker) const { // Test if there is anything to write out. @@ -323,6 +423,7 @@ private: std::cout << std::endl << "-------------------------------------------" << std::endl; } + // The Prctl formula maintained by this filter. std::shared_ptr<AbstractPrctlFormula<T>> child; }; diff --git a/src/formula/prctl/ProbabilisticBoundOperator.h b/src/formula/prctl/ProbabilisticBoundOperator.h index 6905d9069..abaf1e1db 100644 --- a/src/formula/prctl/ProbabilisticBoundOperator.h +++ b/src/formula/prctl/ProbabilisticBoundOperator.h @@ -17,40 +17,51 @@ namespace storm { namespace property { namespace prctl { +// Forward declaration for the interface class. template <class T> class ProbabilisticBoundOperator; /*! - * @brief Interface class for model checkers that support ProbabilisticBoundOperator. + * Interface class for model checkers that support ProbabilisticBoundOperator. * - * All model checkers that support the formula class PathBoundOperator must inherit - * this pure virtual class. + * All model checkers that support the formula class PathBoundOperator must inherit + * this pure virtual class. */ template <class T> class IProbabilisticBoundOperatorModelChecker { public: + + /*! + * Empty virtual destructor. + */ + virtual ~IProbabilisticBoundOperatorModelChecker() { + // Intentionally left empty + } + + /*! + * Evaluates a ProbabilisticBoundOperator within a model checker. + * + * @param obj Formula object with subformulas. + * @return The modelchecking result of the formula for every state. + */ virtual storm::storage::BitVector checkProbabilisticBoundOperator(const ProbabilisticBoundOperator<T>& obj) const = 0; }; /*! - * @brief - * Class for an abstract formula tree with a P (probablistic) operator node over a probability interval - * as root. + * Class for a Prctl formula tree with a P (probablistic) bound operator node as root. * - * Has one Abstract path formula as sub formula/tree. + * Has one path formula as sub formula/tree. * * @par Semantics - * The formula holds iff the probability that the path formula holds is inside the bounds - * specified in this operator - * - * The subtree is seen as part of the object and deleted with it - * (this behavior can be prevented by setting them to NULL before deletion) + * The formula holds iff the probability that the path formula holds meets the bound + * specified in this operator. * + * The object has shared ownership of its subtree. If this object is deleted and no other object has a shared + * ownership of the subtree it will be deleted as well. * * @see AbstractStateFormula * @see AbstractPathFormula - * @see ProbabilisticOperator - * @see ProbabilisticNoBoundsOperator * @see AbstractPrctlFormula + * @see RewardBoundOperator */ template<class T> class ProbabilisticBoundOperator : public AbstractStateFormula<T> { @@ -58,18 +69,19 @@ class ProbabilisticBoundOperator : public AbstractStateFormula<T> { public: /*! - * Empty constructor + * Creates a ProbabilisticBoundOperator node without a subnode. + * The resulting object will not represent a complete formula! */ ProbabilisticBoundOperator() : comparisonOperator(LESS), bound(0), child(nullptr) { // Intentionally left empty. } /*! - * Constructor for non-optimizing operator. + * Creates a ProbabilisticBoundOperator node using the given parameters. * * @param comparisonOperator The relation for the bound. - * @param bound The bound for the probability - * @param child The child node + * @param bound The bound for the probability. + * @param child The child formula subtree. */ ProbabilisticBoundOperator(storm::property::ComparisonType comparisonOperator, T bound, std::shared_ptr<AbstractPathFormula<T>> const & child) : comparisonOperator(comparisonOperator), bound(bound), child(child) { @@ -77,9 +89,7 @@ public: } /*! - * Destructor - * - * Deletes the subtree iff this object is the last remaining owner of the subtree. + * Empty virtual destructor. */ virtual ~ProbabilisticBoundOperator() { // Intentionally left empty. @@ -88,9 +98,9 @@ public: /*! * Clones the called object. * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. * - * @returns a new AND-object that is identical the called object. + * @returns A new ProbabilisticBoundOperator object that is a deep copy of the called object. */ virtual std::shared_ptr<AbstractStateFormula<T>> clone() const override { std::shared_ptr<ProbabilisticBoundOperator<T>> result(new ProbabilisticBoundOperator<T>()); @@ -114,7 +124,9 @@ public: } /*! - * @returns a string representation of the formula + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. */ virtual std::string toString() const override { std::string result = "P "; @@ -133,56 +145,74 @@ public: } /*! - * @returns the child node (representation of a formula) + * Gets the child node. + * + * @returns The child node. */ std::shared_ptr<AbstractPathFormula<T>> const & getChild () const { return child; } /*! - * Sets the child node + * Sets the subtree. * - * @param child the path formula that becomes the new child node + * @param child The new child. */ void setChild(std::shared_ptr<AbstractPathFormula<T>> const & child) { this->child = child; } /*! + * Checks if the child is set, i.e. it does not point to null. * - * @return True if the path formula is set, i.e. it does not point to nullptr; false otherwise + * @return True iff the child is set. */ - bool childIsSet() const { + bool isChildSet() const { return child.get() != nullptr; } /*! - * @returns the comparison relation + * Gets the comparison operator. + * + * @returns An enum value representing the comparison relation. */ storm::property::ComparisonType const getComparisonOperator() const { return comparisonOperator; } + /*! + * Sets the comparison operator. + * + * @param comparisonOperator An enum value representing the new comparison relation. + */ void setComparisonOperator(storm::property::ComparisonType comparisonOperator) { this->comparisonOperator = comparisonOperator; } /*! - * @returns the bound for the measure + * Gets the bound which the probability that the path formula holds has to obey. + * + * @returns The probability bound. */ T const & getBound() const { return bound; } /*! - * Sets the interval in which the probability that the path formula holds may lie in. + * Sets the bound which the probability that the path formula holds has to obey. * - * @param bound The bound for the measure + * @param bound The new probability bound. */ void setBound(T bound) { this->bound = bound; } + /*! + * Checks if the bound is met by the given value. + * + * @param value The value to test against the bound. + * @returns True iff value <comparisonOperator> bound holds. + */ bool meetsBound(T value) const { switch (comparisonOperator) { case LESS: return value < bound; break; @@ -194,8 +224,14 @@ public: } private: + + // The operator used to indicate the kind of bound that is to be met. storm::property::ComparisonType comparisonOperator; + + // The probability bound. T bound; + + // The path formula for which the probability to be satisfied has to meet the bound. std::shared_ptr<AbstractPathFormula<T>> child; }; diff --git a/src/formula/prctl/ReachabilityReward.h b/src/formula/prctl/ReachabilityReward.h index 0fe5f5792..2187b6250 100644 --- a/src/formula/prctl/ReachabilityReward.h +++ b/src/formula/prctl/ReachabilityReward.h @@ -15,62 +15,77 @@ namespace storm { namespace property { namespace prctl { +// Forward declaration for the interface class. template <class T> class ReachabilityReward; /*! - * @brief Interface class for model checkers that support ReachabilityReward. + * Interface class for model checkers that support ReachabilityReward. * - * All model checkers that support the formula class ReachabilityReward must inherit - * this pure virtual class. + * All model checkers that support the formula class ReachabilityReward must inherit + * this pure virtual class. */ template <class T> class IReachabilityRewardModelChecker { public: + + /*! + * Empty virtual destructor. + */ + virtual ~IReachabilityRewardModelChecker() { + // Intentionally left empty + } + /*! - * @brief Evaluates ReachabilityReward formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ + * Evaluates a ReachabilityReward formula within a model checker. + * + * @param obj Formula object with subformulas. + * @param qualitative A flag indicating whether the formula only needs to be evaluated qualitatively, i.e. if the + * results are only compared against the bounds 0 and 1. + * @return The modelchecking result of the formula for every state. + */ virtual std::vector<T> checkReachabilityReward(const ReachabilityReward<T>& obj, bool qualitative) const = 0; }; /*! - * @brief - * Class for an abstract (path) formula tree with an Reachability Reward node as root. + * Class for an Prctl (reward path) formula tree with an Reachability Reward node as root. + * + * Has one state formula as sub formula/tree. * - * Has one Abstract state formula as sub formula/tree. + * This formula expresses the rewards received or costs needed to reach a state satisfying the formula \e child. + * In case the state under consiteration itself satisfies the formula \e child the rewards are zero. + * In case that there is a non zero probability of not reaching any of the target states the rewards are infinite. + * Also note that for this formula both state and transition rewards are considered and use if available in the model. * - * The subtree is seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to nullptr before deletion) + * The object has shared ownership of its subtree. If this object is deleted and no other object has a shared + * ownership of the subtree it will be deleted as well. * - * @see AbstractPathFormula + * @see AbstractRewardPathFormula * @see AbstractPrctlFormula */ template <class T> class ReachabilityReward : public AbstractRewardPathFormula<T> { public: + /*! - * Empty constructor + * Creates a ReachabilityReward node without a subnode. + * The resulting object will not represent a complete formula! */ ReachabilityReward() : child(nullptr){ // Intentionally left empty } /*! - * Constructor + * Creates an Eventually node using the given parameter. * - * @param child The child node + * @param child The child formula subtree. */ ReachabilityReward(std::shared_ptr<AbstractStateFormula<T>> child) : child(child){ // Intentionally left empty } /*! - * Destructor. - * - * Deletes the subtree iff this object is the last remaining owner of the subtree. + * Empty virtual destructor. */ virtual ~ReachabilityReward() { // Intentionally left empty. @@ -79,13 +94,13 @@ public: /*! * Clones the called object. * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. * - * @returns a new ReachabilityReward-object that is identical the called object. + * @returns A new ReachabilityReward object that is a deep copy of the called object. */ virtual std::shared_ptr<AbstractRewardPathFormula<T>> clone() const override { std::shared_ptr<ReachabilityReward<T>> result(new ReachabilityReward<T>()); - if (this->childIsSet()) { + if (this->isChildSet()) { result->setChild(child->clone()); } return result; @@ -105,7 +120,9 @@ public: } /*! - * @returns a string representation of the formula + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. */ virtual std::string toString() const override { std::string result = "F "; @@ -114,29 +131,35 @@ public: } /*! - * @returns the child node + * Gets the child node. + * + * @returns The child node. */ std::shared_ptr<AbstractStateFormula<T>> const & getChild() const { return child; } /*! - * Sets the subtree - * @param child the new child node + * Sets the subtree. + * + * @param child The new child. */ void setChild(std::shared_ptr<AbstractStateFormula<T>> const & child) { this->child = child; } /*! + * Checks if the child is set, i.e. it does not point to null. * - * @return True if the child node is set, i.e. it does not point to nullptr; false otherwise + * @return True iff the child is set. */ - bool childIsSet() const { + bool isChildSet() const { return child.get() != nullptr; } private: + + // The child node. std::shared_ptr<AbstractStateFormula<T>> child; }; diff --git a/src/formula/prctl/RewardBoundOperator.h b/src/formula/prctl/RewardBoundOperator.h index 12900c58c..a7a4089a9 100644 --- a/src/formula/prctl/RewardBoundOperator.h +++ b/src/formula/prctl/RewardBoundOperator.h @@ -17,57 +17,72 @@ namespace storm { namespace property { namespace prctl { +// Forward declaration for the interface class. template <class T> class RewardBoundOperator; /*! - * @brief Interface class for model checkers that support RewardBoundOperator. + * Interface class for model checkers that support RewardBoundOperator. * - * All model checkers that support the formula class PathBoundOperator must inherit - * this pure virtual class. + * All model checkers that support the formula class PathBoundOperator must inherit + * this pure virtual class. */ template <class T> class IRewardBoundOperatorModelChecker { public: + + /*! + * Empty virtual destructor. + */ + virtual ~IRewardBoundOperatorModelChecker() { + // Intentionally left empty + } + + /*! + * Evaluates a RewardBoundOperator within a model checker. + * + * @param obj Formula object with subformulas. + * @return The modelchecking result of the formula for every state. + */ virtual storm::storage::BitVector checkRewardBoundOperator(const RewardBoundOperator<T>& obj) const = 0; }; /*! - * @brief - * Class for an abstract formula tree with a R (reward) operator node over a reward interval as root. + * Class for a Prctl formula tree with an R (reward) operator node as root. * * Has a reward path formula as sub formula/tree. * * @par Semantics - * The formula holds iff the reward of the reward path formula is inside the bounds - * specified in this operator + * The formula holds iff the reward of the reward path formula meets the bound + * specified in this operator. * - * The subtree is seen as part of the object and deleted with it - * (this behavior can be prevented by setting them to NULL before deletion) + * The object has shared ownership of its subtree. If this object is deleted and no other object has a shared + * ownership of the subtree it will be deleted as well. * * * @see AbstractStateFormula - * @see AbstractPathFormula - * @see ProbabilisticOperator - * @see ProbabilisticNoBoundsOperator + * @see AbstractRewardPathFormula * @see AbstractPrctlFormula + * @see ProbabilisticBoundOperator */ template<class T> class RewardBoundOperator : public AbstractStateFormula<T> { public: + /*! - * Empty constructor + * Creates a RewardBoundOperator node without a subnode. + * The resulting object will not represent a complete formula! */ RewardBoundOperator() : comparisonOperator(LESS), bound(0), child(nullptr){ // Intentionally left empty } /*! - * Constructor for non-optimizing operator. + * Creates a ProbabilisticBoundOperator node using the given parameters. * * @param comparisonOperator The relation for the bound. - * @param bound The bound for the probability - * @param child The child node + * @param bound The bound for the rewards. + * @param child The child formula subtree. */ RewardBoundOperator(storm::property::ComparisonType comparisonOperator, T bound, std::shared_ptr<AbstractRewardPathFormula<T>> const & child) : comparisonOperator(comparisonOperator), bound(bound), child(child) { @@ -75,9 +90,7 @@ public: } /*! - * Destructor - * - * Deletes the subtree iff this object is the last remaining owner of the subtree. + * Empty virtual destructor. */ virtual ~RewardBoundOperator() { // Intentionally left empty. @@ -86,9 +99,9 @@ public: /*! * Clones the called object. * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. * - * @returns a new AND-object that is identical the called object. + * @returns A new RewardBoundOperator object that is a deep copy of the called object. */ virtual std::shared_ptr<AbstractStateFormula<T>> clone() const override { std::shared_ptr<RewardBoundOperator<T>> result(new RewardBoundOperator<T>()); @@ -112,7 +125,9 @@ public: } /*! - * @returns a string representation of the formula + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. */ virtual std::string toString() const override { std::string result = "R "; @@ -131,56 +146,74 @@ public: } /*! - * @returns the child node (representation of a formula) + * Gets the child node. + * + * @returns The child node. */ std::shared_ptr<AbstractRewardPathFormula<T>> const & getChild () const { return child; } /*! - * Sets the child node + * Sets the subtree. * - * @param child the path formula that becomes the new child node + * @param child The new child. */ void setChild(std::shared_ptr<AbstractRewardPathFormula<T>> const & child) { this->child = child; } /*! + * Checks if the child is set, i.e. it does not point to null. * - * @return True if the path formula is set, i.e. it does not point to nullptr; false otherwise + * @return True iff the child is set. */ - bool childIsSet() const { + bool isChildSet() const { return child.get() != nullptr; } /*! - * @returns the comparison relation + * Gets the comparison operator. + * + * @returns An enum value representing the comparison relation. */ storm::property::ComparisonType const getComparisonOperator() const { return comparisonOperator; } + /*! + * Sets the comparison operator. + * + * @param comparisonOperator An enum value representing the new comparison relation. + */ void setComparisonOperator(storm::property::ComparisonType comparisonOperator) { this->comparisonOperator = comparisonOperator; } /*! - * @returns the bound for the measure + * Gets the bound which is to be obeyed by the rewards of the reward path formula. + * + * @returns The probability bound. */ T const & getBound() const { return bound; } /*! - * Sets the interval in which the probability that the path formula holds may lie in. + * Sets the bound which is to be obeyed by the rewards of the reward path formula * - * @param bound The bound for the measure + * @param bound The new reward bound. */ void setBound(T bound) { this->bound = bound; } + /*! + * Checks if the bound is met by the given value. + * + * @param value The value to test against the bound. + * @returns True iff value <comparisonOperator> bound holds. + */ bool meetsBound(T value) const { switch (comparisonOperator) { case LESS: return value < bound; break; @@ -192,8 +225,14 @@ public: } private: + + // The operator used to indicate the kind of bound that is to be met. storm::property::ComparisonType comparisonOperator; + + // The reward bound. T bound; + + // The reward path formula whose rewards have to meet the bound. std::shared_ptr<AbstractRewardPathFormula<T>> child; }; diff --git a/src/formula/prctl/SteadyStateReward.h b/src/formula/prctl/SteadyStateReward.h index 84774998f..c075abba9 100644 --- a/src/formula/prctl/SteadyStateReward.h +++ b/src/formula/prctl/SteadyStateReward.h @@ -15,43 +15,60 @@ namespace storm { namespace property { namespace prctl { +// Forward declaration for the interface class. template <class T> class SteadyStateReward; /*! - * @brief Interface class for model checkers that support SteadyStateReward. + * Interface class for model checkers that support SteadyStateReward. * - * All model checkers that support the formula class SteadyStateReward must inherit - * this pure virtual class. + * All model checkers that support the formula class SteadyStateReward must inherit + * this pure virtual class. */ template <class T> class ISteadyStateRewardModelChecker { public: + + /*! + * Empty virtual destructor. + */ + virtual ~ISteadyStateRewardModelChecker() { + // Intentionally left empty + } + /*! - * @brief Evaluates CumulativeReward formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ + * Evaluates a SteadyStateReward formula within a model checker. + * + * @param obj Formula object with subformulas. + * @param qualitative A flag indicating whether the formula only needs to be evaluated qualitatively, i.e. if the + * results are only compared against the bounds 0 and 1. + * @return The modelchecking result of the formula for every state. + */ virtual std::vector<T> checkSteadyStateReward(const SteadyStateReward<T>& obj, bool qualitative) const = 0; }; /*! - * @brief - * Class for an abstract (path) formula tree with a Steady State Reward node as root. + * Class for a Steady State Reward formula. + * This class represents a possible leaf in a reward formula tree. + * + * This formula expresses the expected long-run rewards for each state in the model. * - * @see AbstractPathFormula + * @see AbstractRewardPathFormula * @see AbstractPrctlFormula */ template <class T> class SteadyStateReward: public AbstractRewardPathFormula<T> { public: + /*! - * Empty constructor + * Creates a new SteadyStateReward node. */ SteadyStateReward() { // Intentionally left empty. } + /*! + * Empty virtual destructor. + */ virtual ~SteadyStateReward() { // Intentionally left empty. } @@ -59,12 +76,12 @@ public: /*! * Clones the called object. * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. * - * @returns a new SteadyState-object that is identical the called object. + * @returns A new SteadyStateReward object that is a deep copy of the called object. */ virtual std::shared_ptr<AbstractRewardPathFormula<T>> clone() const override { - std::shared_ptr<SteadyStateReward<T>> result(new SteadyStateReward<T>()); + auto result = std::make_shared<SteadyStateReward<T>>(); return result; } @@ -82,7 +99,9 @@ public: } /*! - * @returns a string representation of the formula + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. */ virtual std::string toString() const override { return "S"; diff --git a/src/formula/prctl/Until.h b/src/formula/prctl/Until.h index eb939b54f..27eb89167 100644 --- a/src/formula/prctl/Until.h +++ b/src/formula/prctl/Until.h @@ -15,41 +15,52 @@ namespace storm { namespace property { namespace prctl { +// Forward declaration for the interface class. template <class T> class Until; /*! - * @brief Interface class for model checkers that support Until. + * Interface class for model checkers that support Until. * - * All model checkers that support the formula class Until must inherit - * this pure virtual class. + * All model checkers that support the formula class Until must inherit + * this pure virtual class. */ template <class T> class IUntilModelChecker { public: + + /*! + * Empty virtual destructor. + */ + virtual ~IUntilModelChecker() { + // Intentionally left empty + } + /*! - * @brief Evaluates Until formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ + * Evaluates an Until formula within a model checker. + * + * @param obj Formula object with subformulas. + * @param qualitative A flag indicating whether the formula only needs to be evaluated qualitatively, i.e. if the + * results are only compared against the bounds 0 and 1. + * @return The modelchecking result of the formula for every state. + */ virtual std::vector<T> checkUntil(const Until<T>& obj, bool qualitative) const = 0; }; /*! - * @brief - * Class for an abstract (path) formula tree with an Until node as root. + * Class for a Prctl (path) formula tree with an Until node as root. * - * Has two Abstract state formulas as sub formulas/trees. + * Has two state formulas as sub formulas/trees. * * @par Semantics * The formula holds iff eventually, formula \e right (the right subtree) holds, and before, * \e left holds always. * - * The subtrees are seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) + * The object has shared ownership of its subtrees. If this object is deleted and no other object has a shared + * ownership of the subtrees they will be deleted as well. * * @see AbstractPathFormula * @see AbstractPrctlFormula + * @see BoundedUntil */ template <class T> class Until : public AbstractPathFormula<T> { @@ -57,26 +68,25 @@ class Until : public AbstractPathFormula<T> { public: /*! - * Empty constructor + * Creates an Until node without subnodes. + * The resulting object will not represent a complete formula! */ - Until() : left(nullptr), right(nullptr){ + Until() : left(nullptr), right(nullptr) { // Intentionally left empty. } /*! - * Constructor + * Creates an Until node using the given parameters. * - * @param left The left formula subtree - * @param right The left formula subtree + * @param left The left formula subtree. + * @param right The right formula subtree. */ - Until(std::shared_ptr<AbstractStateFormula<T>> const & left, std::shared_ptr<AbstractStateFormula<T>> const & right) : left(left), right(right){ + Until(std::shared_ptr<AbstractStateFormula<T>> const & left, std::shared_ptr<AbstractStateFormula<T>> const & right) : left(left), right(right) { // Intentionally left empty. } /*! - * Destructor. - * - * Deletes the subtrees iff this object is the last remaining owner of the subtree to be deleted. + * Empty virtual destructor. */ virtual ~Until() { // Intentionally left empty. @@ -85,16 +95,16 @@ public: /*! * Clones the called object. * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. * - * @returns a new BoundedUntil-object that is identical the called object. + * @returns A new Until object that is a deep copy of the called object. */ virtual std::shared_ptr<AbstractPathFormula<T>> clone() const override { std::shared_ptr<Until<T>> result(new Until()); - if (this->leftIsSet()) { + if (this->isLeftSet()) { result->setLeft(left->clone()); } - if (this->rightIsSet()) { + if (this->isRightSet()) { result->setRight(right->clone()); } return result; @@ -114,7 +124,9 @@ public: } /*! - * @returns a string representation of the formula + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. */ virtual std::string toString() const override { std::string result = left->toString(); @@ -124,55 +136,65 @@ public: } /*! - * Sets the left child node. + * Gets the left child node. * - * @param newLeft the new left child. + * @returns The left child node. */ - void setLeft(std::shared_ptr<AbstractStateFormula<T>> const & newLeft) { - left = newLeft; + std::shared_ptr<AbstractStateFormula<T>> const & getLeft() const { + return left; } /*! - * Sets the right child node. + * Gets the right child node. * - * @param newRight the new right child. + * @returns The right child node. */ - void setRight(std::shared_ptr<AbstractStateFormula<T>> const & newRight) { - right = newRight; + std::shared_ptr<AbstractStateFormula<T>> const & getRight() const { + return right; } /*! - * @returns a pointer to the left child node + * Sets the left child node. + * + * @param newLeft The new left child. */ - std::shared_ptr<AbstractStateFormula<T>> const & getLeft() const { - return left; + void setLeft(std::shared_ptr<AbstractStateFormula<T>> const & newLeft) { + left = newLeft; } /*! - * @returns a pointer to the right child node + * Sets the right child node. + * + * @param newRight The new right child. */ - std::shared_ptr<AbstractStateFormula<T>> const & getRight() const { - return right; + void setRight(std::shared_ptr<AbstractStateFormula<T>> const & newRight) { + right = newRight; } /*! + * Checks if the left child is set, i.e. it does not point to null. * - * @return True if the left child is set, i.e. it does not point to nullptr; false otherwise + * @return True iff the left child is set. */ - bool leftIsSet() const { + bool isLeftSet() const { return left.get() != nullptr; } /*! + * Checks if the right child is set, i.e. it does not point to null. * - * @return True if the right child is set, i.e. it does not point to nullptr; false otherwise + * @return True iff the right child is set. */ - bool rightIsSet() const { + bool isRightSet() const { return right.get() != nullptr; } private: + + // The left child node. std::shared_ptr<AbstractStateFormula<T>> left; + + // The right child node. std::shared_ptr<AbstractStateFormula<T>> right; }; diff --git a/src/parser/CslParser.h b/src/parser/CslParser.h index 9e9b85da5..ccb5b90c3 100644 --- a/src/parser/CslParser.h +++ b/src/parser/CslParser.h @@ -15,6 +15,11 @@ namespace storm { namespace parser { +/*! + * Reads a Csl formula from a string and returns the formula tree. + * + * If you want to read the formula from a file, use the LtlFileParser class instead. + */ class CslParser { public: @@ -24,8 +29,9 @@ public: * * If the string could not be parsed successfully, it will throw a wrongFormatException. * - * @param formulaString The string representation of the formula - * @throw wrongFormatException If the input could not be parsed successfully + * @param formulaString The string representation of the formula. + * @throw wrongFormatException If the input could not be parsed successfully. + * @return A CslFilter maintaining the parsed formula. */ static std::shared_ptr<storm::property::csl::CslFilter<double>> parseCslFormula(std::string formulaString); diff --git a/src/parser/LtlFileParser.h b/src/parser/LtlFileParser.h index 2fd73d10f..f21210b7d 100644 --- a/src/parser/LtlFileParser.h +++ b/src/parser/LtlFileParser.h @@ -22,8 +22,8 @@ public: /*! * Parses each line of a given file as prctl formula and returns a list containing the results of the parsing. * - * @param filename - * @return The list of parsed formulas + * @param filename Name and path to the file in which the formula strings can be found. + * @return The list of parsed formulas. */ static std::list<std::shared_ptr<storm::property::ltl::LtlFilter<double>>> parseLtlFile(std::string filename); }; diff --git a/src/parser/LtlParser.h b/src/parser/LtlParser.h index e5f24dec3..ebbad77c0 100644 --- a/src/parser/LtlParser.h +++ b/src/parser/LtlParser.h @@ -28,8 +28,9 @@ public: * * If the string could not be parsed successfully, it will throw a wrongFormatException. * - * @param formulaString The string representation of the formula - * @throw wrongFormatException If the input could not be parsed successfully + * @param formulaString The string representation of the formula. + * @throw wrongFormatException If the input could not be parsed successfully. + * @return A LtlFilter maintaining the parsed formula. */ static std::shared_ptr<storm::property::ltl::LtlFilter<double>> parseLtlFormula(std::string formulaString); diff --git a/src/parser/PrctlFileParser.h b/src/parser/PrctlFileParser.h index c992ddf03..615e219c1 100644 --- a/src/parser/PrctlFileParser.h +++ b/src/parser/PrctlFileParser.h @@ -20,9 +20,9 @@ class PrctlFileParser { public: /*! - * Parses each line of a given file as prctl formula and returns a list containing the results of the parsing. + * Parses each line of a given file as Prctl formula and returns a list containing the results of the parsing. * - * @param filename + * @param filename Name and path to the file in which the formula strings can be found. * @return The list of parsed formulas */ static std::list<std::shared_ptr<storm::property::prctl::PrctlFilter<double>>> parsePrctlFile(std::string filename); diff --git a/src/parser/PrctlParser.h b/src/parser/PrctlParser.h index f8d5d6e78..75e13c117 100644 --- a/src/parser/PrctlParser.h +++ b/src/parser/PrctlParser.h @@ -16,14 +16,14 @@ class PrctlParser { public: /*! - * Reads a PRCTL formula from its string representation and parses it into a formula tree, consisting of + * Reads a Prctl formula from its string representation and parses it into a formula tree, consisting of * classes in the namespace storm::property. * * If the string could not be parsed successfully, it will throw a wrongFormatException. * * @param formulaString The string representation of the formula * @throw wrongFormatException If the input could not be parsed successfully - * @return A pointer to the parsed Prctl formula. If the line just contained a comment a nullptr will be returned instead. + * @return A PrctlFilter maintaining the parsed formula. If the line just contained a comment a nullptr will be returned instead. */ static std::shared_ptr<storm::property::prctl::PrctlFilter<double>> parsePrctlFormula(std::string formulaString); From d75e32b83e1517bbb3f0ed2b670790ae5b1421fc Mon Sep 17 00:00:00 2001 From: masawei <manuel.sascha.weiand@rwth-aachen.de> Date: Fri, 29 Aug 2014 13:16:56 +0200 Subject: [PATCH 29/30] Renames the folder formula to properties and the namespace property to properties. Former-commit-id: 236ed22c7d628528c6919704580b6c689ea921d7 --- .../MILPMinimalLabelSetGenerator.h | 16 +-- .../PathBasedSubsystemGenerator.h | 12 +- .../SMTMinimalCommandSetGenerator.h | 16 +-- src/modelchecker/csl/AbstractModelChecker.h | 38 ++--- .../SparseMarkovAutomatonCslModelChecker.h | 16 +-- src/modelchecker/ltl/AbstractModelChecker.h | 30 ++-- src/modelchecker/prctl/AbstractModelChecker.h | 50 +++---- .../prctl/SparseDtmcPrctlModelChecker.h | 26 ++-- .../prctl/SparseMdpPrctlModelChecker.h | 32 ++--- src/parser/CslParser.cpp | 76 +++++----- src/parser/CslParser.h | 8 +- src/parser/LtlFileParser.cpp | 4 +- src/parser/LtlFileParser.h | 6 +- src/parser/LtlParser.cpp | 104 +++++++------- src/parser/LtlParser.h | 8 +- src/parser/PrctlFileParser.cpp | 6 +- src/parser/PrctlFileParser.h | 6 +- src/parser/PrctlParser.cpp | 130 +++++++++--------- src/parser/PrctlParser.h | 8 +- src/{formula => properties}/AbstractFilter.h | 8 +- src/{formula => properties}/AbstractFormula.h | 12 +- src/{formula => properties}/ComparisonType.h | 2 +- src/{formula => properties}/Csl.h | 0 src/{formula => properties}/Ltl.h | 0 src/{formula => properties}/Prctl.h | 0 .../actions/AbstractAction.h | 4 +- .../actions/BoundAction.h | 28 ++-- .../actions/FormulaAction.h | 18 +-- .../actions/InvertAction.h | 6 +- .../actions/RangeAction.h | 6 +- .../actions/SortAction.h | 6 +- .../csl/AbstractCslFormula.h | 22 +-- .../csl/AbstractPathFormula.h | 8 +- .../csl/AbstractStateFormula.h | 8 +- src/{formula => properties}/csl/And.h | 6 +- src/{formula => properties}/csl/Ap.h | 6 +- src/{formula => properties}/csl/CslFilter.h | 18 +-- src/{formula => properties}/csl/Eventually.h | 8 +- src/{formula => properties}/csl/Globally.h | 8 +- src/{formula => properties}/csl/Next.h | 8 +- src/{formula => properties}/csl/Not.h | 6 +- src/{formula => properties}/csl/Or.h | 6 +- .../csl/ProbabilisticBoundOperator.h | 18 +-- .../csl/SteadyStateBoundOperator.h | 8 +- .../csl/TimeBoundedEventually.h | 13 +- .../csl/TimeBoundedUntil.h | 15 +- src/{formula => properties}/csl/Until.h | 8 +- .../ltl/AbstractLtlFormula.h | 8 +- src/{formula => properties}/ltl/And.h | 4 +- src/{formula => properties}/ltl/Ap.h | 6 +- .../ltl/BoundedEventually.h | 4 +- .../ltl/BoundedUntil.h | 6 +- src/{formula => properties}/ltl/Eventually.h | 6 +- src/{formula => properties}/ltl/Globally.h | 4 +- src/{formula => properties}/ltl/LtlFilter.h | 14 +- src/{formula => properties}/ltl/Next.h | 4 +- src/{formula => properties}/ltl/Not.h | 4 +- src/{formula => properties}/ltl/Or.h | 6 +- src/{formula => properties}/ltl/Until.h | 4 +- .../prctl/AbstractPathFormula.h | 8 +- .../prctl/AbstractPrctlFormula.h | 22 +-- .../prctl/AbstractRewardPathFormula.h | 8 +- .../prctl/AbstractStateFormula.h | 8 +- src/{formula => properties}/prctl/And.h | 6 +- src/{formula => properties}/prctl/Ap.h | 6 +- .../prctl/BoundedEventually.h | 8 +- .../prctl/BoundedNaryUntil.h | 8 +- .../prctl/BoundedUntil.h | 8 +- .../prctl/CumulativeReward.h | 4 +- .../prctl/Eventually.h | 8 +- src/{formula => properties}/prctl/Globally.h | 8 +- .../prctl/InstantaneousReward.h | 4 +- src/{formula => properties}/prctl/Next.h | 8 +- src/{formula => properties}/prctl/Not.h | 4 +- src/{formula => properties}/prctl/Or.h | 6 +- .../prctl/PrctlFilter.h | 24 ++-- .../prctl/ProbabilisticBoundOperator.h | 14 +- .../prctl/ReachabilityReward.h | 4 +- .../prctl/RewardBoundOperator.h | 14 +- .../prctl/SteadyStateReward.h | 4 +- src/{formula => properties}/prctl/Until.h | 4 +- src/storm.cpp | 12 +- test/functional/modelchecker/ActionTest.cpp | 102 +++++++------- .../EigenDtmcPrctlModelCheckerTest.cpp | 60 ++++---- test/functional/modelchecker/FilterTest.cpp | 38 ++--- .../GmmxxDtmcPrctlModelCheckerTest.cpp | 40 +++--- .../SparseMdpPrctlModelCheckerTest.cpp | 36 ++--- test/functional/parser/CslParserTest.cpp | 34 ++--- test/functional/parser/LtlParserTest.cpp | 26 ++-- test/functional/parser/PrctlParserTest.cpp | 30 ++-- .../GmmxxDtmcPrctModelCheckerTest.cpp | 24 ++-- .../SparseMdpPrctlModelCheckerTest.cpp | 50 +++---- 92 files changed, 779 insertions(+), 779 deletions(-) rename src/{formula => properties}/AbstractFilter.h (97%) rename src/{formula => properties}/AbstractFormula.h (92%) rename src/{formula => properties}/ComparisonType.h (95%) rename src/{formula => properties}/Csl.h (100%) rename src/{formula => properties}/Ltl.h (100%) rename src/{formula => properties}/Prctl.h (100%) rename src/{formula => properties}/actions/AbstractAction.h (99%) rename src/{formula => properties}/actions/BoundAction.h (90%) rename src/{formula => properties}/actions/FormulaAction.h (84%) rename src/{formula => properties}/actions/InvertAction.h (97%) rename src/{formula => properties}/actions/RangeAction.h (98%) rename src/{formula => properties}/actions/SortAction.h (98%) rename src/{formula => properties}/csl/AbstractCslFormula.h (73%) rename src/{formula => properties}/csl/AbstractPathFormula.h (90%) rename src/{formula => properties}/csl/AbstractStateFormula.h (89%) rename src/{formula => properties}/csl/And.h (98%) rename src/{formula => properties}/csl/Ap.h (97%) rename src/{formula => properties}/csl/CslFilter.h (97%) rename src/{formula => properties}/csl/Eventually.h (96%) rename src/{formula => properties}/csl/Globally.h (96%) rename src/{formula => properties}/csl/Next.h (96%) rename src/{formula => properties}/csl/Not.h (97%) rename src/{formula => properties}/csl/Or.h (98%) rename src/{formula => properties}/csl/ProbabilisticBoundOperator.h (91%) rename src/{formula => properties}/csl/SteadyStateBoundOperator.h (96%) rename src/{formula => properties}/csl/TimeBoundedEventually.h (94%) rename src/{formula => properties}/csl/TimeBoundedUntil.h (94%) rename src/{formula => properties}/csl/Until.h (97%) rename src/{formula => properties}/ltl/AbstractLtlFormula.h (90%) rename src/{formula => properties}/ltl/And.h (99%) rename src/{formula => properties}/ltl/Ap.h (96%) rename src/{formula => properties}/ltl/BoundedEventually.h (99%) rename src/{formula => properties}/ltl/BoundedUntil.h (98%) rename src/{formula => properties}/ltl/Eventually.h (97%) rename src/{formula => properties}/ltl/Globally.h (98%) rename src/{formula => properties}/ltl/LtlFilter.h (96%) rename src/{formula => properties}/ltl/Next.h (98%) rename src/{formula => properties}/ltl/Not.h (98%) rename src/{formula => properties}/ltl/Or.h (97%) rename src/{formula => properties}/ltl/Until.h (99%) rename src/{formula => properties}/prctl/AbstractPathFormula.h (90%) rename src/{formula => properties}/prctl/AbstractPrctlFormula.h (73%) rename src/{formula => properties}/prctl/AbstractRewardPathFormula.h (90%) rename src/{formula => properties}/prctl/AbstractStateFormula.h (88%) rename src/{formula => properties}/prctl/And.h (98%) rename src/{formula => properties}/prctl/Ap.h (96%) rename src/{formula => properties}/prctl/BoundedEventually.h (97%) rename src/{formula => properties}/prctl/BoundedNaryUntil.h (97%) rename src/{formula => properties}/prctl/BoundedUntil.h (97%) rename src/{formula => properties}/prctl/CumulativeReward.h (98%) rename src/{formula => properties}/prctl/Eventually.h (96%) rename src/{formula => properties}/prctl/Globally.h (96%) rename src/{formula => properties}/prctl/InstantaneousReward.h (98%) rename src/{formula => properties}/prctl/Next.h (96%) rename src/{formula => properties}/prctl/Not.h (98%) rename src/{formula => properties}/prctl/Or.h (98%) rename src/{formula => properties}/prctl/PrctlFilter.h (95%) rename src/{formula => properties}/prctl/ProbabilisticBoundOperator.h (93%) rename src/{formula => properties}/prctl/ReachabilityReward.h (99%) rename src/{formula => properties}/prctl/RewardBoundOperator.h (93%) rename src/{formula => properties}/prctl/SteadyStateReward.h (98%) rename src/{formula => properties}/prctl/Until.h (99%) diff --git a/src/counterexamples/MILPMinimalLabelSetGenerator.h b/src/counterexamples/MILPMinimalLabelSetGenerator.h index 7e57fff60..33e632cc0 100644 --- a/src/counterexamples/MILPMinimalLabelSetGenerator.h +++ b/src/counterexamples/MILPMinimalLabelSetGenerator.h @@ -1000,35 +1000,35 @@ namespace storm { * @param formulaPtr A pointer to a safety formula. The outermost operator must be a probabilistic bound operator with a strict upper bound. The nested * formula can be either an unbounded until formula or an eventually formula. */ - static void computeCounterexample(storm::ir::Program const& program, storm::models::Mdp<T> const& labeledMdp, std::shared_ptr<storm::property::prctl::AbstractPrctlFormula<double>> const & formulaPtr) { + static void computeCounterexample(storm::ir::Program const& program, storm::models::Mdp<T> const& labeledMdp, std::shared_ptr<storm::properties::prctl::AbstractPrctlFormula<double>> const & formulaPtr) { std::cout << std::endl << "Generating minimal label counterexample for formula " << formulaPtr->toString() << std::endl; // First, we need to check whether the current formula is an Until-Formula. - std::shared_ptr<storm::property::prctl::ProbabilisticBoundOperator<double>> probBoundFormula = std::dynamic_pointer_cast<storm::property::prctl::ProbabilisticBoundOperator<double>>(formulaPtr); + std::shared_ptr<storm::properties::prctl::ProbabilisticBoundOperator<double>> probBoundFormula = std::dynamic_pointer_cast<storm::properties::prctl::ProbabilisticBoundOperator<double>>(formulaPtr); if (probBoundFormula.get() == nullptr) { LOG4CPLUS_ERROR(logger, "Illegal formula " << probBoundFormula->toString() << " for counterexample generation."); throw storm::exceptions::InvalidPropertyException() << "Illegal formula " << probBoundFormula->toString() << " for counterexample generation."; } - if (probBoundFormula->getComparisonOperator() != storm::property::ComparisonType::LESS && probBoundFormula->getComparisonOperator() != storm::property::ComparisonType::LESS_EQUAL) { + if (probBoundFormula->getComparisonOperator() != storm::properties::ComparisonType::LESS && probBoundFormula->getComparisonOperator() != storm::properties::ComparisonType::LESS_EQUAL) { LOG4CPLUS_ERROR(logger, "Illegal comparison operator in formula " << probBoundFormula->toString() << ". Only upper bounds are supported for counterexample generation."); throw storm::exceptions::InvalidPropertyException() << "Illegal comparison operator in formula " << probBoundFormula->toString() << ". Only upper bounds are supported for counterexample generation."; } - bool strictBound = !(probBoundFormula->getComparisonOperator() == storm::property::ComparisonType::LESS); + bool strictBound = !(probBoundFormula->getComparisonOperator() == storm::properties::ComparisonType::LESS); // Now derive the probability threshold we need to exceed as well as the phi and psi states. Simultaneously, check whether the formula is of a valid shape. double bound = probBoundFormula->getBound(); - std::shared_ptr<storm::property::prctl::AbstractPathFormula<double>> pathFormula = probBoundFormula->getChild(); + std::shared_ptr<storm::properties::prctl::AbstractPathFormula<double>> pathFormula = probBoundFormula->getChild(); storm::storage::BitVector phiStates; storm::storage::BitVector psiStates; storm::modelchecker::prctl::SparseMdpPrctlModelChecker<T> modelchecker(labeledMdp); - std::shared_ptr<storm::property::prctl::Until<double>> untilFormula = std::dynamic_pointer_cast<storm::property::prctl::Until<double>>(pathFormula); + std::shared_ptr<storm::properties::prctl::Until<double>> untilFormula = std::dynamic_pointer_cast<storm::properties::prctl::Until<double>>(pathFormula); if(untilFormula.get() != nullptr) { phiStates = untilFormula->getLeft()->check(modelchecker); psiStates = untilFormula->getRight()->check(modelchecker); - } if (std::dynamic_pointer_cast<storm::property::prctl::Eventually<double>>(pathFormula).get() != nullptr) { + } if (std::dynamic_pointer_cast<storm::properties::prctl::Eventually<double>>(pathFormula).get() != nullptr) { // If the nested formula was not an until formula, it remains to check whether it's an eventually formula. - std::shared_ptr<storm::property::prctl::Eventually<double>> eventuallyFormula = std::dynamic_pointer_cast<storm::property::prctl::Eventually<double>>(pathFormula); + std::shared_ptr<storm::properties::prctl::Eventually<double>> eventuallyFormula = std::dynamic_pointer_cast<storm::properties::prctl::Eventually<double>>(pathFormula); phiStates = storm::storage::BitVector(labeledMdp.getNumberOfStates(), true); psiStates = eventuallyFormula->getChild()->check(modelchecker); diff --git a/src/counterexamples/PathBasedSubsystemGenerator.h b/src/counterexamples/PathBasedSubsystemGenerator.h index 2713643bf..c4e7a6558 100644 --- a/src/counterexamples/PathBasedSubsystemGenerator.h +++ b/src/counterexamples/PathBasedSubsystemGenerator.h @@ -375,7 +375,7 @@ public: /*! * */ - static storm::models::Dtmc<T> computeCriticalSubsystem(storm::models::Dtmc<T> const & model, std::shared_ptr<storm::property::prctl::AbstractStateFormula<T>> const & stateFormula) { + static storm::models::Dtmc<T> computeCriticalSubsystem(storm::models::Dtmc<T> const & model, std::shared_ptr<storm::properties::prctl::AbstractStateFormula<T>> const & stateFormula) { //------------------------------------------------------------- // 1. Strip and handle formulas @@ -395,14 +395,14 @@ public: // Strip bound operator - std::shared_ptr<storm::property::prctl::ProbabilisticBoundOperator<T>> boundOperator = std::dynamic_pointer_cast<storm::property::prctl::ProbabilisticBoundOperator<T>>(stateFormula); + 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."); return model.getSubDtmc(subSys); } T bound = boundOperator->getBound(); - std::shared_ptr<storm::property::prctl::AbstractPathFormula<T>> pathFormula = boundOperator->getChild(); + std::shared_ptr<storm::properties::prctl::AbstractPathFormula<T>> pathFormula = boundOperator->getChild(); // get "init" labeled states storm::storage::BitVector initStates = model.getLabeledStates("init"); @@ -423,9 +423,9 @@ public: storm::storage::BitVector allowedStates; storm::storage::BitVector targetStates; - std::shared_ptr<storm::property::prctl::Eventually<T>> eventually = std::dynamic_pointer_cast<storm::property::prctl::Eventually<T>>(pathFormula); - std::shared_ptr<storm::property::prctl::Globally<T>> globally = std::dynamic_pointer_cast<storm::property::prctl::Globally<T>>(pathFormula); - std::shared_ptr<storm::property::prctl::Until<T>> until = std::dynamic_pointer_cast<storm::property::prctl::Until<T>>(pathFormula); + std::shared_ptr<storm::properties::prctl::Eventually<T>> eventually = std::dynamic_pointer_cast<storm::properties::prctl::Eventually<T>>(pathFormula); + std::shared_ptr<storm::properties::prctl::Globally<T>> globally = std::dynamic_pointer_cast<storm::properties::prctl::Globally<T>>(pathFormula); + std::shared_ptr<storm::properties::prctl::Until<T>> until = std::dynamic_pointer_cast<storm::properties::prctl::Until<T>>(pathFormula); if(eventually.get() != nullptr) { targetStates = eventually->getChild()->check(modelCheck); allowedStates = storm::storage::BitVector(targetStates.size(), true); diff --git a/src/counterexamples/SMTMinimalCommandSetGenerator.h b/src/counterexamples/SMTMinimalCommandSetGenerator.h index dee532960..3d2c5be49 100644 --- a/src/counterexamples/SMTMinimalCommandSetGenerator.h +++ b/src/counterexamples/SMTMinimalCommandSetGenerator.h @@ -1773,37 +1773,37 @@ namespace storm { #endif } - static void computeCounterexample(storm::ir::Program program, std::string const& constantDefinitionString, storm::models::Mdp<T> const& labeledMdp, std::shared_ptr<storm::property::prctl::AbstractPrctlFormula<double>> const & formulaPtr) { + static void computeCounterexample(storm::ir::Program program, std::string const& constantDefinitionString, storm::models::Mdp<T> const& labeledMdp, std::shared_ptr<storm::properties::prctl::AbstractPrctlFormula<double>> const & formulaPtr) { #ifdef STORM_HAVE_Z3 std::cout << std::endl << "Generating minimal label counterexample for formula " << formulaPtr->toString() << std::endl; // First, we need to check whether the current formula is an Until-Formula. - std::shared_ptr<storm::property::prctl::ProbabilisticBoundOperator<double>> probBoundFormula = std::dynamic_pointer_cast<storm::property::prctl::ProbabilisticBoundOperator<double>>(formulaPtr); + std::shared_ptr<storm::properties::prctl::ProbabilisticBoundOperator<double>> probBoundFormula = std::dynamic_pointer_cast<storm::properties::prctl::ProbabilisticBoundOperator<double>>(formulaPtr); if (probBoundFormula.get() == nullptr) { LOG4CPLUS_ERROR(logger, "Illegal formula " << probBoundFormula->toString() << " for counterexample generation."); throw storm::exceptions::InvalidPropertyException() << "Illegal formula " << probBoundFormula->toString() << " for counterexample generation."; } // Check whether we were given an upper bound, because counterexample generation is limited to this case. - if (probBoundFormula->getComparisonOperator() != storm::property::ComparisonType::LESS && probBoundFormula->getComparisonOperator() != storm::property::ComparisonType::LESS_EQUAL) { + if (probBoundFormula->getComparisonOperator() != storm::properties::ComparisonType::LESS && probBoundFormula->getComparisonOperator() != storm::properties::ComparisonType::LESS_EQUAL) { LOG4CPLUS_ERROR(logger, "Illegal comparison operator in formula " << probBoundFormula->toString() << ". Only upper bounds are supported for counterexample generation."); throw storm::exceptions::InvalidPropertyException() << "Illegal comparison operator in formula " << probBoundFormula->toString() << ". Only upper bounds are supported for counterexample generation."; } - bool strictBound = !(probBoundFormula->getComparisonOperator() == storm::property::ComparisonType::LESS); + bool strictBound = !(probBoundFormula->getComparisonOperator() == storm::properties::ComparisonType::LESS); // Now derive the probability threshold we need to exceed as well as the phi and psi states. Simultaneously, check whether the formula is of a valid shape. double bound = probBoundFormula->getBound(); - std::shared_ptr<storm::property::prctl::AbstractPathFormula<double>> pathFormula = probBoundFormula->getPathFormula(); + std::shared_ptr<storm::properties::prctl::AbstractPathFormula<double>> pathFormula = probBoundFormula->getPathFormula(); storm::storage::BitVector phiStates; storm::storage::BitVector psiStates; storm::modelchecker::prctl::SparseMdpPrctlModelChecker<T> modelchecker(labeledMdp); - std::shared_ptr<storm::property::prctl::Until<double>> untilFormula = std::dynamic_pointer_cast<storm::property::prctl::Until<double>>(pathFormula); + std::shared_ptr<storm::properties::prctl::Until<double>> untilFormula = std::dynamic_pointer_cast<storm::properties::prctl::Until<double>>(pathFormula); if(untilFormula.get() != nullptr) { phiStates = untilFormula->getLeft()->check(modelchecker); psiStates = untilFormula->getRight()->check(modelchecker); - } if (std::dynamic_pointer_cast<storm::property::prctl::Eventually<double>>(pathFormula).get() != nullptr) { + } if (std::dynamic_pointer_cast<storm::properties::prctl::Eventually<double>>(pathFormula).get() != nullptr) { // If the nested formula was not an until formula, it remains to check whether it's an eventually formula. - std::shared_ptr<storm::property::prctl::Eventually<double>> eventuallyFormula = std::dynamic_pointer_cast<storm::property::prctl::Eventually<double>>(pathFormula); + std::shared_ptr<storm::properties::prctl::Eventually<double>> eventuallyFormula = std::dynamic_pointer_cast<storm::properties::prctl::Eventually<double>>(pathFormula); phiStates = storm::storage::BitVector(labeledMdp.getNumberOfStates(), true); psiStates = eventuallyFormula->getChild()->check(modelchecker); diff --git a/src/modelchecker/csl/AbstractModelChecker.h b/src/modelchecker/csl/AbstractModelChecker.h index 3a9ff9285..e2c68e740 100644 --- a/src/modelchecker/csl/AbstractModelChecker.h +++ b/src/modelchecker/csl/AbstractModelChecker.h @@ -10,7 +10,7 @@ #include <stack> #include "src/exceptions/InvalidPropertyException.h" -#include "src/formula/Csl.h" +#include "src/properties/Csl.h" #include "src/storage/BitVector.h" #include "src/models/AbstractModel.h" @@ -37,17 +37,17 @@ template<class Type> class AbstractModelChecker : // A list of interfaces the model checker supports. Typically, for each of the interfaces, a check method needs to // be implemented that performs the corresponding check. - public virtual storm::property::csl::IApModelChecker<Type>, - public virtual storm::property::csl::IAndModelChecker<Type>, - public virtual storm::property::csl::IOrModelChecker<Type>, - public virtual storm::property::csl::INotModelChecker<Type>, - public virtual storm::property::csl::IUntilModelChecker<Type>, - public virtual storm::property::csl::IEventuallyModelChecker<Type>, - public virtual storm::property::csl::IGloballyModelChecker<Type>, - public virtual storm::property::csl::INextModelChecker<Type>, - public virtual storm::property::csl::ITimeBoundedUntilModelChecker<Type>, - public virtual storm::property::csl::ITimeBoundedEventuallyModelChecker<Type>, - public virtual storm::property::csl::IProbabilisticBoundOperatorModelChecker<Type> { + public virtual storm::properties::csl::IApModelChecker<Type>, + public virtual storm::properties::csl::IAndModelChecker<Type>, + public virtual storm::properties::csl::IOrModelChecker<Type>, + public virtual storm::properties::csl::INotModelChecker<Type>, + public virtual storm::properties::csl::IUntilModelChecker<Type>, + public virtual storm::properties::csl::IEventuallyModelChecker<Type>, + public virtual storm::properties::csl::IGloballyModelChecker<Type>, + public virtual storm::properties::csl::INextModelChecker<Type>, + public virtual storm::properties::csl::ITimeBoundedUntilModelChecker<Type>, + public virtual storm::properties::csl::ITimeBoundedEventuallyModelChecker<Type>, + public virtual storm::properties::csl::IProbabilisticBoundOperatorModelChecker<Type> { public: /*! @@ -112,7 +112,7 @@ public: * @param formula The formula to be checked. * @returns The set of states satisfying the formula represented by a bit vector. */ - storm::storage::BitVector checkAp(storm::property::csl::Ap<Type> const& formula) const { + storm::storage::BitVector checkAp(storm::properties::csl::Ap<Type> const& formula) const { if (formula.getAp() == "true") { return storm::storage::BitVector(model.getNumberOfStates(), true); } else if (formula.getAp() == "false") { @@ -133,7 +133,7 @@ public: * @param formula The formula to be checked. * @returns The set of states satisfying the formula represented by a bit vector. */ - storm::storage::BitVector checkAnd(storm::property::csl::And<Type> const& formula) const { + storm::storage::BitVector checkAnd(storm::properties::csl::And<Type> const& formula) const { storm::storage::BitVector result = formula.getLeft()->check(*this); storm::storage::BitVector right = formula.getRight()->check(*this); result &= right; @@ -146,7 +146,7 @@ public: * @param formula The formula to check. * @returns The set of states satisfying the formula represented by a bit vector. */ - storm::storage::BitVector checkOr(storm::property::csl::Or<Type> const& formula) const { + storm::storage::BitVector checkOr(storm::properties::csl::Or<Type> const& formula) const { storm::storage::BitVector result = formula.getLeft()->check(*this); storm::storage::BitVector right = formula.getRight()->check(*this); result |= right; @@ -159,7 +159,7 @@ public: * @param formula The formula to check. * @returns The set of states satisfying the formula represented by a bit vector. */ - storm::storage::BitVector checkNot(const storm::property::csl::Not<Type>& formula) const { + storm::storage::BitVector checkNot(const storm::properties::csl::Not<Type>& formula) const { storm::storage::BitVector result = formula.getChild()->check(*this); result.complement(); return result; @@ -172,7 +172,7 @@ public: * @param formula The formula to check. * @returns The set of states satisfying the formula represented by a bit vector. */ - virtual storm::storage::BitVector checkProbabilisticBoundOperator(storm::property::csl::ProbabilisticBoundOperator<Type> const& formula) const { + virtual storm::storage::BitVector checkProbabilisticBoundOperator(storm::properties::csl::ProbabilisticBoundOperator<Type> const& formula) const { // First, we need to compute the probability for satisfying the path formula for each state. std::vector<Type> quantitativeResult = formula.getChild()->check(*this, false); @@ -197,7 +197,7 @@ public: * @param minimumOperator True iff minimum probabilities/rewards are to be computed. * @returns The probabilities to satisfy the formula or the rewards accumulated by it, represented by a vector. */ - virtual std::vector<Type> checkMinMaxOperator(storm::property::csl::AbstractPathFormula<Type> const & formula, bool minimumOperator) const { + virtual std::vector<Type> checkMinMaxOperator(storm::properties::csl::AbstractPathFormula<Type> const & formula, bool minimumOperator) const { minimumOperatorStack.push(minimumOperator); std::vector<Type> result = formula.check(*this, false); minimumOperatorStack.pop(); @@ -211,7 +211,7 @@ public: * @param minimumOperator True iff minimum probabilities/rewards are to be computed. * @returns The set of states satisfying the formula represented by a bit vector. */ - virtual storm::storage::BitVector checkMinMaxOperator(storm::property::csl::AbstractStateFormula<Type> const & formula, bool minimumOperator) const { + virtual storm::storage::BitVector checkMinMaxOperator(storm::properties::csl::AbstractStateFormula<Type> const & formula, bool minimumOperator) const { minimumOperatorStack.push(minimumOperator); storm::storage::BitVector result = formula.check(*this); minimumOperatorStack.pop(); diff --git a/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h b/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h index 71213f1b8..b3f1dfe40 100644 --- a/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h +++ b/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h @@ -54,10 +54,10 @@ public: * @param formula The formula to check. * @returns The set of states satisfying the formula represented by a bit vector. */ - virtual storm::storage::BitVector checkProbabilisticBoundOperator(storm::property::csl::ProbabilisticBoundOperator<ValueType> const& formula) const override{ + virtual storm::storage::BitVector checkProbabilisticBoundOperator(storm::properties::csl::ProbabilisticBoundOperator<ValueType> const& formula) const override{ // For P< and P<= the MA satisfies the formula iff the probability maximizing scheduler is used. // For P> and P>= " iff the probability minimizing " . - if(formula.getComparisonOperator() == storm::property::LESS || formula.getComparisonOperator() == storm::property::LESS_EQUAL) { + if(formula.getComparisonOperator() == storm::properties::LESS || formula.getComparisonOperator() == storm::properties::LESS_EQUAL) { this->minimumOperatorStack.push(false); } else { @@ -84,7 +84,7 @@ public: return result; } - std::vector<ValueType> checkUntil(storm::property::csl::Until<ValueType> const& formula, bool qualitative) const { + std::vector<ValueType> checkUntil(storm::properties::csl::Until<ValueType> const& formula, bool qualitative) const { // Test whether it is specified if the minimum or maximum probabilities are to be computed. if(this->minimumOperatorStack.empty()) { LOG4CPLUS_ERROR(logger, "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."); @@ -100,11 +100,11 @@ public: return storm::modelchecker::prctl::SparseMdpPrctlModelChecker<ValueType>::computeUnboundedUntilProbabilities(min, this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), this->getModel().getInitialStates(), leftStates, rightStates, nondeterministicLinearEquationSolver, qualitative); } - std::vector<ValueType> checkTimeBoundedUntil(storm::property::csl::TimeBoundedUntil<ValueType> const& formula, bool qualitative) const { + std::vector<ValueType> checkTimeBoundedUntil(storm::properties::csl::TimeBoundedUntil<ValueType> const& formula, bool qualitative) const { throw storm::exceptions::NotImplementedException() << "Model checking Until formulas on Markov automata is not yet implemented."; } - std::vector<ValueType> checkTimeBoundedEventually(storm::property::csl::TimeBoundedEventually<ValueType> const& formula, bool qualitative) const { + std::vector<ValueType> checkTimeBoundedEventually(storm::properties::csl::TimeBoundedEventually<ValueType> const& formula, bool qualitative) const { // Test whether it is specified if the minimum or maximum probabilities are to be computed. if(this->minimumOperatorStack.empty()) { LOG4CPLUS_ERROR(logger, "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."); @@ -115,11 +115,11 @@ public: return this->checkTimeBoundedEventually(this->minimumOperatorStack.top(), goalStates, formula.getLowerBound(), formula.getUpperBound()); } - std::vector<ValueType> checkGlobally(storm::property::csl::Globally<ValueType> const& formula, bool qualitative) const { + std::vector<ValueType> checkGlobally(storm::properties::csl::Globally<ValueType> const& formula, bool qualitative) const { throw storm::exceptions::NotImplementedException() << "Model checking Globally formulas on Markov automata is not yet implemented."; } - std::vector<ValueType> checkEventually(storm::property::csl::Eventually<ValueType> const& formula, bool qualitative) const { + std::vector<ValueType> checkEventually(storm::properties::csl::Eventually<ValueType> const& formula, bool qualitative) const { // Test whether it is specified if the minimum or maximum probabilities are to be computed. if(this->minimumOperatorStack.empty()) { LOG4CPLUS_ERROR(logger, "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."); @@ -130,7 +130,7 @@ public: return computeUnboundedUntilProbabilities(this->minimumOperatorStack.top(), storm::storage::BitVector(this->getModel().getNumberOfStates(), true), subFormulaStates, qualitative).first; } - std::vector<ValueType> checkNext(storm::property::csl::Next<ValueType> const& formula, bool qualitative) const { + std::vector<ValueType> checkNext(storm::properties::csl::Next<ValueType> const& formula, bool qualitative) const { throw storm::exceptions::NotImplementedException() << "Model checking Next formulas on Markov automata is not yet implemented."; } diff --git a/src/modelchecker/ltl/AbstractModelChecker.h b/src/modelchecker/ltl/AbstractModelChecker.h index 03284fed6..ce18dfb48 100644 --- a/src/modelchecker/ltl/AbstractModelChecker.h +++ b/src/modelchecker/ltl/AbstractModelChecker.h @@ -9,7 +9,7 @@ #define STORM_MODELCHECKER_LTL_ABSTRACTMODELCHECKER_H_ #include "src/exceptions/InvalidPropertyException.h" -#include "src/formula/Ltl.h" +#include "src/properties/Ltl.h" #include "src/storage/BitVector.h" #include "src/models/AbstractModel.h" @@ -36,16 +36,16 @@ template<class Type> class AbstractModelChecker : // A list of interfaces the model checker supports. Typically, for each of the interfaces, a check method needs to // be implemented that performs the corresponding check. - public virtual storm::property::ltl::IApModelChecker<Type>, - public virtual storm::property::ltl::IAndModelChecker<Type>, - public virtual storm::property::ltl::IOrModelChecker<Type>, - public virtual storm::property::ltl::INotModelChecker<Type>, - public virtual storm::property::ltl::IUntilModelChecker<Type>, - public virtual storm::property::ltl::IEventuallyModelChecker<Type>, - public virtual storm::property::ltl::IGloballyModelChecker<Type>, - public virtual storm::property::ltl::INextModelChecker<Type>, - public virtual storm::property::ltl::IBoundedUntilModelChecker<Type>, - public virtual storm::property::ltl::IBoundedEventuallyModelChecker<Type> { + public virtual storm::properties::ltl::IApModelChecker<Type>, + public virtual storm::properties::ltl::IAndModelChecker<Type>, + public virtual storm::properties::ltl::IOrModelChecker<Type>, + public virtual storm::properties::ltl::INotModelChecker<Type>, + public virtual storm::properties::ltl::IUntilModelChecker<Type>, + public virtual storm::properties::ltl::IEventuallyModelChecker<Type>, + public virtual storm::properties::ltl::IGloballyModelChecker<Type>, + public virtual storm::properties::ltl::INextModelChecker<Type>, + public virtual storm::properties::ltl::IBoundedUntilModelChecker<Type>, + public virtual storm::properties::ltl::IBoundedEventuallyModelChecker<Type> { public: /*! @@ -110,7 +110,7 @@ public: * @param formula The formula to be checked. * @returns The set of states satisfying the formula represented by a bit vector. */ - virtual std::vector<Type> checkAp(storm::property::ltl::Ap<Type> const& formula) const = 0; + virtual std::vector<Type> checkAp(storm::properties::ltl::Ap<Type> const& formula) const = 0; /*! * Checks the given formula that is a logical "and" of two formulae. @@ -118,7 +118,7 @@ public: * @param formula The formula to be checked. * @returns The set of states satisfying the formula represented by a bit vector. */ - virtual std::vector<Type> checkAnd(storm::property::ltl::And<Type> const& formula) const = 0; + virtual std::vector<Type> checkAnd(storm::properties::ltl::And<Type> const& formula) const = 0; /*! * Checks the given formula that is a logical "or" of two formulae. @@ -126,7 +126,7 @@ public: * @param formula The formula to check. * @returns The set of states satisfying the formula represented by a bit vector. */ - virtual std::vector<Type> checkOr(storm::property::ltl::Or<Type> const& formula) const = 0; + virtual std::vector<Type> checkOr(storm::properties::ltl::Or<Type> const& formula) const = 0; /*! * Checks the given formula that is a logical "not" of a sub-formula. @@ -134,7 +134,7 @@ public: * @param formula The formula to check. * @returns The set of states satisfying the formula represented by a bit vector. */ - virtual std::vector<Type> checkNot(const storm::property::ltl::Not<Type>& formula) const = 0; + virtual std::vector<Type> checkNot(const storm::properties::ltl::Not<Type>& formula) const = 0; private: diff --git a/src/modelchecker/prctl/AbstractModelChecker.h b/src/modelchecker/prctl/AbstractModelChecker.h index f33cd8952..930c002db 100644 --- a/src/modelchecker/prctl/AbstractModelChecker.h +++ b/src/modelchecker/prctl/AbstractModelChecker.h @@ -19,7 +19,7 @@ namespace prctl { #include <stack> #include "src/exceptions/InvalidPropertyException.h" -#include "src/formula/Prctl.h" +#include "src/properties/Prctl.h" #include "src/storage/BitVector.h" #include "src/models/AbstractModel.h" #include "src/settings/Settings.h" @@ -47,21 +47,21 @@ template<class Type> class AbstractModelChecker : // A list of interfaces the model checker supports. Typically, for each of the interfaces, a check method needs to // be implemented that performs the corresponding check. - public virtual storm::property::prctl::IApModelChecker<Type>, - public virtual storm::property::prctl::IAndModelChecker<Type>, - public virtual storm::property::prctl::IOrModelChecker<Type>, - public virtual storm::property::prctl::INotModelChecker<Type>, - public virtual storm::property::prctl::IUntilModelChecker<Type>, - public virtual storm::property::prctl::IEventuallyModelChecker<Type>, - public virtual storm::property::prctl::IGloballyModelChecker<Type>, - public virtual storm::property::prctl::INextModelChecker<Type>, - public virtual storm::property::prctl::IBoundedUntilModelChecker<Type>, - public virtual storm::property::prctl::IBoundedEventuallyModelChecker<Type>, - public virtual storm::property::prctl::IProbabilisticBoundOperatorModelChecker<Type>, - public virtual storm::property::prctl::IRewardBoundOperatorModelChecker<Type>, - public virtual storm::property::prctl::IReachabilityRewardModelChecker<Type>, - public virtual storm::property::prctl::ICumulativeRewardModelChecker<Type>, - public virtual storm::property::prctl::IInstantaneousRewardModelChecker<Type> { + public virtual storm::properties::prctl::IApModelChecker<Type>, + public virtual storm::properties::prctl::IAndModelChecker<Type>, + public virtual storm::properties::prctl::IOrModelChecker<Type>, + public virtual storm::properties::prctl::INotModelChecker<Type>, + public virtual storm::properties::prctl::IUntilModelChecker<Type>, + public virtual storm::properties::prctl::IEventuallyModelChecker<Type>, + public virtual storm::properties::prctl::IGloballyModelChecker<Type>, + public virtual storm::properties::prctl::INextModelChecker<Type>, + public virtual storm::properties::prctl::IBoundedUntilModelChecker<Type>, + public virtual storm::properties::prctl::IBoundedEventuallyModelChecker<Type>, + public virtual storm::properties::prctl::IProbabilisticBoundOperatorModelChecker<Type>, + public virtual storm::properties::prctl::IRewardBoundOperatorModelChecker<Type>, + public virtual storm::properties::prctl::IReachabilityRewardModelChecker<Type>, + public virtual storm::properties::prctl::ICumulativeRewardModelChecker<Type>, + public virtual storm::properties::prctl::IInstantaneousRewardModelChecker<Type> { public: /*! @@ -127,7 +127,7 @@ public: * @param formula The formula to be checked. * @return The set of states satisfying the formula represented by a bit vector. */ - storm::storage::BitVector checkAp(storm::property::prctl::Ap<Type> const& formula) const { + storm::storage::BitVector checkAp(storm::properties::prctl::Ap<Type> const& formula) const { if (formula.getAp() == "true") { return storm::storage::BitVector(model.getNumberOfStates(), true); } else if (formula.getAp() == "false") { @@ -148,7 +148,7 @@ public: * @param formula The formula to be checked. * @return The set of states satisfying the formula represented by a bit vector. */ - storm::storage::BitVector checkAnd(storm::property::prctl::And<Type> const& formula) const { + storm::storage::BitVector checkAnd(storm::properties::prctl::And<Type> const& formula) const { storm::storage::BitVector result = formula.getLeft()->check(*this); storm::storage::BitVector right = formula.getRight()->check(*this); result &= right; @@ -161,7 +161,7 @@ public: * @param formula The formula to check. * @return The set of states satisfying the formula represented by a bit vector. */ - storm::storage::BitVector checkOr(storm::property::prctl::Or<Type> const& formula) const { + storm::storage::BitVector checkOr(storm::properties::prctl::Or<Type> const& formula) const { storm::storage::BitVector result = formula.getLeft()->check(*this); storm::storage::BitVector right = formula.getRight()->check(*this); result |= right; @@ -174,7 +174,7 @@ public: * @param formula The formula to check. * @return The set of states satisfying the formula represented by a bit vector. */ - storm::storage::BitVector checkNot(const storm::property::prctl::Not<Type>& formula) const { + storm::storage::BitVector checkNot(const storm::properties::prctl::Not<Type>& formula) const { storm::storage::BitVector result = formula.getChild()->check(*this); result.complement(); return result; @@ -187,7 +187,7 @@ public: * @param formula The formula to check. * @return The set of states satisfying the formula represented by a bit vector. */ - virtual storm::storage::BitVector checkProbabilisticBoundOperator(storm::property::prctl::ProbabilisticBoundOperator<Type> const& formula) const { + virtual storm::storage::BitVector checkProbabilisticBoundOperator(storm::properties::prctl::ProbabilisticBoundOperator<Type> const& formula) const { // First, we need to compute the probability for satisfying the path formula for each state. std::vector<Type> quantitativeResult = formula.getChild()->check(*this, false); @@ -211,7 +211,7 @@ public: * @param formula The formula to check. * @return The set of states satisfying the formula represented by a bit vector. */ - virtual storm::storage::BitVector checkRewardBoundOperator(const storm::property::prctl::RewardBoundOperator<Type>& formula) const { + virtual storm::storage::BitVector checkRewardBoundOperator(const storm::properties::prctl::RewardBoundOperator<Type>& formula) const { // First, we need to compute the probability for satisfying the path formula for each state. std::vector<Type> quantitativeResult = formula.getChild()->check(*this, false); @@ -236,7 +236,7 @@ public: * @param optOperator True iff minimum probabilities are to be computed. * @returns The probabilities to satisfy the formula, represented by a vector. */ - virtual std::vector<Type> checkOptimizingOperator(storm::property::prctl::AbstractPathFormula<Type> const & formula, bool optOperator) const { + virtual std::vector<Type> checkOptimizingOperator(storm::properties::prctl::AbstractPathFormula<Type> const & formula, bool optOperator) const { minimumOperatorStack.push(optOperator); std::vector<Type> result = formula.check(*this, false); minimumOperatorStack.pop(); @@ -250,7 +250,7 @@ public: * @param optOperator True iff minimum rewards are to be computed. * @returns The the rewards accumulated by the formula, represented by a vector. */ - virtual std::vector<Type> checkOptimizingOperator(storm::property::prctl::AbstractRewardPathFormula<Type> const & formula, bool optOperator) const { + virtual std::vector<Type> checkOptimizingOperator(storm::properties::prctl::AbstractRewardPathFormula<Type> const & formula, bool optOperator) const { minimumOperatorStack.push(optOperator); std::vector<Type> result = formula.check(*this, false); minimumOperatorStack.pop(); @@ -264,7 +264,7 @@ public: * @param optOperator True iff minimum probabilities/rewards are to be computed. * @returns The set of states satisfying the formula represented by a bit vector. */ - virtual storm::storage::BitVector checkOptimizingOperator(storm::property::prctl::AbstractStateFormula<Type> const & formula, bool optOperator) const { + virtual storm::storage::BitVector checkOptimizingOperator(storm::properties::prctl::AbstractStateFormula<Type> const & formula, bool optOperator) const { minimumOperatorStack.push(optOperator); storm::storage::BitVector result = formula.check(*this); minimumOperatorStack.pop(); diff --git a/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h b/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h index 74557fbea..e10fd77e4 100644 --- a/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h +++ b/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h @@ -71,7 +71,7 @@ public: * @returns The probabilities for the given formula to hold on every state of the model associated with this model * checker. If the qualitative flag is set, exact probabilities might not be computed. */ - virtual std::vector<Type> checkBoundedUntil(storm::property::prctl::BoundedUntil<Type> const& formula, bool qualitative) const { + virtual std::vector<Type> checkBoundedUntil(storm::properties::prctl::BoundedUntil<Type> const& formula, bool qualitative) const { return this->checkBoundedUntil(formula.getLeft()->check(*this), formula.getRight()->check(*this), formula.getBound(), qualitative); } @@ -145,7 +145,7 @@ public: * @returns The probabilities for the given formula to hold on every state of the model associated with this model * checker. If the qualitative flag is set, exact probabilities might not be computed. */ - virtual std::vector<Type> checkNext(storm::property::prctl::Next<Type> const& formula, bool qualitative) const { + virtual std::vector<Type> checkNext(storm::properties::prctl::Next<Type> const& formula, bool qualitative) const { // First, we need to compute the states that satisfy the child formula of the next-formula. storm::storage::BitVector nextStates = formula.getChild()->check(*this); @@ -174,7 +174,7 @@ public: * @returns The probabilities for the given formula to hold on every state of the model associated with this model * checker. If the qualitative flag is set, exact probabilities might not be computed. */ - virtual std::vector<Type> checkBoundedEventually(storm::property::prctl::BoundedEventually<Type> const& formula, bool qualitative) const { + virtual std::vector<Type> checkBoundedEventually(storm::properties::prctl::BoundedEventually<Type> const& formula, bool qualitative) const { return this->checkBoundedUntil(storm::storage::BitVector(this->getModel().getNumberOfStates(), true), formula.getChild()->check(*this), formula.getBound(), qualitative); } @@ -189,9 +189,9 @@ public: * @returns The probabilities for the given formula to hold on every state of the model associated with this model * checker. If the qualitative flag is set, exact probabilities might not be computed. */ - virtual std::vector<Type> checkEventually(storm::property::prctl::Eventually<Type> const& formula, bool qualitative) const { + virtual std::vector<Type> checkEventually(storm::properties::prctl::Eventually<Type> const& formula, bool qualitative) const { // Create equivalent temporary until formula and check it. - storm::property::prctl::Until<Type> temporaryUntilFormula(std::shared_ptr<storm::property::prctl::Ap<Type>>(new storm::property::prctl::Ap<Type>("true")), formula.getChild()); + storm::properties::prctl::Until<Type> temporaryUntilFormula(std::shared_ptr<storm::properties::prctl::Ap<Type>>(new storm::properties::prctl::Ap<Type>("true")), formula.getChild()); return this->checkUntil(temporaryUntilFormula, qualitative); } @@ -206,9 +206,9 @@ public: * @returns The probabilities for the given formula to hold on every state of the model associated with this model * checker. If the qualitative flag is set, exact probabilities might not be computed. */ - virtual std::vector<Type> checkGlobally(storm::property::prctl::Globally<Type> const& formula, bool qualitative) const { + virtual std::vector<Type> checkGlobally(storm::properties::prctl::Globally<Type> const& formula, bool qualitative) const { // Create "equivalent" (equivalent up to negation) temporary eventually formula and check it. - storm::property::prctl::Eventually<Type> temporaryEventuallyFormula(std::shared_ptr<storm::property::prctl::Not<Type>>(new storm::property::prctl::Not<Type>(formula.getChild()))); + storm::properties::prctl::Eventually<Type> temporaryEventuallyFormula(std::shared_ptr<storm::properties::prctl::Not<Type>>(new storm::properties::prctl::Not<Type>(formula.getChild()))); std::vector<Type> result = this->checkEventually(temporaryEventuallyFormula, qualitative); // Now subtract the resulting vector from the constant one vector to obtain final result. @@ -228,7 +228,7 @@ public: * @returns The probabilities for the given formula to hold on every state of the model associated with this model * checker. If the qualitative flag is set, exact probabilities might not be computed. */ - virtual std::vector<Type> checkUntil(storm::property::prctl::Until<Type> const& formula, bool qualitative) const { + virtual std::vector<Type> checkUntil(storm::properties::prctl::Until<Type> const& formula, bool qualitative) const { return this->checkUntil(formula.getLeft()->check(*this), formula.getRight()->check(*this), qualitative); } @@ -319,7 +319,7 @@ public: * @returns The reward values for the given formula for every state of the model associated with this model * checker. If the qualitative flag is set, exact values might not be computed. */ - virtual std::vector<Type> checkInstantaneousReward(storm::property::prctl::InstantaneousReward<Type> const& formula, bool qualitative) const { + virtual std::vector<Type> checkInstantaneousReward(storm::properties::prctl::InstantaneousReward<Type> const& formula, bool qualitative) const { // Only compute the result if the model has a state-based reward model. if (!this->getModel().hasStateRewards()) { LOG4CPLUS_ERROR(logger, "Missing (state-based) reward model for formula."); @@ -350,7 +350,7 @@ public: * @returns The reward values for the given formula for every state of the model associated with this model * checker. If the qualitative flag is set, exact values might not be computed. */ - virtual std::vector<Type> checkCumulativeReward(storm::property::prctl::CumulativeReward<Type> const& formula, bool qualitative) const { + virtual std::vector<Type> checkCumulativeReward(storm::properties::prctl::CumulativeReward<Type> const& formula, bool qualitative) const { // Only compute the result if the model has at least one reward model. if (!this->getModel().hasStateRewards() && !this->getModel().hasTransitionRewards()) { LOG4CPLUS_ERROR(logger, "Missing reward model for formula."); @@ -397,7 +397,7 @@ public: * @returns The reward values for the given formula for every state of the model associated with this model * checker. If the qualitative flag is set, exact values might not be computed. */ - virtual std::vector<Type> checkReachabilityReward(storm::property::prctl::ReachabilityReward<Type> const& formula, bool qualitative) const { + virtual std::vector<Type> checkReachabilityReward(storm::properties::prctl::ReachabilityReward<Type> const& formula, bool qualitative) const { // Only compute the result if the model has at least one reward model. if (!this->getModel().hasStateRewards() && !this->getModel().hasTransitionRewards()) { LOG4CPLUS_ERROR(logger, "Missing reward model for formula. Skipping formula"); @@ -491,7 +491,7 @@ public: * @param optOperator True iff minimum probabilities/rewards are to be computed. * @returns The probabilities to satisfy the formula or the rewards accumulated by it, represented by a vector. */ - virtual std::vector<Type> checkOptimizingOperator(storm::property::prctl::AbstractPathFormula<Type> const & formula, bool optOperator) const override { + virtual std::vector<Type> checkOptimizingOperator(storm::properties::prctl::AbstractPathFormula<Type> const & formula, bool optOperator) const override { LOG4CPLUS_WARN(logger, "Formula contains min/max operator, which is not meaningful over deterministic models."); @@ -509,7 +509,7 @@ public: * @param optOperator True iff minimum probabilities/rewards are to be computed. * @returns The set of states satisfying the formula represented by a bit vector. */ - virtual storm::storage::BitVector checkOptimizingOperator(storm::property::prctl::AbstractStateFormula<Type> const & formula, bool optOperator) const override { + virtual storm::storage::BitVector checkOptimizingOperator(storm::properties::prctl::AbstractStateFormula<Type> const & formula, bool optOperator) const override { LOG4CPLUS_WARN(logger, "Formula contains min/max operator, which is not meaningful over deterministic models."); diff --git a/src/modelchecker/prctl/SparseMdpPrctlModelChecker.h b/src/modelchecker/prctl/SparseMdpPrctlModelChecker.h index 239a0a37f..4c193c4ed 100644 --- a/src/modelchecker/prctl/SparseMdpPrctlModelChecker.h +++ b/src/modelchecker/prctl/SparseMdpPrctlModelChecker.h @@ -75,11 +75,11 @@ namespace storm { * @param formula The formula to check. * @return The set of states satisfying the formula represented by a bit vector. */ - virtual storm::storage::BitVector checkProbabilisticBoundOperator(storm::property::prctl::ProbabilisticBoundOperator<Type> const& formula) const override { + virtual storm::storage::BitVector checkProbabilisticBoundOperator(storm::properties::prctl::ProbabilisticBoundOperator<Type> const& formula) const override { // For P< and P<= the MDP satisfies the formula iff the probability maximizing scheduler is used. // For P> and P>= " iff the probability minimizing " . - if(formula.getComparisonOperator() == storm::property::LESS || formula.getComparisonOperator() == storm::property::LESS_EQUAL) { + if(formula.getComparisonOperator() == storm::properties::LESS || formula.getComparisonOperator() == storm::properties::LESS_EQUAL) { this->minimumOperatorStack.push(false); } else { @@ -112,11 +112,11 @@ namespace storm { * @param formula The formula to check. * @return The set of states satisfying the formula represented by a bit vector. */ - virtual storm::storage::BitVector checkRewardBoundOperator(const storm::property::prctl::RewardBoundOperator<Type>& formula) const override { + virtual storm::storage::BitVector checkRewardBoundOperator(const storm::properties::prctl::RewardBoundOperator<Type>& formula) const override { // For R< and R<= the MDP satisfies the formula iff the reward maximizing scheduler is used. // For R> and R>= " iff the reward minimizing " . - if(formula.getComparisonOperator() == storm::property::LESS || formula.getComparisonOperator() == storm::property::LESS_EQUAL) { + if(formula.getComparisonOperator() == storm::properties::LESS || formula.getComparisonOperator() == storm::properties::LESS_EQUAL) { this->minimumOperatorStack.push(false); } else { @@ -218,7 +218,7 @@ namespace storm { * @return The probabilities for the given formula to hold on every state of the model associated with this model * checker. If the qualitative flag is set, exact probabilities might not be computed. */ - virtual std::vector<Type> checkBoundedUntil(storm::property::prctl::BoundedUntil<Type> const& formula, bool qualitative) const { + virtual std::vector<Type> checkBoundedUntil(storm::properties::prctl::BoundedUntil<Type> const& formula, bool qualitative) const { return checkBoundedUntil(formula.getLeft()->check(*this), formula.getRight()->check(*this), formula.getBound(), qualitative); } @@ -260,7 +260,7 @@ namespace storm { * @return The probabilities for the given formula to hold on every state of the model associated with this model * checker. If the qualitative flag is set, exact probabilities might not be computed. */ - virtual std::vector<Type> checkNext(const storm::property::prctl::Next<Type>& formula, bool qualitative) const { + virtual std::vector<Type> checkNext(const storm::properties::prctl::Next<Type>& formula, bool qualitative) const { return checkNext(formula.getChild()->check(*this), qualitative); } @@ -275,9 +275,9 @@ namespace storm { * @returns The probabilities for the given formula to hold on every state of the model associated with this model * checker. If the qualitative flag is set, exact probabilities might not be computed. */ - virtual std::vector<Type> checkBoundedEventually(const storm::property::prctl::BoundedEventually<Type>& formula, bool qualitative) const { + virtual std::vector<Type> checkBoundedEventually(const storm::properties::prctl::BoundedEventually<Type>& formula, bool qualitative) const { // Create equivalent temporary bounded until formula and check it. - storm::property::prctl::BoundedUntil<Type> temporaryBoundedUntilFormula(std::shared_ptr<storm::property::prctl::Ap<Type>>(new storm::property::prctl::Ap<Type>("true")), formula.getChild(), formula.getBound()); + storm::properties::prctl::BoundedUntil<Type> temporaryBoundedUntilFormula(std::shared_ptr<storm::properties::prctl::Ap<Type>>(new storm::properties::prctl::Ap<Type>("true")), formula.getChild(), formula.getBound()); return this->checkBoundedUntil(temporaryBoundedUntilFormula, qualitative); } @@ -292,9 +292,9 @@ namespace storm { * @returns The probabilities for the given formula to hold on every state of the model associated with this model * checker. If the qualitative flag is set, exact probabilities might not be computed. */ - virtual std::vector<Type> checkEventually(const storm::property::prctl::Eventually<Type>& formula, bool qualitative) const { + virtual std::vector<Type> checkEventually(const storm::properties::prctl::Eventually<Type>& formula, bool qualitative) const { // Create equivalent temporary until formula and check it. - storm::property::prctl::Until<Type> temporaryUntilFormula(std::shared_ptr<storm::property::prctl::Ap<Type>>(new storm::property::prctl::Ap<Type>("true")), formula.getChild()); + storm::properties::prctl::Until<Type> temporaryUntilFormula(std::shared_ptr<storm::properties::prctl::Ap<Type>>(new storm::properties::prctl::Ap<Type>("true")), formula.getChild()); return this->checkUntil(temporaryUntilFormula, qualitative); } @@ -309,9 +309,9 @@ namespace storm { * @returns The probabilities for the given formula to hold on every state of the model associated with this model * checker. If the qualitative flag is set, exact probabilities might not be computed. */ - virtual std::vector<Type> checkGlobally(const storm::property::prctl::Globally<Type>& formula, bool qualitative) const { + virtual std::vector<Type> checkGlobally(const storm::properties::prctl::Globally<Type>& formula, bool qualitative) const { // Create "equivalent" temporary eventually formula and check it. - storm::property::prctl::Eventually<Type> temporaryEventuallyFormula(std::shared_ptr<storm::property::prctl::Not<Type>>(new storm::property::prctl::Not<Type>(formula.getChild()))); + storm::properties::prctl::Eventually<Type> temporaryEventuallyFormula(std::shared_ptr<storm::properties::prctl::Not<Type>>(new storm::properties::prctl::Not<Type>(formula.getChild()))); std::vector<Type> result = this->checkEventually(temporaryEventuallyFormula, qualitative); // Now subtract the resulting vector from the constant one vector to obtain final result. @@ -333,7 +333,7 @@ namespace storm { * @return The probabilities for the given formula to hold on every state of the model associated with this model * checker. If the qualitative flag is set, exact probabilities might not be computed. */ - virtual std::vector<Type> checkUntil(const storm::property::prctl::Until<Type>& formula, bool qualitative) const { + virtual std::vector<Type> checkUntil(const storm::properties::prctl::Until<Type>& formula, bool qualitative) const { // First test if it is specified if the minimum or maximum probabilities are to be computed. if(this->minimumOperatorStack.empty()) { LOG4CPLUS_ERROR(logger, "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."); @@ -438,7 +438,7 @@ namespace storm { * @return The reward values for the given formula for every state of the model associated with this model * checker. If the qualitative flag is set, exact values might not be computed. */ - virtual std::vector<Type> checkInstantaneousReward(const storm::property::prctl::InstantaneousReward<Type>& formula, bool qualitative) const { + virtual std::vector<Type> checkInstantaneousReward(const storm::properties::prctl::InstantaneousReward<Type>& formula, bool qualitative) const { // Only compute the result if the model has a state-based reward model. if (!this->getModel().hasStateRewards()) { LOG4CPLUS_ERROR(logger, "Missing (state-based) reward model for formula."); @@ -470,7 +470,7 @@ namespace storm { * @return The reward values for the given formula for every state of the model associated with this model * checker. If the qualitative flag is set, exact values might not be computed. */ - virtual std::vector<Type> checkCumulativeReward(const storm::property::prctl::CumulativeReward<Type>& formula, bool qualitative) const { + virtual std::vector<Type> checkCumulativeReward(const storm::properties::prctl::CumulativeReward<Type>& formula, bool qualitative) const { // Only compute the result if the model has at least one reward model. if (!this->getModel().hasStateRewards() && !this->getModel().hasTransitionRewards()) { LOG4CPLUS_ERROR(logger, "Missing reward model for formula."); @@ -518,7 +518,7 @@ namespace storm { * @return The reward values for the given formula for every state of the model associated with this model * checker. If the qualitative flag is set, exact values might not be computed. */ - virtual std::vector<Type> checkReachabilityReward(const storm::property::prctl::ReachabilityReward<Type>& formula, bool qualitative) const { + virtual std::vector<Type> checkReachabilityReward(const storm::properties::prctl::ReachabilityReward<Type>& formula, bool qualitative) const { // First test whether it is specified if the minimum or maximum probabilities are to be computed. if(this->minimumOperatorStack.empty()) { LOG4CPLUS_ERROR(logger, "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."); diff --git a/src/parser/CslParser.cpp b/src/parser/CslParser.cpp index 1f2f66361..1739ebecd 100644 --- a/src/parser/CslParser.cpp +++ b/src/parser/CslParser.cpp @@ -10,12 +10,12 @@ #include "src/utility/constants.h" // The action class headers. -#include "src/formula/actions/AbstractAction.h" -#include "src/formula/actions/BoundAction.h" -#include "src/formula/actions/InvertAction.h" -#include "src/formula/actions/FormulaAction.h" -#include "src/formula/actions/RangeAction.h" -#include "src/formula/actions/SortAction.h" +#include "src/properties/actions/AbstractAction.h" +#include "src/properties/actions/BoundAction.h" +#include "src/properties/actions/InvertAction.h" +#include "src/properties/actions/FormulaAction.h" +#include "src/properties/actions/RangeAction.h" +#include "src/properties/actions/SortAction.h" // If the parser fails due to ill-formed data, this exception is thrown. #include "src/exceptions/WrongFormatException.h" @@ -41,7 +41,7 @@ typedef std::string::const_iterator BaseIteratorType; typedef boost::spirit::classic::position_iterator2<BaseIteratorType> PositionIteratorType; namespace qi = boost::spirit::qi; namespace phoenix = boost::phoenix; -namespace csl = storm::property::csl; +namespace csl = storm::properties::csl; namespace storm { namespace parser { @@ -52,13 +52,13 @@ struct CslParser::CslGrammar : qi::grammar<Iterator, std::shared_ptr<csl::CslFil //This block contains helper rules that may be used several times freeIdentifierName = qi::lexeme[qi::alpha >> *(qi::alnum | qi::char_('_'))]; comparisonType = ( - (qi::lit(">="))[qi::_val = storm::property::GREATER_EQUAL] | - (qi::lit(">"))[qi::_val = storm::property::GREATER] | - (qi::lit("<="))[qi::_val = storm::property::LESS_EQUAL] | - (qi::lit("<"))[qi::_val = storm::property::LESS]); + (qi::lit(">="))[qi::_val = storm::properties::GREATER_EQUAL] | + (qi::lit(">"))[qi::_val = storm::properties::GREATER] | + (qi::lit("<="))[qi::_val = storm::properties::LESS_EQUAL] | + (qi::lit("<"))[qi::_val = storm::properties::LESS]); sortingCategory = ( - (qi::lit("index"))[qi::_val = storm::property::action::SortAction<double>::INDEX] | - (qi::lit("value"))[qi::_val = storm::property::action::SortAction<double>::VALUE] + (qi::lit("index"))[qi::_val = storm::properties::action::SortAction<double>::INDEX] | + (qi::lit("value"))[qi::_val = storm::properties::action::SortAction<double>::VALUE] ); //Comment: Empty line or line starting with "//" comment = (qi::lit("//") >> *(qi::char_))[qi::_val = nullptr]; @@ -136,43 +136,43 @@ struct CslParser::CslGrammar : qi::grammar<Iterator, std::shared_ptr<csl::CslFil noBoundOperator.name("no bound operator"); probabilisticNoBoundOperator = (qi::lit("P") >> qi::lit("min") >> qi::lit("=") > qi::lit("?") >> pathFormula)[qi::_val = - MAKE(csl::CslFilter<double>, qi::_1, storm::property::MINIMIZE)] | + MAKE(csl::CslFilter<double>, qi::_1, storm::properties::MINIMIZE)] | (qi::lit("P") >> qi::lit("max") >> qi::lit("=") > qi::lit("?") >> pathFormula)[qi::_val = - MAKE(csl::CslFilter<double>, qi::_1, storm::property::MAXIMIZE)] | + MAKE(csl::CslFilter<double>, qi::_1, storm::properties::MAXIMIZE)] | (qi::lit("P") >> qi::lit("=") > qi::lit("?") >> pathFormula)[qi::_val = MAKE(csl::CslFilter<double>, qi::_1)]; probabilisticNoBoundOperator.name("probabilistic no bound operator"); steadyStateNoBoundOperator = (qi::lit("S") >> qi::lit("=") > qi::lit("?") >> stateFormula )[qi::_val = - MAKE(csl::CslFilter<double>, qi::_1, storm::property::UNDEFINED, true)]; + MAKE(csl::CslFilter<double>, qi::_1, storm::properties::UNDEFINED, true)]; steadyStateNoBoundOperator.name("steady state no bound operator"); // This block defines rules for parsing filter actions. boundAction = (qi::lit("bound") > qi::lit("(") >> comparisonType >> qi::lit(",") >> qi::double_ >> qi::lit(")"))[qi::_val = - MAKE(storm::property::action::BoundAction<double> ,qi::_1, qi::_2)]; + MAKE(storm::properties::action::BoundAction<double> ,qi::_1, qi::_2)]; boundAction.name("bound action"); - invertAction = qi::lit("invert")[qi::_val = MAKE(storm::property::action::InvertAction<double>, )]; + invertAction = qi::lit("invert")[qi::_val = MAKE(storm::properties::action::InvertAction<double>, )]; invertAction.name("invert action"); formulaAction = (qi::lit("formula") > qi::lit("(") >> stateFormula >> qi::lit(")"))[qi::_val = - MAKE(storm::property::action::FormulaAction<double>, qi::_1)]; + MAKE(storm::properties::action::FormulaAction<double>, qi::_1)]; formulaAction.name("formula action"); rangeAction = ( (qi::lit("range") >> qi::lit("(") >> qi::uint_ >> qi::lit(",") > qi::uint_ >> qi::lit(")"))[qi::_val = - MAKE(storm::property::action::RangeAction<double>, qi::_1, qi::_2)] | + MAKE(storm::properties::action::RangeAction<double>, qi::_1, qi::_2)] | (qi::lit("range") >> qi::lit("(") >> qi::uint_ >> qi::lit(")"))[qi::_val = - MAKE(storm::property::action::RangeAction<double>, qi::_1, qi::_1 + 1)] + MAKE(storm::properties::action::RangeAction<double>, qi::_1, qi::_1 + 1)] ); rangeAction.name("range action"); sortAction = ( (qi::lit("sort") >> qi::lit("(") >> sortingCategory >> qi::lit(")"))[qi::_val = - MAKE(storm::property::action::SortAction<double>, qi::_1)] | + MAKE(storm::properties::action::SortAction<double>, qi::_1)] | (qi::lit("sort") >> qi::lit("(") >> sortingCategory >> qi::lit(", ") >> (qi::lit("ascending") | qi::lit("asc")) > qi::lit(")"))[qi::_val = - MAKE(storm::property::action::SortAction<double>, qi::_1, true)] | + MAKE(storm::properties::action::SortAction<double>, qi::_1, true)] | (qi::lit("sort") >> qi::lit("(") >> sortingCategory >> qi::lit(", ") >> (qi::lit("descending") | qi::lit("desc")) > qi::lit(")"))[qi::_val = - MAKE(storm::property::action::SortAction<double>, qi::_1, false)] + MAKE(storm::properties::action::SortAction<double>, qi::_1, false)] ); sortAction.name("sort action"); @@ -182,9 +182,9 @@ struct CslParser::CslGrammar : qi::grammar<Iterator, std::shared_ptr<csl::CslFil filter = (qi::lit("filter") >> qi::lit("[") >> +abstractAction >> qi::lit("]") >> qi::lit("(") >> formula >> qi::lit(")"))[qi::_val = MAKE(csl::CslFilter<double>, qi::_2, qi::_1)] | (qi::lit("filter") >> qi::lit("[") >> qi::lit("max") > +abstractAction >> qi::lit("]") >> qi::lit("(") >> formula >> qi::lit(")"))[qi::_val = - MAKE(csl::CslFilter<double>, qi::_2, qi::_1, storm::property::MAXIMIZE)] | + MAKE(csl::CslFilter<double>, qi::_2, qi::_1, storm::properties::MAXIMIZE)] | (qi::lit("filter") >> qi::lit("[") >> qi::lit("min") > +abstractAction >> qi::lit("]") >> qi::lit("(") >> formula >> qi::lit(")"))[qi::_val = - MAKE(csl::CslFilter<double>, qi::_2, qi::_1, storm::property::MINIMIZE)] | + MAKE(csl::CslFilter<double>, qi::_2, qi::_1, storm::properties::MINIMIZE)] | (noBoundOperator)[qi::_val = qi::_1] | (formula)[qi::_val = @@ -204,12 +204,12 @@ struct CslParser::CslGrammar : qi::grammar<Iterator, std::shared_ptr<csl::CslFil qi::rule<Iterator, std::shared_ptr<csl::CslFilter<double>>(), Skipper> probabilisticNoBoundOperator; qi::rule<Iterator, std::shared_ptr<csl::CslFilter<double>>(), Skipper> steadyStateNoBoundOperator; - qi::rule<Iterator, std::shared_ptr<storm::property::action::AbstractAction<double>>(), Skipper> abstractAction; - qi::rule<Iterator, std::shared_ptr<storm::property::action::BoundAction<double>>(), Skipper> boundAction; - qi::rule<Iterator, std::shared_ptr<storm::property::action::InvertAction<double>>(), Skipper> invertAction; - qi::rule<Iterator, std::shared_ptr<storm::property::action::FormulaAction<double>>(), Skipper> formulaAction; - qi::rule<Iterator, std::shared_ptr<storm::property::action::RangeAction<double>>(), Skipper> rangeAction; - qi::rule<Iterator, std::shared_ptr<storm::property::action::SortAction<double>>(), Skipper> sortAction; + qi::rule<Iterator, std::shared_ptr<storm::properties::action::AbstractAction<double>>(), Skipper> abstractAction; + qi::rule<Iterator, std::shared_ptr<storm::properties::action::BoundAction<double>>(), Skipper> boundAction; + qi::rule<Iterator, std::shared_ptr<storm::properties::action::InvertAction<double>>(), Skipper> invertAction; + qi::rule<Iterator, std::shared_ptr<storm::properties::action::FormulaAction<double>>(), Skipper> formulaAction; + qi::rule<Iterator, std::shared_ptr<storm::properties::action::RangeAction<double>>(), Skipper> rangeAction; + qi::rule<Iterator, std::shared_ptr<storm::properties::action::SortAction<double>>(), Skipper> sortAction; qi::rule<Iterator, std::shared_ptr<csl::AbstractCslFormula<double>>(), Skipper> formula; qi::rule<Iterator, std::shared_ptr<csl::AbstractCslFormula<double>>(), Skipper> comment; @@ -229,17 +229,17 @@ struct CslParser::CslGrammar : qi::grammar<Iterator, std::shared_ptr<csl::CslFil qi::rule<Iterator, std::shared_ptr<csl::Eventually<double>>(), Skipper> eventually; qi::rule<Iterator, std::shared_ptr<csl::Next<double>>(), Skipper> next; qi::rule<Iterator, std::shared_ptr<csl::Globally<double>>(), Skipper> globally; - qi::rule<Iterator, std::shared_ptr<csl::TimeBoundedUntil<double>>(), qi::locals< std::shared_ptr<storm::property::csl::AbstractStateFormula<double>>>, Skipper> timeBoundedUntil; - qi::rule<Iterator, std::shared_ptr<csl::Until<double>>(), qi::locals< std::shared_ptr<storm::property::csl::AbstractStateFormula<double>>>, Skipper> until; + qi::rule<Iterator, std::shared_ptr<csl::TimeBoundedUntil<double>>(), qi::locals< std::shared_ptr<storm::properties::csl::AbstractStateFormula<double>>>, Skipper> timeBoundedUntil; + qi::rule<Iterator, std::shared_ptr<csl::Until<double>>(), qi::locals< std::shared_ptr<storm::properties::csl::AbstractStateFormula<double>>>, Skipper> until; qi::rule<Iterator, std::string(), Skipper> freeIdentifierName; - qi::rule<Iterator, storm::property::ComparisonType(), Skipper> comparisonType; - qi::rule<Iterator, storm::property::action::SortAction<double>::SortingCategory(), Skipper> sortingCategory; + qi::rule<Iterator, storm::properties::ComparisonType(), Skipper> comparisonType; + qi::rule<Iterator, storm::properties::action::SortAction<double>::SortingCategory(), Skipper> sortingCategory; }; -std::shared_ptr<storm::property::csl::CslFilter<double>> CslParser::parseCslFormula(std::string formulaString) { +std::shared_ptr<storm::properties::csl::CslFilter<double>> CslParser::parseCslFormula(std::string formulaString) { // Prepare iterators to input. BaseIteratorType stringIteratorBegin = formulaString.begin(); BaseIteratorType stringIteratorEnd = formulaString.end(); @@ -248,7 +248,7 @@ std::shared_ptr<storm::property::csl::CslFilter<double>> CslParser::parseCslForm // Prepare resulting intermediate representation of input. - std::shared_ptr<storm::property::csl::CslFilter<double>> result_pointer(nullptr); + std::shared_ptr<storm::properties::csl::CslFilter<double>> result_pointer(nullptr); CslGrammar<PositionIteratorType, BOOST_TYPEOF(boost::spirit::ascii::space)> grammar; diff --git a/src/parser/CslParser.h b/src/parser/CslParser.h index ccb5b90c3..78b42c844 100644 --- a/src/parser/CslParser.h +++ b/src/parser/CslParser.h @@ -8,8 +8,8 @@ #ifndef STORM_PARSER_CSLPARSER_H_ #define STORM_PARSER_CSLPARSER_H_ -#include "src/formula/Csl.h" -#include "src/formula/csl/CslFilter.h" +#include "src/properties/Csl.h" +#include "src/properties/csl/CslFilter.h" #include <functional> namespace storm { @@ -25,7 +25,7 @@ public: /*! * Reads a CSL formula from its string representation and parses it into a formula tree, consisting of - * classes in the namespace storm::property. + * classes in the namespace storm::properties. * * If the string could not be parsed successfully, it will throw a wrongFormatException. * @@ -33,7 +33,7 @@ public: * @throw wrongFormatException If the input could not be parsed successfully. * @return A CslFilter maintaining the parsed formula. */ - static std::shared_ptr<storm::property::csl::CslFilter<double>> parseCslFormula(std::string formulaString); + static std::shared_ptr<storm::properties::csl::CslFilter<double>> parseCslFormula(std::string formulaString); private: diff --git a/src/parser/LtlFileParser.cpp b/src/parser/LtlFileParser.cpp index e056a99ee..c7b056183 100644 --- a/src/parser/LtlFileParser.cpp +++ b/src/parser/LtlFileParser.cpp @@ -15,7 +15,7 @@ namespace storm { namespace parser { -std::list<std::shared_ptr<storm::property::ltl::LtlFilter<double>>> LtlFileParser::parseLtlFile(std::string filename) { +std::list<std::shared_ptr<storm::properties::ltl::LtlFilter<double>>> LtlFileParser::parseLtlFile(std::string filename) { // Open file std::ifstream inputFileStream(filename, std::ios::in); @@ -24,7 +24,7 @@ std::list<std::shared_ptr<storm::property::ltl::LtlFilter<double>>> LtlFileParse throw storm::exceptions::FileIoException() << message << filename; } - std::list<std::shared_ptr<storm::property::ltl::LtlFilter<double>>> result; + std::list<std::shared_ptr<storm::properties::ltl::LtlFilter<double>>> result; while(!inputFileStream.eof()) { std::string line; diff --git a/src/parser/LtlFileParser.h b/src/parser/LtlFileParser.h index f21210b7d..4caa67d8f 100644 --- a/src/parser/LtlFileParser.h +++ b/src/parser/LtlFileParser.h @@ -8,8 +8,8 @@ #ifndef LTLFILEPARSER_H_ #define LTLFILEPARSER_H_ -#include "formula/Ltl.h" -#include "src/formula/ltl/LtlFilter.h" +#include "properties/Ltl.h" +#include "src/properties/ltl/LtlFilter.h" #include <list> @@ -25,7 +25,7 @@ public: * @param filename Name and path to the file in which the formula strings can be found. * @return The list of parsed formulas. */ - static std::list<std::shared_ptr<storm::property::ltl::LtlFilter<double>>> parseLtlFile(std::string filename); + static std::list<std::shared_ptr<storm::properties::ltl::LtlFilter<double>>> parseLtlFile(std::string filename); }; } //namespace parser diff --git a/src/parser/LtlParser.cpp b/src/parser/LtlParser.cpp index bb87ab79c..df4d28c9e 100644 --- a/src/parser/LtlParser.cpp +++ b/src/parser/LtlParser.cpp @@ -11,11 +11,11 @@ #include "src/utility/constants.h" // The action class headers. -#include "src/formula/actions/AbstractAction.h" -#include "src/formula/actions/BoundAction.h" -#include "src/formula/actions/InvertAction.h" -#include "src/formula/actions/RangeAction.h" -#include "src/formula/actions/SortAction.h" +#include "src/properties/actions/AbstractAction.h" +#include "src/properties/actions/BoundAction.h" +#include "src/properties/actions/InvertAction.h" +#include "src/properties/actions/RangeAction.h" +#include "src/properties/actions/SortAction.h" // If the parser fails due to ill-formed data, this exception is thrown. #include "src/exceptions/WrongFormatException.h" @@ -41,7 +41,7 @@ typedef std::string::const_iterator BaseIteratorType; typedef boost::spirit::classic::position_iterator2<BaseIteratorType> PositionIteratorType; namespace qi = boost::spirit::qi; namespace phoenix = boost::phoenix; -namespace ltl = storm::property::ltl; +namespace ltl = storm::properties::ltl; namespace storm { @@ -49,18 +49,18 @@ namespace storm { namespace parser { template<typename Iterator, typename Skipper> -struct LtlParser::LtlGrammar : qi::grammar<Iterator, std::shared_ptr<storm::property::ltl::LtlFilter<double>>(), Skipper > { +struct LtlParser::LtlGrammar : qi::grammar<Iterator, std::shared_ptr<storm::properties::ltl::LtlFilter<double>>(), Skipper > { LtlGrammar() : LtlGrammar::base_type(start) { //This block contains helper rules that may be used several times freeIdentifierName = qi::lexeme[qi::alpha >> *(qi::alnum | qi::char_('_'))]; comparisonType = ( - (qi::lit(">="))[qi::_val = storm::property::GREATER_EQUAL] | - (qi::lit(">"))[qi::_val = storm::property::GREATER] | - (qi::lit("<="))[qi::_val = storm::property::LESS_EQUAL] | - (qi::lit("<"))[qi::_val = storm::property::LESS]); + (qi::lit(">="))[qi::_val = storm::properties::GREATER_EQUAL] | + (qi::lit(">"))[qi::_val = storm::properties::GREATER] | + (qi::lit("<="))[qi::_val = storm::properties::LESS_EQUAL] | + (qi::lit("<"))[qi::_val = storm::properties::LESS]); sortingCategory = ( - (qi::lit("index"))[qi::_val = storm::property::action::SortAction<double>::INDEX] | - (qi::lit("value"))[qi::_val = storm::property::action::SortAction<double>::VALUE] + (qi::lit("index"))[qi::_val = storm::properties::action::SortAction<double>::INDEX] | + (qi::lit("value"))[qi::_val = storm::properties::action::SortAction<double>::VALUE] ); // Comment: Empty line or line starting with "//" comment = (qi::lit("//") >> *(qi::char_))[qi::_val = nullptr]; @@ -110,27 +110,27 @@ struct LtlParser::LtlGrammar : qi::grammar<Iterator, std::shared_ptr<storm::prop // This block defines rules for parsing filter actions. boundAction = (qi::lit("bound") > qi::lit("(") >> comparisonType >> qi::lit(",") >> qi::double_ >> qi::lit(")"))[qi::_val = - MAKE(storm::property::action::BoundAction<double> ,qi::_1, qi::_2)]; + MAKE(storm::properties::action::BoundAction<double> ,qi::_1, qi::_2)]; boundAction.name("bound action"); - invertAction = qi::lit("invert")[qi::_val = MAKE(storm::property::action::InvertAction<double>, )]; + invertAction = qi::lit("invert")[qi::_val = MAKE(storm::properties::action::InvertAction<double>, )]; invertAction.name("invert action"); rangeAction = ( (qi::lit("range") >> qi::lit("(") >> qi::uint_ >> qi::lit(",") > qi::uint_ >> qi::lit(")"))[qi::_val = - MAKE(storm::property::action::RangeAction<double>, qi::_1, qi::_2)] | + MAKE(storm::properties::action::RangeAction<double>, qi::_1, qi::_2)] | (qi::lit("range") >> qi::lit("(") >> qi::uint_ >> qi::lit(")"))[qi::_val = - MAKE(storm::property::action::RangeAction<double>, qi::_1, qi::_1 + 1)] + MAKE(storm::properties::action::RangeAction<double>, qi::_1, qi::_1 + 1)] ); rangeAction.name("range action"); sortAction = ( (qi::lit("sort") >> qi::lit("(") >> sortingCategory >> qi::lit(")"))[qi::_val = - MAKE(storm::property::action::SortAction<double>, qi::_1)] | + MAKE(storm::properties::action::SortAction<double>, qi::_1)] | (qi::lit("sort") >> qi::lit("(") >> sortingCategory >> qi::lit(", ") >> (qi::lit("ascending") | qi::lit("asc")) > qi::lit(")"))[qi::_val = - MAKE(storm::property::action::SortAction<double>, qi::_1, true)] | + MAKE(storm::properties::action::SortAction<double>, qi::_1, true)] | (qi::lit("sort") >> qi::lit("(") >> sortingCategory >> qi::lit(", ") >> (qi::lit("descending") | qi::lit("desc")) > qi::lit(")"))[qi::_val = - MAKE(storm::property::action::SortAction<double>, qi::_1, false)] + MAKE(storm::properties::action::SortAction<double>, qi::_1, false)] ); sortAction.name("sort action"); @@ -140,9 +140,9 @@ struct LtlParser::LtlGrammar : qi::grammar<Iterator, std::shared_ptr<storm::prop filter = (qi::lit("filter") >> qi::lit("[") >> +abstractAction >> qi::lit("]") > qi::lit("(") >> formula >> qi::lit(")"))[qi::_val = MAKE(ltl::LtlFilter<double>, qi::_2, qi::_1)] | (qi::lit("filter") >> qi::lit("[") >> qi::lit("max") > +abstractAction >> qi::lit("]") >> qi::lit("(") >> formula >> qi::lit(")"))[qi::_val = - MAKE(ltl::LtlFilter<double>, qi::_2, qi::_1, storm::property::MAXIMIZE)] | + MAKE(ltl::LtlFilter<double>, qi::_2, qi::_1, storm::properties::MAXIMIZE)] | (qi::lit("filter") >> qi::lit("[") >> qi::lit("min") > +abstractAction >> qi::lit("]") >> qi::lit("(") >> formula >> qi::lit(")"))[qi::_val = - MAKE(ltl::LtlFilter<double>, qi::_2, qi::_1, storm::property::MINIMIZE)] | + MAKE(ltl::LtlFilter<double>, qi::_2, qi::_1, storm::properties::MINIMIZE)] | (formula)[qi::_val = MAKE(ltl::LtlFilter<double>, qi::_1)]; filter.name("LTL formula filter"); @@ -151,39 +151,39 @@ struct LtlParser::LtlGrammar : qi::grammar<Iterator, std::shared_ptr<storm::prop start.name("start"); } - qi::rule<Iterator, std::shared_ptr<storm::property::ltl::LtlFilter<double>>(), Skipper> start; - qi::rule<Iterator, std::shared_ptr<storm::property::ltl::LtlFilter<double>>(), Skipper> filter; - - qi::rule<Iterator, std::shared_ptr<storm::property::action::AbstractAction<double>>(), Skipper> abstractAction; - qi::rule<Iterator, std::shared_ptr<storm::property::action::BoundAction<double>>(), Skipper> boundAction; - qi::rule<Iterator, std::shared_ptr<storm::property::action::InvertAction<double>>(), Skipper> invertAction; - qi::rule<Iterator, std::shared_ptr<storm::property::action::RangeAction<double>>(), Skipper> rangeAction; - qi::rule<Iterator, std::shared_ptr<storm::property::action::SortAction<double>>(), Skipper> sortAction; - - qi::rule<Iterator, std::shared_ptr<storm::property::ltl::AbstractLtlFormula<double>>(), Skipper> comment; - qi::rule<Iterator, std::shared_ptr<storm::property::ltl::AbstractLtlFormula<double>>(), Skipper> formula; - qi::rule<Iterator, std::shared_ptr<storm::property::ltl::AbstractLtlFormula<double>>(), Skipper> atomicLtlFormula; - - qi::rule<Iterator, std::shared_ptr<storm::property::ltl::AbstractLtlFormula<double>>(), Skipper> andFormula; - qi::rule<Iterator, std::shared_ptr<storm::property::ltl::AbstractLtlFormula<double>>(), Skipper> untilFormula; - qi::rule<Iterator, std::shared_ptr<storm::property::ltl::AbstractLtlFormula<double>>(), Skipper> atomicProposition; - qi::rule<Iterator, std::shared_ptr<storm::property::ltl::AbstractLtlFormula<double>>(), Skipper> orFormula; - qi::rule<Iterator, std::shared_ptr<storm::property::ltl::AbstractLtlFormula<double>>(), Skipper> notFormula; - - qi::rule<Iterator, std::shared_ptr<storm::property::ltl::AbstractLtlFormula<double>>(), Skipper> pathFormula; - qi::rule<Iterator, std::shared_ptr<storm::property::ltl::BoundedEventually<double>>(), Skipper> boundedEventually; - qi::rule<Iterator, std::shared_ptr<storm::property::ltl::Eventually<double>>(), Skipper> eventually; - qi::rule<Iterator, std::shared_ptr<storm::property::ltl::Globally<double>>(), Skipper> globally; - qi::rule<Iterator, std::shared_ptr<storm::property::ltl::Next<double>>(), Skipper> next; - qi::rule<Iterator, std::shared_ptr<storm::property::ltl::AbstractLtlFormula<double>>(), qi::locals< std::shared_ptr<storm::property::ltl::AbstractLtlFormula<double>>>, Skipper> boundedUntil; - qi::rule<Iterator, std::shared_ptr<storm::property::ltl::AbstractLtlFormula<double>>(), qi::locals< std::shared_ptr<storm::property::ltl::AbstractLtlFormula<double>>>, Skipper> until; + qi::rule<Iterator, std::shared_ptr<storm::properties::ltl::LtlFilter<double>>(), Skipper> start; + qi::rule<Iterator, std::shared_ptr<storm::properties::ltl::LtlFilter<double>>(), Skipper> filter; + + qi::rule<Iterator, std::shared_ptr<storm::properties::action::AbstractAction<double>>(), Skipper> abstractAction; + qi::rule<Iterator, std::shared_ptr<storm::properties::action::BoundAction<double>>(), Skipper> boundAction; + qi::rule<Iterator, std::shared_ptr<storm::properties::action::InvertAction<double>>(), Skipper> invertAction; + qi::rule<Iterator, std::shared_ptr<storm::properties::action::RangeAction<double>>(), Skipper> rangeAction; + qi::rule<Iterator, std::shared_ptr<storm::properties::action::SortAction<double>>(), Skipper> sortAction; + + qi::rule<Iterator, std::shared_ptr<storm::properties::ltl::AbstractLtlFormula<double>>(), Skipper> comment; + qi::rule<Iterator, std::shared_ptr<storm::properties::ltl::AbstractLtlFormula<double>>(), Skipper> formula; + qi::rule<Iterator, std::shared_ptr<storm::properties::ltl::AbstractLtlFormula<double>>(), Skipper> atomicLtlFormula; + + qi::rule<Iterator, std::shared_ptr<storm::properties::ltl::AbstractLtlFormula<double>>(), Skipper> andFormula; + qi::rule<Iterator, std::shared_ptr<storm::properties::ltl::AbstractLtlFormula<double>>(), Skipper> untilFormula; + qi::rule<Iterator, std::shared_ptr<storm::properties::ltl::AbstractLtlFormula<double>>(), Skipper> atomicProposition; + qi::rule<Iterator, std::shared_ptr<storm::properties::ltl::AbstractLtlFormula<double>>(), Skipper> orFormula; + qi::rule<Iterator, std::shared_ptr<storm::properties::ltl::AbstractLtlFormula<double>>(), Skipper> notFormula; + + qi::rule<Iterator, std::shared_ptr<storm::properties::ltl::AbstractLtlFormula<double>>(), Skipper> pathFormula; + qi::rule<Iterator, std::shared_ptr<storm::properties::ltl::BoundedEventually<double>>(), Skipper> boundedEventually; + qi::rule<Iterator, std::shared_ptr<storm::properties::ltl::Eventually<double>>(), Skipper> eventually; + qi::rule<Iterator, std::shared_ptr<storm::properties::ltl::Globally<double>>(), Skipper> globally; + qi::rule<Iterator, std::shared_ptr<storm::properties::ltl::Next<double>>(), Skipper> next; + qi::rule<Iterator, std::shared_ptr<storm::properties::ltl::AbstractLtlFormula<double>>(), qi::locals< std::shared_ptr<storm::properties::ltl::AbstractLtlFormula<double>>>, Skipper> boundedUntil; + qi::rule<Iterator, std::shared_ptr<storm::properties::ltl::AbstractLtlFormula<double>>(), qi::locals< std::shared_ptr<storm::properties::ltl::AbstractLtlFormula<double>>>, Skipper> until; qi::rule<Iterator, std::string(), Skipper> freeIdentifierName; - qi::rule<Iterator, storm::property::ComparisonType(), Skipper> comparisonType; - qi::rule<Iterator, storm::property::action::SortAction<double>::SortingCategory(), Skipper> sortingCategory; + qi::rule<Iterator, storm::properties::ComparisonType(), Skipper> comparisonType; + qi::rule<Iterator, storm::properties::action::SortAction<double>::SortingCategory(), Skipper> sortingCategory; }; -std::shared_ptr<storm::property::ltl::LtlFilter<double>> LtlParser::parseLtlFormula(std::string formulaString) { +std::shared_ptr<storm::properties::ltl::LtlFilter<double>> LtlParser::parseLtlFormula(std::string formulaString) { // Prepare iterators to input. BaseIteratorType stringIteratorBegin = formulaString.begin(); BaseIteratorType stringIteratorEnd = formulaString.end(); @@ -192,7 +192,7 @@ std::shared_ptr<storm::property::ltl::LtlFilter<double>> LtlParser::parseLtlForm // Prepare resulting intermediate representation of input. - std::shared_ptr<storm::property::ltl::LtlFilter<double>> result_pointer(nullptr); + std::shared_ptr<storm::properties::ltl::LtlFilter<double>> result_pointer(nullptr); LtlGrammar<PositionIteratorType, BOOST_TYPEOF(boost::spirit::ascii::space)> grammar; diff --git a/src/parser/LtlParser.h b/src/parser/LtlParser.h index ebbad77c0..dac3a63ec 100644 --- a/src/parser/LtlParser.h +++ b/src/parser/LtlParser.h @@ -8,8 +8,8 @@ #ifndef STORM_PARSER_LTLPARSER_H_ #define STORM_PARSER_LTLPARSER_H_ -#include "src/formula/Ltl.h" -#include "src/formula/ltl/LtlFilter.h" +#include "src/properties/Ltl.h" +#include "src/properties/ltl/LtlFilter.h" namespace storm { namespace parser { @@ -24,7 +24,7 @@ public: /*! * Reads a LTL formula from its string representation and parses it into a formula tree, consisting of - * classes in the namespace storm::property. + * classes in the namespace storm::properties. * * If the string could not be parsed successfully, it will throw a wrongFormatException. * @@ -32,7 +32,7 @@ public: * @throw wrongFormatException If the input could not be parsed successfully. * @return A LtlFilter maintaining the parsed formula. */ - static std::shared_ptr<storm::property::ltl::LtlFilter<double>> parseLtlFormula(std::string formulaString); + static std::shared_ptr<storm::properties::ltl::LtlFilter<double>> parseLtlFormula(std::string formulaString); private: diff --git a/src/parser/PrctlFileParser.cpp b/src/parser/PrctlFileParser.cpp index 323d5984b..64abd2b15 100644 --- a/src/parser/PrctlFileParser.cpp +++ b/src/parser/PrctlFileParser.cpp @@ -14,7 +14,7 @@ namespace storm { namespace parser { -std::list<std::shared_ptr<storm::property::prctl::PrctlFilter<double>>> PrctlFileParser::parsePrctlFile(std::string filename) { +std::list<std::shared_ptr<storm::properties::prctl::PrctlFilter<double>>> PrctlFileParser::parsePrctlFile(std::string filename) { // Open file std::ifstream inputFileStream; inputFileStream.open(filename, std::ios::in); @@ -24,12 +24,12 @@ std::list<std::shared_ptr<storm::property::prctl::PrctlFilter<double>>> PrctlFil throw storm::exceptions::FileIoException() << message << filename; } - std::list<std::shared_ptr<storm::property::prctl::PrctlFilter<double>>> result; + std::list<std::shared_ptr<storm::properties::prctl::PrctlFilter<double>>> result; std::string line; //The while loop reads the input file line by line while (std::getline(inputFileStream, line)) { - std::shared_ptr<storm::property::prctl::PrctlFilter<double>> formula = PrctlParser::parsePrctlFormula(line); + std::shared_ptr<storm::properties::prctl::PrctlFilter<double>> formula = PrctlParser::parsePrctlFormula(line); if (formula != nullptr) { //lines containing comments will be skipped. LOG4CPLUS_INFO(logger, "Parsed formula \"" + line + "\" into \"" + formula->toString() + "\""); diff --git a/src/parser/PrctlFileParser.h b/src/parser/PrctlFileParser.h index 615e219c1..dbf458fbf 100644 --- a/src/parser/PrctlFileParser.h +++ b/src/parser/PrctlFileParser.h @@ -8,8 +8,8 @@ #ifndef STORM_PARSER_PRCTLFILEPARSER_H_ #define STORM_PARSER_PRCTLFILEPARSER_H_ -#include "formula/Prctl.h" -#include "src/formula/prctl/PrctlFilter.h" +#include "properties/Prctl.h" +#include "src/properties/prctl/PrctlFilter.h" #include <list> @@ -25,7 +25,7 @@ public: * @param filename Name and path to the file in which the formula strings can be found. * @return The list of parsed formulas */ - static std::list<std::shared_ptr<storm::property::prctl::PrctlFilter<double>>> parsePrctlFile(std::string filename); + static std::list<std::shared_ptr<storm::properties::prctl::PrctlFilter<double>>> parsePrctlFile(std::string filename); }; diff --git a/src/parser/PrctlParser.cpp b/src/parser/PrctlParser.cpp index bd9590980..41a9ab701 100644 --- a/src/parser/PrctlParser.cpp +++ b/src/parser/PrctlParser.cpp @@ -3,12 +3,12 @@ #include "src/utility/constants.h" // The action class headers. -#include "src/formula/actions/AbstractAction.h" -#include "src/formula/actions/BoundAction.h" -#include "src/formula/actions/InvertAction.h" -#include "src/formula/actions/FormulaAction.h" -#include "src/formula/actions/RangeAction.h" -#include "src/formula/actions/SortAction.h" +#include "src/properties/actions/AbstractAction.h" +#include "src/properties/actions/BoundAction.h" +#include "src/properties/actions/InvertAction.h" +#include "src/properties/actions/FormulaAction.h" +#include "src/properties/actions/RangeAction.h" +#include "src/properties/actions/SortAction.h" // If the parser fails due to ill-formed data, this exception is thrown. #include "src/exceptions/WrongFormatException.h" @@ -35,7 +35,7 @@ typedef std::string::const_iterator BaseIteratorType; typedef boost::spirit::classic::position_iterator2<BaseIteratorType> PositionIteratorType; namespace qi = boost::spirit::qi; namespace phoenix = boost::phoenix; -namespace prctl = storm::property::prctl; +namespace prctl = storm::properties::prctl; namespace storm { @@ -43,18 +43,18 @@ namespace storm { namespace parser { template<typename Iterator, typename Skipper> -struct PrctlParser::PrctlGrammar : qi::grammar<Iterator, std::shared_ptr<storm::property::prctl::PrctlFilter<double>>(), Skipper > { +struct PrctlParser::PrctlGrammar : qi::grammar<Iterator, std::shared_ptr<storm::properties::prctl::PrctlFilter<double>>(), Skipper > { PrctlGrammar() : PrctlGrammar::base_type(start) { // This block contains helper rules that may be used several times freeIdentifierName = qi::lexeme[qi::alpha >> *(qi::alnum | qi::char_('_'))]; comparisonType = ( - (qi::lit(">="))[qi::_val = storm::property::GREATER_EQUAL] | - (qi::lit(">"))[qi::_val = storm::property::GREATER] | - (qi::lit("<="))[qi::_val = storm::property::LESS_EQUAL] | - (qi::lit("<"))[qi::_val = storm::property::LESS]); + (qi::lit(">="))[qi::_val = storm::properties::GREATER_EQUAL] | + (qi::lit(">"))[qi::_val = storm::properties::GREATER] | + (qi::lit("<="))[qi::_val = storm::properties::LESS_EQUAL] | + (qi::lit("<"))[qi::_val = storm::properties::LESS]); sortingCategory = ( - (qi::lit("index"))[qi::_val = storm::property::action::SortAction<double>::INDEX] | - (qi::lit("value"))[qi::_val = storm::property::action::SortAction<double>::VALUE] + (qi::lit("index"))[qi::_val = storm::properties::action::SortAction<double>::INDEX] | + (qi::lit("value"))[qi::_val = storm::properties::action::SortAction<double>::VALUE] ); // Comment: Empty line or line starting with "//" comment = (qi::lit("//") >> *(qi::char_))[qi::_val = nullptr]; @@ -133,9 +133,9 @@ struct PrctlParser::PrctlGrammar : qi::grammar<Iterator, std::shared_ptr<storm:: noBoundOperator.name("no bound operator"); probabilisticNoBoundOperator = ( (qi::lit("P") >> qi::lit("min") >> qi::lit("=") > qi::lit("?") >> pathFormula )[qi::_val = - MAKE(prctl::PrctlFilter<double>, qi::_1, storm::property::MINIMIZE)] | + MAKE(prctl::PrctlFilter<double>, qi::_1, storm::properties::MINIMIZE)] | (qi::lit("P") >> qi::lit("max") >> qi::lit("=") > qi::lit("?") >> pathFormula )[qi::_val = - MAKE(prctl::PrctlFilter<double>, qi::_1, storm::property::MAXIMIZE)] | + MAKE(prctl::PrctlFilter<double>, qi::_1, storm::properties::MAXIMIZE)] | (qi::lit("P") >> qi::lit("=") > qi::lit("?") >> pathFormula )[qi::_val = MAKE(prctl::PrctlFilter<double>, qi::_1)] ); @@ -143,9 +143,9 @@ struct PrctlParser::PrctlGrammar : qi::grammar<Iterator, std::shared_ptr<storm:: rewardNoBoundOperator = ( (qi::lit("R") >> qi::lit("min") >> qi::lit("=") > qi::lit("?") >> rewardPathFormula )[qi::_val = - MAKE(prctl::PrctlFilter<double>, qi::_1, storm::property::MINIMIZE)] | + MAKE(prctl::PrctlFilter<double>, qi::_1, storm::properties::MINIMIZE)] | (qi::lit("R") >> qi::lit("max") >> qi::lit("=") > qi::lit("?") >> rewardPathFormula )[qi::_val = - MAKE(prctl::PrctlFilter<double>, qi::_1, storm::property::MAXIMIZE)] | + MAKE(prctl::PrctlFilter<double>, qi::_1, storm::properties::MAXIMIZE)] | (qi::lit("R") >> qi::lit("=") > qi::lit("?") >> rewardPathFormula )[qi::_val = MAKE(prctl::PrctlFilter<double>, qi::_1)] @@ -155,31 +155,31 @@ struct PrctlParser::PrctlGrammar : qi::grammar<Iterator, std::shared_ptr<storm:: // This block defines rules for parsing filter actions. boundAction = (qi::lit("bound") > qi::lit("(") >> comparisonType >> qi::lit(",") >> qi::double_ >> qi::lit(")"))[qi::_val = - MAKE(storm::property::action::BoundAction<double> ,qi::_1, qi::_2)]; + MAKE(storm::properties::action::BoundAction<double> ,qi::_1, qi::_2)]; boundAction.name("bound action"); - invertAction = qi::lit("invert")[qi::_val = MAKE(storm::property::action::InvertAction<double>, )]; + invertAction = qi::lit("invert")[qi::_val = MAKE(storm::properties::action::InvertAction<double>, )]; invertAction.name("invert action"); formulaAction = (qi::lit("formula") > qi::lit("(") >> stateFormula >> qi::lit(")"))[qi::_val = - MAKE(storm::property::action::FormulaAction<double>, qi::_1)]; + MAKE(storm::properties::action::FormulaAction<double>, qi::_1)]; formulaAction.name("formula action"); rangeAction = ( (qi::lit("range") >> qi::lit("(") >> qi::uint_ >> qi::lit(",") > qi::uint_ >> qi::lit(")"))[qi::_val = - MAKE(storm::property::action::RangeAction<double>, qi::_1, qi::_2)] | + MAKE(storm::properties::action::RangeAction<double>, qi::_1, qi::_2)] | (qi::lit("range") >> qi::lit("(") >> qi::uint_ >> qi::lit(")"))[qi::_val = - MAKE(storm::property::action::RangeAction<double>, qi::_1, qi::_1 + 1)] + MAKE(storm::properties::action::RangeAction<double>, qi::_1, qi::_1 + 1)] ); rangeAction.name("range action"); sortAction = ( (qi::lit("sort") >> qi::lit("(") >> sortingCategory >> qi::lit(")"))[qi::_val = - MAKE(storm::property::action::SortAction<double>, qi::_1)] | + MAKE(storm::properties::action::SortAction<double>, qi::_1)] | (qi::lit("sort") >> qi::lit("(") >> sortingCategory >> qi::lit(", ") >> (qi::lit("ascending") | qi::lit("asc")) > qi::lit(")"))[qi::_val = - MAKE(storm::property::action::SortAction<double>, qi::_1, true)] | + MAKE(storm::properties::action::SortAction<double>, qi::_1, true)] | (qi::lit("sort") >> qi::lit("(") >> sortingCategory >> qi::lit(", ") >> (qi::lit("descending") | qi::lit("desc")) > qi::lit(")"))[qi::_val = - MAKE(storm::property::action::SortAction<double>, qi::_1, false)] + MAKE(storm::properties::action::SortAction<double>, qi::_1, false)] ); sortAction.name("sort action"); @@ -189,9 +189,9 @@ struct PrctlParser::PrctlGrammar : qi::grammar<Iterator, std::shared_ptr<storm:: filter = (qi::lit("filter") >> qi::lit("[") >> +abstractAction >> qi::lit("]") > qi::lit("(") >> formula >> qi::lit(")"))[qi::_val = MAKE(prctl::PrctlFilter<double>, qi::_2, qi::_1)] | (qi::lit("filter") >> qi::lit("[") >> qi::lit("max") > +abstractAction >> qi::lit("]") >> qi::lit("(") >> formula >> qi::lit(")"))[qi::_val = - MAKE(prctl::PrctlFilter<double>, qi::_2, qi::_1, storm::property::MAXIMIZE)] | + MAKE(prctl::PrctlFilter<double>, qi::_2, qi::_1, storm::properties::MAXIMIZE)] | (qi::lit("filter") >> qi::lit("[") >> qi::lit("min") > +abstractAction >> qi::lit("]") >> qi::lit("(") >> formula >> qi::lit(")"))[qi::_val = - MAKE(prctl::PrctlFilter<double>, qi::_2, qi::_1, storm::property::MINIMIZE)] | + MAKE(prctl::PrctlFilter<double>, qi::_2, qi::_1, storm::properties::MINIMIZE)] | (noBoundOperator)[qi::_val = qi::_1] | (formula)[qi::_val = @@ -203,54 +203,54 @@ struct PrctlParser::PrctlGrammar : qi::grammar<Iterator, std::shared_ptr<storm:: } - qi::rule<Iterator, std::shared_ptr<storm::property::prctl::PrctlFilter<double>>(), Skipper> start; - qi::rule<Iterator, std::shared_ptr<storm::property::prctl::PrctlFilter<double>>(), Skipper> filter; + qi::rule<Iterator, std::shared_ptr<storm::properties::prctl::PrctlFilter<double>>(), Skipper> start; + qi::rule<Iterator, std::shared_ptr<storm::properties::prctl::PrctlFilter<double>>(), Skipper> filter; - qi::rule<Iterator, std::shared_ptr<storm::property::prctl::PrctlFilter<double>>(), Skipper> noBoundOperator; - qi::rule<Iterator, std::shared_ptr<storm::property::prctl::PrctlFilter<double>>(), Skipper> probabilisticNoBoundOperator; - qi::rule<Iterator, std::shared_ptr<storm::property::prctl::PrctlFilter<double>>(), Skipper> rewardNoBoundOperator; + qi::rule<Iterator, std::shared_ptr<storm::properties::prctl::PrctlFilter<double>>(), Skipper> noBoundOperator; + qi::rule<Iterator, std::shared_ptr<storm::properties::prctl::PrctlFilter<double>>(), Skipper> probabilisticNoBoundOperator; + qi::rule<Iterator, std::shared_ptr<storm::properties::prctl::PrctlFilter<double>>(), Skipper> rewardNoBoundOperator; - qi::rule<Iterator, std::shared_ptr<storm::property::action::AbstractAction<double>>(), Skipper> abstractAction; - qi::rule<Iterator, std::shared_ptr<storm::property::action::BoundAction<double>>(), Skipper> boundAction; - qi::rule<Iterator, std::shared_ptr<storm::property::action::InvertAction<double>>(), Skipper> invertAction; - qi::rule<Iterator, std::shared_ptr<storm::property::action::FormulaAction<double>>(), Skipper> formulaAction; - qi::rule<Iterator, std::shared_ptr<storm::property::action::RangeAction<double>>(), Skipper> rangeAction; - qi::rule<Iterator, std::shared_ptr<storm::property::action::SortAction<double>>(), Skipper> sortAction; + qi::rule<Iterator, std::shared_ptr<storm::properties::action::AbstractAction<double>>(), Skipper> abstractAction; + qi::rule<Iterator, std::shared_ptr<storm::properties::action::BoundAction<double>>(), Skipper> boundAction; + qi::rule<Iterator, std::shared_ptr<storm::properties::action::InvertAction<double>>(), Skipper> invertAction; + qi::rule<Iterator, std::shared_ptr<storm::properties::action::FormulaAction<double>>(), Skipper> formulaAction; + qi::rule<Iterator, std::shared_ptr<storm::properties::action::RangeAction<double>>(), Skipper> rangeAction; + qi::rule<Iterator, std::shared_ptr<storm::properties::action::SortAction<double>>(), Skipper> sortAction; - qi::rule<Iterator, std::shared_ptr<storm::property::prctl::AbstractPrctlFormula<double>>(), Skipper> formula; - qi::rule<Iterator, std::shared_ptr<storm::property::prctl::AbstractPrctlFormula<double>>(), Skipper> comment; + qi::rule<Iterator, std::shared_ptr<storm::properties::prctl::AbstractPrctlFormula<double>>(), Skipper> formula; + qi::rule<Iterator, std::shared_ptr<storm::properties::prctl::AbstractPrctlFormula<double>>(), Skipper> comment; - qi::rule<Iterator, std::shared_ptr<storm::property::prctl::AbstractStateFormula<double>>(), Skipper> stateFormula; - qi::rule<Iterator, std::shared_ptr<storm::property::prctl::AbstractStateFormula<double>>(), Skipper> atomicStateFormula; + qi::rule<Iterator, std::shared_ptr<storm::properties::prctl::AbstractStateFormula<double>>(), Skipper> stateFormula; + qi::rule<Iterator, std::shared_ptr<storm::properties::prctl::AbstractStateFormula<double>>(), Skipper> atomicStateFormula; - qi::rule<Iterator, std::shared_ptr<storm::property::prctl::AbstractStateFormula<double>>(), Skipper> andFormula; - qi::rule<Iterator, std::shared_ptr<storm::property::prctl::AbstractStateFormula<double>>(), Skipper> atomicProposition; - qi::rule<Iterator, std::shared_ptr<storm::property::prctl::AbstractStateFormula<double>>(), Skipper> orFormula; - qi::rule<Iterator, std::shared_ptr<storm::property::prctl::AbstractStateFormula<double>>(), Skipper> notFormula; - qi::rule<Iterator, std::shared_ptr<storm::property::prctl::ProbabilisticBoundOperator<double>>(), Skipper> probabilisticBoundOperator; - qi::rule<Iterator, std::shared_ptr<storm::property::prctl::RewardBoundOperator<double>>(), Skipper> rewardBoundOperator; + qi::rule<Iterator, std::shared_ptr<storm::properties::prctl::AbstractStateFormula<double>>(), Skipper> andFormula; + qi::rule<Iterator, std::shared_ptr<storm::properties::prctl::AbstractStateFormula<double>>(), Skipper> atomicProposition; + qi::rule<Iterator, std::shared_ptr<storm::properties::prctl::AbstractStateFormula<double>>(), Skipper> orFormula; + qi::rule<Iterator, std::shared_ptr<storm::properties::prctl::AbstractStateFormula<double>>(), Skipper> notFormula; + qi::rule<Iterator, std::shared_ptr<storm::properties::prctl::ProbabilisticBoundOperator<double>>(), Skipper> probabilisticBoundOperator; + qi::rule<Iterator, std::shared_ptr<storm::properties::prctl::RewardBoundOperator<double>>(), Skipper> rewardBoundOperator; - qi::rule<Iterator, std::shared_ptr<storm::property::prctl::AbstractPathFormula<double>>(), Skipper> pathFormula; - qi::rule<Iterator, std::shared_ptr<storm::property::prctl::BoundedEventually<double>>(), Skipper> boundedEventually; - qi::rule<Iterator, std::shared_ptr<storm::property::prctl::Eventually<double>>(), Skipper> eventually; - qi::rule<Iterator, std::shared_ptr<storm::property::prctl::Next<double>>(), Skipper> next; - qi::rule<Iterator, std::shared_ptr<storm::property::prctl::Globally<double>>(), Skipper> globally; - qi::rule<Iterator, std::shared_ptr<storm::property::prctl::BoundedUntil<double>>(), qi::locals< std::shared_ptr<storm::property::prctl::AbstractStateFormula<double>>>, Skipper> boundedUntil; - qi::rule<Iterator, std::shared_ptr<storm::property::prctl::Until<double>>(), qi::locals< std::shared_ptr<storm::property::prctl::AbstractStateFormula<double>>>, Skipper> until; + qi::rule<Iterator, std::shared_ptr<storm::properties::prctl::AbstractPathFormula<double>>(), Skipper> pathFormula; + qi::rule<Iterator, std::shared_ptr<storm::properties::prctl::BoundedEventually<double>>(), Skipper> boundedEventually; + qi::rule<Iterator, std::shared_ptr<storm::properties::prctl::Eventually<double>>(), Skipper> eventually; + qi::rule<Iterator, std::shared_ptr<storm::properties::prctl::Next<double>>(), Skipper> next; + qi::rule<Iterator, std::shared_ptr<storm::properties::prctl::Globally<double>>(), Skipper> globally; + qi::rule<Iterator, std::shared_ptr<storm::properties::prctl::BoundedUntil<double>>(), qi::locals< std::shared_ptr<storm::properties::prctl::AbstractStateFormula<double>>>, Skipper> boundedUntil; + qi::rule<Iterator, std::shared_ptr<storm::properties::prctl::Until<double>>(), qi::locals< std::shared_ptr<storm::properties::prctl::AbstractStateFormula<double>>>, Skipper> until; - qi::rule<Iterator, std::shared_ptr<storm::property::prctl::AbstractRewardPathFormula<double>>(), Skipper> rewardPathFormula; - qi::rule<Iterator, std::shared_ptr<storm::property::prctl::CumulativeReward<double>>(), Skipper> cumulativeReward; - qi::rule<Iterator, std::shared_ptr<storm::property::prctl::ReachabilityReward<double>>(), Skipper> reachabilityReward; - qi::rule<Iterator, std::shared_ptr<storm::property::prctl::InstantaneousReward<double>>(), Skipper> instantaneousReward; - qi::rule<Iterator, std::shared_ptr<storm::property::prctl::SteadyStateReward<double>>(), Skipper> steadyStateReward; + qi::rule<Iterator, std::shared_ptr<storm::properties::prctl::AbstractRewardPathFormula<double>>(), Skipper> rewardPathFormula; + qi::rule<Iterator, std::shared_ptr<storm::properties::prctl::CumulativeReward<double>>(), Skipper> cumulativeReward; + qi::rule<Iterator, std::shared_ptr<storm::properties::prctl::ReachabilityReward<double>>(), Skipper> reachabilityReward; + qi::rule<Iterator, std::shared_ptr<storm::properties::prctl::InstantaneousReward<double>>(), Skipper> instantaneousReward; + qi::rule<Iterator, std::shared_ptr<storm::properties::prctl::SteadyStateReward<double>>(), Skipper> steadyStateReward; qi::rule<Iterator, std::string(), Skipper> freeIdentifierName; - qi::rule<Iterator, storm::property::ComparisonType(), Skipper> comparisonType; - qi::rule<Iterator, storm::property::action::SortAction<double>::SortingCategory(), Skipper> sortingCategory; + qi::rule<Iterator, storm::properties::ComparisonType(), Skipper> comparisonType; + qi::rule<Iterator, storm::properties::action::SortAction<double>::SortingCategory(), Skipper> sortingCategory; }; -std::shared_ptr<storm::property::prctl::PrctlFilter<double>> PrctlParser::parsePrctlFormula(std::string formulaString) { +std::shared_ptr<storm::properties::prctl::PrctlFilter<double>> PrctlParser::parsePrctlFormula(std::string formulaString) { // Prepare iterators to input. BaseIteratorType stringIteratorBegin = formulaString.begin(); BaseIteratorType stringIteratorEnd = formulaString.end(); @@ -259,7 +259,7 @@ std::shared_ptr<storm::property::prctl::PrctlFilter<double>> PrctlParser::parseP // Prepare resulting intermediate representation of input. - std::shared_ptr<storm::property::prctl::PrctlFilter<double>> result_pointer(nullptr); + std::shared_ptr<storm::properties::prctl::PrctlFilter<double>> result_pointer(nullptr); PrctlGrammar<PositionIteratorType, BOOST_TYPEOF(boost::spirit::ascii::space)> grammar; diff --git a/src/parser/PrctlParser.h b/src/parser/PrctlParser.h index 75e13c117..c1fc798bb 100644 --- a/src/parser/PrctlParser.h +++ b/src/parser/PrctlParser.h @@ -1,8 +1,8 @@ #ifndef STORM_PARSER_PRCTLPARSER_H_ #define STORM_PARSER_PRCTLPARSER_H_ -#include "src/formula/Prctl.h" -#include "src/formula/prctl/PrctlFilter.h" +#include "src/properties/Prctl.h" +#include "src/properties/prctl/PrctlFilter.h" namespace storm { namespace parser { @@ -17,7 +17,7 @@ public: /*! * Reads a Prctl formula from its string representation and parses it into a formula tree, consisting of - * classes in the namespace storm::property. + * classes in the namespace storm::properties. * * If the string could not be parsed successfully, it will throw a wrongFormatException. * @@ -25,7 +25,7 @@ public: * @throw wrongFormatException If the input could not be parsed successfully * @return A PrctlFilter maintaining the parsed formula. If the line just contained a comment a nullptr will be returned instead. */ - static std::shared_ptr<storm::property::prctl::PrctlFilter<double>> parsePrctlFormula(std::string formulaString); + static std::shared_ptr<storm::properties::prctl::PrctlFilter<double>> parsePrctlFormula(std::string formulaString); private: diff --git a/src/formula/AbstractFilter.h b/src/properties/AbstractFilter.h similarity index 97% rename from src/formula/AbstractFilter.h rename to src/properties/AbstractFilter.h index 3824817fe..5c8899a09 100644 --- a/src/formula/AbstractFilter.h +++ b/src/properties/AbstractFilter.h @@ -10,11 +10,11 @@ #include <vector> #include <string> -#include "src/formula/AbstractFormula.h" -#include "src/formula/actions/AbstractAction.h" +#include "src/properties/AbstractFormula.h" +#include "src/properties/actions/AbstractAction.h" namespace storm { -namespace property { +namespace properties { /*! * This enum contains value indicating which kind of scheduler is to be used @@ -215,7 +215,7 @@ protected: OptimizingOperator opt; }; -} //namespace property +} //namespace properties } //namespace storm diff --git a/src/formula/AbstractFormula.h b/src/properties/AbstractFormula.h similarity index 92% rename from src/formula/AbstractFormula.h rename to src/properties/AbstractFormula.h index 9b009f208..9c55dc370 100644 --- a/src/formula/AbstractFormula.h +++ b/src/properties/AbstractFormula.h @@ -12,21 +12,19 @@ #include <memory> namespace storm { -namespace property { +namespace properties { template <class T> class AbstractFormula; -} //namespace property +} //namespace properties } //namespace storm namespace storm { -namespace property { - -// do properties +namespace properties { /*! * This is the abstract base class for every formula class in every logic. * * There are currently three implemented logics Ltl, Csl and Pctl. - * The implementation of these logics can be found in the namespaces storm::property::<logic> + * The implementation of these logics can be found in the namespaces storm::properties::<logic> * where <logic> is one of ltl, pctl and csl. * * @note While formula classes do have copy constructors using a copy constructor @@ -66,7 +64,7 @@ public: } }; -} // namespace property +} // namespace properties } // namespace storm #endif /* STORM_FORMULA_ABSTRACTFORMULA_H_ */ diff --git a/src/formula/ComparisonType.h b/src/properties/ComparisonType.h similarity index 95% rename from src/formula/ComparisonType.h rename to src/properties/ComparisonType.h index bb6ea82ee..c0eb598bc 100644 --- a/src/formula/ComparisonType.h +++ b/src/properties/ComparisonType.h @@ -9,7 +9,7 @@ #define STORM_FORMULA_COMPARISONTYPE_H_ namespace storm { -namespace property { +namespace properties { /*! * An enum representing the greater- and less-than operators in both diff --git a/src/formula/Csl.h b/src/properties/Csl.h similarity index 100% rename from src/formula/Csl.h rename to src/properties/Csl.h diff --git a/src/formula/Ltl.h b/src/properties/Ltl.h similarity index 100% rename from src/formula/Ltl.h rename to src/properties/Ltl.h diff --git a/src/formula/Prctl.h b/src/properties/Prctl.h similarity index 100% rename from src/formula/Prctl.h rename to src/properties/Prctl.h diff --git a/src/formula/actions/AbstractAction.h b/src/properties/actions/AbstractAction.h similarity index 99% rename from src/formula/actions/AbstractAction.h rename to src/properties/actions/AbstractAction.h index 0912751fd..b0f17bb28 100644 --- a/src/formula/actions/AbstractAction.h +++ b/src/properties/actions/AbstractAction.h @@ -16,7 +16,7 @@ #include "src/modelchecker/ltl/AbstractModelChecker.h" namespace storm { -namespace property { +namespace properties { namespace action { /*! @@ -141,7 +141,7 @@ public: }; } //namespace action -} //namespace property +} //namespace properties } //namespace storm diff --git a/src/formula/actions/BoundAction.h b/src/properties/actions/BoundAction.h similarity index 90% rename from src/formula/actions/BoundAction.h rename to src/properties/actions/BoundAction.h index 1603c3308..7dadc4c37 100644 --- a/src/formula/actions/BoundAction.h +++ b/src/properties/actions/BoundAction.h @@ -8,12 +8,12 @@ #ifndef STORM_FORMULA_ACTION_BOUNDACTION_H_ #define STORM_FORMULA_ACTION_BOUNDACTION_H_ -#include "src/formula/actions/AbstractAction.h" -#include "src/formula/ComparisonType.h" +#include "src/properties/actions/AbstractAction.h" +#include "src/properties/ComparisonType.h" #include "src/exceptions/InvalidArgumentException.h" namespace storm { -namespace property { +namespace properties { namespace action { /*! @@ -34,7 +34,7 @@ public: * Constructs an empty BoundAction. * The bound is set to >= 0. Thus, all states will be selected by the action. */ - BoundAction() : comparisonOperator(storm::property::GREATER_EQUAL), bound(0) { + BoundAction() : comparisonOperator(storm::properties::GREATER_EQUAL), bound(0) { //Intentionally left empty. } @@ -44,7 +44,7 @@ public: * @param comparisonOperator The operator used to make the comparison between the bound and the modelchecking values for each state. * @param bound The bound to compare the modelchecking values against. */ - BoundAction(storm::property::ComparisonType comparisonOperator, T bound) : comparisonOperator(comparisonOperator), bound(bound) { + BoundAction(storm::properties::ComparisonType comparisonOperator, T bound) : comparisonOperator(comparisonOperator), bound(bound) { //Intentionally left empty. } @@ -148,16 +148,16 @@ private: for(uint_fast64_t i = 0; i < result.pathResult.size(); i++) { if(result.selection[i]) { switch(comparisonOperator) { - case storm::property::GREATER_EQUAL: + case storm::properties::GREATER_EQUAL: out.set(i, result.pathResult[i] >= bound); break; - case storm::property::GREATER: + case storm::properties::GREATER: out.set(i, result.pathResult[i] > bound); break; - case storm::property::LESS_EQUAL: + case storm::properties::LESS_EQUAL: out.set(i, result.pathResult[i] <= bound); break; - case storm::property::LESS: + case storm::properties::LESS: out.set(i, result.pathResult[i] < bound); break; default: @@ -173,16 +173,16 @@ private: for(uint_fast64_t i = 0; i < result.stateMap.size(); i++) { if(result.selection[i]) { switch(comparisonOperator) { - case storm::property::GREATER_EQUAL: + case storm::properties::GREATER_EQUAL: out.set(i, result.stateResult[i] >= bound); break; - case storm::property::GREATER: + case storm::properties::GREATER: out.set(i, result.stateResult[i] > bound); break; - case storm::property::LESS_EQUAL: + case storm::properties::LESS_EQUAL: out.set(i, result.stateResult[i] <= bound); break; - case storm::property::LESS: + case storm::properties::LESS: out.set(i, result.stateResult[i] < bound); break; default: @@ -198,7 +198,7 @@ private: } // The operator used to make the comparison between the bound and the modelchecking values for each state at time of evaluation. - storm::property::ComparisonType comparisonOperator; + storm::properties::ComparisonType comparisonOperator; // The bound to compare the modelchecking values against during evaluation. T bound; diff --git a/src/formula/actions/FormulaAction.h b/src/properties/actions/FormulaAction.h similarity index 84% rename from src/formula/actions/FormulaAction.h rename to src/properties/actions/FormulaAction.h index 5028253fe..744c76038 100644 --- a/src/formula/actions/FormulaAction.h +++ b/src/properties/actions/FormulaAction.h @@ -8,15 +8,15 @@ #ifndef STORM_FORMULA_ACTION_FORMULAACTION_H_ #define STORM_FORMULA_ACTION_FORMULAACTION_H_ -#include "src/formula/actions/AbstractAction.h" -#include "src/formula/prctl/AbstractStateFormula.h" -#include "src/formula/csl/AbstractStateFormula.h" +#include "src/properties/actions/AbstractAction.h" +#include "src/properties/prctl/AbstractStateFormula.h" +#include "src/properties/csl/AbstractStateFormula.h" #include <string> namespace storm { -namespace property { +namespace properties { namespace action { /*! @@ -48,7 +48,7 @@ public: * * @param prctlFormula The Prctl state formula used to filter the selection during evaluation. */ - FormulaAction(std::shared_ptr<storm::property::prctl::AbstractStateFormula<T>> const & prctlFormula) : prctlFormula(prctlFormula), cslFormula(nullptr) { + FormulaAction(std::shared_ptr<storm::properties::prctl::AbstractStateFormula<T>> const & prctlFormula) : prctlFormula(prctlFormula), cslFormula(nullptr) { //Intentionally left empty. } @@ -57,7 +57,7 @@ public: * * @param cslFormula The Csl state formula used to filter the selection during evaluation. */ - FormulaAction(std::shared_ptr<storm::property::csl::AbstractStateFormula<T>> const & cslFormula) : prctlFormula(nullptr), cslFormula(cslFormula) { + FormulaAction(std::shared_ptr<storm::properties::csl::AbstractStateFormula<T>> const & cslFormula) : prctlFormula(nullptr), cslFormula(cslFormula) { //Intentionally left empty. } @@ -126,15 +126,15 @@ public: private: // The Prctl state formula used during evaluation. - std::shared_ptr<storm::property::prctl::AbstractStateFormula<T>> prctlFormula; + std::shared_ptr<storm::properties::prctl::AbstractStateFormula<T>> prctlFormula; // The Csl state formula used during evaluation. - std::shared_ptr<storm::property::csl::AbstractStateFormula<T>> cslFormula; + std::shared_ptr<storm::properties::csl::AbstractStateFormula<T>> cslFormula; }; } //namespace action -} //namespace property +} //namespace properties } //namespace storm #endif /* STORM_FORMULA_ACTION_FORMULAACTION_H_ */ diff --git a/src/formula/actions/InvertAction.h b/src/properties/actions/InvertAction.h similarity index 97% rename from src/formula/actions/InvertAction.h rename to src/properties/actions/InvertAction.h index 7084d52e2..69c7baa23 100644 --- a/src/formula/actions/InvertAction.h +++ b/src/properties/actions/InvertAction.h @@ -8,10 +8,10 @@ #ifndef STORM_FORMULA_ACTION_INVERTACTION_H_ #define STORM_FORMULA_ACTION_INVERTACTION_H_ -#include "src/formula/actions/AbstractAction.h" +#include "src/properties/actions/AbstractAction.h" namespace storm { -namespace property { +namespace properties { namespace action { /*! @@ -103,7 +103,7 @@ private: }; } //namespace action -} //namespace property +} //namespace properties } //namespace storm diff --git a/src/formula/actions/RangeAction.h b/src/properties/actions/RangeAction.h similarity index 98% rename from src/formula/actions/RangeAction.h rename to src/properties/actions/RangeAction.h index 8136715b2..5647deca4 100644 --- a/src/formula/actions/RangeAction.h +++ b/src/properties/actions/RangeAction.h @@ -8,10 +8,10 @@ #ifndef STORM_FORMULA_ACTION_RANGEACTION_H_ #define STORM_FORMULA_ACTION_RANGEACTION_H_ -#include "src/formula/actions/AbstractAction.h" +#include "src/properties/actions/AbstractAction.h" namespace storm { -namespace property { +namespace properties { namespace action { /*! @@ -149,7 +149,7 @@ private: }; } //namespace action -} //namespace property +} //namespace properties } //namespace storm #endif /* STORM_FORMULA_ACTION_RANGEACTION_H_ */ diff --git a/src/formula/actions/SortAction.h b/src/properties/actions/SortAction.h similarity index 98% rename from src/formula/actions/SortAction.h rename to src/properties/actions/SortAction.h index 289426f6f..7498eb7bf 100644 --- a/src/formula/actions/SortAction.h +++ b/src/properties/actions/SortAction.h @@ -8,11 +8,11 @@ #ifndef STORM_FORMULA_ACTION_SORTACTION_H_ #define STORM_FORMULA_ACTION_SORTACTION_H_ -#include "src/formula/actions/AbstractAction.h" +#include "src/properties/actions/AbstractAction.h" #include <cctype> namespace storm { -namespace property { +namespace properties { namespace action { /*! @@ -225,7 +225,7 @@ private: }; } //namespace action -} //namespace property +} //namespace properties } //namespace storm #endif /* STORM_FORMULA_ACTION_SORTACTION_H_ */ diff --git a/src/formula/csl/AbstractCslFormula.h b/src/properties/csl/AbstractCslFormula.h similarity index 73% rename from src/formula/csl/AbstractCslFormula.h rename to src/properties/csl/AbstractCslFormula.h index 360b5d411..4f8694340 100644 --- a/src/formula/csl/AbstractCslFormula.h +++ b/src/properties/csl/AbstractCslFormula.h @@ -8,10 +8,10 @@ #ifndef STORM_FORMULA_CSL_ABSTRACTCSLFORMULA_H_ #define STORM_FORMULA_CSL_ABSTRACTCSLFORMULA_H_ -#include "src/formula/AbstractFormula.h" +#include "src/properties/AbstractFormula.h" namespace storm { -namespace property { +namespace properties { namespace csl { // Forward declarations. @@ -25,7 +25,7 @@ template <class T> class Until; } namespace storm { -namespace property { +namespace properties { namespace csl { /*! @@ -37,7 +37,7 @@ namespace csl { * the original and the copy. */ template <class T> -class AbstractCslFormula : public virtual storm::property::AbstractFormula<T>{ +class AbstractCslFormula : public virtual storm::properties::AbstractFormula<T>{ public: /*! @@ -59,23 +59,23 @@ public: bool isProbEventuallyAP() const { // Test if a probabilistic bound operator is at the root. - if(dynamic_cast<storm::property::csl::ProbabilisticBoundOperator<T> const *>(this) == nullptr) { + if(dynamic_cast<storm::properties::csl::ProbabilisticBoundOperator<T> const *>(this) == nullptr) { return false; } - auto probFormula = dynamic_cast<storm::property::csl::ProbabilisticBoundOperator<T> const *>(this); + auto probFormula = dynamic_cast<storm::properties::csl::ProbabilisticBoundOperator<T> const *>(this); // Check if the direct subformula of the probabilistic bound operator is an eventually or until formula. - if(std::dynamic_pointer_cast<storm::property::csl::Eventually<T>>(probFormula->getChild()).get() != nullptr) { + if(std::dynamic_pointer_cast<storm::properties::csl::Eventually<T>>(probFormula->getChild()).get() != nullptr) { // Get the subformula and check if its subformulas are propositional. - auto eventuallyFormula = std::dynamic_pointer_cast<storm::property::csl::Eventually<T>>(probFormula->getChild()); + auto eventuallyFormula = std::dynamic_pointer_cast<storm::properties::csl::Eventually<T>>(probFormula->getChild()); return eventuallyFormula->getChild()->isPropositional(); } - else if(std::dynamic_pointer_cast<storm::property::csl::Until<T>>(probFormula->getChild()).get() != nullptr) { + else if(std::dynamic_pointer_cast<storm::properties::csl::Until<T>>(probFormula->getChild()).get() != nullptr) { // Get the subformula and check if its subformulas are propositional. - auto untilFormula = std::dynamic_pointer_cast<storm::property::csl::Until<T>>(probFormula->getChild()); + auto untilFormula = std::dynamic_pointer_cast<storm::properties::csl::Until<T>>(probFormula->getChild()); return untilFormula->getLeft()->isPropositional() && untilFormula->getRight()->isPropositional(); } @@ -84,6 +84,6 @@ public: }; } /* namespace csl */ -} /* namespace property */ +} /* namespace properties */ } /* namespace storm */ #endif /* STORM_FORMULA_CSL_ABSTRACTCSLFORMULA_H_ */ diff --git a/src/formula/csl/AbstractPathFormula.h b/src/properties/csl/AbstractPathFormula.h similarity index 90% rename from src/formula/csl/AbstractPathFormula.h rename to src/properties/csl/AbstractPathFormula.h index a8d415616..e7aa31e08 100644 --- a/src/formula/csl/AbstractPathFormula.h +++ b/src/properties/csl/AbstractPathFormula.h @@ -8,7 +8,7 @@ #ifndef STORM_FORMULA_CSL_ABSTRACTPATHFORMULA_H_ #define STORM_FORMULA_CSL_ABSTRACTPATHFORMULA_H_ -#include "src/formula/csl/AbstractCslFormula.h" +#include "src/properties/csl/AbstractCslFormula.h" #include "src/modelchecker/csl/ForwardDeclarations.h" #include <vector> @@ -16,7 +16,7 @@ #include <typeinfo> namespace storm { -namespace property { +namespace properties { namespace csl { /*! @@ -26,7 +26,7 @@ namespace csl { * The result of a modelchecking process on such a formula is a vector representing the satisfaction probabilities for each state of the model. */ template <class T> -class AbstractPathFormula : public virtual storm::property::csl::AbstractCslFormula<T> { +class AbstractPathFormula : public virtual storm::properties::csl::AbstractCslFormula<T> { public: @@ -63,7 +63,7 @@ public: }; } //namespace csl -} //namespace property +} //namespace properties } //namespace storm #endif /* STORM_FORMULA_CSL_ABSTRACTPATHFORMULA_H_ */ diff --git a/src/formula/csl/AbstractStateFormula.h b/src/properties/csl/AbstractStateFormula.h similarity index 89% rename from src/formula/csl/AbstractStateFormula.h rename to src/properties/csl/AbstractStateFormula.h index dec96eb45..9c48a1007 100644 --- a/src/formula/csl/AbstractStateFormula.h +++ b/src/properties/csl/AbstractStateFormula.h @@ -8,19 +8,19 @@ #ifndef STORM_FORMULA_CSL_ABSTRACTSTATEFORMULA_H_ #define STORM_FORMULA_CSL_ABSTRACTSTATEFORMULA_H_ -#include "src/formula/csl/AbstractCslFormula.h" +#include "src/properties/csl/AbstractCslFormula.h" #include "src/storage/BitVector.h" #include "src/modelchecker/csl/ForwardDeclarations.h" namespace storm { -namespace property { +namespace properties { namespace csl { /*! * Abstract base class for Csl state formulas. */ template <class T> -class AbstractStateFormula : public storm::property::csl::AbstractCslFormula<T> { +class AbstractStateFormula : public storm::properties::csl::AbstractCslFormula<T> { public: @@ -57,7 +57,7 @@ public: }; } //namespace csl -} //namespace property +} //namespace properties } //namespace storm diff --git a/src/formula/csl/And.h b/src/properties/csl/And.h similarity index 98% rename from src/formula/csl/And.h rename to src/properties/csl/And.h index a5ebaffb2..f9aaa1a85 100644 --- a/src/formula/csl/And.h +++ b/src/properties/csl/And.h @@ -8,12 +8,12 @@ #ifndef STORM_FORMULA_CSL_AND_H_ #define STORM_FORMULA_CSL_AND_H_ -#include "src/formula/csl/AbstractStateFormula.h" +#include "src/properties/csl/AbstractStateFormula.h" #include "src/modelchecker/csl/ForwardDeclarations.h" #include <string> namespace storm { -namespace property { +namespace properties { namespace csl { // Forward declaration for the interface class. @@ -209,7 +209,7 @@ private: } //namespace csl -} //namespace property +} //namespace properties } //namespace storm diff --git a/src/formula/csl/Ap.h b/src/properties/csl/Ap.h similarity index 97% rename from src/formula/csl/Ap.h rename to src/properties/csl/Ap.h index 8ab7600fe..9dc5f2392 100644 --- a/src/formula/csl/Ap.h +++ b/src/properties/csl/Ap.h @@ -8,11 +8,11 @@ #ifndef STORM_FORMULA_CSL_AP_H_ #define STORM_FORMULA_CSL_AP_H_ -#include "src/formula/csl/AbstractStateFormula.h" +#include "src/properties/csl/AbstractStateFormula.h" #include "src/modelchecker/csl/ForwardDeclarations.h" namespace storm { -namespace property { +namespace properties { namespace csl { // Forward declaration for the interface class. @@ -134,7 +134,7 @@ private: } //namespace abstract -} //namespace property +} //namespace properties } //namespace storm diff --git a/src/formula/csl/CslFilter.h b/src/properties/csl/CslFilter.h similarity index 97% rename from src/formula/csl/CslFilter.h rename to src/properties/csl/CslFilter.h index 4d92829e5..560a65faf 100644 --- a/src/formula/csl/CslFilter.h +++ b/src/properties/csl/CslFilter.h @@ -8,16 +8,16 @@ #ifndef STORM_FORMULA_PRCTL_CSLFILTER_H_ #define STORM_FORMULA_PRCTL_CSLFILTER_H_ -#include "src/formula/AbstractFilter.h" -#include "src/formula/csl/AbstractCslFormula.h" -#include "src/formula/csl/AbstractPathFormula.h" -#include "src/formula/csl/AbstractStateFormula.h" +#include "src/properties/AbstractFilter.h" +#include "src/properties/csl/AbstractCslFormula.h" +#include "src/properties/csl/AbstractPathFormula.h" +#include "src/properties/csl/AbstractStateFormula.h" #include "src/modelchecker/csl/AbstractModelChecker.h" -#include "src/formula/actions/AbstractAction.h" +#include "src/properties/actions/AbstractAction.h" namespace storm { -namespace property { +namespace properties { namespace csl { /*! @@ -27,10 +27,10 @@ namespace csl { * Additionally it maintains a list of filter actions that are used to further manipulate the modelchecking results and prepare them for output. */ template <class T> -class CslFilter : public storm::property::AbstractFilter<T> { +class CslFilter : public storm::properties::AbstractFilter<T> { // Convenience typedef to make the code more readable. - typedef typename storm::property::action::AbstractAction<T>::Result Result; + typedef typename storm::properties::action::AbstractAction<T>::Result Result; public: @@ -408,7 +408,7 @@ private: }; } //namespace csl -} //namespace property +} //namespace properties } //namespace storm #endif /* STORM_FORMULA_CSL_CSLFILTER_H_ */ diff --git a/src/formula/csl/Eventually.h b/src/properties/csl/Eventually.h similarity index 96% rename from src/formula/csl/Eventually.h rename to src/properties/csl/Eventually.h index 6c27dfa75..b156280aa 100644 --- a/src/formula/csl/Eventually.h +++ b/src/properties/csl/Eventually.h @@ -8,12 +8,12 @@ #ifndef STORM_FORMULA_CSL_EVENTUALLY_H_ #define STORM_FORMULA_CSL_EVENTUALLY_H_ -#include "src/formula/csl/AbstractPathFormula.h" -#include "src/formula/csl/AbstractStateFormula.h" +#include "src/properties/csl/AbstractPathFormula.h" +#include "src/properties/csl/AbstractStateFormula.h" #include "src/modelchecker/csl/ForwardDeclarations.h" namespace storm { -namespace property { +namespace properties { namespace csl { // Forward declaration for the interface class. @@ -164,7 +164,7 @@ private: }; } //namespace csl -} //namespace property +} //namespace properties } //namespace storm #endif /* STORM_FORMULA_CSL_EVENTUALLY_H_ */ diff --git a/src/formula/csl/Globally.h b/src/properties/csl/Globally.h similarity index 96% rename from src/formula/csl/Globally.h rename to src/properties/csl/Globally.h index 421d9e354..52f25ba24 100644 --- a/src/formula/csl/Globally.h +++ b/src/properties/csl/Globally.h @@ -8,12 +8,12 @@ #ifndef STORM_FORMULA_CSL_GLOBALLY_H_ #define STORM_FORMULA_CSL_GLOBALLY_H_ -#include "src/formula/csl/AbstractPathFormula.h" -#include "src/formula/csl/AbstractStateFormula.h" +#include "src/properties/csl/AbstractPathFormula.h" +#include "src/properties/csl/AbstractStateFormula.h" #include "src/modelchecker/csl/ForwardDeclarations.h" namespace storm { -namespace property { +namespace properties { namespace csl { // Forward declaration for the interface class. @@ -163,7 +163,7 @@ private: }; } //namespace csl -} //namespace property +} //namespace properties } //namespace storm #endif /* STORM_FORMULA_CSL_GLOBALLY_H_ */ diff --git a/src/formula/csl/Next.h b/src/properties/csl/Next.h similarity index 96% rename from src/formula/csl/Next.h rename to src/properties/csl/Next.h index 478247de6..462a5eae4 100644 --- a/src/formula/csl/Next.h +++ b/src/properties/csl/Next.h @@ -8,11 +8,11 @@ #ifndef STORM_FORMULA_CSL_NEXT_H_ #define STORM_FORMULA_CSL_NEXT_H_ -#include "src/formula/csl/AbstractPathFormula.h" -#include "src/formula/csl/AbstractStateFormula.h" +#include "src/properties/csl/AbstractPathFormula.h" +#include "src/properties/csl/AbstractStateFormula.h" namespace storm { -namespace property { +namespace properties { namespace csl { // Forward declaration for the interface class. @@ -162,7 +162,7 @@ private: }; } //namespace csl -} //namespace property +} //namespace properties } //namespace storm #endif /* STORM_FORMULA_CSL_NEXT_H_ */ diff --git a/src/formula/csl/Not.h b/src/properties/csl/Not.h similarity index 97% rename from src/formula/csl/Not.h rename to src/properties/csl/Not.h index 5e382893d..de2f4acfb 100644 --- a/src/formula/csl/Not.h +++ b/src/properties/csl/Not.h @@ -8,11 +8,11 @@ #ifndef STORM_FORMULA_CSL_NOT_H_ #define STORM_FORMULA_CSL_NOT_H_ -#include "src/formula/csl/AbstractStateFormula.h" +#include "src/properties/csl/AbstractStateFormula.h" #include "src/modelchecker/csl/ForwardDeclarations.h" namespace storm { -namespace property { +namespace properties { namespace csl { // Forward declaration for the interface class. @@ -166,7 +166,7 @@ private: }; } //namespace csl -} //namespace property +} //namespace properties } //namespace storm #endif /* STORM_FORMULA_CSL_NOT_H_ */ diff --git a/src/formula/csl/Or.h b/src/properties/csl/Or.h similarity index 98% rename from src/formula/csl/Or.h rename to src/properties/csl/Or.h index d1c1a795c..f70144634 100644 --- a/src/formula/csl/Or.h +++ b/src/properties/csl/Or.h @@ -8,10 +8,10 @@ #ifndef STORM_FORMULA_CSL_OR_H_ #define STORM_FORMULA_CSL_OR_H_ -#include "src/formula/csl/AbstractStateFormula.h" +#include "src/properties/csl/AbstractStateFormula.h" namespace storm { -namespace property { +namespace properties { namespace csl { // Forward declaration for the interface class. @@ -206,7 +206,7 @@ private: }; } //namespace csl -} //namespace property +} //namespace properties } //namespace storm #endif /* STORM_FORMULA_CSL_OR_H_ */ diff --git a/src/formula/csl/ProbabilisticBoundOperator.h b/src/properties/csl/ProbabilisticBoundOperator.h similarity index 91% rename from src/formula/csl/ProbabilisticBoundOperator.h rename to src/properties/csl/ProbabilisticBoundOperator.h index a9adc4d6b..d8005d2fe 100644 --- a/src/formula/csl/ProbabilisticBoundOperator.h +++ b/src/properties/csl/ProbabilisticBoundOperator.h @@ -8,13 +8,13 @@ #ifndef STORM_FORMULA_CSL_PROBABILISTICBOUNDOPERATOR_H_ #define STORM_FORMULA_CSL_PROBABILISTICBOUNDOPERATOR_H_ -#include "src/formula/csl/AbstractStateFormula.h" -#include "src/formula/csl/AbstractPathFormula.h" -#include "src/formula/ComparisonType.h" +#include "src/properties/csl/AbstractStateFormula.h" +#include "src/properties/csl/AbstractPathFormula.h" +#include "src/properties/ComparisonType.h" #include "utility/constants.h" namespace storm { -namespace property { +namespace properties { namespace csl { // Forward declaration for the interface class. @@ -82,7 +82,7 @@ public: * @param bound The bound for the probability. * @param child The child formula subtree. */ - ProbabilisticBoundOperator(storm::property::ComparisonType comparisonOperator, T bound, std::shared_ptr<AbstractPathFormula<T>> const & child) + ProbabilisticBoundOperator(storm::properties::ComparisonType comparisonOperator, T bound, std::shared_ptr<AbstractPathFormula<T>> const & child) : comparisonOperator(comparisonOperator), bound(bound), child(child) { // Intentionally left empty. } @@ -175,7 +175,7 @@ public: * * @returns An enum value representing the comparison relation. */ - storm::property::ComparisonType const getComparisonOperator() const { + storm::properties::ComparisonType const getComparisonOperator() const { return comparisonOperator; } @@ -184,7 +184,7 @@ public: * * @param comparisonOperator An enum value representing the new comparison relation. */ - void setComparisonOperator(storm::property::ComparisonType comparisonOperator) { + void setComparisonOperator(storm::properties::ComparisonType comparisonOperator) { this->comparisonOperator = comparisonOperator; } @@ -225,7 +225,7 @@ public: private: // The operator used to indicate the kind of bound that is to be met. - storm::property::ComparisonType comparisonOperator; + storm::properties::ComparisonType comparisonOperator; // The probability bound. T bound; @@ -235,7 +235,7 @@ private: }; } //namespace csl -} //namespace property +} //namespace properties } //namespace storm #endif /* STORM_FORMULA_CSL_PROBABILISTICBOUNDOPERATOR_H_ */ diff --git a/src/formula/csl/SteadyStateBoundOperator.h b/src/properties/csl/SteadyStateBoundOperator.h similarity index 96% rename from src/formula/csl/SteadyStateBoundOperator.h rename to src/properties/csl/SteadyStateBoundOperator.h index 4ca8a2cba..141f070b7 100644 --- a/src/formula/csl/SteadyStateBoundOperator.h +++ b/src/properties/csl/SteadyStateBoundOperator.h @@ -9,10 +9,10 @@ #define STORM_FORMULA_CSL_STEADYSTATEOPERATOR_H_ #include "AbstractStateFormula.h" -#include "src/formula/ComparisonType.h" +#include "src/properties/ComparisonType.h" namespace storm { -namespace property { +namespace properties { namespace csl { // Forward declaration for the interface class. @@ -78,7 +78,7 @@ public: * @param bound The bound for the probability. * @param child The child formula subtree. */ - SteadyStateBoundOperator(storm::property::ComparisonType comparisonOperator, T bound, std::shared_ptr<AbstractStateFormula<T>> const & child) + SteadyStateBoundOperator(storm::properties::ComparisonType comparisonOperator, T bound, std::shared_ptr<AbstractStateFormula<T>> const & child) : comparisonOperator(comparisonOperator), bound(bound), child(child) { // Intentionally left empty } @@ -228,7 +228,7 @@ private: }; } //namespace csl -} //namespace property +} //namespace properties } //namespace storm #endif /* STORM_FORMULA_CSL_STEADYSTATEOPERATOR_H_ */ diff --git a/src/formula/csl/TimeBoundedEventually.h b/src/properties/csl/TimeBoundedEventually.h similarity index 94% rename from src/formula/csl/TimeBoundedEventually.h rename to src/properties/csl/TimeBoundedEventually.h index 785a1677a..3d537a34a 100644 --- a/src/formula/csl/TimeBoundedEventually.h +++ b/src/properties/csl/TimeBoundedEventually.h @@ -8,11 +8,11 @@ #ifndef STORM_FORMULA_CSL_TIMEBOUNDEDEVENTUALLY_H_ #define STORM_FORMULA_CSL_TIMEBOUNDEDEVENTUALLY_H_ -#include "src/formula/csl/AbstractPathFormula.h" -#include "src/formula/csl/AbstractStateFormula.h" +#include "src/properties/csl/AbstractPathFormula.h" +#include "src/properties/csl/AbstractStateFormula.h" namespace storm { -namespace property { +namespace properties { namespace csl { // Forward declaration for the interface class. @@ -68,7 +68,7 @@ public: * Creates a TimeBoundedEventually node without a subnode. * The resulting object will not represent a complete formula! */ - TimeBoundedEventually() : lowerBound(0), upperBound(0), child(nullptr) { + TimeBoundedEventually() : child(nullptr), lowerBound(0), upperBound(0) { // Intentionally left empty. } @@ -98,7 +98,8 @@ public: * @returns A new TimeBoundedEventually object that is a deep copy of the called object. */ virtual std::shared_ptr<AbstractPathFormula<T>> clone() const override { - std::shared_ptr<TimeBoundedEventually<T>> result(new TimeBoundedEventually<T>(lowerBound, upperBound)); + auto result = std::make_shared<TimeBoundedEventually<T>>(); + result->setInterval(lowerBound, upperBound); if (this->isChildSet()) { result->setChild(child->clone()); } @@ -212,7 +213,7 @@ private: }; } /* namespace csl */ -} /* namespace property */ +} /* namespace properties */ } /* namespace storm */ #endif /* STORM_FORMULA_CSL_TIMEBOUNDEDEVENTUALLY_H_ */ diff --git a/src/formula/csl/TimeBoundedUntil.h b/src/properties/csl/TimeBoundedUntil.h similarity index 94% rename from src/formula/csl/TimeBoundedUntil.h rename to src/properties/csl/TimeBoundedUntil.h index 5e27edd37..c224f93df 100644 --- a/src/formula/csl/TimeBoundedUntil.h +++ b/src/properties/csl/TimeBoundedUntil.h @@ -8,11 +8,11 @@ #ifndef STORM_FORMULA_CSL_TIMEBOUNDEDUNTIL_H_ #define STORM_FORMULA_CSL_TIMEBOUNDEDUNTIL_H_ -#include "src/formula/csl/AbstractPathFormula.h" -#include "src/formula/csl/AbstractStateFormula.h" +#include "src/properties/csl/AbstractPathFormula.h" +#include "src/properties/csl/AbstractStateFormula.h" namespace storm { -namespace property { +namespace properties { namespace csl { // Forward declaration for the interface class. @@ -70,8 +70,8 @@ public: * Creates a TimeBoundedUntil node without a subnode. * The resulting object will not represent a complete formula! */ - TimeBoundedUntil() : lowerBound(0), upperBound(0), left(nullptr), right(nullptr) { - setInterval(lowerBound, upperBound); + TimeBoundedUntil() : left(nullptr), right(nullptr), lowerBound(0), upperBound(0) { + // Intentionally left empty. } /*! @@ -100,7 +100,8 @@ public: * @returns A new TimeBoundedUntil object that is a deep copy of the called object. */ virtual std::shared_ptr<AbstractPathFormula<T>> clone() const override { - std::shared_ptr<TimeBoundedUntil<T>> result(new TimeBoundedUntil<T>(lowerBound, upperBound)); + auto result = std::make_shared<TimeBoundedUntil<T>>(); + result->setInterval(lowerBound, upperBound); if (this->isLeftSet()) { result->setLeft(left->clone()); } @@ -249,7 +250,7 @@ private: }; } /* namespace csl */ -} /* namespace property */ +} /* namespace properties */ } /* namespace storm */ #endif /* STORM_FORMULA_CSL_TIMEBOUNDEDUNTIL_H_ */ diff --git a/src/formula/csl/Until.h b/src/properties/csl/Until.h similarity index 97% rename from src/formula/csl/Until.h rename to src/properties/csl/Until.h index 8db1fa7d6..b709a1d82 100644 --- a/src/formula/csl/Until.h +++ b/src/properties/csl/Until.h @@ -8,11 +8,11 @@ #ifndef STORM_FORMULA_CSL_UNTIL_H_ #define STORM_FORMULA_CSL_UNTIL_H_ -#include "src/formula/csl/AbstractPathFormula.h" -#include "src/formula/csl/AbstractStateFormula.h" +#include "src/properties/csl/AbstractPathFormula.h" +#include "src/properties/csl/AbstractStateFormula.h" namespace storm { -namespace property { +namespace properties { namespace csl { // Forward declaration for the interface class. @@ -199,7 +199,7 @@ private: }; } //namespace csl -} //namespace property +} //namespace properties } //namespace storm #endif /* STORM_FORMULA_CSL_UNTIL_H_ */ diff --git a/src/formula/ltl/AbstractLtlFormula.h b/src/properties/ltl/AbstractLtlFormula.h similarity index 90% rename from src/formula/ltl/AbstractLtlFormula.h rename to src/properties/ltl/AbstractLtlFormula.h index 3605779be..c4ff5ad5a 100644 --- a/src/formula/ltl/AbstractLtlFormula.h +++ b/src/properties/ltl/AbstractLtlFormula.h @@ -10,10 +10,10 @@ #include <vector> #include "src/modelchecker/ltl/ForwardDeclarations.h" -#include "src/formula/AbstractFormula.h" +#include "src/properties/AbstractFormula.h" namespace storm { -namespace property { +namespace properties { namespace ltl { /*! @@ -25,7 +25,7 @@ namespace ltl { * the original and the copy. */ template <class T> -class AbstractLtlFormula : public virtual storm::property::AbstractFormula<T> { +class AbstractLtlFormula : public virtual storm::properties::AbstractFormula<T> { public: /*! @@ -59,6 +59,6 @@ public: }; } /* namespace ltl */ -} /* namespace property */ +} /* namespace properties */ } /* namespace storm */ #endif /* STORM_LTL_ABSTRACTLTLFORMULA_H_ */ diff --git a/src/formula/ltl/And.h b/src/properties/ltl/And.h similarity index 99% rename from src/formula/ltl/And.h rename to src/properties/ltl/And.h index 67656ef9b..51c88651b 100644 --- a/src/formula/ltl/And.h +++ b/src/properties/ltl/And.h @@ -13,7 +13,7 @@ #include <string> namespace storm { -namespace property { +namespace properties { namespace ltl { // Forward declaration for the interface class. @@ -209,7 +209,7 @@ private: } //namespace ltl -} //namespace property +} //namespace properties } //namespace storm diff --git a/src/formula/ltl/Ap.h b/src/properties/ltl/Ap.h similarity index 96% rename from src/formula/ltl/Ap.h rename to src/properties/ltl/Ap.h index 544d84ed5..ed5356720 100644 --- a/src/formula/ltl/Ap.h +++ b/src/properties/ltl/Ap.h @@ -11,7 +11,7 @@ #include "AbstractLtlFormula.h" namespace storm { -namespace property { +namespace properties { namespace ltl { // Forward declaration for the interface class. @@ -51,7 +51,7 @@ class IApModelChecker { * @see AbstractLtlFormula */ template <class T> -class Ap: public storm::property::ltl::AbstractLtlFormula<T> { +class Ap: public storm::properties::ltl::AbstractLtlFormula<T> { public: @@ -131,6 +131,6 @@ private: }; } /* namespace ltl */ -} /* namespace property */ +} /* namespace properties */ } /* namespace storm */ #endif /* STORM_FORMULA_LTL_AP_H_ */ diff --git a/src/formula/ltl/BoundedEventually.h b/src/properties/ltl/BoundedEventually.h similarity index 99% rename from src/formula/ltl/BoundedEventually.h rename to src/properties/ltl/BoundedEventually.h index 57027cea3..120dec759 100644 --- a/src/formula/ltl/BoundedEventually.h +++ b/src/properties/ltl/BoundedEventually.h @@ -14,7 +14,7 @@ #include "src/modelchecker/ltl/ForwardDeclarations.h" namespace storm { -namespace property { +namespace properties { namespace ltl { // Forward declaration for the interface class. @@ -190,7 +190,7 @@ private: }; } //namespace ltl -} //namespace property +} //namespace properties } //namespace storm #endif /* STORM_FORMULA_LTL_BOUNDEDUNTIL_H_ */ diff --git a/src/formula/ltl/BoundedUntil.h b/src/properties/ltl/BoundedUntil.h similarity index 98% rename from src/formula/ltl/BoundedUntil.h rename to src/properties/ltl/BoundedUntil.h index 748e3ae0e..01e7dd14b 100644 --- a/src/formula/ltl/BoundedUntil.h +++ b/src/properties/ltl/BoundedUntil.h @@ -8,13 +8,13 @@ #ifndef STORM_FORMULA_LTL_BOUNDEDUNTIL_H_ #define STORM_FORMULA_LTL_BOUNDEDUNTIL_H_ -#include "src/formula/ltl/AbstractLtlFormula.h" +#include "src/properties/ltl/AbstractLtlFormula.h" #include <cstdint> #include <string> #include "src/modelchecker/ltl/ForwardDeclarations.h" namespace storm { -namespace property { +namespace properties { namespace ltl { // Forward declaration for the interface class. @@ -223,7 +223,7 @@ private: }; } //namespace ltl -} //namespace property +} //namespace properties } //namespace storm #endif /* STORM_FORMULA_LTL_BOUNDEDUNTIL_H_ */ diff --git a/src/formula/ltl/Eventually.h b/src/properties/ltl/Eventually.h similarity index 97% rename from src/formula/ltl/Eventually.h rename to src/properties/ltl/Eventually.h index 9af8ad9b2..6c2ac2940 100644 --- a/src/formula/ltl/Eventually.h +++ b/src/properties/ltl/Eventually.h @@ -8,11 +8,11 @@ #ifndef STORM_FORMULA_LTL_EVENTUALLY_H_ #define STORM_FORMULA_LTL_EVENTUALLY_H_ -#include "src/formula/ltl/AbstractLtlFormula.h" +#include "src/properties/ltl/AbstractLtlFormula.h" #include "src/modelchecker/ltl/ForwardDeclarations.h" namespace storm { -namespace property { +namespace properties { namespace ltl { // Forward declaration for the interface class. @@ -159,7 +159,7 @@ private: }; } //namespace ltl -} //namespace property +} //namespace properties } //namespace storm #endif /* STORM_FORMULA_LTL_EVENTUALLY_H_ */ diff --git a/src/formula/ltl/Globally.h b/src/properties/ltl/Globally.h similarity index 98% rename from src/formula/ltl/Globally.h rename to src/properties/ltl/Globally.h index 0e0af887a..443ac20bb 100644 --- a/src/formula/ltl/Globally.h +++ b/src/properties/ltl/Globally.h @@ -12,7 +12,7 @@ #include "src/modelchecker/ltl/ForwardDeclarations.h" namespace storm { -namespace property { +namespace properties { namespace ltl { // Forward declaration for the interface class. @@ -159,7 +159,7 @@ private: }; } //namespace ltl -} //namespace property +} //namespace properties } //namespace storm #endif /* STORM_FORMULA_LTL_GLOBALLY_H_ */ diff --git a/src/formula/ltl/LtlFilter.h b/src/properties/ltl/LtlFilter.h similarity index 96% rename from src/formula/ltl/LtlFilter.h rename to src/properties/ltl/LtlFilter.h index 4b7704b10..5e4760fa2 100644 --- a/src/formula/ltl/LtlFilter.h +++ b/src/properties/ltl/LtlFilter.h @@ -8,14 +8,14 @@ #ifndef STORM_FORMULA_LTL_LTLFILTER_H_ #define STORM_FORMULA_LTL_LTLFILTER_H_ -#include "src/formula/AbstractFilter.h" +#include "src/properties/AbstractFilter.h" #include "src/modelchecker/ltl/AbstractModelChecker.h" -#include "src/formula/ltl/AbstractLtlFormula.h" -#include "src/formula/actions/AbstractAction.h" +#include "src/properties/ltl/AbstractLtlFormula.h" +#include "src/properties/actions/AbstractAction.h" #include "src/exceptions/NotImplementedException.h" namespace storm { -namespace property { +namespace properties { namespace ltl { /*! @@ -25,10 +25,10 @@ namespace ltl { * Additionally it maintains a list of filter actions that are used to further manipulate the modelchecking results and prepare them for output. */ template <class T> -class LtlFilter : public storm::property::AbstractFilter<T> { +class LtlFilter : public storm::properties::AbstractFilter<T> { // Convenience typedef to make the code more readable. - typedef typename storm::property::action::AbstractAction<T>::Result Result; + typedef typename storm::properties::action::AbstractAction<T>::Result Result; public: @@ -275,7 +275,7 @@ private: } //namespace ltl -} //namespace property +} //namespace properties } //namespace storm #endif /* STORM_FORMULA_LTL_LTLFILTER_H_ */ diff --git a/src/formula/ltl/Next.h b/src/properties/ltl/Next.h similarity index 98% rename from src/formula/ltl/Next.h rename to src/properties/ltl/Next.h index 0eb64a2ed..40ad52b0c 100644 --- a/src/formula/ltl/Next.h +++ b/src/properties/ltl/Next.h @@ -11,7 +11,7 @@ #include "AbstractLtlFormula.h" namespace storm { -namespace property { +namespace properties { namespace ltl { // Forward declaration for the interface class. @@ -158,7 +158,7 @@ private: }; } //namespace ltl -} //namespace property +} //namespace properties } //namespace storm #endif /* STORM_FORMULA_LTL_NEXT_H_ */ diff --git a/src/formula/ltl/Not.h b/src/properties/ltl/Not.h similarity index 98% rename from src/formula/ltl/Not.h rename to src/properties/ltl/Not.h index cd1edd251..e0accc91f 100644 --- a/src/formula/ltl/Not.h +++ b/src/properties/ltl/Not.h @@ -11,7 +11,7 @@ #include "AbstractLtlFormula.h" namespace storm { -namespace property { +namespace properties { namespace ltl { // Forward declaration for the interface class. @@ -165,7 +165,7 @@ private: }; } //namespace ltl -} //namespace property +} //namespace properties } //namespace storm #endif /* STORM_FORMULA_LTL_NOT_H_ */ diff --git a/src/formula/ltl/Or.h b/src/properties/ltl/Or.h similarity index 97% rename from src/formula/ltl/Or.h rename to src/properties/ltl/Or.h index a7c73a1f1..5a2f20ab6 100644 --- a/src/formula/ltl/Or.h +++ b/src/properties/ltl/Or.h @@ -11,7 +11,7 @@ #include "AbstractLtlFormula.h" namespace storm { -namespace property { +namespace properties { namespace ltl { // Forward declaration for the interface class. @@ -57,7 +57,7 @@ class IOrModelChecker { * @see AbstractLtlFormula */ template <class T> -class Or: public storm::property::ltl::AbstractLtlFormula<T> { +class Or: public storm::properties::ltl::AbstractLtlFormula<T> { public: @@ -205,6 +205,6 @@ private: }; } /* namespace ltl */ -} /* namespace property */ +} /* namespace properties */ } /* namespace storm */ #endif /* OR_H_ */ diff --git a/src/formula/ltl/Until.h b/src/properties/ltl/Until.h similarity index 99% rename from src/formula/ltl/Until.h rename to src/properties/ltl/Until.h index 56301c0f4..2d415aeac 100644 --- a/src/formula/ltl/Until.h +++ b/src/properties/ltl/Until.h @@ -11,7 +11,7 @@ #include "AbstractLtlFormula.h" namespace storm { -namespace property { +namespace properties { namespace ltl { // Forward declaration for the interface class. @@ -194,7 +194,7 @@ private: }; } //namespace ltl -} //namespace property +} //namespace properties } //namespace storm #endif /* STORM_FORMULA_LTL_UNTIL_H_ */ diff --git a/src/formula/prctl/AbstractPathFormula.h b/src/properties/prctl/AbstractPathFormula.h similarity index 90% rename from src/formula/prctl/AbstractPathFormula.h rename to src/properties/prctl/AbstractPathFormula.h index 1caf60297..98ba51f19 100644 --- a/src/formula/prctl/AbstractPathFormula.h +++ b/src/properties/prctl/AbstractPathFormula.h @@ -8,7 +8,7 @@ #ifndef STORM_FORMULA_PRCTL_ABSTRACTPATHFORMULA_H_ #define STORM_FORMULA_PRCTL_ABSTRACTPATHFORMULA_H_ -#include "src/formula/prctl/AbstractPrctlFormula.h" +#include "src/properties/prctl/AbstractPrctlFormula.h" #include "src/modelchecker/prctl/ForwardDeclarations.h" #include <vector> @@ -16,7 +16,7 @@ #include <typeinfo> namespace storm { -namespace property { +namespace properties { namespace prctl { /*! @@ -26,7 +26,7 @@ namespace prctl { * The result of a modelchecking process on such a formula is a vector representing the satisfaction probabilities for each state of the model. */ template <class T> -class AbstractPathFormula : public virtual storm::property::prctl::AbstractPrctlFormula<T> { +class AbstractPathFormula : public virtual storm::properties::prctl::AbstractPrctlFormula<T> { public: @@ -63,7 +63,7 @@ public: }; } //namespace prctl -} //namespace property +} //namespace properties } //namespace storm #endif /* STORM_FORMULA_PRCTL_ABSTRACTPATHFORMULA_H_ */ diff --git a/src/formula/prctl/AbstractPrctlFormula.h b/src/properties/prctl/AbstractPrctlFormula.h similarity index 73% rename from src/formula/prctl/AbstractPrctlFormula.h rename to src/properties/prctl/AbstractPrctlFormula.h index e7b165afa..cefe91e4b 100644 --- a/src/formula/prctl/AbstractPrctlFormula.h +++ b/src/properties/prctl/AbstractPrctlFormula.h @@ -8,10 +8,10 @@ #ifndef STORM_FORMULA_PRCTL_ABSTRACTPRCTLFORMULA_H_ #define STORM_FORMULA_PRCTL_ABSTRACTPRCTLFORMULA_H_ -#include "src/formula/AbstractFormula.h" +#include "src/properties/AbstractFormula.h" namespace storm { -namespace property { +namespace properties { namespace prctl { // Forward declarations. @@ -25,7 +25,7 @@ template <class T> class Until; } namespace storm { -namespace property { +namespace properties { namespace prctl { /*! @@ -37,7 +37,7 @@ namespace prctl { * the original and the copy. */ template<class T> -class AbstractPrctlFormula : public virtual storm::property::AbstractFormula<T> { +class AbstractPrctlFormula : public virtual storm::properties::AbstractFormula<T> { public: /*! @@ -59,23 +59,23 @@ public: bool isProbEventuallyAP() const { // Test if a probabilistic bound operator is at the root. - if(dynamic_cast<storm::property::prctl::ProbabilisticBoundOperator<T> const *>(this) == nullptr) { + if(dynamic_cast<storm::properties::prctl::ProbabilisticBoundOperator<T> const *>(this) == nullptr) { return false; } - auto probFormula = dynamic_cast<storm::property::prctl::ProbabilisticBoundOperator<T> const *>(this); + auto probFormula = dynamic_cast<storm::properties::prctl::ProbabilisticBoundOperator<T> const *>(this); // Check if the direct subformula of the probabilistic bound operator is an eventually or until formula. - if(std::dynamic_pointer_cast<storm::property::prctl::Eventually<T>>(probFormula->getChild()).get() != nullptr) { + if(std::dynamic_pointer_cast<storm::properties::prctl::Eventually<T>>(probFormula->getChild()).get() != nullptr) { // Get the subformula and check if its subformulas are propositional. - auto eventuallyFormula = std::dynamic_pointer_cast<storm::property::prctl::Eventually<T>>(probFormula->getChild()); + auto eventuallyFormula = std::dynamic_pointer_cast<storm::properties::prctl::Eventually<T>>(probFormula->getChild()); return eventuallyFormula->getChild()->isPropositional(); } - else if(std::dynamic_pointer_cast<storm::property::prctl::Until<T>>(probFormula->getChild()).get() != nullptr) { + else if(std::dynamic_pointer_cast<storm::properties::prctl::Until<T>>(probFormula->getChild()).get() != nullptr) { // Get the subformula and check if its subformulas are propositional. - auto untilFormula = std::dynamic_pointer_cast<storm::property::prctl::Until<T>>(probFormula->getChild()); + auto untilFormula = std::dynamic_pointer_cast<storm::properties::prctl::Until<T>>(probFormula->getChild()); return untilFormula->getLeft()->isPropositional() && untilFormula->getRight()->isPropositional(); } @@ -84,6 +84,6 @@ public: }; } /* namespace prctl */ -} /* namespace property */ +} /* namespace properties */ } /* namespace storm */ #endif /* ABSTRACTPRCTLFORMULA_H_ */ diff --git a/src/formula/prctl/AbstractRewardPathFormula.h b/src/properties/prctl/AbstractRewardPathFormula.h similarity index 90% rename from src/formula/prctl/AbstractRewardPathFormula.h rename to src/properties/prctl/AbstractRewardPathFormula.h index 09d0dcbf2..e19523679 100644 --- a/src/formula/prctl/AbstractRewardPathFormula.h +++ b/src/properties/prctl/AbstractRewardPathFormula.h @@ -8,10 +8,10 @@ #ifndef STORM_FORMULA_PRCTL_ABSTRACTREWARDPATHFORMULA_H_ #define STORM_FORMULA_PRCTL_ABSTRACTREWARDPATHFORMULA_H_ -#include "src/formula/prctl/AbstractPrctlFormula.h" +#include "src/properties/prctl/AbstractPrctlFormula.h" namespace storm { -namespace property { +namespace properties { namespace prctl { /*! @@ -25,7 +25,7 @@ namespace prctl { * @see AbstractPrctlFormula */ template <class T> -class AbstractRewardPathFormula : public virtual storm::property::prctl::AbstractPrctlFormula<T> { +class AbstractRewardPathFormula : public virtual storm::properties::prctl::AbstractPrctlFormula<T> { public: @@ -62,7 +62,7 @@ public: }; } //namespace prctl -} //namespace property +} //namespace properties } //namespace storm diff --git a/src/formula/prctl/AbstractStateFormula.h b/src/properties/prctl/AbstractStateFormula.h similarity index 88% rename from src/formula/prctl/AbstractStateFormula.h rename to src/properties/prctl/AbstractStateFormula.h index 2da8c093b..2e088d88e 100644 --- a/src/formula/prctl/AbstractStateFormula.h +++ b/src/properties/prctl/AbstractStateFormula.h @@ -8,19 +8,19 @@ #ifndef STORM_FORMULA_PRCTL_ABSTRACTSTATEFORMULA_H_ #define STORM_FORMULA_PRCTL_ABSTRACTSTATEFORMULA_H_ -#include "src/formula/prctl/AbstractPrctlFormula.h" +#include "src/properties/prctl/AbstractPrctlFormula.h" #include "src/storage/BitVector.h" #include "src/modelchecker/prctl/ForwardDeclarations.h" namespace storm { -namespace property { +namespace properties { namespace prctl { /*! * Abstract base class for Prctl state formulas. */ template <class T> -class AbstractStateFormula : public storm::property::prctl::AbstractPrctlFormula<T> { +class AbstractStateFormula : public storm::properties::prctl::AbstractPrctlFormula<T> { public: @@ -57,7 +57,7 @@ public: }; } //namespace prctl -} //namespace property +} //namespace properties } //namespace storm diff --git a/src/formula/prctl/And.h b/src/properties/prctl/And.h similarity index 98% rename from src/formula/prctl/And.h rename to src/properties/prctl/And.h index c312f30c5..adbff8c92 100644 --- a/src/formula/prctl/And.h +++ b/src/properties/prctl/And.h @@ -8,12 +8,12 @@ #ifndef STORM_FORMULA_PRCTL_AND_H_ #define STORM_FORMULA_PRCTL_AND_H_ -#include "src/formula/prctl/AbstractStateFormula.h" +#include "src/properties/prctl/AbstractStateFormula.h" #include "src/modelchecker/prctl/ForwardDeclarations.h" #include <string> namespace storm { -namespace property { +namespace properties { namespace prctl { // Forward declaration for the interface class. @@ -210,7 +210,7 @@ private: } //namespace prctl -} //namespace property +} //namespace properties } //namespace storm diff --git a/src/formula/prctl/Ap.h b/src/properties/prctl/Ap.h similarity index 96% rename from src/formula/prctl/Ap.h rename to src/properties/prctl/Ap.h index 15bd442ca..fb9fe1361 100644 --- a/src/formula/prctl/Ap.h +++ b/src/properties/prctl/Ap.h @@ -8,11 +8,11 @@ #ifndef STORM_FORMULA_PRCTL_AP_H_ #define STORM_FORMULA_PRCTL_AP_H_ -#include "src/formula/prctl/AbstractStateFormula.h" +#include "src/properties/prctl/AbstractStateFormula.h" #include "src/modelchecker/prctl/ForwardDeclarations.h" namespace storm { -namespace property { +namespace properties { namespace prctl { // Forward declaration for the interface class. @@ -134,7 +134,7 @@ private: } //namespace abstract -} //namespace property +} //namespace properties } //namespace storm diff --git a/src/formula/prctl/BoundedEventually.h b/src/properties/prctl/BoundedEventually.h similarity index 97% rename from src/formula/prctl/BoundedEventually.h rename to src/properties/prctl/BoundedEventually.h index 920a6a073..980717cfa 100644 --- a/src/formula/prctl/BoundedEventually.h +++ b/src/properties/prctl/BoundedEventually.h @@ -8,14 +8,14 @@ #ifndef STORM_FORMULA_PRCTL_BOUNDEDEVENTUALLY_H_ #define STORM_FORMULA_PRCTL_BOUNDEDEVENTUALLY_H_ -#include "src/formula/prctl/AbstractPathFormula.h" -#include "src/formula/prctl/AbstractStateFormula.h" +#include "src/properties/prctl/AbstractPathFormula.h" +#include "src/properties/prctl/AbstractStateFormula.h" #include <cstdint> #include <string> #include "src/modelchecker/prctl/ForwardDeclarations.h" namespace storm { -namespace property { +namespace properties { namespace prctl{ // Forward declaration for the interface class. @@ -191,7 +191,7 @@ private: }; } //namespace prctl -} //namespace property +} //namespace properties } //namespace storm #endif /* STORM_FORMULA_PRCTL_BOUNDEDUNTIL_H_ */ diff --git a/src/formula/prctl/BoundedNaryUntil.h b/src/properties/prctl/BoundedNaryUntil.h similarity index 97% rename from src/formula/prctl/BoundedNaryUntil.h rename to src/properties/prctl/BoundedNaryUntil.h index c6e4092e9..526c236ad 100644 --- a/src/formula/prctl/BoundedNaryUntil.h +++ b/src/properties/prctl/BoundedNaryUntil.h @@ -8,8 +8,8 @@ #ifndef STORM_FORMULA_PRCTL_BOUNDEDNARYUNTIL_H_ #define STORM_FORMULA_PRCTL_BOUNDEDNARYUNTIL_H_ -#include "src/formula/prctl/AbstractPathFormula.h" -#include "src/formula/prctl/AbstractStateFormula.h" +#include "src/properties/prctl/AbstractPathFormula.h" +#include "src/properties/prctl/AbstractStateFormula.h" #include <cstdint> #include <string> #include <vector> @@ -18,7 +18,7 @@ #include "src/modelchecker/prctl/ForwardDeclarations.h" namespace storm { -namespace property { +namespace properties { namespace prctl { // Forward declaration for the interface class. @@ -226,7 +226,7 @@ private: }; } //namespace prctl -} //namespace property +} //namespace properties } //namespace storm #endif /* STORM_FORMULA_PRCTL_BOUNDEDNARYUNTIL_H_ */ diff --git a/src/formula/prctl/BoundedUntil.h b/src/properties/prctl/BoundedUntil.h similarity index 97% rename from src/formula/prctl/BoundedUntil.h rename to src/properties/prctl/BoundedUntil.h index ec0b59f51..b52fffe55 100644 --- a/src/formula/prctl/BoundedUntil.h +++ b/src/properties/prctl/BoundedUntil.h @@ -8,14 +8,14 @@ #ifndef STORM_FORMULA_PRCTL_BOUNDEDUNTIL_H_ #define STORM_FORMULA_PRCTL_BOUNDEDUNTIL_H_ -#include "src/formula/prctl/AbstractPathFormula.h" -#include "src/formula/prctl/AbstractStateFormula.h" +#include "src/properties/prctl/AbstractPathFormula.h" +#include "src/properties/prctl/AbstractStateFormula.h" #include <cstdint> #include <string> #include "src/modelchecker/prctl/ForwardDeclarations.h" namespace storm { -namespace property { +namespace properties { namespace prctl { // Forward declaration for the interface class. @@ -227,7 +227,7 @@ private: }; } //namespace prctl -} //namespace property +} //namespace properties } //namespace storm #endif /* STORM_FORMULA_PRCTL_BOUNDEDUNTIL_H_ */ diff --git a/src/formula/prctl/CumulativeReward.h b/src/properties/prctl/CumulativeReward.h similarity index 98% rename from src/formula/prctl/CumulativeReward.h rename to src/properties/prctl/CumulativeReward.h index fd51db72c..9b27aefd6 100644 --- a/src/formula/prctl/CumulativeReward.h +++ b/src/properties/prctl/CumulativeReward.h @@ -12,7 +12,7 @@ #include <string> namespace storm { -namespace property { +namespace properties { namespace prctl { // Forward declaration for the interface class. @@ -142,7 +142,7 @@ private: }; } //namespace prctl -} //namespace property +} //namespace properties } //namespace storm #endif /* STORM_FORMULA_PRCTL_INSTANTANEOUSREWARD_H_ */ diff --git a/src/formula/prctl/Eventually.h b/src/properties/prctl/Eventually.h similarity index 96% rename from src/formula/prctl/Eventually.h rename to src/properties/prctl/Eventually.h index 6d22e1dd4..01ed2150b 100644 --- a/src/formula/prctl/Eventually.h +++ b/src/properties/prctl/Eventually.h @@ -8,12 +8,12 @@ #ifndef STORM_FORMULA_PRCTL_EVENTUALLY_H_ #define STORM_FORMULA_PRCTL_EVENTUALLY_H_ -#include "src/formula/prctl/AbstractPathFormula.h" -#include "src/formula/prctl/AbstractStateFormula.h" +#include "src/properties/prctl/AbstractPathFormula.h" +#include "src/properties/prctl/AbstractStateFormula.h" #include "src/modelchecker/prctl/ForwardDeclarations.h" namespace storm { -namespace property { +namespace properties { namespace prctl { // Forward declaration for the interface class. @@ -163,7 +163,7 @@ private: }; } //namespace prctl -} //namespace property +} //namespace properties } //namespace storm #endif /* STORM_FORMULA_PRCTL_EVENTUALLY_H_ */ diff --git a/src/formula/prctl/Globally.h b/src/properties/prctl/Globally.h similarity index 96% rename from src/formula/prctl/Globally.h rename to src/properties/prctl/Globally.h index 12f29f19d..2a1f85dec 100644 --- a/src/formula/prctl/Globally.h +++ b/src/properties/prctl/Globally.h @@ -8,12 +8,12 @@ #ifndef STORM_FORMULA_PRCTL_GLOBALLY_H_ #define STORM_FORMULA_PRCTL_GLOBALLY_H_ -#include "src/formula/prctl/AbstractPathFormula.h" -#include "src/formula/prctl/AbstractStateFormula.h" +#include "src/properties/prctl/AbstractPathFormula.h" +#include "src/properties/prctl/AbstractStateFormula.h" #include "src/modelchecker/prctl/ForwardDeclarations.h" namespace storm { -namespace property { +namespace properties { namespace prctl { // Forward declaration for the interface class. @@ -163,7 +163,7 @@ private: }; } //namespace prctl -} //namespace property +} //namespace properties } //namespace storm #endif /* STORM_FORMULA_PRCTL_GLOBALLY_H_ */ diff --git a/src/formula/prctl/InstantaneousReward.h b/src/properties/prctl/InstantaneousReward.h similarity index 98% rename from src/formula/prctl/InstantaneousReward.h rename to src/properties/prctl/InstantaneousReward.h index c8f61b120..d2f6d21a6 100644 --- a/src/formula/prctl/InstantaneousReward.h +++ b/src/properties/prctl/InstantaneousReward.h @@ -13,7 +13,7 @@ #include <string> namespace storm { -namespace property { +namespace properties { namespace prctl { // Forward declaration for the interface class. @@ -143,7 +143,7 @@ private: }; } //namespace prctl -} //namespace property +} //namespace properties } //namespace storm #endif /* STORM_FORMULA_PRCTL_INSTANTANEOUSREWARD_H_ */ diff --git a/src/formula/prctl/Next.h b/src/properties/prctl/Next.h similarity index 96% rename from src/formula/prctl/Next.h rename to src/properties/prctl/Next.h index a83ff1690..642754ec1 100644 --- a/src/formula/prctl/Next.h +++ b/src/properties/prctl/Next.h @@ -8,11 +8,11 @@ #ifndef STORM_FORMULA_PRCTL_NEXT_H_ #define STORM_FORMULA_PRCTL_NEXT_H_ -#include "src/formula/prctl/AbstractPathFormula.h" -#include "src/formula/prctl/AbstractStateFormula.h" +#include "src/properties/prctl/AbstractPathFormula.h" +#include "src/properties/prctl/AbstractStateFormula.h" namespace storm { -namespace property { +namespace properties { namespace prctl { // Forward declaration for the interface class. @@ -162,7 +162,7 @@ private: }; } //namespace prctl -} //namespace property +} //namespace properties } //namespace storm #endif /* STORM_FORMULA_PRCTL_NEXT_H_ */ diff --git a/src/formula/prctl/Not.h b/src/properties/prctl/Not.h similarity index 98% rename from src/formula/prctl/Not.h rename to src/properties/prctl/Not.h index 83af85e53..db3e2ce7d 100644 --- a/src/formula/prctl/Not.h +++ b/src/properties/prctl/Not.h @@ -12,7 +12,7 @@ #include "src/modelchecker/prctl/ForwardDeclarations.h" namespace storm { -namespace property { +namespace properties { namespace prctl { // Forward declaration for the interface class. @@ -167,7 +167,7 @@ private: }; } //namespace prctl -} //namespace property +} //namespace properties } //namespace storm #endif /* STORM_FORMULA_PRCTL_NOT_H_ */ diff --git a/src/formula/prctl/Or.h b/src/properties/prctl/Or.h similarity index 98% rename from src/formula/prctl/Or.h rename to src/properties/prctl/Or.h index 3044ce3e7..3a897ec6f 100644 --- a/src/formula/prctl/Or.h +++ b/src/properties/prctl/Or.h @@ -8,10 +8,10 @@ #ifndef STORM_FORMULA_PRCTL_OR_H_ #define STORM_FORMULA_PRCTL_OR_H_ -#include "src/formula/prctl/AbstractStateFormula.h" +#include "src/properties/prctl/AbstractStateFormula.h" namespace storm { -namespace property { +namespace properties { namespace prctl { // Forward declaration for the interface class. @@ -207,7 +207,7 @@ private: }; } //namespace prctl -} //namespace property +} //namespace properties } //namespace storm #endif /* STORM_FORMULA_PRCTL_OR_H_ */ diff --git a/src/formula/prctl/PrctlFilter.h b/src/properties/prctl/PrctlFilter.h similarity index 95% rename from src/formula/prctl/PrctlFilter.h rename to src/properties/prctl/PrctlFilter.h index 02ffa5c5a..1e742a515 100644 --- a/src/formula/prctl/PrctlFilter.h +++ b/src/properties/prctl/PrctlFilter.h @@ -8,18 +8,18 @@ #ifndef STORM_FORMULA_PRCTL_PRCTLFILTER_H_ #define STORM_FORMULA_PRCTL_PRCTLFILTER_H_ -#include "src/formula/AbstractFilter.h" -#include "src/formula/prctl/AbstractPrctlFormula.h" -#include "src/formula/prctl/AbstractPathFormula.h" -#include "src/formula/prctl/AbstractStateFormula.h" +#include "src/properties/AbstractFilter.h" +#include "src/properties/prctl/AbstractPrctlFormula.h" +#include "src/properties/prctl/AbstractPathFormula.h" +#include "src/properties/prctl/AbstractStateFormula.h" #include "src/modelchecker/prctl/AbstractModelChecker.h" -#include "src/formula/actions/AbstractAction.h" +#include "src/properties/actions/AbstractAction.h" #include <algorithm> #include <memory> namespace storm { -namespace property { +namespace properties { namespace prctl { /*! @@ -29,10 +29,10 @@ namespace prctl { * Additionally it maintains a list of filter actions that are used to further manipulate the modelchecking results and prepare them for output. */ template <class T> -class PrctlFilter : public storm::property::AbstractFilter<T> { +class PrctlFilter : public storm::properties::AbstractFilter<T> { // Convenience typedef to make the code more readable. - typedef typename storm::property::action::AbstractAction<T>::Result Result; + typedef typename storm::properties::action::AbstractAction<T>::Result Result; public: @@ -271,7 +271,7 @@ private: if(this->opt != UNDEFINED) { // If it is specified that min/max probabilities/rewards should be computed, call the appropriate method of the model checker. - result.stateResult = modelchecker.checkOptimizingOperator(*formula, this->opt == storm::property::MINIMIZE ? true : false); + result.stateResult = modelchecker.checkOptimizingOperator(*formula, this->opt == storm::properties::MINIMIZE ? true : false); } else { result.stateResult = formula->check(modelchecker); } @@ -295,7 +295,7 @@ private: if(this->opt != UNDEFINED) { // If it is specified that min/max probabilities/rewards should be computed, call the appropriate method of the model checker. - result.pathResult = modelchecker.checkOptimizingOperator(*formula, this->opt == storm::property::MINIMIZE ? true : false); + result.pathResult = modelchecker.checkOptimizingOperator(*formula, this->opt == storm::properties::MINIMIZE ? true : false); } else { result.pathResult = formula->check(modelchecker, false); } @@ -319,7 +319,7 @@ private: if(this->opt != UNDEFINED) { // If it is specified that min/max probabilities/rewards should be computed, call the appropriate method of the model checker. - result.pathResult = modelchecker.checkOptimizingOperator(*formula, this->opt == storm::property::MINIMIZE ? true : false); + result.pathResult = modelchecker.checkOptimizingOperator(*formula, this->opt == storm::properties::MINIMIZE ? true : false); } else { result.pathResult = formula->check(modelchecker, false); } @@ -428,7 +428,7 @@ private: }; } //namespace prctl -} //namespace property +} //namespace properties } //namespace storm diff --git a/src/formula/prctl/ProbabilisticBoundOperator.h b/src/properties/prctl/ProbabilisticBoundOperator.h similarity index 93% rename from src/formula/prctl/ProbabilisticBoundOperator.h rename to src/properties/prctl/ProbabilisticBoundOperator.h index abaf1e1db..c7b4e075a 100644 --- a/src/formula/prctl/ProbabilisticBoundOperator.h +++ b/src/properties/prctl/ProbabilisticBoundOperator.h @@ -11,10 +11,10 @@ #include "AbstractStateFormula.h" #include "AbstractPathFormula.h" #include "utility/constants.h" -#include "src/formula/ComparisonType.h" +#include "src/properties/ComparisonType.h" namespace storm { -namespace property { +namespace properties { namespace prctl { // Forward declaration for the interface class. @@ -83,7 +83,7 @@ public: * @param bound The bound for the probability. * @param child The child formula subtree. */ - ProbabilisticBoundOperator(storm::property::ComparisonType comparisonOperator, T bound, std::shared_ptr<AbstractPathFormula<T>> const & child) + ProbabilisticBoundOperator(storm::properties::ComparisonType comparisonOperator, T bound, std::shared_ptr<AbstractPathFormula<T>> const & child) : comparisonOperator(comparisonOperator), bound(bound), child(child) { // Intentionally left empty. } @@ -176,7 +176,7 @@ public: * * @returns An enum value representing the comparison relation. */ - storm::property::ComparisonType const getComparisonOperator() const { + storm::properties::ComparisonType const getComparisonOperator() const { return comparisonOperator; } @@ -185,7 +185,7 @@ public: * * @param comparisonOperator An enum value representing the new comparison relation. */ - void setComparisonOperator(storm::property::ComparisonType comparisonOperator) { + void setComparisonOperator(storm::properties::ComparisonType comparisonOperator) { this->comparisonOperator = comparisonOperator; } @@ -226,7 +226,7 @@ public: private: // The operator used to indicate the kind of bound that is to be met. - storm::property::ComparisonType comparisonOperator; + storm::properties::ComparisonType comparisonOperator; // The probability bound. T bound; @@ -236,7 +236,7 @@ private: }; } //namespace prctl -} //namespace property +} //namespace properties } //namespace storm #endif /* STORM_FORMULA_PRCTL_PROBABILISTICBOUNDOPERATOR_H_ */ diff --git a/src/formula/prctl/ReachabilityReward.h b/src/properties/prctl/ReachabilityReward.h similarity index 99% rename from src/formula/prctl/ReachabilityReward.h rename to src/properties/prctl/ReachabilityReward.h index 2187b6250..3b20fe7f5 100644 --- a/src/formula/prctl/ReachabilityReward.h +++ b/src/properties/prctl/ReachabilityReward.h @@ -12,7 +12,7 @@ #include "AbstractStateFormula.h" namespace storm { -namespace property { +namespace properties { namespace prctl { // Forward declaration for the interface class. @@ -164,7 +164,7 @@ private: }; } //namespace prctl -} //namespace property +} //namespace properties } //namespace storm #endif /* STORM_FORMULA_PRCTL_REACHABILITYREWARD_H_ */ diff --git a/src/formula/prctl/RewardBoundOperator.h b/src/properties/prctl/RewardBoundOperator.h similarity index 93% rename from src/formula/prctl/RewardBoundOperator.h rename to src/properties/prctl/RewardBoundOperator.h index a7a4089a9..30322f2be 100644 --- a/src/formula/prctl/RewardBoundOperator.h +++ b/src/properties/prctl/RewardBoundOperator.h @@ -11,10 +11,10 @@ #include "AbstractRewardPathFormula.h" #include "AbstractStateFormula.h" #include "utility/constants.h" -#include "src/formula/ComparisonType.h" +#include "src/properties/ComparisonType.h" namespace storm { -namespace property { +namespace properties { namespace prctl { // Forward declaration for the interface class. @@ -84,7 +84,7 @@ public: * @param bound The bound for the rewards. * @param child The child formula subtree. */ - RewardBoundOperator(storm::property::ComparisonType comparisonOperator, T bound, std::shared_ptr<AbstractRewardPathFormula<T>> const & child) + RewardBoundOperator(storm::properties::ComparisonType comparisonOperator, T bound, std::shared_ptr<AbstractRewardPathFormula<T>> const & child) : comparisonOperator(comparisonOperator), bound(bound), child(child) { // Intentionally left empty } @@ -177,7 +177,7 @@ public: * * @returns An enum value representing the comparison relation. */ - storm::property::ComparisonType const getComparisonOperator() const { + storm::properties::ComparisonType const getComparisonOperator() const { return comparisonOperator; } @@ -186,7 +186,7 @@ public: * * @param comparisonOperator An enum value representing the new comparison relation. */ - void setComparisonOperator(storm::property::ComparisonType comparisonOperator) { + void setComparisonOperator(storm::properties::ComparisonType comparisonOperator) { this->comparisonOperator = comparisonOperator; } @@ -227,7 +227,7 @@ public: private: // The operator used to indicate the kind of bound that is to be met. - storm::property::ComparisonType comparisonOperator; + storm::properties::ComparisonType comparisonOperator; // The reward bound. T bound; @@ -237,7 +237,7 @@ private: }; } //namespace prctl -} //namespace property +} //namespace properties } //namespace storm #endif /* STORM_FORMULA_PRCTL_REWARDBOUNDOPERATOR_H_ */ diff --git a/src/formula/prctl/SteadyStateReward.h b/src/properties/prctl/SteadyStateReward.h similarity index 98% rename from src/formula/prctl/SteadyStateReward.h rename to src/properties/prctl/SteadyStateReward.h index c075abba9..0143c91a1 100644 --- a/src/formula/prctl/SteadyStateReward.h +++ b/src/properties/prctl/SteadyStateReward.h @@ -12,7 +12,7 @@ #include <string> namespace storm { -namespace property { +namespace properties { namespace prctl { // Forward declaration for the interface class. @@ -109,6 +109,6 @@ public: }; } //namespace prctl -} //namespace property +} //namespace properties } //namespace storm #endif /* STORM_FORMULA_PRCTL_STEADYSTATEREWARD_H_ */ diff --git a/src/formula/prctl/Until.h b/src/properties/prctl/Until.h similarity index 99% rename from src/formula/prctl/Until.h rename to src/properties/prctl/Until.h index 27eb89167..f9e19955b 100644 --- a/src/formula/prctl/Until.h +++ b/src/properties/prctl/Until.h @@ -12,7 +12,7 @@ #include "AbstractStateFormula.h" namespace storm { -namespace property { +namespace properties { namespace prctl { // Forward declaration for the interface class. @@ -199,7 +199,7 @@ private: }; } //namespace prctl -} //namespace property +} //namespace properties } //namespace storm #endif /* STORM_FORMULA_PRCTL_UNTIL_H_ */ diff --git a/src/storm.cpp b/src/storm.cpp index 2896bd4b9..e3786c35f 100644 --- a/src/storm.cpp +++ b/src/storm.cpp @@ -40,7 +40,7 @@ #include "src/parser/MarkovAutomatonParser.h" #include "src/parser/PrctlParser.h" #include "src/utility/ErrorHandling.h" -#include "src/formula/Prctl.h" +#include "src/properties/Prctl.h" #include "src/utility/vector.h" #include "src/settings/Settings.h" @@ -285,7 +285,7 @@ void checkPrctlFormulae(storm::modelchecker::prctl::AbstractModelChecker<double> if (s->isSet("prctl")) { std::string const chosenPrctlFile = s->getOptionByLongName("prctl").getArgument(0).getValueAsString(); LOG4CPLUS_INFO(logger, "Parsing prctl file: " << chosenPrctlFile << "."); - std::list<std::shared_ptr<storm::property::prctl::PrctlFilter<double>>> formulaList = storm::parser::PrctlFileParser::parsePrctlFile(chosenPrctlFile); + std::list<std::shared_ptr<storm::properties::prctl::PrctlFilter<double>>> formulaList = storm::parser::PrctlFileParser::parsePrctlFile(chosenPrctlFile); for (auto formula : formulaList) { formula->check(modelchecker); @@ -338,7 +338,7 @@ void checkPrctlFormulae(storm::modelchecker::prctl::AbstractModelChecker<double> std::string const chosenPrctlFile = s->getOptionByLongName("prctl").getArgument(0).getValueAsString(); LOG4CPLUS_INFO(logger, "Parsing prctl file: " << chosenPrctlFile << "."); - std::list<std::shared_ptr<storm::property::prctl::PrctlFilter<double>>> formulaList = storm::parser::PrctlFileParser::parsePrctlFile(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) { @@ -368,12 +368,12 @@ void checkPrctlFormulae(storm::modelchecker::prctl::AbstractModelChecker<double> for (auto formula : formulaList) { // First check if it is a formula type for which a counterexample can be generated. - if (std::dynamic_pointer_cast<storm::property::prctl::AbstractStateFormula<double>>(formula->getChild()).get() == nullptr) { + 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."); continue; } - std::shared_ptr<storm::property::prctl::AbstractStateFormula<double>> stateForm = std::static_pointer_cast<storm::property::prctl::AbstractStateFormula<double>>(formula->getChild()); + std::shared_ptr<storm::properties::prctl::AbstractStateFormula<double>> stateForm = std::static_pointer_cast<storm::properties::prctl::AbstractStateFormula<double>>(formula->getChild()); // Do some output std::cout << "Generating counterexample for formula " << fIndex << ":" << std::endl; @@ -548,7 +548,7 @@ int main(const int argc, const char* argv[]) { // Now parse the property file and receive the list of parsed formulas. std::string const& propertyFile = s->getOptionByLongName("mincmd").getArgumentByName("propertyFile").getValueAsString(); - std::list<std::shared_ptr<storm::property::prctl::PrctlFilter<double>>> formulaList = storm::parser::PrctlFileParser::parsePrctlFile(propertyFile); + std::list<std::shared_ptr<storm::properties::prctl::PrctlFilter<double>>> formulaList = storm::parser::PrctlFileParser::parsePrctlFile(propertyFile); // Now generate the counterexamples for each formula. for (auto formulaPtr : formulaList) { diff --git a/test/functional/modelchecker/ActionTest.cpp b/test/functional/modelchecker/ActionTest.cpp index 647d8464f..83113a614 100644 --- a/test/functional/modelchecker/ActionTest.cpp +++ b/test/functional/modelchecker/ActionTest.cpp @@ -8,11 +8,11 @@ #include "gtest/gtest.h" #include "storm-config.h" -#include "src/formula/actions/BoundAction.h" -#include "src/formula/actions/FormulaAction.h" -#include "src/formula/actions/InvertAction.h" -#include "src/formula/actions/RangeAction.h" -#include "src/formula/actions/SortAction.h" +#include "src/properties/actions/BoundAction.h" +#include "src/properties/actions/FormulaAction.h" +#include "src/properties/actions/InvertAction.h" +#include "src/properties/actions/RangeAction.h" +#include "src/properties/actions/SortAction.h" #include "src/parser/MarkovAutomatonParser.h" #include "src/parser/DeterministicModelParser.h" @@ -21,7 +21,7 @@ #include "src/solver/GmmxxLinearEquationSolver.h" #include "src/exceptions/InvalidArgumentException.h" -typedef typename storm::property::action::AbstractAction<double>::Result Result; +typedef typename storm::properties::action::AbstractAction<double>::Result Result; TEST(ActionTest, BoundActionFunctionality) { @@ -31,7 +31,7 @@ TEST(ActionTest, BoundActionFunctionality) { // Build the filter input. // Basically the modelchecking result of "F a" on the used DTMC. - std::vector<double> pathResult = mc.checkEventually(storm::property::prctl::Eventually<double>(std::make_shared<storm::property::prctl::Ap<double>>("a")), false); + std::vector<double> pathResult = mc.checkEventually(storm::properties::prctl::Eventually<double>(std::make_shared<storm::properties::prctl::Ap<double>>("a")), false); std::vector<uint_fast64_t> stateMap(pathResult.size()); for(uint_fast64_t i = 0; i < pathResult.size(); i++) { stateMap[i] = i; @@ -40,7 +40,7 @@ TEST(ActionTest, BoundActionFunctionality) { // Test the action. // First test that the boundAction build by the empty constructor does not change the selection. - storm::property::action::BoundAction<double> action; + storm::properties::action::BoundAction<double> action; Result result = action.evaluate(input, mc); for(auto value : result.selection) { @@ -48,7 +48,7 @@ TEST(ActionTest, BoundActionFunctionality) { } // Test that using a strict bound can give different results than using a non-strict bound. - action = storm::property::action::BoundAction<double>(storm::property::GREATER, 0); + action = storm::properties::action::BoundAction<double>(storm::properties::GREATER, 0); result = action.evaluate(input, mc); for(uint_fast64_t i = 0; i < result.selection.size()-2; i++) { @@ -58,7 +58,7 @@ TEST(ActionTest, BoundActionFunctionality) { ASSERT_FALSE(result.selection[7]); // Test whether the filter actually uses the selection given by the input. - action = storm::property::action::BoundAction<double>(storm::property::LESS, 0.5); + action = storm::properties::action::BoundAction<double>(storm::properties::LESS, 0.5); result = action.evaluate(result, mc); ASSERT_FALSE(result.selection[0]); @@ -71,7 +71,7 @@ TEST(ActionTest, BoundActionFunctionality) { stateMap[i] = pathResult.size() - i - 1; } - action = storm::property::action::BoundAction<double>(storm::property::GREATER, 0); + action = storm::properties::action::BoundAction<double>(storm::properties::GREATER, 0); result = action.evaluate(input, mc); for(uint_fast64_t i = 0; i < result.selection.size()-2; i++) { @@ -82,8 +82,8 @@ TEST(ActionTest, BoundActionFunctionality) { // Test the functionality for state formulas instead. input.pathResult = std::vector<double>(); - input.stateResult = mc.checkAp(storm::property::prctl::Ap<double>("a")); - action = storm::property::action::BoundAction<double>(storm::property::GREATER, 0.5); + input.stateResult = mc.checkAp(storm::properties::prctl::Ap<double>("a")); + action = storm::properties::action::BoundAction<double>(storm::properties::GREATER, 0.5); result = action.evaluate(input, mc); for(uint_fast64_t i = 0; i < result.selection.size(); i++) { @@ -116,8 +116,8 @@ TEST(ActionTest, BoundActionSafety) { // Build the filter input. // Basically the modelchecking result of "F a" on the used DTMC. - std::vector<double> pathResult = mc.checkEventually(storm::property::prctl::Eventually<double>(std::make_shared<storm::property::prctl::Ap<double>>("a")), false); - storm::storage::BitVector stateResult = mc.checkAp(storm::property::prctl::Ap<double>("a")); + std::vector<double> pathResult = mc.checkEventually(storm::properties::prctl::Eventually<double>(std::make_shared<storm::properties::prctl::Ap<double>>("a")), false); + storm::storage::BitVector stateResult = mc.checkAp(storm::properties::prctl::Ap<double>("a")); std::vector<uint_fast64_t> stateMap(pathResult.size()); for(uint_fast64_t i = 0; i < pathResult.size(); i++) { stateMap[i] = i; @@ -125,30 +125,30 @@ TEST(ActionTest, BoundActionSafety) { Result input(storm::storage::BitVector(pathResult.size(), true), stateMap, pathResult, storm::storage::BitVector()); // First, test unusual bounds. - storm::property::action::BoundAction<double> action(storm::property::LESS, -2044); + storm::properties::action::BoundAction<double> action(storm::properties::LESS, -2044); Result result; ASSERT_NO_THROW(result = action.evaluate(input, mc)); ASSERT_EQ(0, result.selection.getNumberOfSetBits()); - action = storm::property::action::BoundAction<double>(storm::property::GREATER_EQUAL, 5879); + action = storm::properties::action::BoundAction<double>(storm::properties::GREATER_EQUAL, 5879); ASSERT_NO_THROW(result = action.evaluate(input, mc)); ASSERT_EQ(0, result.selection.getNumberOfSetBits()); - action = storm::property::action::BoundAction<double>(storm::property::LESS_EQUAL, 5879); + action = storm::properties::action::BoundAction<double>(storm::properties::LESS_EQUAL, 5879); ASSERT_NO_THROW(result = action.evaluate(input, mc)); ASSERT_EQ(result.selection.size(), result.selection.getNumberOfSetBits()); // Now, check the behavior under a undefined comparison type. - action = storm::property::action::BoundAction<double>(static_cast<storm::property::ComparisonType>(10), 5879); + action = storm::properties::action::BoundAction<double>(static_cast<storm::properties::ComparisonType>(10), 5879); ASSERT_THROW(action.toString(), storm::exceptions::InvalidArgumentException); ASSERT_THROW(action.evaluate(input, mc), storm::exceptions::InvalidArgumentException); // Test for a result input with both results filled. // It should put out a warning and use the pathResult. - action = storm::property::action::BoundAction<double>(storm::property::GREATER_EQUAL, 0.5); + action = storm::properties::action::BoundAction<double>(storm::properties::GREATER_EQUAL, 0.5); input.stateResult = stateResult; // To capture the warning, redirect cout and test the written buffer content. @@ -177,8 +177,8 @@ TEST(ActionTest, FormulaActionFunctionality) { // Build the filter input. // Basically the modelchecking result of "F a" on the used DTMC. - std::vector<double> pathResult = mc.checkEventually(storm::property::prctl::Eventually<double>(std::make_shared<storm::property::prctl::Ap<double>>("a")), false); - storm::storage::BitVector stateResult = mc.checkAp(storm::property::prctl::Ap<double>("c")); + std::vector<double> pathResult = mc.checkEventually(storm::properties::prctl::Eventually<double>(std::make_shared<storm::properties::prctl::Ap<double>>("a")), false); + storm::storage::BitVector stateResult = mc.checkAp(storm::properties::prctl::Ap<double>("c")); std::vector<uint_fast64_t> stateMap(pathResult.size()); for(uint_fast64_t i = 0; i < pathResult.size(); i++) { stateMap[i] = i; @@ -188,7 +188,7 @@ TEST(ActionTest, FormulaActionFunctionality) { // Test the action. // First test that the empty action does no change to the input. - storm::property::action::FormulaAction<double> action; + storm::properties::action::FormulaAction<double> action; input.selection.set(0,false); ASSERT_NO_THROW(result = action.evaluate(input, mc)); for(uint_fast64_t i = 0; i < pathResult.size(); i++) { @@ -204,7 +204,7 @@ TEST(ActionTest, FormulaActionFunctionality) { input.selection.set(0,true); // Now test the general functionality. - action = storm::property::action::FormulaAction<double>(std::make_shared<storm::property::prctl::ProbabilisticBoundOperator<double>>(storm::property::LESS, 0.5, std::make_shared<storm::property::prctl::Eventually<double>>(std::make_shared<storm::property::prctl::Ap<double>>("b")))); + action = storm::properties::action::FormulaAction<double>(std::make_shared<storm::properties::prctl::ProbabilisticBoundOperator<double>>(storm::properties::LESS, 0.5, std::make_shared<storm::properties::prctl::Eventually<double>>(std::make_shared<storm::properties::prctl::Ap<double>>("b")))); ASSERT_NO_THROW(result = action.evaluate(input, mc)); ASSERT_TRUE(result.selection[0]); ASSERT_TRUE(result.selection[1]); @@ -249,7 +249,7 @@ TEST(ActionTest, FormulaActionSafety){ // Build the filter input. // Basically the modelchecking result of "F a" on the used DTMC. - std::vector<double> pathResult = mc.checkEventually(storm::property::prctl::Eventually<double>(std::make_shared<storm::property::prctl::Ap<double>>("a")), false); + std::vector<double> pathResult = mc.checkEventually(storm::properties::prctl::Eventually<double>(std::make_shared<storm::properties::prctl::Ap<double>>("a")), false); std::vector<uint_fast64_t> stateMap(pathResult.size()); for(uint_fast64_t i = 0; i < pathResult.size(); i++) { stateMap[i] = i; @@ -258,7 +258,7 @@ TEST(ActionTest, FormulaActionSafety){ Result result; // Check that constructing the action using a nullptr and using an empty constructor leads to the same behavior. - storm::property::action::FormulaAction<double> action(std::shared_ptr<storm::property::csl::AbstractStateFormula<double>>(nullptr)); + storm::properties::action::FormulaAction<double> action(std::shared_ptr<storm::properties::csl::AbstractStateFormula<double>>(nullptr)); input.selection.set(0,false); ASSERT_NO_THROW(result = action.evaluate(input, mc)); for(uint_fast64_t i = 0; i < pathResult.size(); i++) { @@ -282,8 +282,8 @@ TEST(ActionTest, InvertActionFunctionality){ // Build the filter input. // Basically the modelchecking result of "F a" on the used DTMC. - std::vector<double> pathResult = mc.checkEventually(storm::property::prctl::Eventually<double>(std::make_shared<storm::property::prctl::Ap<double>>("a")), false); - storm::storage::BitVector stateResult = mc.checkAp(storm::property::prctl::Ap<double>("c")); + std::vector<double> pathResult = mc.checkEventually(storm::properties::prctl::Eventually<double>(std::make_shared<storm::properties::prctl::Ap<double>>("a")), false); + storm::storage::BitVector stateResult = mc.checkAp(storm::properties::prctl::Ap<double>("c")); std::vector<uint_fast64_t> stateMap(pathResult.size()); for(uint_fast64_t i = 0; i < pathResult.size(); i++) { stateMap[i] = pathResult.size()-i-1; @@ -292,7 +292,7 @@ TEST(ActionTest, InvertActionFunctionality){ Result result; // Check whether the selection becomes inverted while the rest stays the same. - storm::property::action::InvertAction<double> action; + storm::properties::action::InvertAction<double> action; input.selection.set(0,false); ASSERT_NO_THROW(result = action.evaluate(input, mc)); for(uint_fast64_t i = 0; i < pathResult.size(); i++) { @@ -316,8 +316,8 @@ TEST(ActionTest, RangeActionFunctionality){ // Build the filter input. // Basically the modelchecking result of "F a" on the used DTMC. - std::vector<double> pathResult = mc.checkEventually(storm::property::prctl::Eventually<double>(std::make_shared<storm::property::prctl::Ap<double>>("a")), false); - storm::storage::BitVector stateResult = mc.checkAp(storm::property::prctl::Ap<double>("c")); + std::vector<double> pathResult = mc.checkEventually(storm::properties::prctl::Eventually<double>(std::make_shared<storm::properties::prctl::Ap<double>>("a")), false); + storm::storage::BitVector stateResult = mc.checkAp(storm::properties::prctl::Ap<double>("c")); std::vector<uint_fast64_t> stateMap(pathResult.size()); for(uint_fast64_t i = 0; i < pathResult.size(); i++) { stateMap[i] = i; @@ -327,7 +327,7 @@ TEST(ActionTest, RangeActionFunctionality){ // Test if the action selects the first 3 states in relation to the order given by the stateMap. // First in index order. - storm::property::action::RangeAction<double> action(0,2); + storm::properties::action::RangeAction<double> action(0,2); ASSERT_NO_THROW(result = action.evaluate(input, mc)); for(uint_fast64_t i = 0; i < result.selection.size(); i++) { ASSERT_EQ(input.stateMap[i], result.stateMap[i]); @@ -384,7 +384,7 @@ TEST(ActionTest, RangeActionFunctionality){ // Test that specifying and interval of (i,i) selects only state i. for(uint_fast64_t i = 0; i < input.selection.size(); i++) { - action = storm::property::action::RangeAction<double>(i,i); + action = storm::properties::action::RangeAction<double>(i,i); ASSERT_NO_THROW(result = action.evaluate(input, mc)); ASSERT_EQ(1, result.selection.getNumberOfSetBits()); ASSERT_TRUE(result.selection[result.stateMap[i]]); @@ -398,8 +398,8 @@ TEST(ActionTest, RangeActionSafety){ // Build the filter input. // Basically the modelchecking result of "F a" on the used DTMC. - std::vector<double> pathResult = mc.checkEventually(storm::property::prctl::Eventually<double>(std::make_shared<storm::property::prctl::Ap<double>>("a")), false); - storm::storage::BitVector stateResult = mc.checkAp(storm::property::prctl::Ap<double>("c")); + std::vector<double> pathResult = mc.checkEventually(storm::properties::prctl::Eventually<double>(std::make_shared<storm::properties::prctl::Ap<double>>("a")), false); + storm::storage::BitVector stateResult = mc.checkAp(storm::properties::prctl::Ap<double>("c")); std::vector<uint_fast64_t> stateMap(pathResult.size()); for(uint_fast64_t i = 0; i < pathResult.size(); i++) { stateMap[i] = i; @@ -414,21 +414,21 @@ TEST(ActionTest, RangeActionSafety){ std::streambuf * sbuf = std::cout.rdbuf(); std::cout.rdbuf(buffer.rdbuf()); - storm::property::action::RangeAction<double> action(0,42); + storm::properties::action::RangeAction<double> action(0,42); ASSERT_NO_THROW(result = action.evaluate(input, mc)); ASSERT_TRUE(result.selection.full()); ASSERT_FALSE(buffer.str().empty()); buffer.str(""); - action = storm::property::action::RangeAction<double>(42,98); + action = storm::properties::action::RangeAction<double>(42,98); ASSERT_NO_THROW(result = action.evaluate(input, mc)); ASSERT_TRUE(result.selection.empty()); ASSERT_FALSE(buffer.str().empty()); std::cout.rdbuf(sbuf); - ASSERT_THROW(storm::property::action::RangeAction<double>(3,1), storm::exceptions::IllegalArgumentValueException); + ASSERT_THROW(storm::properties::action::RangeAction<double>(3,1), storm::exceptions::IllegalArgumentValueException); } TEST(ActionTest, SortActionFunctionality){ @@ -438,8 +438,8 @@ TEST(ActionTest, SortActionFunctionality){ // Build the filter input. // Basically the modelchecking result of "F a" on the used DTMC. - std::vector<double> pathResult = mc.checkEventually(storm::property::prctl::Eventually<double>(std::make_shared<storm::property::prctl::Ap<double>>("a")), false); - storm::storage::BitVector stateResult = mc.checkAp(storm::property::prctl::Ap<double>("c")); + std::vector<double> pathResult = mc.checkEventually(storm::properties::prctl::Eventually<double>(std::make_shared<storm::properties::prctl::Ap<double>>("a")), false); + storm::storage::BitVector stateResult = mc.checkAp(storm::properties::prctl::Ap<double>("c")); std::vector<uint_fast64_t> stateMap(pathResult.size()); for(uint_fast64_t i = 0; i < pathResult.size(); i++) { stateMap[i] = pathResult.size()-i-1; @@ -448,7 +448,7 @@ TEST(ActionTest, SortActionFunctionality){ Result result; // Test that sorting preserves everything except the state map. - storm::property::action::SortAction<double> action; + storm::properties::action::SortAction<double> action; ASSERT_NO_THROW(action.toString()); input.selection.set(0,false); ASSERT_NO_THROW(result = action.evaluate(input, mc)); @@ -468,14 +468,14 @@ TEST(ActionTest, SortActionFunctionality){ // 1) index, ascending -> see above // 2) index descending input.selection.set(3,false); - action = storm::property::action::SortAction<double>(storm::property::action::SortAction<double>::INDEX, false); + action = storm::properties::action::SortAction<double>(storm::properties::action::SortAction<double>::INDEX, false); ASSERT_NO_THROW(result = action.evaluate(input, mc)); for(uint_fast64_t i = 0; i < pathResult.size(); i++) { ASSERT_EQ(pathResult.size()-i-1, result.stateMap[i]); } // 3) value, ascending - action = storm::property::action::SortAction<double>(storm::property::action::SortAction<double>::VALUE); + action = storm::properties::action::SortAction<double>(storm::properties::action::SortAction<double>::VALUE); ASSERT_NO_THROW(result = action.evaluate(input, mc)); ASSERT_EQ(6, result.stateMap[0]); ASSERT_EQ(7, result.stateMap[1]); @@ -487,7 +487,7 @@ TEST(ActionTest, SortActionFunctionality){ ASSERT_EQ(5, result.stateMap[7]); // 3) value, decending - action = storm::property::action::SortAction<double>(storm::property::action::SortAction<double>::VALUE, false); + action = storm::properties::action::SortAction<double>(storm::properties::action::SortAction<double>::VALUE, false); ASSERT_NO_THROW(result = action.evaluate(input, mc)); ASSERT_EQ(5, result.stateMap[0]); ASSERT_EQ(2, result.stateMap[1]); @@ -502,7 +502,7 @@ TEST(ActionTest, SortActionFunctionality){ input.pathResult = std::vector<double>(); input.stateResult = stateResult; - action = storm::property::action::SortAction<double>(storm::property::action::SortAction<double>::VALUE); + action = storm::properties::action::SortAction<double>(storm::properties::action::SortAction<double>::VALUE); ASSERT_NO_THROW(result = action.evaluate(input, mc)); ASSERT_EQ(5, result.stateMap[0]); ASSERT_EQ(6, result.stateMap[1]); @@ -513,7 +513,7 @@ TEST(ActionTest, SortActionFunctionality){ ASSERT_EQ(3, result.stateMap[6]); ASSERT_EQ(4, result.stateMap[7]); - action = storm::property::action::SortAction<double>(storm::property::action::SortAction<double>::VALUE, false); + action = storm::properties::action::SortAction<double>(storm::properties::action::SortAction<double>::VALUE, false); ASSERT_NO_THROW(result = action.evaluate(input, mc)); ASSERT_EQ(0, result.stateMap[0]); ASSERT_EQ(1, result.stateMap[1]); @@ -528,9 +528,9 @@ TEST(ActionTest, SortActionFunctionality){ input.stateResult = storm::storage::BitVector(); input.pathResult = pathResult; - action = storm::property::action::SortAction<double>(storm::property::action::SortAction<double>::INDEX); + action = storm::properties::action::SortAction<double>(storm::properties::action::SortAction<double>::INDEX); ASSERT_NO_THROW(input = action.evaluate(input, mc)); - action = storm::property::action::SortAction<double>(storm::property::action::SortAction<double>::VALUE); + action = storm::properties::action::SortAction<double>(storm::properties::action::SortAction<double>::VALUE); ASSERT_NO_THROW(result = action.evaluate(input, mc)); ASSERT_EQ(6, result.stateMap[0]); ASSERT_EQ(7, result.stateMap[1]); @@ -551,8 +551,8 @@ TEST(ActionTest, SortActionSafety){ // Build the filter input. // Basically the modelchecking result of "F a" on the used DTMC. - std::vector<double> pathResult = mc.checkEventually(storm::property::prctl::Eventually<double>(std::make_shared<storm::property::prctl::Ap<double>>("a")), false); - storm::storage::BitVector stateResult = mc.checkAp(storm::property::prctl::Ap<double>("c")); + std::vector<double> pathResult = mc.checkEventually(storm::properties::prctl::Eventually<double>(std::make_shared<storm::properties::prctl::Ap<double>>("a")), false); + storm::storage::BitVector stateResult = mc.checkAp(storm::properties::prctl::Ap<double>("c")); std::vector<uint_fast64_t> stateMap(pathResult.size()); for(uint_fast64_t i = 0; i < pathResult.size(); i++) { stateMap[i] = pathResult.size()-i-1; @@ -560,7 +560,7 @@ TEST(ActionTest, SortActionSafety){ Result input(storm::storage::BitVector(pathResult.size(), true), stateMap, pathResult, stateResult); Result result; - storm::property::action::SortAction<double> action(storm::property::action::SortAction<double>::VALUE); + storm::properties::action::SortAction<double> action(storm::properties::action::SortAction<double>::VALUE); ASSERT_NO_THROW(result = action.evaluate(input, mc)); ASSERT_EQ(6, result.stateMap[0]); ASSERT_EQ(7, result.stateMap[1]); diff --git a/test/functional/modelchecker/EigenDtmcPrctlModelCheckerTest.cpp b/test/functional/modelchecker/EigenDtmcPrctlModelCheckerTest.cpp index 0d36a1d77..8cb8d131d 100644 --- a/test/functional/modelchecker/EigenDtmcPrctlModelCheckerTest.cpp +++ b/test/functional/modelchecker/EigenDtmcPrctlModelCheckerTest.cpp @@ -21,9 +21,9 @@ TEST(EigenDtmcPrctlModelCheckerTest, Die) { storm::modelChecker::EigenDtmcPrctlModelChecker<double> mc(*dtmc); - storm::property::Ap<double>* apFormula = new storm::property::Ap<double>("one"); - storm::property::Eventually<double>* eventuallyFormula = new storm::property::Eventually<double>(apFormula); - storm::property::ProbabilisticNoBoundOperator<double>* probFormula = new storm::property::ProbabilisticNoBoundOperator<double>(eventuallyFormula); + storm::properties::Ap<double>* apFormula = new storm::properties::Ap<double>("one"); + storm::properties::Eventually<double>* eventuallyFormula = new storm::properties::Eventually<double>(apFormula); + storm::properties::ProbabilisticNoBoundOperator<double>* probFormula = new storm::properties::ProbabilisticNoBoundOperator<double>(eventuallyFormula); std::vector<double>* result = probFormula->check(mc); @@ -32,9 +32,9 @@ TEST(EigenDtmcPrctlModelCheckerTest, Die) { delete probFormula; delete result; - apFormula = new storm::property::Ap<double>("two"); - eventuallyFormula = new storm::property::Eventually<double>(apFormula); - probFormula = new storm::property::ProbabilisticNoBoundOperator<double>(eventuallyFormula); + apFormula = new storm::properties::Ap<double>("two"); + eventuallyFormula = new storm::properties::Eventually<double>(apFormula); + probFormula = new storm::properties::ProbabilisticNoBoundOperator<double>(eventuallyFormula); result = probFormula->check(mc); @@ -43,9 +43,9 @@ TEST(EigenDtmcPrctlModelCheckerTest, Die) { delete probFormula; delete result; - apFormula = new storm::property::Ap<double>("three"); - eventuallyFormula = new storm::property::Eventually<double>(apFormula); - probFormula = new storm::property::ProbabilisticNoBoundOperator<double>(eventuallyFormula); + apFormula = new storm::properties::Ap<double>("three"); + eventuallyFormula = new storm::properties::Eventually<double>(apFormula); + probFormula = new storm::properties::ProbabilisticNoBoundOperator<double>(eventuallyFormula); result = probFormula->check(mc); @@ -54,9 +54,9 @@ TEST(EigenDtmcPrctlModelCheckerTest, Die) { delete probFormula; delete result; - storm::property::Ap<double>* done = new storm::property::Ap<double>("done"); - storm::property::ReachabilityReward<double>* reachabilityRewardFormula = new storm::property::ReachabilityReward<double>(done); - storm::property::RewardNoBoundOperator<double>* rewardFormula = new storm::property::RewardNoBoundOperator<double>(reachabilityRewardFormula); + storm::properties::Ap<double>* done = new storm::properties::Ap<double>("done"); + storm::properties::ReachabilityReward<double>* reachabilityRewardFormula = new storm::properties::ReachabilityReward<double>(done); + storm::properties::RewardNoBoundOperator<double>* rewardFormula = new storm::properties::RewardNoBoundOperator<double>(reachabilityRewardFormula); result = rewardFormula->check(mc); @@ -82,9 +82,9 @@ TEST(EigenDtmcPrctlModelCheckerTest, Crowds) { storm::modelChecker::EigenDtmcPrctlModelChecker<double> mc(*dtmc); - storm::property::Ap<double>* apFormula = new storm::property::Ap<double>("observe0Greater1"); - storm::property::Eventually<double>* eventuallyFormula = new storm::property::Eventually<double>(apFormula); - storm::property::ProbabilisticNoBoundOperator<double>* probFormula = new storm::property::ProbabilisticNoBoundOperator<double>(eventuallyFormula); + storm::properties::Ap<double>* apFormula = new storm::properties::Ap<double>("observe0Greater1"); + storm::properties::Eventually<double>* eventuallyFormula = new storm::properties::Eventually<double>(apFormula); + storm::properties::ProbabilisticNoBoundOperator<double>* probFormula = new storm::properties::ProbabilisticNoBoundOperator<double>(eventuallyFormula); std::vector<double>* result = probFormula->check(mc); @@ -93,9 +93,9 @@ TEST(EigenDtmcPrctlModelCheckerTest, Crowds) { delete probFormula; delete result; - apFormula = new storm::property::Ap<double>("observeIGreater1"); - eventuallyFormula = new storm::property::Eventually<double>(apFormula); - probFormula = new storm::property::ProbabilisticNoBoundOperator<double>(eventuallyFormula); + apFormula = new storm::properties::Ap<double>("observeIGreater1"); + eventuallyFormula = new storm::properties::Eventually<double>(apFormula); + probFormula = new storm::properties::ProbabilisticNoBoundOperator<double>(eventuallyFormula); result = probFormula->check(mc); @@ -104,9 +104,9 @@ TEST(EigenDtmcPrctlModelCheckerTest, Crowds) { delete probFormula; delete result; - apFormula = new storm::property::Ap<double>("observeOnlyTrueSender"); - eventuallyFormula = new storm::property::Eventually<double>(apFormula); - probFormula = new storm::property::ProbabilisticNoBoundOperator<double>(eventuallyFormula); + apFormula = new storm::properties::Ap<double>("observeOnlyTrueSender"); + eventuallyFormula = new storm::properties::Eventually<double>(apFormula); + probFormula = new storm::properties::ProbabilisticNoBoundOperator<double>(eventuallyFormula); result = probFormula->check(mc); @@ -131,9 +131,9 @@ TEST(EigenDtmcPrctlModelCheckerTest, SynchronousLeader) { storm::modelChecker::EigenDtmcPrctlModelChecker<double> mc(*dtmc); - storm::property::Ap<double>* apFormula = new storm::property::Ap<double>("elected"); - storm::property::Eventually<double>* eventuallyFormula = new storm::property::Eventually<double>(apFormula); - storm::property::ProbabilisticNoBoundOperator<double>* probFormula = new storm::property::ProbabilisticNoBoundOperator<double>(eventuallyFormula); + storm::properties::Ap<double>* apFormula = new storm::properties::Ap<double>("elected"); + storm::properties::Eventually<double>* eventuallyFormula = new storm::properties::Eventually<double>(apFormula); + storm::properties::ProbabilisticNoBoundOperator<double>* probFormula = new storm::properties::ProbabilisticNoBoundOperator<double>(eventuallyFormula); std::vector<double>* result = probFormula->check(mc); @@ -142,9 +142,9 @@ TEST(EigenDtmcPrctlModelCheckerTest, SynchronousLeader) { delete probFormula; delete result; - apFormula = new storm::property::Ap<double>("elected"); - storm::property::BoundedUntil<double>* boundedUntilFormula = new storm::property::BoundedUntil<double>(new storm::property::Ap<double>("true"), apFormula, 20); - probFormula = new storm::property::ProbabilisticNoBoundOperator<double>(boundedUntilFormula); + apFormula = new storm::properties::Ap<double>("elected"); + storm::properties::BoundedUntil<double>* boundedUntilFormula = new storm::properties::BoundedUntil<double>(new storm::properties::Ap<double>("true"), apFormula, 20); + probFormula = new storm::properties::ProbabilisticNoBoundOperator<double>(boundedUntilFormula); result = probFormula->check(mc); @@ -153,9 +153,9 @@ TEST(EigenDtmcPrctlModelCheckerTest, SynchronousLeader) { delete probFormula; delete result; - apFormula = new storm::property::Ap<double>("elected"); - storm::property::ReachabilityReward<double>* reachabilityRewardFormula = new storm::property::ReachabilityReward<double>(apFormula); - storm::property::RewardNoBoundOperator<double>* rewardFormula = new storm::property::RewardNoBoundOperator<double>(reachabilityRewardFormula); + apFormula = new storm::properties::Ap<double>("elected"); + storm::properties::ReachabilityReward<double>* reachabilityRewardFormula = new storm::properties::ReachabilityReward<double>(apFormula); + storm::properties::RewardNoBoundOperator<double>* rewardFormula = new storm::properties::RewardNoBoundOperator<double>(reachabilityRewardFormula); result = rewardFormula->check(mc); diff --git a/test/functional/modelchecker/FilterTest.cpp b/test/functional/modelchecker/FilterTest.cpp index ffbd11978..f85382bbb 100644 --- a/test/functional/modelchecker/FilterTest.cpp +++ b/test/functional/modelchecker/FilterTest.cpp @@ -13,17 +13,17 @@ #include "src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h" #include "src/solver/GmmxxLinearEquationSolver.h" #include "src/solver/GmmxxNondeterministicLinearEquationSolver.h" -#include "src/formula/prctl/PrctlFilter.h" -#include "src/formula/csl/CslFilter.h" -#include "src/formula/ltl/LtlFilter.h" +#include "src/properties/prctl/PrctlFilter.h" +#include "src/properties/csl/CslFilter.h" +#include "src/properties/ltl/LtlFilter.h" #include "src/parser/PrctlParser.h" #include "src/parser/CslParser.h" #include "src/parser/MarkovAutomatonParser.h" -#include "src/formula/actions/InvertAction.h" +#include "src/properties/actions/InvertAction.h" #include <memory> -typedef typename storm::property::action::AbstractAction<double>::Result Result; +typedef typename storm::properties::action::AbstractAction<double>::Result Result; TEST(PrctlFilterTest, generalFunctionality) { // Test filter queries of increasing complexity. @@ -34,7 +34,7 @@ TEST(PrctlFilterTest, generalFunctionality) { // Find the best valued state to finally reach a 'b' state. std::string input = "filter[sort(value, descending); range(0,0)](F b)"; - std::shared_ptr<storm::property::prctl::PrctlFilter<double>> formula(nullptr); + std::shared_ptr<storm::properties::prctl::PrctlFilter<double>> formula(nullptr); ASSERT_NO_THROW( formula = storm::parser::PrctlParser::parsePrctlFormula(input) ); @@ -151,26 +151,26 @@ TEST(PrctlFilterTest, Safety) { storm::modelchecker::prctl::SparseDtmcPrctlModelChecker<double> mc(model, new storm::solver::GmmxxLinearEquationSolver<double>()); // Make a stub formula as child. - auto apFormula = std::make_shared<storm::property::prctl::Ap<double>>("a"); + auto apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("a"); // Test the filter for nullptr action handling. - auto formula = std::make_shared<storm::property::prctl::PrctlFilter<double>>(apFormula, nullptr); + auto formula = std::make_shared<storm::properties::prctl::PrctlFilter<double>>(apFormula, nullptr); ASSERT_EQ(0, formula->getActionCount()); ASSERT_NO_THROW(formula->evaluate(mc)); // Repeat with vector containing only one action but three nullptr. - std::vector<std::shared_ptr<storm::property::action::AbstractAction<double>>> actions(4, nullptr); - actions[1] = std::make_shared<storm::property::action::InvertAction<double>>(); + std::vector<std::shared_ptr<storm::properties::action::AbstractAction<double>>> actions(4, nullptr); + actions[1] = std::make_shared<storm::properties::action::InvertAction<double>>(); - formula = std::make_shared<storm::property::prctl::PrctlFilter<double>>(apFormula, actions); + formula = std::make_shared<storm::properties::prctl::PrctlFilter<double>>(apFormula, actions); ASSERT_EQ(1, formula->getActionCount()); ASSERT_NO_THROW(formula->evaluate(mc)); // Test the filter for nullptr child formula handling. // It sholud not write anything to the standard out and return an empty result. - formula = std::make_shared<storm::property::prctl::PrctlFilter<double>>(); + formula = std::make_shared<storm::properties::prctl::PrctlFilter<double>>(); Result result; // To capture the output, redirect cout and test the written buffer content. @@ -200,7 +200,7 @@ TEST(CslFilterTest, generalFunctionality) { // Find the best valued state to finally reach a 'r1' state. std::string input = "filter[max; sort(value, descending); range(0,0)](F r1)"; - std::shared_ptr<storm::property::csl::CslFilter<double>> formula(nullptr); + std::shared_ptr<storm::properties::csl::CslFilter<double>> formula(nullptr); ASSERT_NO_THROW( formula = storm::parser::CslParser::parseCslFormula(input) ); @@ -317,26 +317,26 @@ TEST(CslFilterTest, Safety) { storm::modelchecker::csl::SparseMarkovAutomatonCslModelChecker<double> mc(model, std::make_shared<storm::solver::GmmxxNondeterministicLinearEquationSolver<double>>()); // Make a stub formula as child. - auto apFormula = std::make_shared<storm::property::csl::Ap<double>>("r1"); + auto apFormula = std::make_shared<storm::properties::csl::Ap<double>>("r1"); // Test the filter for nullptr action handling. - auto formula = std::make_shared<storm::property::csl::CslFilter<double>>(apFormula, nullptr, storm::property::MAXIMIZE); + auto formula = std::make_shared<storm::properties::csl::CslFilter<double>>(apFormula, nullptr, storm::properties::MAXIMIZE); ASSERT_NO_THROW(formula->evaluate(mc)); ASSERT_EQ(0, formula->getActionCount()); // Repeat with vector containing only one action but three nullptr. - std::vector<std::shared_ptr<storm::property::action::AbstractAction<double>>> actions(4, nullptr); - actions[1] = std::make_shared<storm::property::action::InvertAction<double>>(); + std::vector<std::shared_ptr<storm::properties::action::AbstractAction<double>>> actions(4, nullptr); + actions[1] = std::make_shared<storm::properties::action::InvertAction<double>>(); - formula = std::make_shared<storm::property::csl::CslFilter<double>>(apFormula, actions, storm::property::MAXIMIZE); + formula = std::make_shared<storm::properties::csl::CslFilter<double>>(apFormula, actions, storm::properties::MAXIMIZE); ASSERT_EQ(1, formula->getActionCount()); ASSERT_NO_THROW(formula->evaluate(mc)); // Test the filter for nullptr child formula handling. // It sholud not write anything to the standard out and return an empty result. - formula = std::make_shared<storm::property::csl::CslFilter<double>>(); + formula = std::make_shared<storm::properties::csl::CslFilter<double>>(); Result result; // To capture the output, redirect cout and test the written buffer content. diff --git a/test/functional/modelchecker/GmmxxDtmcPrctlModelCheckerTest.cpp b/test/functional/modelchecker/GmmxxDtmcPrctlModelCheckerTest.cpp index 15d0a7814..183072ce2 100644 --- a/test/functional/modelchecker/GmmxxDtmcPrctlModelCheckerTest.cpp +++ b/test/functional/modelchecker/GmmxxDtmcPrctlModelCheckerTest.cpp @@ -22,29 +22,29 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, Die) { storm::modelchecker::prctl::SparseDtmcPrctlModelChecker<double> mc(*dtmc, new storm::solver::GmmxxLinearEquationSolver<double>()); - auto apFormula = std::make_shared<storm::property::prctl::Ap<double>>("one"); - auto eventuallyFormula = std::make_shared<storm::property::prctl::Eventually<double>>(apFormula); + auto apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("one"); + auto eventuallyFormula = std::make_shared<storm::properties::prctl::Eventually<double>>(apFormula); std::vector<double> result = eventuallyFormula->check(mc, false); ASSERT_LT(std::abs(result[0] - ((double)1.0/6.0)), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - apFormula = std::make_shared<storm::property::prctl::Ap<double>>("two"); - eventuallyFormula = std::make_shared<storm::property::prctl::Eventually<double>>(apFormula); + apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("two"); + eventuallyFormula = std::make_shared<storm::properties::prctl::Eventually<double>>(apFormula); result = eventuallyFormula->check(mc, false); ASSERT_LT(std::abs(result[0] - ((double)1.0/6.0)), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - apFormula = std::make_shared<storm::property::prctl::Ap<double>>("three"); - eventuallyFormula = std::make_shared<storm::property::prctl::Eventually<double>>(apFormula); + apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("three"); + eventuallyFormula = std::make_shared<storm::properties::prctl::Eventually<double>>(apFormula); result = eventuallyFormula->check(mc, false); ASSERT_LT(std::abs(result[0] - ((double)1.0/6.0)), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - auto done = std::make_shared<storm::property::prctl::Ap<double>>("done"); - auto reachabilityRewardFormula = std::make_shared<storm::property::prctl::ReachabilityReward<double>>(done); + auto done = std::make_shared<storm::properties::prctl::Ap<double>>("done"); + auto reachabilityRewardFormula = std::make_shared<storm::properties::prctl::ReachabilityReward<double>>(done); result = reachabilityRewardFormula->check(mc, false); @@ -66,22 +66,22 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, Crowds) { storm::modelchecker::prctl::SparseDtmcPrctlModelChecker<double> mc(*dtmc, new storm::solver::GmmxxLinearEquationSolver<double>()); - auto apFormula = std::make_shared<storm::property::prctl::Ap<double>>("observe0Greater1"); - auto eventuallyFormula = std::make_shared<storm::property::prctl::Eventually<double>>(apFormula); + auto apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("observe0Greater1"); + auto eventuallyFormula = std::make_shared<storm::properties::prctl::Eventually<double>>(apFormula); std::vector<double> result = eventuallyFormula->check(mc, false); ASSERT_LT(std::abs(result[0] - 0.3328800375801578281), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - apFormula = std::make_shared<storm::property::prctl::Ap<double>>("observeIGreater1"); - eventuallyFormula = std::make_shared<storm::property::prctl::Eventually<double>>(apFormula); + apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("observeIGreater1"); + eventuallyFormula = std::make_shared<storm::properties::prctl::Eventually<double>>(apFormula); result = eventuallyFormula->check(mc, false); ASSERT_LT(std::abs(result[0] - 0.1522194965), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - apFormula = std::make_shared<storm::property::prctl::Ap<double>>("observeOnlyTrueSender"); - eventuallyFormula = std::make_shared<storm::property::prctl::Eventually<double>>(apFormula); + apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("observeOnlyTrueSender"); + eventuallyFormula = std::make_shared<storm::properties::prctl::Eventually<double>>(apFormula); result = eventuallyFormula->check(mc, false); @@ -102,22 +102,22 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, SynchronousLeader) { storm::modelchecker::prctl::SparseDtmcPrctlModelChecker<double> mc(*dtmc, new storm::solver::GmmxxLinearEquationSolver<double>()); - auto apFormula = std::make_shared<storm::property::prctl::Ap<double>>("elected"); - auto eventuallyFormula = std::make_shared<storm::property::prctl::Eventually<double>>(apFormula); + auto apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("elected"); + auto eventuallyFormula = std::make_shared<storm::properties::prctl::Eventually<double>>(apFormula); std::vector<double> result = eventuallyFormula->check(mc, false); ASSERT_LT(std::abs(result[0] - 1.0), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - apFormula = std::make_shared<storm::property::prctl::Ap<double>>("elected"); - auto boundedUntilFormula = std::make_shared<storm::property::prctl::BoundedUntil<double>>(std::make_shared<storm::property::prctl::Ap<double>>("true"), apFormula, 20); + apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("elected"); + auto boundedUntilFormula = std::make_shared<storm::properties::prctl::BoundedUntil<double>>(std::make_shared<storm::properties::prctl::Ap<double>>("true"), apFormula, 20); result = boundedUntilFormula->check(mc, false); ASSERT_LT(std::abs(result[0] - 0.9999965911265462636), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - apFormula = std::make_shared<storm::property::prctl::Ap<double>>("elected"); - auto reachabilityRewardFormula = std::make_shared<storm::property::prctl::ReachabilityReward<double>>(apFormula); + apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("elected"); + auto reachabilityRewardFormula = std::make_shared<storm::properties::prctl::ReachabilityReward<double>>(apFormula); result = reachabilityRewardFormula->check(mc, false); diff --git a/test/functional/modelchecker/SparseMdpPrctlModelCheckerTest.cpp b/test/functional/modelchecker/SparseMdpPrctlModelCheckerTest.cpp index bc423ad02..0cb31fcec 100644 --- a/test/functional/modelchecker/SparseMdpPrctlModelCheckerTest.cpp +++ b/test/functional/modelchecker/SparseMdpPrctlModelCheckerTest.cpp @@ -19,8 +19,8 @@ TEST(SparseMdpPrctlModelCheckerTest, Dice) { storm::modelchecker::prctl::SparseMdpPrctlModelChecker<double> mc(*mdp, std::shared_ptr<storm::solver::NativeNondeterministicLinearEquationSolver<double>>(new storm::solver::NativeNondeterministicLinearEquationSolver<double>())); - auto apFormula = std::make_shared<storm::property::prctl::Ap<double>>("two"); - auto eventuallyFormula = std::make_shared<storm::property::prctl::Eventually<double>>(apFormula); + auto apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("two"); + auto eventuallyFormula = std::make_shared<storm::properties::prctl::Eventually<double>>(apFormula); std::vector<double> result = mc.checkOptimizingOperator(*eventuallyFormula, true); @@ -30,8 +30,8 @@ TEST(SparseMdpPrctlModelCheckerTest, Dice) { ASSERT_LT(std::abs(result[0] - 0.0277777612209320068), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - apFormula = std::make_shared<storm::property::prctl::Ap<double>>("three"); - eventuallyFormula = std::make_shared<storm::property::prctl::Eventually<double>>(apFormula); + apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("three"); + eventuallyFormula = std::make_shared<storm::properties::prctl::Eventually<double>>(apFormula); result = mc.checkOptimizingOperator(*eventuallyFormula, true); @@ -41,8 +41,8 @@ TEST(SparseMdpPrctlModelCheckerTest, Dice) { ASSERT_LT(std::abs(result[0] - 0.0555555224418640136), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - apFormula = std::make_shared<storm::property::prctl::Ap<double>>("four"); - eventuallyFormula = std::make_shared<storm::property::prctl::Eventually<double>>(apFormula); + apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("four"); + eventuallyFormula = std::make_shared<storm::properties::prctl::Eventually<double>>(apFormula); result = mc.checkOptimizingOperator(*eventuallyFormula, true); @@ -52,8 +52,8 @@ TEST(SparseMdpPrctlModelCheckerTest, Dice) { ASSERT_LT(std::abs(result[0] - 0.083333283662796020508), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - apFormula = std::make_shared<storm::property::prctl::Ap<double>>("done"); - auto reachabilityRewardFormula = std::make_shared<storm::property::prctl::ReachabilityReward<double>>(apFormula); + apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("done"); + auto reachabilityRewardFormula = std::make_shared<storm::properties::prctl::ReachabilityReward<double>>(apFormula); result = mc.checkOptimizingOperator(*reachabilityRewardFormula, true); @@ -71,8 +71,8 @@ TEST(SparseMdpPrctlModelCheckerTest, Dice) { storm::modelchecker::prctl::SparseMdpPrctlModelChecker<double> stateRewardModelChecker(*stateRewardMdp, std::shared_ptr<storm::solver::NativeNondeterministicLinearEquationSolver<double>>(new storm::solver::NativeNondeterministicLinearEquationSolver<double>())); - apFormula = std::make_shared<storm::property::prctl::Ap<double>>("done"); - reachabilityRewardFormula = std::make_shared<storm::property::prctl::ReachabilityReward<double>>(apFormula); + apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("done"); + reachabilityRewardFormula = std::make_shared<storm::properties::prctl::ReachabilityReward<double>>(apFormula); result = stateRewardModelChecker.checkOptimizingOperator(*reachabilityRewardFormula, true); @@ -90,8 +90,8 @@ TEST(SparseMdpPrctlModelCheckerTest, Dice) { storm::modelchecker::prctl::SparseMdpPrctlModelChecker<double> stateAndTransitionRewardModelChecker(*stateAndTransitionRewardMdp, std::shared_ptr<storm::solver::NativeNondeterministicLinearEquationSolver<double>>(new storm::solver::NativeNondeterministicLinearEquationSolver<double>())); - apFormula = std::make_shared<storm::property::prctl::Ap<double>>("done"); - reachabilityRewardFormula = std::make_shared<storm::property::prctl::ReachabilityReward<double>>(apFormula); + apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("done"); + reachabilityRewardFormula = std::make_shared<storm::properties::prctl::ReachabilityReward<double>>(apFormula); result = stateAndTransitionRewardModelChecker.checkOptimizingOperator(*reachabilityRewardFormula, true); @@ -115,8 +115,8 @@ TEST(SparseMdpPrctlModelCheckerTest, AsynchronousLeader) { storm::modelchecker::prctl::SparseMdpPrctlModelChecker<double> mc(*mdp, std::shared_ptr<storm::solver::NativeNondeterministicLinearEquationSolver<double>>(new storm::solver::NativeNondeterministicLinearEquationSolver<double>())); - auto apFormula = std::make_shared<storm::property::prctl::Ap<double>>("elected"); - auto eventuallyFormula = std::make_shared<storm::property::prctl::Eventually<double>>(apFormula); + auto apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("elected"); + auto eventuallyFormula = std::make_shared<storm::properties::prctl::Eventually<double>>(apFormula); std::vector<double> result = mc.checkOptimizingOperator(*eventuallyFormula, true); @@ -126,8 +126,8 @@ TEST(SparseMdpPrctlModelCheckerTest, AsynchronousLeader) { ASSERT_LT(std::abs(result[0] - 1), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - apFormula = std::make_shared<storm::property::prctl::Ap<double>>("elected"); - auto boundedEventuallyFormula = std::make_shared<storm::property::prctl::BoundedEventually<double>>(apFormula, 25); + apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("elected"); + auto boundedEventuallyFormula = std::make_shared<storm::properties::prctl::BoundedEventually<double>>(apFormula, 25); result = mc.checkOptimizingOperator(*boundedEventuallyFormula, true); @@ -137,8 +137,8 @@ TEST(SparseMdpPrctlModelCheckerTest, AsynchronousLeader) { ASSERT_LT(std::abs(result[0] - 0.0625), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - apFormula = std::make_shared<storm::property::prctl::Ap<double>>("elected"); - auto reachabilityRewardFormula = std::make_shared<storm::property::prctl::ReachabilityReward<double>>(apFormula); + apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("elected"); + auto reachabilityRewardFormula = std::make_shared<storm::properties::prctl::ReachabilityReward<double>>(apFormula); result = mc.checkOptimizingOperator(*reachabilityRewardFormula, true); diff --git a/test/functional/parser/CslParserTest.cpp b/test/functional/parser/CslParserTest.cpp index ecff80e4d..42b805ac4 100644 --- a/test/functional/parser/CslParserTest.cpp +++ b/test/functional/parser/CslParserTest.cpp @@ -9,13 +9,13 @@ #include "storm-config.h" #include "src/parser/CslParser.h" #include "src/exceptions/WrongFormatException.h" -#include "src/formula/actions/FormulaAction.h" -#include "src/formula/actions/InvertAction.h" -#include "src/formula/actions/SortAction.h" -#include "src/formula/actions/RangeAction.h" -#include "src/formula/actions/BoundAction.h" +#include "src/properties/actions/FormulaAction.h" +#include "src/properties/actions/InvertAction.h" +#include "src/properties/actions/SortAction.h" +#include "src/properties/actions/RangeAction.h" +#include "src/properties/actions/BoundAction.h" -namespace csl = storm::property::csl; +namespace csl = storm::properties::csl; TEST(CslParserTest, parseApOnlyTest) { std::string input = "ap"; @@ -70,7 +70,7 @@ TEST(CslParserTest, parsePathFormulaTest) { ASSERT_NE(std::dynamic_pointer_cast<csl::ProbabilisticBoundOperator<double>>(nextFormula->getChild()).get(), nullptr); auto probBoundFormula = std::dynamic_pointer_cast<csl::ProbabilisticBoundOperator<double>>(nextFormula->getChild()); ASSERT_EQ(0.9, probBoundFormula->getBound()); - ASSERT_EQ(storm::property::LESS, probBoundFormula->getComparisonOperator()); + ASSERT_EQ(storm::properties::LESS, probBoundFormula->getComparisonOperator()); ASSERT_FALSE(probBoundFormula->isPropositional()); ASSERT_TRUE(probBoundFormula->isProbEventuallyAP()); @@ -99,9 +99,9 @@ TEST(CslParserTest, parseProbabilisticFormulaTest) { // The parser did not falsely recognize the input as a comment. ASSERT_NE(formula.get(), nullptr); - auto op = std::dynamic_pointer_cast<storm::property::csl::ProbabilisticBoundOperator<double>>(formula->getChild()); + auto op = std::dynamic_pointer_cast<storm::properties::csl::ProbabilisticBoundOperator<double>>(formula->getChild()); ASSERT_NE(op.get(), nullptr); - ASSERT_EQ(storm::property::GREATER, op->getComparisonOperator()); + ASSERT_EQ(storm::properties::GREATER, op->getComparisonOperator()); ASSERT_EQ(0.5, op->getBound()); ASSERT_FALSE(op->isPropositional()); ASSERT_TRUE(op->isProbEventuallyAP()); @@ -120,9 +120,9 @@ TEST(CslParserTest, parseSteadyStateBoundFormulaTest) { // The parser did not falsely recognize the input as a comment. ASSERT_NE(formula.get(), nullptr); - auto op = std::dynamic_pointer_cast<storm::property::csl::SteadyStateBoundOperator<double>>(formula->getChild()); + auto op = std::dynamic_pointer_cast<storm::properties::csl::SteadyStateBoundOperator<double>>(formula->getChild()); ASSERT_NE(op.get(), nullptr); - ASSERT_EQ(storm::property::GREATER_EQUAL, op->getComparisonOperator()); + ASSERT_EQ(storm::properties::GREATER_EQUAL, op->getComparisonOperator()); ASSERT_EQ(15.0, op->getBound()); ASSERT_FALSE(op->isPropositional()); ASSERT_FALSE(op->isProbEventuallyAP()); @@ -193,14 +193,14 @@ TEST(CslParserTest, parseCslFilterTest) { // The parser did not falsely recognize the input as a comment. ASSERT_NE(formula, nullptr); - ASSERT_EQ(storm::property::MAXIMIZE, formula->getOptimizingOperator()); + ASSERT_EQ(storm::properties::MAXIMIZE, formula->getOptimizingOperator()); ASSERT_EQ(5, formula->getActionCount()); - ASSERT_NE(std::dynamic_pointer_cast<storm::property::action::FormulaAction<double>>(formula->getAction(0)).get(), nullptr); - ASSERT_NE(std::dynamic_pointer_cast<storm::property::action::InvertAction<double>>(formula->getAction(1)).get(), nullptr); - ASSERT_NE(std::dynamic_pointer_cast<storm::property::action::BoundAction<double>>(formula->getAction(2)).get(), nullptr); - ASSERT_NE(std::dynamic_pointer_cast<storm::property::action::SortAction<double>>(formula->getAction(3)).get(), nullptr); - ASSERT_NE(std::dynamic_pointer_cast<storm::property::action::RangeAction<double>>(formula->getAction(4)).get(), nullptr); + ASSERT_NE(std::dynamic_pointer_cast<storm::properties::action::FormulaAction<double>>(formula->getAction(0)).get(), nullptr); + ASSERT_NE(std::dynamic_pointer_cast<storm::properties::action::InvertAction<double>>(formula->getAction(1)).get(), nullptr); + ASSERT_NE(std::dynamic_pointer_cast<storm::properties::action::BoundAction<double>>(formula->getAction(2)).get(), nullptr); + ASSERT_NE(std::dynamic_pointer_cast<storm::properties::action::SortAction<double>>(formula->getAction(3)).get(), nullptr); + ASSERT_NE(std::dynamic_pointer_cast<storm::properties::action::RangeAction<double>>(formula->getAction(4)).get(), nullptr); ASSERT_FALSE(formula->getChild()->isPropositional()); ASSERT_FALSE(formula->getChild()->isProbEventuallyAP()); diff --git a/test/functional/parser/LtlParserTest.cpp b/test/functional/parser/LtlParserTest.cpp index e44f84f0e..d13c48688 100644 --- a/test/functional/parser/LtlParserTest.cpp +++ b/test/functional/parser/LtlParserTest.cpp @@ -9,16 +9,16 @@ #include "storm-config.h" #include "src/parser/LtlParser.h" #include "src/exceptions/WrongFormatException.h" -#include "src/formula/actions/InvertAction.h" -#include "src/formula/actions/SortAction.h" -#include "src/formula/actions/RangeAction.h" -#include "src/formula/actions/BoundAction.h" +#include "src/properties/actions/InvertAction.h" +#include "src/properties/actions/SortAction.h" +#include "src/properties/actions/RangeAction.h" +#include "src/properties/actions/BoundAction.h" -namespace ltl = storm::property::ltl; +namespace ltl = storm::properties::ltl; TEST(LtlParserTest, parseApOnlyTest) { std::string input = "ap"; - std::shared_ptr<storm::property::ltl::LtlFilter<double>> formula(nullptr); + std::shared_ptr<storm::properties::ltl::LtlFilter<double>> formula(nullptr); ASSERT_NO_THROW( formula = storm::parser::LtlParser::parseLtlFormula(input); ); @@ -87,7 +87,7 @@ TEST(LtlParserTest, parseBoundedEventuallyFormulaTest) { ASSERT_FALSE(formula->getChild()->isPropositional()); - std::shared_ptr<storm::property::ltl::BoundedEventually<double>> op = std::dynamic_pointer_cast<storm::property::ltl::BoundedEventually<double>>(formula->getChild()); + std::shared_ptr<storm::properties::ltl::BoundedEventually<double>> op = std::dynamic_pointer_cast<storm::properties::ltl::BoundedEventually<double>>(formula->getChild()); ASSERT_NE(op.get(), nullptr); ASSERT_EQ(static_cast<uint_fast64_t>(5), op->getBound()); @@ -106,7 +106,7 @@ TEST(LtlParserTest, parseBoundedUntilFormulaTest) { ASSERT_FALSE(formula->getChild()->isPropositional()); - std::shared_ptr<storm::property::ltl::BoundedUntil<double>> op = std::dynamic_pointer_cast<storm::property::ltl::BoundedUntil<double>>(formula->getChild()); + std::shared_ptr<storm::properties::ltl::BoundedUntil<double>> op = std::dynamic_pointer_cast<storm::properties::ltl::BoundedUntil<double>>(formula->getChild()); ASSERT_NE(op.get(), nullptr); ASSERT_EQ(static_cast<uint_fast64_t>(3), op->getBound()); @@ -126,13 +126,13 @@ TEST(LtlParserTest, parseLtlFilterTest) { ASSERT_FALSE(formula->getChild()->isPropositional()); - ASSERT_EQ(storm::property::MAXIMIZE, formula->getOptimizingOperator()); + ASSERT_EQ(storm::properties::MAXIMIZE, formula->getOptimizingOperator()); ASSERT_EQ(4, formula->getActionCount()); - ASSERT_NE(std::dynamic_pointer_cast<storm::property::action::InvertAction<double>>(formula->getAction(0)).get(), nullptr); - ASSERT_NE(std::dynamic_pointer_cast<storm::property::action::BoundAction<double>>(formula->getAction(1)).get(), nullptr); - ASSERT_NE(std::dynamic_pointer_cast<storm::property::action::SortAction<double>>(formula->getAction(2)).get(), nullptr); - ASSERT_NE(std::dynamic_pointer_cast<storm::property::action::RangeAction<double>>(formula->getAction(3)).get(), nullptr); + ASSERT_NE(std::dynamic_pointer_cast<storm::properties::action::InvertAction<double>>(formula->getAction(0)).get(), nullptr); + ASSERT_NE(std::dynamic_pointer_cast<storm::properties::action::BoundAction<double>>(formula->getAction(1)).get(), nullptr); + ASSERT_NE(std::dynamic_pointer_cast<storm::properties::action::SortAction<double>>(formula->getAction(2)).get(), nullptr); + ASSERT_NE(std::dynamic_pointer_cast<storm::properties::action::RangeAction<double>>(formula->getAction(3)).get(), nullptr); // The input was parsed correctly. ASSERT_EQ("filter[max; invert; bound(<, 0.500000); sort(value, ascending); range(0, 3)](X a)", formula->toString()); diff --git a/test/functional/parser/PrctlParserTest.cpp b/test/functional/parser/PrctlParserTest.cpp index 1a63495d0..22e52e7d1 100644 --- a/test/functional/parser/PrctlParserTest.cpp +++ b/test/functional/parser/PrctlParserTest.cpp @@ -10,13 +10,13 @@ #include "storm-config.h" #include "src/parser/PrctlParser.h" #include "src/exceptions/WrongFormatException.h" -#include "src/formula/actions/FormulaAction.h" -#include "src/formula/actions/InvertAction.h" -#include "src/formula/actions/SortAction.h" -#include "src/formula/actions/RangeAction.h" -#include "src/formula/actions/BoundAction.h" +#include "src/properties/actions/FormulaAction.h" +#include "src/properties/actions/InvertAction.h" +#include "src/properties/actions/SortAction.h" +#include "src/properties/actions/RangeAction.h" +#include "src/properties/actions/BoundAction.h" -namespace prctl = storm::property::prctl; +namespace prctl = storm::properties::prctl; TEST(PrctlParserTest, parseApOnlyTest) { std::string input = "ap"; @@ -71,7 +71,7 @@ TEST(PrctlParserTest, parsePathFormulaTest) { ASSERT_NE(std::dynamic_pointer_cast<prctl::ProbabilisticBoundOperator<double>>(nextFormula->getChild()).get(), nullptr); auto probBoundFormula = std::dynamic_pointer_cast<prctl::ProbabilisticBoundOperator<double>>(nextFormula->getChild()); ASSERT_EQ(0.9, probBoundFormula->getBound()); - ASSERT_EQ(storm::property::LESS, probBoundFormula->getComparisonOperator()); + ASSERT_EQ(storm::properties::LESS, probBoundFormula->getComparisonOperator()); ASSERT_FALSE(probBoundFormula->isPropositional()); ASSERT_TRUE(probBoundFormula->isProbEventuallyAP()); @@ -103,7 +103,7 @@ TEST(PrctlParserTest, parseProbabilisticFormulaTest) { ASSERT_NE(std::dynamic_pointer_cast<prctl::ProbabilisticBoundOperator<double>>(formula->getChild()).get(), nullptr); std::shared_ptr<prctl::ProbabilisticBoundOperator<double>> op = std::static_pointer_cast<prctl::ProbabilisticBoundOperator<double>>(formula->getChild()); - ASSERT_EQ(storm::property::GREATER, op->getComparisonOperator()); + ASSERT_EQ(storm::properties::GREATER, op->getComparisonOperator()); ASSERT_EQ(0.5, op->getBound()); ASSERT_FALSE(op->isPropositional()); ASSERT_TRUE(op->isProbEventuallyAP()); @@ -125,7 +125,7 @@ TEST(PrctlParserTest, parseRewardFormulaTest) { ASSERT_NE(std::dynamic_pointer_cast<prctl::RewardBoundOperator<double>>(formula->getChild()).get(), nullptr); std::shared_ptr<prctl::RewardBoundOperator<double>> op = std::static_pointer_cast<prctl::RewardBoundOperator<double>>(formula->getChild()); - ASSERT_EQ(storm::property::GREATER_EQUAL, op->getComparisonOperator()); + ASSERT_EQ(storm::properties::GREATER_EQUAL, op->getComparisonOperator()); ASSERT_EQ(15.0, op->getBound()); ASSERT_FALSE(op->isPropositional()); ASSERT_FALSE(op->isProbEventuallyAP()); @@ -195,14 +195,14 @@ TEST(PrctlParserTest, parsePrctlFilterTest) { // The parser did not falsely recognize the input as a comment. ASSERT_NE(formula.get(), nullptr); - ASSERT_EQ(storm::property::MAXIMIZE, formula->getOptimizingOperator()); + ASSERT_EQ(storm::properties::MAXIMIZE, formula->getOptimizingOperator()); ASSERT_EQ(5, formula->getActionCount()); - ASSERT_NE(std::dynamic_pointer_cast<storm::property::action::FormulaAction<double>>(formula->getAction(0)).get(), nullptr); - ASSERT_NE(std::dynamic_pointer_cast<storm::property::action::InvertAction<double>>(formula->getAction(1)).get(), nullptr); - ASSERT_NE(std::dynamic_pointer_cast<storm::property::action::BoundAction<double>>(formula->getAction(2)).get(), nullptr); - ASSERT_NE(std::dynamic_pointer_cast<storm::property::action::SortAction<double>>(formula->getAction(3)).get(), nullptr); - ASSERT_NE(std::dynamic_pointer_cast<storm::property::action::RangeAction<double>>(formula->getAction(4)).get(), nullptr); + ASSERT_NE(std::dynamic_pointer_cast<storm::properties::action::FormulaAction<double>>(formula->getAction(0)).get(), nullptr); + ASSERT_NE(std::dynamic_pointer_cast<storm::properties::action::InvertAction<double>>(formula->getAction(1)).get(), nullptr); + ASSERT_NE(std::dynamic_pointer_cast<storm::properties::action::BoundAction<double>>(formula->getAction(2)).get(), nullptr); + ASSERT_NE(std::dynamic_pointer_cast<storm::properties::action::SortAction<double>>(formula->getAction(3)).get(), nullptr); + ASSERT_NE(std::dynamic_pointer_cast<storm::properties::action::RangeAction<double>>(formula->getAction(4)).get(), nullptr); ASSERT_FALSE(formula->getChild()->isPropositional()); ASSERT_FALSE(formula->getChild()->isProbEventuallyAP()); diff --git a/test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp b/test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp index 2d2850ac2..1b6b5e5c8 100644 --- a/test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp +++ b/test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp @@ -21,8 +21,8 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, Crowds) { storm::modelchecker::prctl::SparseDtmcPrctlModelChecker<double> mc(*dtmc, new storm::solver::GmmxxLinearEquationSolver<double>()); - auto apFormula = std::make_shared<storm::property::prctl::Ap<double>>("observe0Greater1"); - auto eventuallyFormula = std::make_shared<storm::property::prctl::Eventually<double>>(apFormula); + auto apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("observe0Greater1"); + auto eventuallyFormula = std::make_shared<storm::properties::prctl::Eventually<double>>(apFormula); LOG4CPLUS_WARN(logger, "Model Checking P=? [F observe0Greater1] on crowds/crowds20_5..."); std::vector<double> result = eventuallyFormula->check(mc, false); @@ -30,8 +30,8 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, Crowds) { ASSERT_LT(std::abs(result[0] - 0.2296800237), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - apFormula = std::make_shared<storm::property::prctl::Ap<double>>("observeIGreater1"); - eventuallyFormula = std::make_shared<storm::property::prctl::Eventually<double>>(apFormula); + apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("observeIGreater1"); + eventuallyFormula = std::make_shared<storm::properties::prctl::Eventually<double>>(apFormula); LOG4CPLUS_WARN(logger, "Model Checking P=? [F observeIGreater1] on crowds/crowds20_5..."); result = eventuallyFormula->check(mc, false); @@ -39,8 +39,8 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, Crowds) { ASSERT_LT(std::abs(result[0] - 0.05073232193), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - apFormula = std::make_shared<storm::property::prctl::Ap<double>>("observeOnlyTrueSender"); - eventuallyFormula = std::make_shared<storm::property::prctl::Eventually<double>>(apFormula); + apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("observeOnlyTrueSender"); + eventuallyFormula = std::make_shared<storm::properties::prctl::Eventually<double>>(apFormula); LOG4CPLUS_WARN(logger, "Model Checking P=? [F observeOnlyTrueSender] on crowds/crowds20_5..."); result = eventuallyFormula->check(mc, false); @@ -65,8 +65,8 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, SynchronousLeader) { storm::modelchecker::prctl::SparseDtmcPrctlModelChecker<double> mc(*dtmc, new storm::solver::GmmxxLinearEquationSolver<double>()); - auto apFormula = std::make_shared<storm::property::prctl::Ap<double>>("elected"); - auto eventuallyFormula = std::make_shared<storm::property::prctl::Eventually<double>>(apFormula); + auto apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("elected"); + auto eventuallyFormula = std::make_shared<storm::properties::prctl::Eventually<double>>(apFormula); LOG4CPLUS_WARN(logger, "Model Checking P=? [F elected] on synchronous_leader/leader6_8..."); std::vector<double> result = eventuallyFormula->check(mc, false); @@ -74,8 +74,8 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, SynchronousLeader) { ASSERT_LT(std::abs(result[0] - 1.0), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - apFormula = std::make_shared<storm::property::prctl::Ap<double>>("elected"); - auto boundedUntilFormula = std::make_shared<storm::property::prctl::BoundedUntil<double>>(std::make_shared<storm::property::prctl::Ap<double>>("true"), apFormula, 20); + apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("elected"); + auto boundedUntilFormula = std::make_shared<storm::properties::prctl::BoundedUntil<double>>(std::make_shared<storm::properties::prctl::Ap<double>>("true"), apFormula, 20); LOG4CPLUS_WARN(logger, "Model Checking P=? [F<=20 elected] on synchronous_leader/leader6_8..."); result = boundedUntilFormula->check(mc, false); @@ -83,8 +83,8 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, SynchronousLeader) { ASSERT_LT(std::abs(result[0] - 0.9993949793), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - apFormula = std::make_shared<storm::property::prctl::Ap<double>>("elected"); - auto reachabilityRewardFormula = std::make_shared<storm::property::prctl::ReachabilityReward<double>>(apFormula); + apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("elected"); + auto reachabilityRewardFormula = std::make_shared<storm::properties::prctl::ReachabilityReward<double>>(apFormula); LOG4CPLUS_WARN(logger, "Model Checking R=? [F elected] on synchronous_leader/leader6_8..."); result = reachabilityRewardFormula->check(mc, false); diff --git a/test/performance/modelchecker/SparseMdpPrctlModelCheckerTest.cpp b/test/performance/modelchecker/SparseMdpPrctlModelCheckerTest.cpp index 3152e0b6d..0a177b588 100644 --- a/test/performance/modelchecker/SparseMdpPrctlModelCheckerTest.cpp +++ b/test/performance/modelchecker/SparseMdpPrctlModelCheckerTest.cpp @@ -19,8 +19,8 @@ TEST(SparseMdpPrctlModelCheckerTest, AsynchronousLeader) { storm::modelchecker::prctl::SparseMdpPrctlModelChecker<double> mc(*mdp, std::shared_ptr<storm::solver::NativeNondeterministicLinearEquationSolver<double>>(new storm::solver::NativeNondeterministicLinearEquationSolver<double>())); - auto apFormula = std::make_shared<storm::property::prctl::Ap<double>>("elected"); - auto eventuallyFormula = std::make_shared<storm::property::prctl::Eventually<double>>(apFormula); + auto apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("elected"); + auto eventuallyFormula = std::make_shared<storm::properties::prctl::Eventually<double>>(apFormula); std::vector<double> result = mc.checkOptimizingOperator(*eventuallyFormula, true); @@ -30,8 +30,8 @@ TEST(SparseMdpPrctlModelCheckerTest, AsynchronousLeader) { ASSERT_LT(std::abs(result[0] - 1.0), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - apFormula = std::make_shared<storm::property::prctl::Ap<double>>("elected"); - auto boundedEventuallyFormula = std::make_shared<storm::property::prctl::BoundedEventually<double>>(apFormula, 25); + apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("elected"); + auto boundedEventuallyFormula = std::make_shared<storm::properties::prctl::BoundedEventually<double>>(apFormula, 25); result = mc.checkOptimizingOperator(*boundedEventuallyFormula, true); @@ -41,8 +41,8 @@ TEST(SparseMdpPrctlModelCheckerTest, AsynchronousLeader) { ASSERT_LT(std::abs(result[0] - 0.0), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - apFormula = std::make_shared<storm::property::prctl::Ap<double>>("elected"); - auto reachabilityRewardFormula = std::make_shared<storm::property::prctl::ReachabilityReward<double>>(apFormula); + apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("elected"); + auto reachabilityRewardFormula = std::make_shared<storm::properties::prctl::ReachabilityReward<double>>(apFormula); result = mc.checkOptimizingOperator(*reachabilityRewardFormula, true); @@ -69,43 +69,43 @@ TEST(SparseMdpPrctlModelCheckerTest, Consensus) { storm::modelchecker::prctl::SparseMdpPrctlModelChecker<double> mc(*mdp, std::shared_ptr<storm::solver::NativeNondeterministicLinearEquationSolver<double>>(new storm::solver::NativeNondeterministicLinearEquationSolver<double>())); - auto apFormula = std::make_shared<storm::property::prctl::Ap<double>>("finished"); - auto eventuallyFormula = std::make_shared<storm::property::prctl::Eventually<double>>(apFormula); + auto apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("finished"); + auto eventuallyFormula = std::make_shared<storm::properties::prctl::Eventually<double>>(apFormula); std::vector<double> result = mc.checkOptimizingOperator(*eventuallyFormula, true); ASSERT_LT(std::abs(result[31168] - 1.0), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - apFormula = std::make_shared<storm::property::prctl::Ap<double>>("finished"); - auto apFormula2 = std::make_shared<storm::property::prctl::Ap<double>>("all_coins_equal_0"); - auto andFormula = std::make_shared<storm::property::prctl::And<double>>(apFormula, apFormula2); - eventuallyFormula = std::make_shared<storm::property::prctl::Eventually<double>>(andFormula); + apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("finished"); + auto apFormula2 = std::make_shared<storm::properties::prctl::Ap<double>>("all_coins_equal_0"); + auto andFormula = std::make_shared<storm::properties::prctl::And<double>>(apFormula, apFormula2); + eventuallyFormula = std::make_shared<storm::properties::prctl::Eventually<double>>(andFormula); result = mc.checkOptimizingOperator(*eventuallyFormula, true); ASSERT_LT(std::abs(result[31168] - 0.4374282832), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - apFormula = std::make_shared<storm::property::prctl::Ap<double>>("finished"); - apFormula2 = std::make_shared<storm::property::prctl::Ap<double>>("all_coins_equal_1"); - andFormula = std::make_shared<storm::property::prctl::And<double>>(apFormula, apFormula2); - eventuallyFormula = std::make_shared<storm::property::prctl::Eventually<double>>(andFormula); + apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("finished"); + apFormula2 = std::make_shared<storm::properties::prctl::Ap<double>>("all_coins_equal_1"); + andFormula = std::make_shared<storm::properties::prctl::And<double>>(apFormula, apFormula2); + eventuallyFormula = std::make_shared<storm::properties::prctl::Eventually<double>>(andFormula); result = mc.checkOptimizingOperator(*eventuallyFormula, false); ASSERT_LT(std::abs(result[31168] - 0.5293286369), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - apFormula = std::make_shared<storm::property::prctl::Ap<double>>("finished"); - apFormula2 = std::make_shared<storm::property::prctl::Ap<double>>("agree"); - auto notFormula = std::make_shared<storm::property::prctl::Not<double>>(apFormula2); - andFormula = std::make_shared<storm::property::prctl::And<double>>(apFormula, notFormula); - eventuallyFormula = std::make_shared<storm::property::prctl::Eventually<double>>(andFormula); + apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("finished"); + apFormula2 = std::make_shared<storm::properties::prctl::Ap<double>>("agree"); + auto notFormula = std::make_shared<storm::properties::prctl::Not<double>>(apFormula2); + andFormula = std::make_shared<storm::properties::prctl::And<double>>(apFormula, notFormula); + eventuallyFormula = std::make_shared<storm::properties::prctl::Eventually<double>>(andFormula); result = mc.checkOptimizingOperator(*eventuallyFormula, false); ASSERT_LT(std::abs(result[31168] - 0.10414097), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - apFormula = std::make_shared<storm::property::prctl::Ap<double>>("finished"); - auto boundedEventuallyFormula = std::make_shared<storm::property::prctl::BoundedEventually<double>>(apFormula, 50ull); + apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("finished"); + auto boundedEventuallyFormula = std::make_shared<storm::properties::prctl::BoundedEventually<double>>(apFormula, 50ull); result = mc.checkOptimizingOperator(*boundedEventuallyFormula, true); @@ -115,8 +115,8 @@ TEST(SparseMdpPrctlModelCheckerTest, Consensus) { ASSERT_LT(std::abs(result[31168] - 0.0), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - apFormula = std::make_shared<storm::property::prctl::Ap<double>>("finished"); - auto reachabilityRewardFormula = std::make_shared<storm::property::prctl::ReachabilityReward<double>>(apFormula); + apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("finished"); + auto reachabilityRewardFormula = std::make_shared<storm::properties::prctl::ReachabilityReward<double>>(apFormula); result = mc.checkOptimizingOperator(*reachabilityRewardFormula, true); From 52cfe9f02d7178118e8497c82422660bb7701059 Mon Sep 17 00:00:00 2001 From: masawei <manuel.sascha.weiand@rwth-aachen.de> Date: Fri, 29 Aug 2014 15:15:15 +0200 Subject: [PATCH 30/30] Fixed some compile errors. - Added a missing inlude (boost/functional/hash.hpp) to SparseMatrix.h. I don't know how this could have been compiled without. - Changed a return type in the stub section of the GurobiLpSolver to void. Not correctly overwrites the base class function. - Went through the change history of the SparseMarkovAutomatonCslModelchecker.h to correctly integrate all changes made in this branch with the changes of the other branches. Former-commit-id: 43ce12274b2531d0a1db75959cda10cea010e344 --- .../MILPMinimalLabelSetGenerator.h | 18 +-- .../SparseMarkovAutomatonCslModelChecker.h | 105 ++++++++++++------ src/solver/GurobiLpSolver.h | 2 +- src/storage/SparseMatrix.h | 2 + 4 files changed, 84 insertions(+), 43 deletions(-) diff --git a/src/counterexamples/MILPMinimalLabelSetGenerator.h b/src/counterexamples/MILPMinimalLabelSetGenerator.h index 516166fd0..a4c8707c7 100644 --- a/src/counterexamples/MILPMinimalLabelSetGenerator.h +++ b/src/counterexamples/MILPMinimalLabelSetGenerator.h @@ -988,35 +988,35 @@ namespace storm { static void computeCounterexample(storm::prism::Program const& program, storm::models::Mdp<T> const& labeledMdp, std::shared_ptr<storm::properties::prctl::AbstractPrctlFormula<double>> const & formulaPtr) { std::cout << std::endl << "Generating minimal label counterexample for formula " << formulaPtr->toString() << std::endl; // First, we need to check whether the current formula is an Until-Formula. - storm::property::prctl::ProbabilisticBoundOperator<double> const* probBoundFormula = dynamic_cast<storm::property::prctl::ProbabilisticBoundOperator<double> const*>(formulaPtr); + auto probBoundFormula = std::dynamic_pointer_cast<storm::properties::prctl::ProbabilisticBoundOperator<double>>(formulaPtr); if (probBoundFormula == nullptr) { LOG4CPLUS_ERROR(logger, "Illegal formula " << probBoundFormula->toString() << " for counterexample generation."); throw storm::exceptions::InvalidPropertyException() << "Illegal formula " << probBoundFormula->toString() << " for counterexample generation."; } - if (probBoundFormula->getComparisonOperator() != storm::property::ComparisonType::LESS && probBoundFormula->getComparisonOperator() != storm::property::ComparisonType::LESS_EQUAL) { + if (probBoundFormula->getComparisonOperator() != storm::properties::ComparisonType::LESS && probBoundFormula->getComparisonOperator() != storm::properties::ComparisonType::LESS_EQUAL) { LOG4CPLUS_ERROR(logger, "Illegal comparison operator in formula " << probBoundFormula->toString() << ". Only upper bounds are supported for counterexample generation."); throw storm::exceptions::InvalidPropertyException() << "Illegal comparison operator in formula " << probBoundFormula->toString() << ". Only upper bounds are supported for counterexample generation."; } - bool strictBound = !(probBoundFormula->getComparisonOperator() == storm::property::ComparisonType::LESS); + bool strictBound = !(probBoundFormula->getComparisonOperator() == storm::properties::ComparisonType::LESS); // Now derive the probability threshold we need to exceed as well as the phi and psi states. Simultaneously, check whether the formula is of a valid shape. double bound = probBoundFormula->getBound(); - storm::property::prctl::AbstractPathFormula<double> const& pathFormula = probBoundFormula->getPathFormula(); + std::shared_ptr<storm::properties::prctl::AbstractPathFormula<double>> pathFormula = probBoundFormula->getChild(); storm::storage::BitVector phiStates; storm::storage::BitVector psiStates; storm::modelchecker::prctl::SparseMdpPrctlModelChecker<T> modelchecker(labeledMdp); try { - storm::property::prctl::Until<double> const& untilFormula = dynamic_cast<storm::property::prctl::Until<double> const&>(pathFormula); + auto untilFormula = std::dynamic_pointer_cast<storm::properties::prctl::Until<double>>(pathFormula); - phiStates = untilFormula.getLeft().check(modelchecker); - psiStates = untilFormula.getRight().check(modelchecker); + phiStates = untilFormula->getLeft()->check(modelchecker); + psiStates = untilFormula->getRight()->check(modelchecker); } catch (std::bad_cast const&) { // If the nested formula was not an until formula, it remains to check whether it's an eventually formula. try { - storm::property::prctl::Eventually<double> const& eventuallyFormula = dynamic_cast<storm::property::prctl::Eventually<double> const&>(pathFormula); + auto eventuallyFormula = std::dynamic_pointer_cast<storm::properties::prctl::Eventually<double>>(pathFormula); phiStates = storm::storage::BitVector(labeledMdp.getNumberOfStates(), true); - psiStates = eventuallyFormula.getChild().check(modelchecker); + psiStates = eventuallyFormula->getChild()->check(modelchecker); } catch (std::bad_cast const&) { // If the nested formula is neither an until nor a finally formula, we throw an exception. throw storm::exceptions::InvalidPropertyException() << "Formula nested inside probability bound operator must be an until or eventually formula for counterexample generation."; diff --git a/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h b/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h index dbcf4d8b1..9b77821c2 100644 --- a/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h +++ b/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h @@ -1,7 +1,6 @@ #ifndef STORM_MODELCHECKER_CSL_SPARSEMARKOVAUTOMATONCSLMODELCHECKER_H_ #define STORM_MODELCHECKER_CSL_SPARSEMARKOVAUTOMATONCSLMODELCHECKER_H_ -#include <stack> #include <utility> #include "src/modelchecker/csl/AbstractModelChecker.h" @@ -22,7 +21,7 @@ namespace storm { template<typename ValueType> class SparseMarkovAutomatonCslModelChecker : public AbstractModelChecker<ValueType> { public: - explicit SparseMarkovAutomatonCslModelChecker(storm::models::MarkovAutomaton<ValueType> const& model, std::shared_ptr<storm::solver::NondeterministicLinearEquationSolver<ValueType>> nondeterministicLinearEquationSolver) : AbstractModelChecker<ValueType>(model), minimumOperatorStack(), nondeterministicLinearEquationSolver(nondeterministicLinearEquationSolver) { + explicit SparseMarkovAutomatonCslModelChecker(storm::models::MarkovAutomaton<ValueType> const& model, std::shared_ptr<storm::solver::NondeterministicLinearEquationSolver<ValueType>> nondeterministicLinearEquationSolver) : AbstractModelChecker<ValueType>(model), nondeterministicLinearEquationSolver(nondeterministicLinearEquationSolver) { // Intentionally left empty. } @@ -30,7 +29,14 @@ namespace storm { This Second constructor is NEEDED and a workaround for a common Bug in C++ with nested templates See: http://stackoverflow.com/questions/14401308/visual-c-cannot-deduce-given-template-arguments-for-function-used-as-defaul */ - explicit SparseMarkovAutomatonCslModelChecker(storm::models::MarkovAutomaton<ValueType> const& model) : AbstractModelChecker<ValueType>(model), minimumOperatorStack(), nondeterministicLinearEquationSolver(storm::utility::solver::getNondeterministicLinearEquationSolver<ValueType>()) { + explicit SparseMarkovAutomatonCslModelChecker(storm::models::MarkovAutomaton<ValueType> const& model) : AbstractModelChecker<ValueType>(model), nondeterministicLinearEquationSolver(storm::utility::solver::getNondeterministicLinearEquationSolver<ValueType>()) { + // Intentionally left empty. + } + + /*! + * Virtual destructor. Needs to be virtual, because this class has virtual methods. + */ + virtual ~SparseMarkovAutomatonCslModelChecker() { // Intentionally left empty. } @@ -42,50 +48,89 @@ namespace storm { return AbstractModelChecker<ValueType>::template getModel<storm::models::MarkovAutomaton<ValueType>>(); } - std::vector<ValueType> checkUntil(storm::property::csl::Until<ValueType> const& formula, bool qualitative) const { - storm::storage::BitVector leftStates = formula.getLeft().check(*this); - storm::storage::BitVector rightStates = formula.getRight().check(*this); - return computeUnboundedUntilProbabilities(minimumOperatorStack.top(), leftStates, rightStates, qualitative).first; + /*! + * Checks the given formula that is a P operator over a path formula featuring a value bound. + * + * @param formula The formula to check. + * @returns The set of states satisfying the formula represented by a bit vector. + */ + virtual storm::storage::BitVector checkProbabilisticBoundOperator(storm::properties::csl::ProbabilisticBoundOperator<ValueType> const& formula) const override{ + // For P< and P<= the MA satisfies the formula iff the probability maximizing scheduler is used. + // For P> and P>= " iff the probability minimizing " . + if(formula.getComparisonOperator() == storm::properties::LESS || formula.getComparisonOperator() == storm::properties::LESS_EQUAL) { + this->minimumOperatorStack.push(false); + } + else { + this->minimumOperatorStack.push(true); + } + + // First, we need to compute the probability for satisfying the path formula for each state. + std::vector<ValueType> quantitativeResult = formula.getChild()->check(*this, false); + + //Remove the minimizing operator entry from the stack. + this->minimumOperatorStack.pop(); + + // Create resulting bit vector that will hold the yes/no-answer for every state. + storm::storage::BitVector result(quantitativeResult.size()); + + // Now, we can compute which states meet the bound specified in this operator and set the + // corresponding bits to true in the resulting vector. + for (uint_fast64_t i = 0; i < quantitativeResult.size(); ++i) { + if (formula.meetsBound(quantitativeResult[i])) { + result.set(i, true); + } + } + + return result; + } + + std::vector<ValueType> checkUntil(storm::properties::csl::Until<ValueType> const& formula, bool qualitative) const { + // Test wheter it is specified if the minimum or the maximum probabilities are to be computed. + if(this->minimumOperatorStack.empty()) { + LOG4CPLUS_ERROR(logger, "Formula does not specify either min or max optimality, which is not meaningful over nondeterministic models."); + throw storm::exceptions::InvalidArgumentException() << "Formula does not specify either min or max optimality, which is not meaningful over nondeterministic models."; + } + storm::storage::BitVector leftStates = formula.getLeft()->check(*this); + storm::storage::BitVector rightStates = formula.getRight()->check(*this); + return computeUnboundedUntilProbabilities(this->minimumOperatorStack.top(), leftStates, rightStates, qualitative).first; } std::pair<std::vector<ValueType>, storm::storage::TotalScheduler> computeUnboundedUntilProbabilities(bool min, storm::storage::BitVector const& leftStates, storm::storage::BitVector const& rightStates, bool qualitative) const { return storm::modelchecker::prctl::SparseMdpPrctlModelChecker<ValueType>::computeUnboundedUntilProbabilities(min, this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), this->getModel().getInitialStates(), leftStates, rightStates, nondeterministicLinearEquationSolver, qualitative); } - std::vector<ValueType> checkTimeBoundedUntil(storm::property::csl::TimeBoundedUntil<ValueType> const& formula, bool qualitative) const { + std::vector<ValueType> checkTimeBoundedUntil(storm::properties::csl::TimeBoundedUntil<ValueType> const& formula, bool qualitative) const { throw storm::exceptions::NotImplementedException() << "Model checking Until formulas on Markov automata is not yet implemented."; } - std::vector<ValueType> checkTimeBoundedEventually(storm::property::csl::TimeBoundedEventually<ValueType> const& formula, bool qualitative) const { - storm::storage::BitVector goalStates = formula.getChild().check(*this); + std::vector<ValueType> checkTimeBoundedEventually(storm::properties::csl::TimeBoundedEventually<ValueType> const& formula, bool qualitative) const { + // Test wheter it is specified if the minimum or the maximum probabilities are to be computed. + if(this->minimumOperatorStack.empty()) { + LOG4CPLUS_ERROR(logger, "Formula does not specify either min or max optimality, which is not meaningful over nondeterministic models."); + throw storm::exceptions::InvalidArgumentException() << "Formula does not specify either min or max optimality, which is not meaningful over nondeterministic models."; + } + storm::storage::BitVector goalStates = formula.getChild()->check(*this); return this->checkTimeBoundedEventually(this->minimumOperatorStack.top(), goalStates, formula.getLowerBound(), formula.getUpperBound()); } - std::vector<ValueType> checkGlobally(storm::property::csl::Globally<ValueType> const& formula, bool qualitative) const { + std::vector<ValueType> checkGlobally(storm::properties::csl::Globally<ValueType> const& formula, bool qualitative) const { throw storm::exceptions::NotImplementedException() << "Model checking Globally formulas on Markov automata is not yet implemented."; } - std::vector<ValueType> checkEventually(storm::property::csl::Eventually<ValueType> const& formula, bool qualitative) const { - storm::storage::BitVector subFormulaStates = formula.getChild().check(*this); - return computeUnboundedUntilProbabilities(minimumOperatorStack.top(), storm::storage::BitVector(this->getModel().getNumberOfStates(), true), subFormulaStates, qualitative).first; + std::vector<ValueType> checkEventually(storm::properties::csl::Eventually<ValueType> const& formula, bool qualitative) const { + // Test wheter it is specified if the minimum or the maximum probabilities are to be computed. + if(this->minimumOperatorStack.empty()) { + LOG4CPLUS_ERROR(logger, "Formula does not specify either min or max optimality, which is not meaningful over nondeterministic models."); + throw storm::exceptions::InvalidArgumentException() << "Formula does not specify either min or max optimality, which is not meaningful over nondeterministic models."; + } + storm::storage::BitVector subFormulaStates = formula.getChild()->check(*this); + return computeUnboundedUntilProbabilities(this->minimumOperatorStack.top(), storm::storage::BitVector(this->getModel().getNumberOfStates(), true), subFormulaStates, qualitative).first; } - std::vector<ValueType> checkNext(storm::property::csl::Next<ValueType> const& formula, bool qualitative) const { + std::vector<ValueType> checkNext(storm::properties::csl::Next<ValueType> const& formula, bool qualitative) const { throw storm::exceptions::NotImplementedException() << "Model checking Next formulas on Markov automata is not yet implemented."; } - std::vector<ValueType> checkNoBoundOperator(storm::property::csl::AbstractNoBoundOperator<ValueType> const& formula) const { - // Check if the operator was an non-optimality operator and report an error in that case. - if (!formula.isOptimalityOperator()) { - LOG4CPLUS_ERROR(logger, "Formula does not specify neither min nor max optimality, which is not meaningful for nondeterministic models."); - throw storm::exceptions::InvalidArgumentException() << "Formula does not specify neither min nor max optimality, which is not meaningful for nondeterministic models."; - } - minimumOperatorStack.push(formula.isMinimumOperator()); - std::vector<ValueType> result = formula.check(*this, false); - minimumOperatorStack.pop(); - return result; - } - static void computeBoundedReachabilityProbabilities(bool min, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRates, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& goalStates, storm::storage::BitVector const& markovianNonGoalStates, storm::storage::BitVector const& probabilisticNonGoalStates, std::vector<ValueType>& markovianNonGoalValues, std::vector<ValueType>& probabilisticNonGoalValues, ValueType delta, uint_fast64_t numberOfSteps) { // Start by computing four sparse matrices: // * a matrix aMarkovian with all (discretized) transitions from Markovian non-goal states to all Markovian non-goal states. @@ -580,12 +625,6 @@ namespace storm { return result; } - /*! - * A stack used for storing whether we are currently computing min or max probabilities or rewards, respectively. - * The topmost element is true if and only if we are currently computing minimum probabilities or rewards. - */ - mutable std::stack<bool> minimumOperatorStack; - /*! * A solver that is used for solving systems of linear equations that are the result of nondeterministic choices. */ diff --git a/src/solver/GurobiLpSolver.h b/src/solver/GurobiLpSolver.h index 90bef47eb..f078ef6dd 100644 --- a/src/solver/GurobiLpSolver.h +++ b/src/solver/GurobiLpSolver.h @@ -176,7 +176,7 @@ namespace storm { throw storm::exceptions::NotImplementedException() << "This version of StoRM was compiled without support for Gurobi. Yet, a method was called that requires this support. Please choose a version of support with Gurobi support."; } - virtual uint_fast64_t addBinaryVariable(std::string const& name, double objectiveFunctionCoefficient = 0) override { + virtual void addBinaryVariable(std::string const& name, double objectiveFunctionCoefficient = 0) override { throw storm::exceptions::NotImplementedException() << "This version of StoRM was compiled without support for Gurobi. Yet, a method was called that requires this support. Please choose a version of support with Gurobi support."; } diff --git a/src/storage/SparseMatrix.h b/src/storage/SparseMatrix.h index b60cbdc16..46eaa0860 100644 --- a/src/storage/SparseMatrix.h +++ b/src/storage/SparseMatrix.h @@ -13,6 +13,8 @@ #include "src/exceptions/InvalidArgumentException.h" #include "src/exceptions/OutOfRangeException.h" +#include <boost/functional/hash.hpp> + // Forward declaration for adapter classes. namespace storm { namespace adapters {