From b772c92edb01257ae6e601ef5e238f442972d1d3 Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Tue, 16 Feb 2016 17:44:27 +0100 Subject: [PATCH 01/23] removed reward path formulas. reward path formulas are now just path formulas. this allows some invalid formulas to be constructed, so this now has to be checked dynamically Former-commit-id: c8527c8e9ab6a78c80f3fd655c2af24c4b64407a --- src/logic/BoundedUntilFormula.cpp | 4 + src/logic/BoundedUntilFormula.h | 1 + src/logic/ConditionalPathFormula.cpp | 4 + src/logic/ConditionalPathFormula.h | 3 +- src/logic/CumulativeRewardFormula.cpp | 4 + src/logic/CumulativeRewardFormula.h | 7 +- src/logic/EventuallyFormula.cpp | 8 ++ src/logic/EventuallyFormula.h | 4 +- src/logic/Formula.cpp | 34 +++----- src/logic/Formula.h | 12 +-- src/logic/Formulas.h | 2 - src/logic/GloballyFormula.cpp | 6 +- src/logic/GloballyFormula.h | 3 +- src/logic/InstantaneousRewardFormula.cpp | 4 + src/logic/InstantaneousRewardFormula.h | 7 +- src/logic/LongRunAverageRewardFormula.cpp | 4 + src/logic/LongRunAverageRewardFormula.h | 10 +-- src/logic/NextFormula.cpp | 4 + src/logic/NextFormula.h | 3 +- src/logic/ReachabilityRewardFormula.cpp | 35 -------- src/logic/ReachabilityRewardFormula.h | 36 --------- src/logic/RewardOperatorFormula.cpp | 3 +- src/logic/RewardPathFormula.cpp | 9 --- src/logic/RewardPathFormula.h | 19 ----- src/logic/UntilFormula.cpp | 4 + src/logic/UntilFormula.h | 3 +- src/modelchecker/AbstractModelChecker.cpp | 80 ++++++++++--------- src/modelchecker/AbstractModelChecker.h | 4 +- src/modelchecker/CheckTask.h | 37 ++++++++- .../csl/HybridCtmcCslModelChecker.cpp | 8 +- .../csl/HybridCtmcCslModelChecker.h | 2 +- .../csl/SparseCtmcCslModelChecker.cpp | 8 +- .../csl/SparseCtmcCslModelChecker.h | 2 +- .../SparseMarkovAutomatonCslModelChecker.cpp | 8 +- .../SparseMarkovAutomatonCslModelChecker.h | 2 +- .../prctl/HybridDtmcPrctlModelChecker.cpp | 8 +- .../prctl/HybridDtmcPrctlModelChecker.h | 2 +- .../prctl/HybridMdpPrctlModelChecker.cpp | 10 +-- .../prctl/HybridMdpPrctlModelChecker.h | 2 +- .../prctl/SparseDtmcPrctlModelChecker.cpp | 10 +-- .../prctl/SparseDtmcPrctlModelChecker.h | 2 +- .../prctl/SparseMdpPrctlModelChecker.cpp | 10 +-- .../prctl/SparseMdpPrctlModelChecker.h | 2 +- .../prctl/SymbolicDtmcPrctlModelChecker.cpp | 10 +-- .../prctl/SymbolicDtmcPrctlModelChecker.h | 2 +- .../prctl/SymbolicMdpPrctlModelChecker.cpp | 10 +-- .../prctl/SymbolicMdpPrctlModelChecker.h | 2 +- .../SparseDtmcEliminationModelChecker.cpp | 15 ++-- .../SparseDtmcEliminationModelChecker.h | 2 +- src/parser/FormulaParser.cpp | 12 +-- .../BisimulationDecomposition.cpp | 5 -- 51 files changed, 212 insertions(+), 276 deletions(-) delete mode 100644 src/logic/ReachabilityRewardFormula.cpp delete mode 100644 src/logic/ReachabilityRewardFormula.h delete mode 100644 src/logic/RewardPathFormula.cpp delete mode 100644 src/logic/RewardPathFormula.h diff --git a/src/logic/BoundedUntilFormula.cpp b/src/logic/BoundedUntilFormula.cpp index 2c7ed2cde..7c29c579b 100644 --- a/src/logic/BoundedUntilFormula.cpp +++ b/src/logic/BoundedUntilFormula.cpp @@ -30,6 +30,10 @@ namespace storm { return bounds.which() == 0; } + bool BoundedUntilFormula::isValidProbabilityPathFormula() const { + return true; + } + bool BoundedUntilFormula::isPctlPathFormula() const { return this->hasDiscreteTimeBound() && this->getLeftSubformula().isPctlStateFormula() && this->getRightSubformula().isPctlStateFormula(); } diff --git a/src/logic/BoundedUntilFormula.h b/src/logic/BoundedUntilFormula.h index 4d72abdc1..7da7e70f6 100644 --- a/src/logic/BoundedUntilFormula.h +++ b/src/logic/BoundedUntilFormula.h @@ -22,6 +22,7 @@ namespace storm { std::pair<double, double> const& getIntervalBounds() const; uint_fast64_t getDiscreteTimeBound() const; + virtual bool isValidProbabilityPathFormula() const override; virtual bool isPctlPathFormula() const override; virtual bool isCslPathFormula() const override; diff --git a/src/logic/ConditionalPathFormula.cpp b/src/logic/ConditionalPathFormula.cpp index b5d8af81d..8ef461e35 100644 --- a/src/logic/ConditionalPathFormula.cpp +++ b/src/logic/ConditionalPathFormula.cpp @@ -10,6 +10,10 @@ namespace storm { return true; } + bool ConditionalPathFormula::isValidProbabilityPathFormula() const { + return true; + } + std::shared_ptr<Formula> ConditionalPathFormula::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const { return std::make_shared<ConditionalPathFormula>(this->getLeftSubformula().substitute(substitution), this->getRightSubformula().substitute(substitution)); } diff --git a/src/logic/ConditionalPathFormula.h b/src/logic/ConditionalPathFormula.h index bd5f3852c..a3e12e20f 100644 --- a/src/logic/ConditionalPathFormula.h +++ b/src/logic/ConditionalPathFormula.h @@ -14,7 +14,8 @@ namespace storm { } virtual bool isConditionalPathFormula() const override; - + virtual bool isValidProbabilityPathFormula() const override; + virtual std::ostream& writeToStream(std::ostream& out) const override; virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override; diff --git a/src/logic/CumulativeRewardFormula.cpp b/src/logic/CumulativeRewardFormula.cpp index ed4b18c85..3f53c2e9d 100644 --- a/src/logic/CumulativeRewardFormula.cpp +++ b/src/logic/CumulativeRewardFormula.cpp @@ -14,6 +14,10 @@ namespace storm { return true; } + bool CumulativeRewardFormula::isValidRewardPathFormula() const { + return true; + } + bool CumulativeRewardFormula::hasDiscreteTimeBound() const { return timeBound.which() == 0; } diff --git a/src/logic/CumulativeRewardFormula.h b/src/logic/CumulativeRewardFormula.h index 8b8692743..4ebf08cd4 100644 --- a/src/logic/CumulativeRewardFormula.h +++ b/src/logic/CumulativeRewardFormula.h @@ -3,11 +3,11 @@ #include <boost/variant.hpp> -#include "src/logic/RewardPathFormula.h" +#include "src/logic/PathFormula.h" namespace storm { namespace logic { - class CumulativeRewardFormula : public RewardPathFormula { + class CumulativeRewardFormula : public PathFormula { public: CumulativeRewardFormula(uint_fast64_t timeBound); @@ -18,7 +18,8 @@ namespace storm { } virtual bool isCumulativeRewardFormula() const override; - + virtual bool isValidRewardPathFormula() const override; + virtual std::ostream& writeToStream(std::ostream& out) const override; bool hasDiscreteTimeBound() const; diff --git a/src/logic/EventuallyFormula.cpp b/src/logic/EventuallyFormula.cpp index b8ea1aa35..a25d12b33 100644 --- a/src/logic/EventuallyFormula.cpp +++ b/src/logic/EventuallyFormula.cpp @@ -10,6 +10,14 @@ namespace storm { return true; } + bool EventuallyFormula::isValidProbabilityPathFormula() const { + return true; + } + + bool EventuallyFormula::isValidRewardPathFormula() const { + return true; + } + std::shared_ptr<Formula> EventuallyFormula::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const { return std::make_shared<EventuallyFormula>(this->getSubformula().substitute(substitution)); } diff --git a/src/logic/EventuallyFormula.h b/src/logic/EventuallyFormula.h index 816f93c82..a488eb443 100644 --- a/src/logic/EventuallyFormula.h +++ b/src/logic/EventuallyFormula.h @@ -14,7 +14,9 @@ namespace storm { } virtual bool isEventuallyFormula() const override; - + virtual bool isValidProbabilityPathFormula() const override; + virtual bool isValidRewardPathFormula() const override; + virtual std::ostream& writeToStream(std::ostream& out) const override; virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override; diff --git a/src/logic/Formula.cpp b/src/logic/Formula.cpp index 5ba068af9..e3fa84c74 100644 --- a/src/logic/Formula.cpp +++ b/src/logic/Formula.cpp @@ -87,10 +87,6 @@ namespace storm { return false; } - bool Formula::isRewardPathFormula() const { - return false; - } - bool Formula::isCumulativeRewardFormula() const { return false; } @@ -99,10 +95,6 @@ namespace storm { return false; } - bool Formula::isReachabilityRewardFormula() const { - return false; - } - bool Formula::isLongRunAverageRewardFormula() const { return false; } @@ -147,6 +139,14 @@ namespace storm { return false; } + bool Formula::isValidProbabilityPathFormula() const { + return false; + } + + bool Formula::isValidRewardPathFormula() const { + return false; + } + bool Formula::containsBoundedUntilFormula() const { return false; } @@ -327,14 +327,6 @@ namespace storm { return dynamic_cast<ExpectedTimeOperatorFormula const&>(*this); } - RewardPathFormula& Formula::asRewardPathFormula() { - return dynamic_cast<RewardPathFormula&>(*this); - } - - RewardPathFormula const& Formula::asRewardPathFormula() const { - return dynamic_cast<RewardPathFormula const&>(*this); - } - CumulativeRewardFormula& Formula::asCumulativeRewardFormula() { return dynamic_cast<CumulativeRewardFormula&>(*this); } @@ -350,15 +342,7 @@ namespace storm { InstantaneousRewardFormula const& Formula::asInstantaneousRewardFormula() const { return dynamic_cast<InstantaneousRewardFormula const&>(*this); } - - ReachabilityRewardFormula& Formula::asReachabilityRewardFormula() { - return dynamic_cast<ReachabilityRewardFormula&>(*this); - } - - ReachabilityRewardFormula const& Formula::asReachabilityRewardFormula() const { - return dynamic_cast<ReachabilityRewardFormula const&>(*this); - } - + LongRunAverageRewardFormula& Formula::asLongRunAverageRewardFormula() { return dynamic_cast<LongRunAverageRewardFormula&>(*this); } diff --git a/src/logic/Formula.h b/src/logic/Formula.h index 31ee7744a..2ea234449 100644 --- a/src/logic/Formula.h +++ b/src/logic/Formula.h @@ -31,10 +31,8 @@ namespace storm { class NextFormula; class LongRunAverageOperatorFormula; class ExpectedTimeOperatorFormula; - class RewardPathFormula; class CumulativeRewardFormula; class InstantaneousRewardFormula; - class ReachabilityRewardFormula; class LongRunAverageRewardFormula; class ProbabilityOperatorFormula; class RewardOperatorFormula; @@ -74,10 +72,8 @@ namespace storm { virtual bool isNextFormula() const; virtual bool isLongRunAverageOperatorFormula() const; virtual bool isExpectedTimeOperatorFormula() const; - virtual bool isRewardPathFormula() const; virtual bool isCumulativeRewardFormula() const; virtual bool isInstantaneousRewardFormula() const; - virtual bool isReachabilityRewardFormula() const; virtual bool isLongRunAverageRewardFormula() const; virtual bool isProbabilityOperatorFormula() const; virtual bool isRewardOperatorFormula() const; @@ -90,6 +86,8 @@ namespace storm { virtual bool isPltlFormula() const; virtual bool isLtlFormula() const; virtual bool isPropositionalFormula() const; + virtual bool isValidProbabilityPathFormula() const; + virtual bool isValidRewardPathFormula() const; virtual bool containsBoundedUntilFormula() const; virtual bool containsNextFormula() const; virtual bool containsProbabilityOperator() const; @@ -156,18 +154,12 @@ namespace storm { ExpectedTimeOperatorFormula& asExpectedTimeOperatorFormula(); ExpectedTimeOperatorFormula const& asExpectedTimeOperatorFormula() const; - RewardPathFormula& asRewardPathFormula(); - RewardPathFormula const& asRewardPathFormula() const; - CumulativeRewardFormula& asCumulativeRewardFormula(); CumulativeRewardFormula const& asCumulativeRewardFormula() const; InstantaneousRewardFormula& asInstantaneousRewardFormula(); InstantaneousRewardFormula const& asInstantaneousRewardFormula() const; - ReachabilityRewardFormula& asReachabilityRewardFormula(); - ReachabilityRewardFormula const& asReachabilityRewardFormula() const; - LongRunAverageRewardFormula& asLongRunAverageRewardFormula(); LongRunAverageRewardFormula const& asLongRunAverageRewardFormula() const; diff --git a/src/logic/Formulas.h b/src/logic/Formulas.h index 3671b2859..7da9321c6 100644 --- a/src/logic/Formulas.h +++ b/src/logic/Formulas.h @@ -12,10 +12,8 @@ #include "src/logic/InstantaneousRewardFormula.h" #include "src/logic/NextFormula.h" #include "src/logic/PathFormula.h" -#include "src/logic/RewardPathFormula.h" #include "src/logic/OperatorFormula.h" #include "src/logic/ProbabilityOperatorFormula.h" -#include "src/logic/ReachabilityRewardFormula.h" #include "src/logic/LongRunAverageRewardFormula.h" #include "src/logic/RewardOperatorFormula.h" #include "src/logic/StateFormula.h" diff --git a/src/logic/GloballyFormula.cpp b/src/logic/GloballyFormula.cpp index 8d2d1c92a..5ddfd8feb 100644 --- a/src/logic/GloballyFormula.cpp +++ b/src/logic/GloballyFormula.cpp @@ -9,7 +9,11 @@ namespace storm { bool GloballyFormula::isGloballyFormula() const { return true; } - + + bool GloballyFormula::isValidProbabilityPathFormula() const { + return true; + } + std::shared_ptr<Formula> GloballyFormula::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const { return std::make_shared<GloballyFormula>(this->getSubformula().substitute(substitution)); } diff --git a/src/logic/GloballyFormula.h b/src/logic/GloballyFormula.h index 6346200c8..e3fc82f2d 100644 --- a/src/logic/GloballyFormula.h +++ b/src/logic/GloballyFormula.h @@ -14,7 +14,8 @@ namespace storm { } virtual bool isGloballyFormula() const override; - + virtual bool isValidProbabilityPathFormula() const override; + virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override; virtual std::ostream& writeToStream(std::ostream& out) const override; diff --git a/src/logic/InstantaneousRewardFormula.cpp b/src/logic/InstantaneousRewardFormula.cpp index 7d81f1234..77efb5705 100644 --- a/src/logic/InstantaneousRewardFormula.cpp +++ b/src/logic/InstantaneousRewardFormula.cpp @@ -14,6 +14,10 @@ namespace storm { return true; } + bool InstantaneousRewardFormula::isValidRewardPathFormula() const { + return true; + } + bool InstantaneousRewardFormula::hasDiscreteTimeBound() const { return timeBound.which() == 0; } diff --git a/src/logic/InstantaneousRewardFormula.h b/src/logic/InstantaneousRewardFormula.h index 8b29fa740..c895c5b39 100644 --- a/src/logic/InstantaneousRewardFormula.h +++ b/src/logic/InstantaneousRewardFormula.h @@ -3,11 +3,11 @@ #include <boost/variant.hpp> -#include "src/logic/RewardPathFormula.h" +#include "src/logic/PathFormula.h" namespace storm { namespace logic { - class InstantaneousRewardFormula : public RewardPathFormula { + class InstantaneousRewardFormula : public PathFormula { public: InstantaneousRewardFormula(uint_fast64_t timeBound); @@ -18,7 +18,8 @@ namespace storm { } virtual bool isInstantaneousRewardFormula() const override; - + virtual bool isValidRewardPathFormula() const override; + virtual std::ostream& writeToStream(std::ostream& out) const override; bool hasDiscreteTimeBound() const; diff --git a/src/logic/LongRunAverageRewardFormula.cpp b/src/logic/LongRunAverageRewardFormula.cpp index 896e94a31..7bc064c1e 100644 --- a/src/logic/LongRunAverageRewardFormula.cpp +++ b/src/logic/LongRunAverageRewardFormula.cpp @@ -10,6 +10,10 @@ namespace storm { return true; } + bool LongRunAverageRewardFormula::isValidRewardPathFormula() const { + return true; + } + std::shared_ptr<Formula> LongRunAverageRewardFormula::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const { return std::shared_ptr<Formula>(new LongRunAverageRewardFormula()); } diff --git a/src/logic/LongRunAverageRewardFormula.h b/src/logic/LongRunAverageRewardFormula.h index 449d5fd0e..aa4d3f424 100644 --- a/src/logic/LongRunAverageRewardFormula.h +++ b/src/logic/LongRunAverageRewardFormula.h @@ -1,14 +1,11 @@ #ifndef STORM_LOGIC_LONGRUNAVERAGEREWARDFORMULA_H_ #define STORM_LOGIC_LONGRUNAVERAGEREWARDFORMULA_H_ -#include <memory> - -#include "src/logic/RewardPathFormula.h" - +#include "src/logic/PathFormula.h" namespace storm { namespace logic { - class LongRunAverageRewardFormula : public RewardPathFormula { + class LongRunAverageRewardFormula : public PathFormula { public: LongRunAverageRewardFormula(); @@ -17,7 +14,8 @@ namespace storm { } virtual bool isLongRunAverageRewardFormula() const override; - + virtual bool isValidRewardPathFormula() const override; + virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override; virtual std::ostream& writeToStream(std::ostream& out) const override; diff --git a/src/logic/NextFormula.cpp b/src/logic/NextFormula.cpp index b5064253f..b7400eb7d 100644 --- a/src/logic/NextFormula.cpp +++ b/src/logic/NextFormula.cpp @@ -10,6 +10,10 @@ namespace storm { return true; } + bool NextFormula::isValidProbabilityPathFormula() const { + return true; + } + bool NextFormula::containsNextFormula() const { return true; } diff --git a/src/logic/NextFormula.h b/src/logic/NextFormula.h index 2466d0b3d..f0de43cc6 100644 --- a/src/logic/NextFormula.h +++ b/src/logic/NextFormula.h @@ -14,7 +14,8 @@ namespace storm { } virtual bool isNextFormula() const override; - + virtual bool isValidProbabilityPathFormula() const override; + virtual bool containsNextFormula() const override; virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override; diff --git a/src/logic/ReachabilityRewardFormula.cpp b/src/logic/ReachabilityRewardFormula.cpp deleted file mode 100644 index 83ba52f91..000000000 --- a/src/logic/ReachabilityRewardFormula.cpp +++ /dev/null @@ -1,35 +0,0 @@ -#include "src/logic/ReachabilityRewardFormula.h" - -namespace storm { - namespace logic { - ReachabilityRewardFormula::ReachabilityRewardFormula(std::shared_ptr<Formula const> const& subformula) : subformula(subformula) { - // Intentionally left empty. - } - - bool ReachabilityRewardFormula::isReachabilityRewardFormula() const { - return true; - } - - Formula const& ReachabilityRewardFormula::getSubformula() const { - return *subformula; - } - - void ReachabilityRewardFormula::gatherAtomicExpressionFormulas(std::vector<std::shared_ptr<AtomicExpressionFormula const>>& atomicExpressionFormulas) const { - this->getSubformula().gatherAtomicExpressionFormulas(atomicExpressionFormulas); - } - - void ReachabilityRewardFormula::gatherAtomicLabelFormulas(std::vector<std::shared_ptr<AtomicLabelFormula const>>& atomicLabelFormulas) const { - this->getSubformula().gatherAtomicLabelFormulas(atomicLabelFormulas); - } - - std::shared_ptr<Formula> ReachabilityRewardFormula::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const { - return std::make_shared<ReachabilityRewardFormula>(this->getSubformula().substitute(substitution)); - } - - std::ostream& ReachabilityRewardFormula::writeToStream(std::ostream& out) const { - out << "F "; - this->getSubformula().writeToStream(out); - return out; - } - } -} \ No newline at end of file diff --git a/src/logic/ReachabilityRewardFormula.h b/src/logic/ReachabilityRewardFormula.h deleted file mode 100644 index bfef88188..000000000 --- a/src/logic/ReachabilityRewardFormula.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef STORM_LOGIC_REACHABILITYREWARDFORMULA_H_ -#define STORM_LOGIC_REACHABILITYREWARDFORMULA_H_ - -#include <memory> - -#include "src/logic/RewardPathFormula.h" - - -namespace storm { - namespace logic { - class ReachabilityRewardFormula : public RewardPathFormula { - public: - ReachabilityRewardFormula(std::shared_ptr<Formula const> const& subformula); - - virtual ~ReachabilityRewardFormula() { - // Intentionally left empty. - } - - virtual bool isReachabilityRewardFormula() const override; - - Formula const& getSubformula() const; - - virtual void gatherAtomicExpressionFormulas(std::vector<std::shared_ptr<AtomicExpressionFormula const>>& atomicExpressionFormulas) const override; - virtual void gatherAtomicLabelFormulas(std::vector<std::shared_ptr<AtomicLabelFormula const>>& atomicLabelFormulas) const override; - - virtual std::ostream& writeToStream(std::ostream& out) const override; - - virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override; - - private: - std::shared_ptr<Formula const> subformula; - }; - } -} - -#endif /* STORM_LOGIC_REACHABILITYREWARDFORMULA_H_ */ \ No newline at end of file diff --git a/src/logic/RewardOperatorFormula.cpp b/src/logic/RewardOperatorFormula.cpp index 791d1f5cc..1e5390830 100644 --- a/src/logic/RewardOperatorFormula.cpp +++ b/src/logic/RewardOperatorFormula.cpp @@ -23,7 +23,8 @@ namespace storm { } bool RewardOperatorFormula::isPctlStateFormula() const { - return this->getSubformula().isRewardPathFormula(); + Formula const& subformula = this->getSubformula(); + return subformula.isEventuallyFormula() || subformula.isCumulativeRewardFormula() || subformula.isInstantaneousRewardFormula(); } bool RewardOperatorFormula::containsRewardOperator() const { diff --git a/src/logic/RewardPathFormula.cpp b/src/logic/RewardPathFormula.cpp deleted file mode 100644 index 3c97acf74..000000000 --- a/src/logic/RewardPathFormula.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include "src/logic/RewardPathFormula.h" - -namespace storm { - namespace logic { - bool RewardPathFormula::isRewardPathFormula() const { - return true; - } - } -} \ No newline at end of file diff --git a/src/logic/RewardPathFormula.h b/src/logic/RewardPathFormula.h deleted file mode 100644 index 023e76e2d..000000000 --- a/src/logic/RewardPathFormula.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef STORM_LOGIC_PATHREWARDFORMULA_H_ -#define STORM_LOGIC_PATHREWARDFORMULA_H_ - -#include "src/logic/PathFormula.h" - -namespace storm { - namespace logic { - class RewardPathFormula : public Formula { - public: - virtual ~RewardPathFormula() { - // Intentionally left empty. - } - - virtual bool isRewardPathFormula() const override; - }; - } -} - -#endif /* STORM_LOGIC_PATHREWARDFORMULA_H_ */ \ No newline at end of file diff --git a/src/logic/UntilFormula.cpp b/src/logic/UntilFormula.cpp index 94d7c62a8..b15f3743f 100644 --- a/src/logic/UntilFormula.cpp +++ b/src/logic/UntilFormula.cpp @@ -10,6 +10,10 @@ namespace storm { return true; } + bool UntilFormula::isValidProbabilityPathFormula() const { + return true; + } + std::shared_ptr<Formula> UntilFormula::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const { return std::make_shared<UntilFormula>(this->getLeftSubformula().substitute(substitution), this->getRightSubformula().substitute(substitution)); } diff --git a/src/logic/UntilFormula.h b/src/logic/UntilFormula.h index 45a721252..87ceef806 100644 --- a/src/logic/UntilFormula.h +++ b/src/logic/UntilFormula.h @@ -14,7 +14,8 @@ namespace storm { } virtual bool isUntilFormula() const override; - + virtual bool isValidProbabilityPathFormula() const override; + virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override; virtual std::ostream& writeToStream(std::ostream& out) const override; diff --git a/src/modelchecker/AbstractModelChecker.cpp b/src/modelchecker/AbstractModelChecker.cpp index 3b0d55ebf..56a65b39e 100644 --- a/src/modelchecker/AbstractModelChecker.cpp +++ b/src/modelchecker/AbstractModelChecker.cpp @@ -15,11 +15,13 @@ namespace storm { storm::logic::Formula const& formula = checkTask.getFormula(); STORM_LOG_THROW(this->canHandle(formula), storm::exceptions::InvalidArgumentException, "The model checker is not able to check the formula '" << formula << "'."); if (formula.isStateFormula()) { - return this->checkStateFormula(checkTask.replaceFormula(formula.asStateFormula())); + return this->checkStateFormula(checkTask.substituteFormula(formula.asStateFormula())); } else if (formula.isPathFormula()) { - return this->computeProbabilities(checkTask.replaceFormula(formula.asPathFormula())); - } else if (formula.isRewardPathFormula()) { - return this->computeRewards(checkTask.replaceFormula(formula.asRewardPathFormula())); + if (checkTask.computeProbabilities()) { + return this->computeProbabilities(checkTask.substituteFormula(formula.asPathFormula())); + } else if (checkTask.computeRewards()) { + return this->computeRewards(checkTask.substituteFormula(formula.asPathFormula())); + } } STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "The given formula '" << formula << "' is invalid."); } @@ -27,17 +29,17 @@ namespace storm { std::unique_ptr<CheckResult> AbstractModelChecker::computeProbabilities(CheckTask<storm::logic::PathFormula> const& checkTask) { storm::logic::PathFormula const& pathFormula = checkTask.getFormula(); if (pathFormula.isBoundedUntilFormula()) { - return this->computeBoundedUntilProbabilities(checkTask.replaceFormula(pathFormula.asBoundedUntilFormula())); + return this->computeBoundedUntilProbabilities(checkTask.substituteFormula(pathFormula.asBoundedUntilFormula())); } else if (pathFormula.isConditionalPathFormula()) { - return this->computeConditionalProbabilities(checkTask.replaceFormula(pathFormula.asConditionalPathFormula())); + return this->computeConditionalProbabilities(checkTask.substituteFormula(pathFormula.asConditionalPathFormula())); } else if (pathFormula.isEventuallyFormula()) { - return this->computeEventuallyProbabilities(checkTask.replaceFormula(pathFormula.asEventuallyFormula())); + return this->computeEventuallyProbabilities(checkTask.substituteFormula(pathFormula.asEventuallyFormula())); } else if (pathFormula.isGloballyFormula()) { - return this->computeGloballyProbabilities(checkTask.replaceFormula(pathFormula.asGloballyFormula())); + return this->computeGloballyProbabilities(checkTask.substituteFormula(pathFormula.asGloballyFormula())); } else if (pathFormula.isUntilFormula()) { - return this->computeUntilProbabilities(checkTask.replaceFormula(pathFormula.asUntilFormula())); + return this->computeUntilProbabilities(checkTask.substituteFormula(pathFormula.asUntilFormula())); } else if (pathFormula.isNextFormula()) { - return this->computeNextProbabilities(checkTask.replaceFormula(pathFormula.asNextFormula())); + return this->computeNextProbabilities(checkTask.substituteFormula(pathFormula.asNextFormula())); } STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "The given formula '" << pathFormula << "' is invalid."); } @@ -53,7 +55,7 @@ namespace storm { std::unique_ptr<CheckResult> AbstractModelChecker::computeEventuallyProbabilities(CheckTask<storm::logic::EventuallyFormula> const& checkTask) { storm::logic::EventuallyFormula const& pathFormula = checkTask.getFormula(); storm::logic::UntilFormula newFormula(storm::logic::Formula::getTrueFormula(), pathFormula.getSubformula().asSharedPointer()); - return this->computeUntilProbabilities(checkTask.replaceFormula(newFormula)); + return this->computeUntilProbabilities(checkTask.substituteFormula(newFormula)); } std::unique_ptr<CheckResult> AbstractModelChecker::computeGloballyProbabilities(CheckTask<storm::logic::GloballyFormula> const& checkTask) { @@ -68,16 +70,16 @@ namespace storm { STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "This model checker does not support the formula: " << checkTask.getFormula() << "."); } - std::unique_ptr<CheckResult> AbstractModelChecker::computeRewards(CheckTask<storm::logic::RewardPathFormula> const& checkTask) { - storm::logic::RewardPathFormula const& rewardPathFormula = checkTask.getFormula(); + std::unique_ptr<CheckResult> AbstractModelChecker::computeRewards(CheckTask<storm::logic::PathFormula> const& checkTask) { + storm::logic::PathFormula const& rewardPathFormula = checkTask.getFormula(); if (rewardPathFormula.isCumulativeRewardFormula()) { - return this->computeCumulativeRewards(checkTask.replaceFormula(rewardPathFormula.asCumulativeRewardFormula())); + return this->computeCumulativeRewards(checkTask.substituteFormula(rewardPathFormula.asCumulativeRewardFormula())); } else if (rewardPathFormula.isInstantaneousRewardFormula()) { - return this->computeInstantaneousRewards(checkTask.replaceFormula(rewardPathFormula.asInstantaneousRewardFormula())); - } else if (rewardPathFormula.isReachabilityRewardFormula()) { - return this->computeReachabilityRewards(checkTask.replaceFormula(rewardPathFormula.asReachabilityRewardFormula())); + return this->computeInstantaneousRewards(checkTask.substituteFormula(rewardPathFormula.asInstantaneousRewardFormula())); + } else if (rewardPathFormula.isEventuallyFormula()) { + return this->computeReachabilityRewards(checkTask.substituteFormula(rewardPathFormula.asEventuallyFormula())); } else if (rewardPathFormula.isLongRunAverageRewardFormula()) { - return this->computeLongRunAverageRewards(checkTask.replaceFormula(rewardPathFormula.asLongRunAverageRewardFormula())); + return this->computeLongRunAverageRewards(checkTask.substituteFormula(rewardPathFormula.asLongRunAverageRewardFormula())); } STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "The given formula '" << rewardPathFormula << "' is invalid."); } @@ -90,7 +92,7 @@ namespace storm { STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "This model checker does not support the formula: " << checkTask.getFormula() << "."); } - std::unique_ptr<CheckResult> AbstractModelChecker::computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) { + std::unique_ptr<CheckResult> AbstractModelChecker::computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) { STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "This model checker does not support the formula: " << checkTask.getFormula() << "."); } @@ -109,25 +111,25 @@ namespace storm { std::unique_ptr<CheckResult> AbstractModelChecker::checkStateFormula(CheckTask<storm::logic::StateFormula> const& checkTask) { storm::logic::StateFormula const& stateFormula = checkTask.getFormula(); if (stateFormula.isBinaryBooleanStateFormula()) { - return this->checkBinaryBooleanStateFormula(checkTask.replaceFormula(stateFormula.asBinaryBooleanStateFormula())); + return this->checkBinaryBooleanStateFormula(checkTask.substituteFormula(stateFormula.asBinaryBooleanStateFormula())); } else if (stateFormula.isUnaryBooleanStateFormula()) { - return this->checkUnaryBooleanStateFormula(checkTask.replaceFormula(stateFormula.asUnaryBooleanStateFormula())); + return this->checkUnaryBooleanStateFormula(checkTask.substituteFormula(stateFormula.asUnaryBooleanStateFormula())); } else if (stateFormula.isBooleanLiteralFormula()) { - return this->checkBooleanLiteralFormula(checkTask.replaceFormula(stateFormula.asBooleanLiteralFormula())); + return this->checkBooleanLiteralFormula(checkTask.substituteFormula(stateFormula.asBooleanLiteralFormula())); } else if (stateFormula.isProbabilityOperatorFormula()) { - return this->checkProbabilityOperatorFormula(checkTask.replaceFormula(stateFormula.asProbabilityOperatorFormula())); + return this->checkProbabilityOperatorFormula(checkTask.substituteFormula(stateFormula.asProbabilityOperatorFormula())); } else if (stateFormula.isRewardOperatorFormula()) { - return this->checkRewardOperatorFormula(checkTask.replaceFormula(stateFormula.asRewardOperatorFormula())); + return this->checkRewardOperatorFormula(checkTask.substituteFormula(stateFormula.asRewardOperatorFormula())); } else if (stateFormula.isExpectedTimeOperatorFormula()) { - return this->checkExpectedTimeOperatorFormula(checkTask.replaceFormula(stateFormula.asExpectedTimeOperatorFormula())); + return this->checkExpectedTimeOperatorFormula(checkTask.substituteFormula(stateFormula.asExpectedTimeOperatorFormula())); } else if (stateFormula.isLongRunAverageOperatorFormula()) { - return this->checkLongRunAverageOperatorFormula(checkTask.replaceFormula(stateFormula.asLongRunAverageOperatorFormula())); + return this->checkLongRunAverageOperatorFormula(checkTask.substituteFormula(stateFormula.asLongRunAverageOperatorFormula())); } else if (stateFormula.isAtomicExpressionFormula()) { - return this->checkAtomicExpressionFormula(checkTask.replaceFormula(stateFormula.asAtomicExpressionFormula())); + return this->checkAtomicExpressionFormula(checkTask.substituteFormula(stateFormula.asAtomicExpressionFormula())); } else if (stateFormula.isAtomicLabelFormula()) { - return this->checkAtomicLabelFormula(checkTask.replaceFormula(stateFormula.asAtomicLabelFormula())); + return this->checkAtomicLabelFormula(checkTask.substituteFormula(stateFormula.asAtomicLabelFormula())); } else if (stateFormula.isBooleanLiteralFormula()) { - return this->checkBooleanLiteralFormula(checkTask.replaceFormula(stateFormula.asBooleanLiteralFormula())); + return this->checkBooleanLiteralFormula(checkTask.substituteFormula(stateFormula.asBooleanLiteralFormula())); } STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "The given formula '" << stateFormula << "' is invalid."); } @@ -136,7 +138,7 @@ namespace storm { storm::logic::AtomicExpressionFormula const& stateFormula = checkTask.getFormula(); std::stringstream stream; stream << stateFormula.getExpression(); - return this->checkAtomicLabelFormula(checkTask.replaceFormula(storm::logic::AtomicLabelFormula(stream.str()))); + return this->checkAtomicLabelFormula(checkTask.substituteFormula(storm::logic::AtomicLabelFormula(stream.str()))); } std::unique_ptr<CheckResult> AbstractModelChecker::checkAtomicLabelFormula(CheckTask<storm::logic::AtomicLabelFormula> const& checkTask) { @@ -147,8 +149,8 @@ namespace storm { storm::logic::BinaryBooleanStateFormula const& stateFormula = checkTask.getFormula(); STORM_LOG_THROW(stateFormula.getLeftSubformula().isStateFormula() && stateFormula.getRightSubformula().isStateFormula(), storm::exceptions::InvalidArgumentException, "The given formula is invalid."); - std::unique_ptr<CheckResult> leftResult = this->check(checkTask.replaceFormula<storm::logic::Formula>(stateFormula.getLeftSubformula().asStateFormula())); - std::unique_ptr<CheckResult> rightResult = this->check(checkTask.replaceFormula<storm::logic::Formula>(stateFormula.getRightSubformula().asStateFormula())); + std::unique_ptr<CheckResult> leftResult = this->check(checkTask.substituteFormula<storm::logic::Formula>(stateFormula.getLeftSubformula().asStateFormula())); + std::unique_ptr<CheckResult> rightResult = this->check(checkTask.substituteFormula<storm::logic::Formula>(stateFormula.getRightSubformula().asStateFormula())); STORM_LOG_THROW(leftResult->isQualitative() && rightResult->isQualitative(), storm::exceptions::InternalTypeErrorException, "Expected qualitative results."); @@ -169,9 +171,9 @@ namespace storm { std::unique_ptr<CheckResult> AbstractModelChecker::checkProbabilityOperatorFormula(CheckTask<storm::logic::ProbabilityOperatorFormula> const& checkTask) { storm::logic::ProbabilityOperatorFormula const& stateFormula = checkTask.getFormula(); - STORM_LOG_THROW(stateFormula.getSubformula().isPathFormula(), storm::exceptions::InvalidArgumentException, "The given formula is invalid."); + STORM_LOG_THROW(stateFormula.getSubformula().isValidProbabilityPathFormula(), storm::exceptions::InvalidArgumentException, "The given formula is invalid."); - std::unique_ptr<CheckResult> result = this->computeProbabilities(checkTask.replaceFormula(stateFormula.getSubformula().asPathFormula())); + std::unique_ptr<CheckResult> result = this->computeProbabilities(checkTask.substituteFormula(stateFormula.getSubformula().asPathFormula())); if (stateFormula.hasBound()) { STORM_LOG_THROW(result->isQuantitative(), storm::exceptions::InvalidOperationException, "Unable to perform comparison operation on non-quantitative result."); @@ -183,9 +185,9 @@ namespace storm { std::unique_ptr<CheckResult> AbstractModelChecker::checkRewardOperatorFormula(CheckTask<storm::logic::RewardOperatorFormula> const& checkTask) { storm::logic::RewardOperatorFormula const& stateFormula = checkTask.getFormula(); - STORM_LOG_THROW(stateFormula.getSubformula().isRewardPathFormula(), storm::exceptions::InvalidArgumentException, "The given formula is invalid."); + STORM_LOG_THROW(stateFormula.getSubformula().isValidRewardPathFormula(), storm::exceptions::InvalidArgumentException, "The given formula is invalid."); - std::unique_ptr<CheckResult> result = this->computeRewards(checkTask.replaceFormula(stateFormula.getSubformula().asRewardPathFormula())); + std::unique_ptr<CheckResult> result = this->computeRewards(checkTask.substituteFormula(stateFormula.getSubformula().asPathFormula())); if (checkTask.isBoundSet()) { STORM_LOG_THROW(result->isQuantitative(), storm::exceptions::InvalidOperationException, "Unable to perform comparison operation on non-quantitative result."); @@ -199,7 +201,7 @@ namespace storm { storm::logic::ExpectedTimeOperatorFormula const& stateFormula = checkTask.getFormula(); STORM_LOG_THROW(stateFormula.getSubformula().isEventuallyFormula(), storm::exceptions::InvalidArgumentException, "The given formula is invalid."); - std::unique_ptr<CheckResult> result = this->computeExpectedTimes(checkTask.replaceFormula(stateFormula.getSubformula().asEventuallyFormula())); + std::unique_ptr<CheckResult> result = this->computeExpectedTimes(checkTask.substituteFormula(stateFormula.getSubformula().asEventuallyFormula())); if (checkTask.isBoundSet()) { STORM_LOG_THROW(result->isQuantitative(), storm::exceptions::InvalidOperationException, "Unable to perform comparison operation on non-quantitative result."); @@ -213,7 +215,7 @@ namespace storm { storm::logic::LongRunAverageOperatorFormula const& stateFormula = checkTask.getFormula(); STORM_LOG_THROW(stateFormula.getSubformula().isStateFormula(), storm::exceptions::InvalidArgumentException, "The given formula is invalid."); - std::unique_ptr<CheckResult> result = this->computeLongRunAverageProbabilities(checkTask.replaceFormula(stateFormula.getSubformula().asStateFormula())); + std::unique_ptr<CheckResult> result = this->computeLongRunAverageProbabilities(checkTask.substituteFormula(stateFormula.getSubformula().asStateFormula())); if (checkTask.isBoundSet()) { STORM_LOG_THROW(result->isQuantitative(), storm::exceptions::InvalidOperationException, "Unable to perform comparison operation on non-quantitative result."); @@ -225,7 +227,7 @@ namespace storm { std::unique_ptr<CheckResult> AbstractModelChecker::checkUnaryBooleanStateFormula(CheckTask<storm::logic::UnaryBooleanStateFormula> const& checkTask) { storm::logic::UnaryBooleanStateFormula const& stateFormula = checkTask.getFormula(); - std::unique_ptr<CheckResult> subResult = this->check(checkTask.replaceFormula<storm::logic::Formula>(stateFormula.getSubformula())); + std::unique_ptr<CheckResult> subResult = this->check(checkTask.substituteFormula<storm::logic::Formula>(stateFormula.getSubformula())); STORM_LOG_THROW(subResult->isQualitative(), storm::exceptions::InternalTypeErrorException, "Expected qualitative result."); if (stateFormula.isNot()) { subResult->asQualitativeCheckResult().complement(); diff --git a/src/modelchecker/AbstractModelChecker.h b/src/modelchecker/AbstractModelChecker.h index a4ad1b6ac..f827c99ff 100644 --- a/src/modelchecker/AbstractModelChecker.h +++ b/src/modelchecker/AbstractModelChecker.h @@ -44,10 +44,10 @@ namespace storm { virtual std::unique_ptr<CheckResult> computeUntilProbabilities(CheckTask<storm::logic::UntilFormula> const& checkTask); // The methods to compute the rewards for path formulas. - virtual std::unique_ptr<CheckResult> computeRewards(CheckTask<storm::logic::RewardPathFormula> const& checkTask); + virtual std::unique_ptr<CheckResult> computeRewards(CheckTask<storm::logic::PathFormula> const& checkTask); virtual std::unique_ptr<CheckResult> computeCumulativeRewards(CheckTask<storm::logic::CumulativeRewardFormula> const& checkTask); virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(CheckTask<storm::logic::InstantaneousRewardFormula> const& checkTask); - virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask); + virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask); virtual std::unique_ptr<CheckResult> computeLongRunAverageRewards(CheckTask<storm::logic::LongRunAverageRewardFormula> const& checkTask); // The methods to compute the long-run average and expected time. diff --git a/src/modelchecker/CheckTask.h b/src/modelchecker/CheckTask.h index be56e29e1..a780ef168 100644 --- a/src/modelchecker/CheckTask.h +++ b/src/modelchecker/CheckTask.h @@ -16,6 +16,10 @@ namespace storm { namespace modelchecker { + enum class CheckType { + Probabilities, Rewards + }; + /* * This class is used to customize the checking process of a formula. */ @@ -59,6 +63,8 @@ namespace storm { } } } else if (formula.isRewardOperatorFormula()) { + this->checkType = CheckType::Rewards; + storm::logic::RewardOperatorFormula const& rewardOperatorFormula = formula.asRewardOperatorFormula(); this->rewardModel = rewardOperatorFormula.getOptionalRewardModelName(); @@ -75,8 +81,8 @@ namespace storm { * changes the formula type of the check task object. */ template<typename NewFormulaType> - CheckTask<NewFormulaType, ValueType> replaceFormula(NewFormulaType const& newFormula) const { - return CheckTask<NewFormulaType, ValueType>(newFormula, this->optimizationDirection, this->rewardModel, this->onlyInitialStatesRelevant, this->bound, this->qualitative, this->produceSchedulers); + CheckTask<NewFormulaType, ValueType> substituteFormula(NewFormulaType const& newFormula) const { + return CheckTask<NewFormulaType, ValueType>(newFormula, this->checkType, this->optimizationDirection, this->rewardModel, this->onlyInitialStatesRelevant, this->bound, this->qualitative, this->produceSchedulers); } /*! @@ -85,6 +91,27 @@ namespace storm { FormulaType const& getFormula() const { return formula.get(); } + + /*! + * Retrieves whether probabilities are to be computed. + */ + bool computeProbabilities() const { + return checkType == CheckType::Probabilities; + } + + /*! + * Retrieves whether rewards are to be computed. + */ + bool computeRewards() const { + return checkType == CheckType::Rewards; + } + + /*! + * Retrieves the type of this task. + */ + CheckType getCheckType() const { + return checkType; + } /*! * Retrieves whether an optimization direction was set. @@ -184,6 +211,7 @@ namespace storm { * Creates a task object with the given options. * * @param formula The formula to attach to the task. + * @param checkType The type of task: whether to compute probabilities or rewards. * @param optimizationDirection If set, the probabilities will be minimized/maximized. * @param rewardModelName If given, the checking has to be done wrt. to this reward model. * @param onlyInitialStatesRelevant If set to true, the model checker may decide to only compute the values @@ -194,13 +222,16 @@ namespace storm { * @param produceSchedulers If supported by the model checker and the model formalism, schedulers to achieve * a value will be produced if this flag is set. */ - CheckTask(std::reference_wrapper<FormulaType const> const& formula, boost::optional<storm::OptimizationDirection> const& optimizationDirection, boost::optional<std::string> const& rewardModel, bool onlyInitialStatesRelevant, boost::optional<storm::logic::Bound<ValueType>> const& bound, bool qualitative, bool produceSchedulers) : formula(formula), optimizationDirection(optimizationDirection), rewardModel(rewardModel), onlyInitialStatesRelevant(onlyInitialStatesRelevant), bound(bound), qualitative(qualitative), produceSchedulers(produceSchedulers) { + CheckTask(std::reference_wrapper<FormulaType const> const& formula, CheckType checkType, boost::optional<storm::OptimizationDirection> const& optimizationDirection, boost::optional<std::string> const& rewardModel, bool onlyInitialStatesRelevant, boost::optional<storm::logic::Bound<ValueType>> const& bound, bool qualitative, bool produceSchedulers) : formula(formula), checkType(checkType), optimizationDirection(optimizationDirection), rewardModel(rewardModel), onlyInitialStatesRelevant(onlyInitialStatesRelevant), bound(bound), qualitative(qualitative), produceSchedulers(produceSchedulers) { // Intentionally left empty. } // The formula that is to be checked. std::reference_wrapper<FormulaType const> formula; + // A type indicating whether probabilities or rewards are to be computed. + CheckType checkType; + // If set, the probabilities will be minimized/maximized. boost::optional<storm::OptimizationDirection> optimizationDirection; diff --git a/src/modelchecker/csl/HybridCtmcCslModelChecker.cpp b/src/modelchecker/csl/HybridCtmcCslModelChecker.cpp index a5eb27b27..412ab836c 100644 --- a/src/modelchecker/csl/HybridCtmcCslModelChecker.cpp +++ b/src/modelchecker/csl/HybridCtmcCslModelChecker.cpp @@ -25,7 +25,7 @@ namespace storm { template<storm::dd::DdType DdType, class ValueType> bool HybridCtmcCslModelChecker<DdType, ValueType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const { storm::logic::Formula const& formula = checkTask.getFormula(); - return formula.isCslStateFormula() || formula.isCslPathFormula() || formula.isRewardPathFormula(); + return formula.isCslStateFormula() || formula.isCslPathFormula(); } template<storm::dd::DdType DdType, class ValueType> @@ -54,9 +54,9 @@ namespace storm { } template<storm::dd::DdType DdType, class ValueType> - std::unique_ptr<CheckResult> HybridCtmcCslModelChecker<DdType, ValueType>::computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) { - storm::logic::ReachabilityRewardFormula const& rewardPathFormula = checkTask.getFormula(); - std::unique_ptr<CheckResult> subResultPointer = this->check(rewardPathFormula.getSubformula()); + std::unique_ptr<CheckResult> HybridCtmcCslModelChecker<DdType, ValueType>::computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) { + storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula(); + std::unique_ptr<CheckResult> subResultPointer = this->check(eventuallyFormula.getSubformula()); SymbolicQualitativeCheckResult<DdType> const& subResult = subResultPointer->asSymbolicQualitativeCheckResult<DdType>(); return storm::modelchecker::helper::HybridCtmcCslHelper<DdType, ValueType>::computeReachabilityRewards(this->getModel(), this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *linearEquationSolverFactory); diff --git a/src/modelchecker/csl/HybridCtmcCslModelChecker.h b/src/modelchecker/csl/HybridCtmcCslModelChecker.h index ace5b420b..d1e26bcb2 100644 --- a/src/modelchecker/csl/HybridCtmcCslModelChecker.h +++ b/src/modelchecker/csl/HybridCtmcCslModelChecker.h @@ -23,7 +23,7 @@ namespace storm { virtual std::unique_ptr<CheckResult> computeUntilProbabilities(CheckTask<storm::logic::UntilFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(CheckTask<storm::logic::InstantaneousRewardFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeCumulativeRewards(CheckTask<storm::logic::CumulativeRewardFormula> const& checkTask) override; - virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) override; + virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeLongRunAverageProbabilities(CheckTask<storm::logic::StateFormula> const& checkTask) override; protected: diff --git a/src/modelchecker/csl/SparseCtmcCslModelChecker.cpp b/src/modelchecker/csl/SparseCtmcCslModelChecker.cpp index b06cc2a54..e91547e81 100644 --- a/src/modelchecker/csl/SparseCtmcCslModelChecker.cpp +++ b/src/modelchecker/csl/SparseCtmcCslModelChecker.cpp @@ -32,7 +32,7 @@ namespace storm { template <typename SparseCtmcModelType> bool SparseCtmcCslModelChecker<SparseCtmcModelType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const { storm::logic::Formula const& formula = checkTask.getFormula(); - return formula.isCslStateFormula() || formula.isCslPathFormula() || formula.isRewardPathFormula(); + return formula.isCslStateFormula() || formula.isCslPathFormula(); } template <typename SparseCtmcModelType> @@ -91,9 +91,9 @@ namespace storm { } template <typename SparseCtmcModelType> - std::unique_ptr<CheckResult> SparseCtmcCslModelChecker<SparseCtmcModelType>::computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) { - storm::logic::ReachabilityRewardFormula const& rewardPathFormula = checkTask.getFormula(); - std::unique_ptr<CheckResult> subResultPointer = this->check(rewardPathFormula.getSubformula()); + std::unique_ptr<CheckResult> SparseCtmcCslModelChecker<SparseCtmcModelType>::computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) { + storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula(); + std::unique_ptr<CheckResult> subResultPointer = this->check(eventuallyFormula.getSubformula()); ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult(); std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseCtmcCslHelper<ValueType>::computeReachabilityRewards(this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), this->getModel().getExitRateVector(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *linearEquationSolverFactory); diff --git a/src/modelchecker/csl/SparseCtmcCslModelChecker.h b/src/modelchecker/csl/SparseCtmcCslModelChecker.h index d4e36071a..8def83dc7 100644 --- a/src/modelchecker/csl/SparseCtmcCslModelChecker.h +++ b/src/modelchecker/csl/SparseCtmcCslModelChecker.h @@ -26,7 +26,7 @@ namespace storm { virtual std::unique_ptr<CheckResult> computeUntilProbabilities(CheckTask<storm::logic::UntilFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeCumulativeRewards(CheckTask<storm::logic::CumulativeRewardFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(CheckTask<storm::logic::InstantaneousRewardFormula> const& checkTask) override; - virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) override; + virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeLongRunAverageProbabilities(CheckTask<storm::logic::StateFormula> const& checkTask) override; private: diff --git a/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.cpp b/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.cpp index b33b01436..b5966bf4c 100644 --- a/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.cpp +++ b/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.cpp @@ -30,7 +30,7 @@ namespace storm { template<typename SparseMarkovAutomatonModelType> bool SparseMarkovAutomatonCslModelChecker<SparseMarkovAutomatonModelType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const { storm::logic::Formula const& formula = checkTask.getFormula(); - return formula.isCslStateFormula() || formula.isCslPathFormula() || (formula.isRewardPathFormula() && formula.isReachabilityRewardFormula()); + return formula.isCslStateFormula() || formula.isCslPathFormula(); } template<typename SparseMarkovAutomatonModelType> @@ -59,11 +59,11 @@ namespace storm { } template<typename SparseMarkovAutomatonModelType> - std::unique_ptr<CheckResult> SparseMarkovAutomatonCslModelChecker<SparseMarkovAutomatonModelType>::computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) { - storm::logic::ReachabilityRewardFormula const& rewardPathFormula = checkTask.getFormula(); + std::unique_ptr<CheckResult> SparseMarkovAutomatonCslModelChecker<SparseMarkovAutomatonModelType>::computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) { + storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula(); STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); STORM_LOG_THROW(this->getModel().isClosed(), storm::exceptions::InvalidPropertyException, "Unable to compute reachability rewards in non-closed Markov automaton."); - std::unique_ptr<CheckResult> subResultPointer = this->check(rewardPathFormula.getSubformula()); + std::unique_ptr<CheckResult> subResultPointer = this->check(eventuallyFormula.getSubformula()); ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult(); std::vector<ValueType> result = storm::modelchecker::helper::SparseMarkovAutomatonCslHelper<ValueType>::computeReachabilityRewards(checkTask.getOptimizationDirection(), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), this->getModel().getExitRates(), this->getModel().getMarkovianStates(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *minMaxLinearEquationSolverFactory); diff --git a/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h b/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h index e57f9d3e5..4e4f60850 100644 --- a/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h +++ b/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h @@ -23,7 +23,7 @@ namespace storm { virtual bool canHandle(CheckTask<storm::logic::Formula> const& checkTask) const override; virtual std::unique_ptr<CheckResult> computeBoundedUntilProbabilities(CheckTask<storm::logic::BoundedUntilFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeUntilProbabilities(CheckTask<storm::logic::UntilFormula> const& checkTask) override; - virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) override; + virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeLongRunAverageProbabilities(CheckTask<storm::logic::StateFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeExpectedTimes(CheckTask<storm::logic::EventuallyFormula> const& checkTask) override; diff --git a/src/modelchecker/prctl/HybridDtmcPrctlModelChecker.cpp b/src/modelchecker/prctl/HybridDtmcPrctlModelChecker.cpp index c5e2225aa..b9b0bec0a 100644 --- a/src/modelchecker/prctl/HybridDtmcPrctlModelChecker.cpp +++ b/src/modelchecker/prctl/HybridDtmcPrctlModelChecker.cpp @@ -36,7 +36,7 @@ namespace storm { template<storm::dd::DdType DdType, typename ValueType> bool HybridDtmcPrctlModelChecker<DdType, ValueType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const { storm::logic::Formula const& formula = checkTask.getFormula(); - return formula.isPctlStateFormula() || formula.isPctlPathFormula() || formula.isRewardPathFormula(); + return formula.isPctlStateFormula() || formula.isPctlPathFormula(); } template<storm::dd::DdType DdType, typename ValueType> @@ -91,9 +91,9 @@ namespace storm { } template<storm::dd::DdType DdType, typename ValueType> - std::unique_ptr<CheckResult> HybridDtmcPrctlModelChecker<DdType, ValueType>::computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) { - storm::logic::ReachabilityRewardFormula const& rewardPathFormula = checkTask.getFormula(); - std::unique_ptr<CheckResult> subResultPointer = this->check(rewardPathFormula.getSubformula()); + std::unique_ptr<CheckResult> HybridDtmcPrctlModelChecker<DdType, ValueType>::computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) { + storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula(); + std::unique_ptr<CheckResult> subResultPointer = this->check(eventuallyFormula.getSubformula()); SymbolicQualitativeCheckResult<DdType> const& subResult = subResultPointer->asSymbolicQualitativeCheckResult<DdType>(); return storm::modelchecker::helper::HybridDtmcPrctlHelper<DdType, ValueType>::computeReachabilityRewards(this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *this->linearEquationSolverFactory); } diff --git a/src/modelchecker/prctl/HybridDtmcPrctlModelChecker.h b/src/modelchecker/prctl/HybridDtmcPrctlModelChecker.h index 4d64f6f17..b723ea699 100644 --- a/src/modelchecker/prctl/HybridDtmcPrctlModelChecker.h +++ b/src/modelchecker/prctl/HybridDtmcPrctlModelChecker.h @@ -24,7 +24,7 @@ namespace storm { virtual std::unique_ptr<CheckResult> computeGloballyProbabilities(CheckTask<storm::logic::GloballyFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeCumulativeRewards(CheckTask<storm::logic::CumulativeRewardFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(CheckTask<storm::logic::InstantaneousRewardFormula> const& checkTask) override; - virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) override; + virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeLongRunAverageProbabilities(CheckTask<storm::logic::StateFormula> const& checkTask) override; protected: diff --git a/src/modelchecker/prctl/HybridMdpPrctlModelChecker.cpp b/src/modelchecker/prctl/HybridMdpPrctlModelChecker.cpp index 6dfd0d83b..cd39e8c62 100644 --- a/src/modelchecker/prctl/HybridMdpPrctlModelChecker.cpp +++ b/src/modelchecker/prctl/HybridMdpPrctlModelChecker.cpp @@ -30,11 +30,11 @@ namespace storm { template<storm::dd::DdType DdType, typename ValueType> bool HybridMdpPrctlModelChecker<DdType, ValueType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const { storm::logic::Formula const& formula = checkTask.getFormula(); - if (formula.isPctlStateFormula() || formula.isPctlPathFormula() || formula.isRewardPathFormula()) { + if (formula.isPctlStateFormula() || formula.isPctlPathFormula()) { return true; } if (formula.isProbabilityOperatorFormula()) { - return this->canHandle(checkTask.replaceFormula(formula.asProbabilityOperatorFormula().getSubformula())); + return this->canHandle(checkTask.substituteFormula(formula.asProbabilityOperatorFormula().getSubformula())); } if (formula.isGloballyFormula()) { return true; @@ -100,10 +100,10 @@ namespace storm { } template<storm::dd::DdType DdType, typename ValueType> - std::unique_ptr<CheckResult> HybridMdpPrctlModelChecker<DdType, ValueType>::computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) { - storm::logic::ReachabilityRewardFormula const& rewardPathFormula = checkTask.getFormula(); + std::unique_ptr<CheckResult> HybridMdpPrctlModelChecker<DdType, ValueType>::computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) { + storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula(); STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); - std::unique_ptr<CheckResult> subResultPointer = this->check(rewardPathFormula.getSubformula()); + std::unique_ptr<CheckResult> subResultPointer = this->check(eventuallyFormula.getSubformula()); SymbolicQualitativeCheckResult<DdType> const& subResult = subResultPointer->asSymbolicQualitativeCheckResult<DdType>(); return storm::modelchecker::helper::HybridMdpPrctlHelper<DdType, ValueType>::computeReachabilityRewards(checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *this->linearEquationSolverFactory); } diff --git a/src/modelchecker/prctl/HybridMdpPrctlModelChecker.h b/src/modelchecker/prctl/HybridMdpPrctlModelChecker.h index 78612a378..ec3ef2955 100644 --- a/src/modelchecker/prctl/HybridMdpPrctlModelChecker.h +++ b/src/modelchecker/prctl/HybridMdpPrctlModelChecker.h @@ -31,7 +31,7 @@ namespace storm { virtual std::unique_ptr<CheckResult> computeGloballyProbabilities(CheckTask<storm::logic::GloballyFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeCumulativeRewards(CheckTask<storm::logic::CumulativeRewardFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(CheckTask<storm::logic::InstantaneousRewardFormula> const& checkTask) override; - virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) override; + virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) override; protected: storm::models::symbolic::Mdp<DdType, ValueType> const& getModel() const override; diff --git a/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.cpp b/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.cpp index d4bb73950..dce8a8138 100644 --- a/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.cpp +++ b/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.cpp @@ -34,14 +34,14 @@ namespace storm { template<typename SparseDtmcModelType> bool SparseDtmcPrctlModelChecker<SparseDtmcModelType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const { storm::logic::Formula const& formula = checkTask.getFormula(); - if (formula.isPctlStateFormula() || formula.isPctlPathFormula() || formula.isRewardPathFormula()) { + if (formula.isPctlStateFormula() || formula.isPctlPathFormula()) { return true; } if (formula.isGloballyFormula()) { return true; } if (formula.isProbabilityOperatorFormula()) { - return this->canHandle(checkTask.replaceFormula(formula.asProbabilityOperatorFormula().getSubformula())); + return this->canHandle(checkTask.substituteFormula(formula.asProbabilityOperatorFormula().getSubformula())); } if (formula.isConditionalPathFormula()) { storm::logic::ConditionalPathFormula const& conditionalPathFormula = formula.asConditionalPathFormula(); @@ -111,9 +111,9 @@ namespace storm { } template<typename SparseDtmcModelType> - std::unique_ptr<CheckResult> SparseDtmcPrctlModelChecker<SparseDtmcModelType>::computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) { - storm::logic::ReachabilityRewardFormula const& rewardPathFormula = checkTask.getFormula(); - std::unique_ptr<CheckResult> subResultPointer = this->check(rewardPathFormula.getSubformula()); + std::unique_ptr<CheckResult> SparseDtmcPrctlModelChecker<SparseDtmcModelType>::computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) { + storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula(); + std::unique_ptr<CheckResult> subResultPointer = this->check(eventuallyFormula.getSubformula()); ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult(); std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeReachabilityRewards(this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *linearEquationSolverFactory); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); diff --git a/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h b/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h index 77217a3ac..acc7d9283 100644 --- a/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h +++ b/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h @@ -27,7 +27,7 @@ namespace storm { virtual std::unique_ptr<CheckResult> computeConditionalProbabilities(CheckTask<storm::logic::ConditionalPathFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeCumulativeRewards(CheckTask<storm::logic::CumulativeRewardFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(CheckTask<storm::logic::InstantaneousRewardFormula> const& checkTask) override; - virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) override; + virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeLongRunAverageProbabilities(CheckTask<storm::logic::StateFormula> const& checkTask) override; private: diff --git a/src/modelchecker/prctl/SparseMdpPrctlModelChecker.cpp b/src/modelchecker/prctl/SparseMdpPrctlModelChecker.cpp index 710d926a7..a7a56a890 100644 --- a/src/modelchecker/prctl/SparseMdpPrctlModelChecker.cpp +++ b/src/modelchecker/prctl/SparseMdpPrctlModelChecker.cpp @@ -39,11 +39,11 @@ namespace storm { template<typename SparseMdpModelType> bool SparseMdpPrctlModelChecker<SparseMdpModelType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const { storm::logic::Formula const& formula = checkTask.getFormula(); - if (formula.isPctlStateFormula() || formula.isPctlPathFormula() || formula.isRewardPathFormula()) { + if (formula.isPctlStateFormula() || formula.isPctlPathFormula()) { return true; } if (formula.isProbabilityOperatorFormula()) { - return this->canHandle(checkTask.replaceFormula(formula.asProbabilityOperatorFormula().getSubformula())); + return this->canHandle(checkTask.substituteFormula(formula.asProbabilityOperatorFormula().getSubformula())); } if (formula.isGloballyFormula()) { return true; @@ -140,10 +140,10 @@ namespace storm { } template<typename SparseMdpModelType> - std::unique_ptr<CheckResult> SparseMdpPrctlModelChecker<SparseMdpModelType>::computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) { - storm::logic::ReachabilityRewardFormula const& rewardPathFormula = checkTask.getFormula(); + std::unique_ptr<CheckResult> SparseMdpPrctlModelChecker<SparseMdpModelType>::computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) { + storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula(); STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidArgumentException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); - std::unique_ptr<CheckResult> subResultPointer = this->check(rewardPathFormula.getSubformula()); + std::unique_ptr<CheckResult> subResultPointer = this->check(eventuallyFormula.getSubformula()); ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult(); std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeReachabilityRewards(checkTask.getOptimizationDirection(), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *minMaxLinearEquationSolverFactory); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); diff --git a/src/modelchecker/prctl/SparseMdpPrctlModelChecker.h b/src/modelchecker/prctl/SparseMdpPrctlModelChecker.h index 1a0d85b2c..37cd6ef5b 100644 --- a/src/modelchecker/prctl/SparseMdpPrctlModelChecker.h +++ b/src/modelchecker/prctl/SparseMdpPrctlModelChecker.h @@ -25,7 +25,7 @@ namespace storm { virtual std::unique_ptr<CheckResult> computeConditionalProbabilities(CheckTask<storm::logic::ConditionalPathFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeCumulativeRewards(CheckTask<storm::logic::CumulativeRewardFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(CheckTask<storm::logic::InstantaneousRewardFormula> const& checkTask) override; - virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) override; + virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeLongRunAverageProbabilities(CheckTask<storm::logic::StateFormula> const& checkTask) override; private: diff --git a/src/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.cpp b/src/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.cpp index 0053d6b77..2394a3176 100644 --- a/src/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.cpp +++ b/src/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.cpp @@ -32,11 +32,11 @@ namespace storm { template<storm::dd::DdType DdType, typename ValueType> bool SymbolicDtmcPrctlModelChecker<DdType, ValueType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const { storm::logic::Formula const& formula = checkTask.getFormula(); - if (formula.isPctlStateFormula() || formula.isPctlPathFormula() || formula.isRewardPathFormula()) { + if (formula.isPctlStateFormula() || formula.isPctlPathFormula()) { return true; } if (formula.isProbabilityOperatorFormula()) { - return this->canHandle(checkTask.replaceFormula(formula.asProbabilityOperatorFormula().getSubformula())); + return this->canHandle(checkTask.substituteFormula(formula.asProbabilityOperatorFormula().getSubformula())); } if (formula.isGloballyFormula()) { return true; @@ -102,9 +102,9 @@ namespace storm { } template<storm::dd::DdType DdType, typename ValueType> - std::unique_ptr<CheckResult> SymbolicDtmcPrctlModelChecker<DdType, ValueType>::computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) { - storm::logic::ReachabilityRewardFormula const& rewardPathFormula = checkTask.getFormula(); - std::unique_ptr<CheckResult> subResultPointer = this->check(rewardPathFormula.getSubformula()); + std::unique_ptr<CheckResult> SymbolicDtmcPrctlModelChecker<DdType, ValueType>::computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) { + storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula(); + std::unique_ptr<CheckResult> subResultPointer = this->check(eventuallyFormula.getSubformula()); SymbolicQualitativeCheckResult<DdType> const& subResult = subResultPointer->asSymbolicQualitativeCheckResult<DdType>(); storm::dd::Add<DdType> numericResult = storm::modelchecker::helper::SymbolicDtmcPrctlHelper<DdType, ValueType>::computeReachabilityRewards(this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *this->linearEquationSolverFactory); return std::unique_ptr<SymbolicQuantitativeCheckResult<DdType>>(new SymbolicQuantitativeCheckResult<DdType>(this->getModel().getReachableStates(), numericResult)); diff --git a/src/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.h b/src/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.h index a7968a56a..3472ee1b0 100644 --- a/src/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.h +++ b/src/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.h @@ -21,7 +21,7 @@ namespace storm { virtual std::unique_ptr<CheckResult> computeGloballyProbabilities(CheckTask<storm::logic::GloballyFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeCumulativeRewards(CheckTask<storm::logic::CumulativeRewardFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(CheckTask<storm::logic::InstantaneousRewardFormula> const& checkTask) override; - virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) override; + virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) override; protected: storm::models::symbolic::Dtmc<DdType, ValueType> const& getModel() const override; diff --git a/src/modelchecker/prctl/SymbolicMdpPrctlModelChecker.cpp b/src/modelchecker/prctl/SymbolicMdpPrctlModelChecker.cpp index 30891afdf..9b74594dc 100644 --- a/src/modelchecker/prctl/SymbolicMdpPrctlModelChecker.cpp +++ b/src/modelchecker/prctl/SymbolicMdpPrctlModelChecker.cpp @@ -32,11 +32,11 @@ namespace storm { template<storm::dd::DdType DdType, typename ValueType> bool SymbolicMdpPrctlModelChecker<DdType, ValueType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const { storm::logic::Formula const& formula = checkTask.getFormula(); - if (formula.isPctlStateFormula() || formula.isPctlPathFormula() || formula.isRewardPathFormula()) { + if (formula.isPctlStateFormula() || formula.isPctlPathFormula()) { return true; } if (formula.isProbabilityOperatorFormula()) { - return this->canHandle(checkTask.replaceFormula(formula.asProbabilityOperatorFormula().getSubformula())); + return this->canHandle(checkTask.substituteFormula(formula.asProbabilityOperatorFormula().getSubformula())); } if (formula.isGloballyFormula()) { return true; @@ -102,10 +102,10 @@ namespace storm { } template<storm::dd::DdType DdType, typename ValueType> - std::unique_ptr<CheckResult> SymbolicMdpPrctlModelChecker<DdType, ValueType>::computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) { - storm::logic::ReachabilityRewardFormula const& rewardPathFormula = checkTask.getFormula(); + std::unique_ptr<CheckResult> SymbolicMdpPrctlModelChecker<DdType, ValueType>::computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) { + storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula(); STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); - std::unique_ptr<CheckResult> subResultPointer = this->check(rewardPathFormula.getSubformula()); + std::unique_ptr<CheckResult> subResultPointer = this->check(eventuallyFormula.getSubformula()); SymbolicQualitativeCheckResult<DdType> const& subResult = subResultPointer->asSymbolicQualitativeCheckResult<DdType>(); return storm::modelchecker::helper::SymbolicMdpPrctlHelper<DdType, ValueType>::computeReachabilityRewards(checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *this->linearEquationSolverFactory); } diff --git a/src/modelchecker/prctl/SymbolicMdpPrctlModelChecker.h b/src/modelchecker/prctl/SymbolicMdpPrctlModelChecker.h index 1baca69da..488971353 100644 --- a/src/modelchecker/prctl/SymbolicMdpPrctlModelChecker.h +++ b/src/modelchecker/prctl/SymbolicMdpPrctlModelChecker.h @@ -23,7 +23,7 @@ namespace storm { virtual std::unique_ptr<CheckResult> computeGloballyProbabilities(CheckTask<storm::logic::GloballyFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeCumulativeRewards(CheckTask<storm::logic::CumulativeRewardFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(CheckTask<storm::logic::InstantaneousRewardFormula> const& checkTask) override; - virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) override; + virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) override; protected: storm::models::symbolic::Mdp<DdType, ValueType> const& getModel() const override; diff --git a/src/modelchecker/reachability/SparseDtmcEliminationModelChecker.cpp b/src/modelchecker/reachability/SparseDtmcEliminationModelChecker.cpp index 554eba5e3..98afe49a1 100644 --- a/src/modelchecker/reachability/SparseDtmcEliminationModelChecker.cpp +++ b/src/modelchecker/reachability/SparseDtmcEliminationModelChecker.cpp @@ -83,9 +83,9 @@ namespace storm { bool SparseDtmcEliminationModelChecker<SparseDtmcModelType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const { storm::logic::Formula const& formula = checkTask.getFormula(); if (formula.isProbabilityOperatorFormula()) { - return this->canHandle(checkTask.replaceFormula(formula.asProbabilityOperatorFormula().getSubformula())); + return this->canHandle(checkTask.substituteFormula(formula.asProbabilityOperatorFormula().getSubformula())); } else if (formula.isRewardOperatorFormula()) { - return this->canHandle(checkTask.replaceFormula(formula.asRewardOperatorFormula().getSubformula())); + return this->canHandle(checkTask.substituteFormula(formula.asRewardOperatorFormula().getSubformula())); } else if (formula.isUntilFormula() || formula.isEventuallyFormula()) { if (formula.isUntilFormula()) { storm::logic::UntilFormula const& untilFormula = formula.asUntilFormula(); @@ -103,11 +103,6 @@ namespace storm { if (boundedUntilFormula.getLeftSubformula().isPropositionalFormula() && boundedUntilFormula.getRightSubformula().isPropositionalFormula()) { return true; } - } else if (formula.isReachabilityRewardFormula()) { - storm::logic::ReachabilityRewardFormula const& reachabilityRewardFormula = formula.asReachabilityRewardFormula(); - if (reachabilityRewardFormula.getSubformula().isPropositionalFormula()) { - return true; - } } else if (formula.isConditionalPathFormula()) { storm::logic::ConditionalPathFormula const& conditionalPathFormula = formula.asConditionalPathFormula(); if (conditionalPathFormula.getLeftSubformula().isEventuallyFormula() && conditionalPathFormula.getRightSubformula().isEventuallyFormula()) { @@ -579,11 +574,11 @@ namespace storm { } template<typename SparseDtmcModelType> - std::unique_ptr<CheckResult> SparseDtmcEliminationModelChecker<SparseDtmcModelType>::computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) { - storm::logic::ReachabilityRewardFormula const& rewardPathFormula = checkTask.getFormula(); + std::unique_ptr<CheckResult> SparseDtmcEliminationModelChecker<SparseDtmcModelType>::computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) { + storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula(); // Retrieve the appropriate bitvectors by model checking the subformulas. - std::unique_ptr<CheckResult> subResultPointer = this->check(rewardPathFormula.getSubformula()); + std::unique_ptr<CheckResult> subResultPointer = this->check(eventuallyFormula.getSubformula()); storm::storage::BitVector phiStates(this->getModel().getNumberOfStates(), true); storm::storage::BitVector const& psiStates = subResultPointer->asExplicitQualitativeCheckResult().getTruthValuesVector(); diff --git a/src/modelchecker/reachability/SparseDtmcEliminationModelChecker.h b/src/modelchecker/reachability/SparseDtmcEliminationModelChecker.h index 809522260..af5b464be 100644 --- a/src/modelchecker/reachability/SparseDtmcEliminationModelChecker.h +++ b/src/modelchecker/reachability/SparseDtmcEliminationModelChecker.h @@ -26,7 +26,7 @@ namespace storm { virtual bool canHandle(CheckTask<storm::logic::Formula> const& checkTask) const override; virtual std::unique_ptr<CheckResult> computeBoundedUntilProbabilities(CheckTask<storm::logic::BoundedUntilFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeUntilProbabilities(CheckTask<storm::logic::UntilFormula> const& checkTask) override; - virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) override; + virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeLongRunAverageRewards(CheckTask<storm::logic::LongRunAverageRewardFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeConditionalProbabilities(CheckTask<storm::logic::ConditionalPathFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeLongRunAverageProbabilities(CheckTask<storm::logic::StateFormula> const& checkTask) override; diff --git a/src/parser/FormulaParser.cpp b/src/parser/FormulaParser.cpp index c919280b4..4bf036e4f 100644 --- a/src/parser/FormulaParser.cpp +++ b/src/parser/FormulaParser.cpp @@ -129,7 +129,6 @@ namespace storm { qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> rewardPathFormula; qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> cumulativeRewardFormula; - qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> reachabilityRewardFormula; qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> instantaneousRewardFormula; qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> longRunAverageRewardFormula; @@ -139,7 +138,6 @@ namespace storm { // Methods that actually create the expression objects. std::shared_ptr<storm::logic::Formula> createInstantaneousRewardFormula(boost::variant<unsigned, double> const& timeBound) const; std::shared_ptr<storm::logic::Formula> createCumulativeRewardFormula(boost::variant<unsigned, double> const& timeBound) const; - std::shared_ptr<storm::logic::Formula> createReachabilityRewardFormula(std::shared_ptr<storm::logic::Formula> const& stateFormula) const; std::shared_ptr<storm::logic::Formula> createLongRunAverageRewardFormula() const; std::shared_ptr<storm::logic::Formula> createAtomicExpressionFormula(storm::expressions::Expression const& expression) const; std::shared_ptr<storm::logic::Formula> createBooleanLiteralFormula(bool literal) const; @@ -255,10 +253,7 @@ namespace storm { cumulativeRewardFormula = (qi::lit("C<=") >> strict_double)[qi::_val = phoenix::bind(&FormulaParserGrammar::createCumulativeRewardFormula, phoenix::ref(*this), qi::_1)] | (qi::lit("C<=") > qi::uint_)[qi::_val = phoenix::bind(&FormulaParserGrammar::createCumulativeRewardFormula, phoenix::ref(*this), qi::_1)]; cumulativeRewardFormula.name("cumulative reward formula"); - reachabilityRewardFormula = (qi::lit("F") > stateFormula)[qi::_val = phoenix::bind(&FormulaParserGrammar::createReachabilityRewardFormula, phoenix::ref(*this), qi::_1)]; - reachabilityRewardFormula.name("reachability reward formula"); - - rewardPathFormula = reachabilityRewardFormula | cumulativeRewardFormula | instantaneousRewardFormula | longRunAverageRewardFormula; + rewardPathFormula = eventuallyFormula | cumulativeRewardFormula | instantaneousRewardFormula | longRunAverageRewardFormula | conditionalFormula; rewardPathFormula.name("reward path formula"); expressionFormula = expressionParser[qi::_val = phoenix::bind(&FormulaParserGrammar::createAtomicExpressionFormula, phoenix::ref(*this), qi::_1)]; @@ -382,7 +377,6 @@ namespace storm { qi::on_error<qi::fail>(labelFormula, handler(qi::_1, qi::_2, qi::_3, qi::_4)); qi::on_error<qi::fail>(expressionFormula, handler(qi::_1, qi::_2, qi::_3, qi::_4)); qi::on_error<qi::fail>(rewardPathFormula, handler(qi::_1, qi::_2, qi::_3, qi::_4)); - qi::on_error<qi::fail>(reachabilityRewardFormula, handler(qi::_1, qi::_2, qi::_3, qi::_4)); qi::on_error<qi::fail>(cumulativeRewardFormula, handler(qi::_1, qi::_2, qi::_3, qi::_4)); qi::on_error<qi::fail>(instantaneousRewardFormula, handler(qi::_1, qi::_2, qi::_3, qi::_4)); } @@ -411,10 +405,6 @@ namespace storm { } } - std::shared_ptr<storm::logic::Formula> FormulaParserGrammar::createReachabilityRewardFormula(std::shared_ptr<storm::logic::Formula> const& stateFormula) const { - return std::shared_ptr<storm::logic::Formula>(new storm::logic::ReachabilityRewardFormula(stateFormula)); - } - std::shared_ptr<storm::logic::Formula> FormulaParserGrammar::createLongRunAverageRewardFormula() const { return std::shared_ptr<storm::logic::Formula>(new storm::logic::LongRunAverageRewardFormula()); } diff --git a/src/storage/bisimulation/BisimulationDecomposition.cpp b/src/storage/bisimulation/BisimulationDecomposition.cpp index c8c47c5a8..902a69288 100644 --- a/src/storage/bisimulation/BisimulationDecomposition.cpp +++ b/src/storage/bisimulation/BisimulationDecomposition.cpp @@ -122,11 +122,6 @@ namespace storm { if (rightSubformula->isPropositionalFormula()) { measureDrivenInitialPartition = true; } - } else if (newFormula->isReachabilityRewardFormula()) { - rightSubformula = newFormula->asReachabilityRewardFormula().getSubformula().asSharedPointer(); - if (rightSubformula->isPropositionalFormula()) { - measureDrivenInitialPartition = true; - } } if (measureDrivenInitialPartition) { From be8c65525ef1e837a1579e9b8b80a61161c6efff Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Tue, 16 Feb 2016 21:12:55 +0100 Subject: [PATCH 02/23] introduced some methods to query formula type Former-commit-id: 9ecc13566de3141c424483b3e06094889c5ae0de --- src/logic/AtomicExpressionFormula.cpp | 4 +++ src/logic/AtomicExpressionFormula.h | 1 + src/logic/AtomicLabelFormula.cpp | 4 +++ src/logic/AtomicLabelFormula.h | 1 + src/logic/BinaryPathFormula.cpp | 4 +++ src/logic/BinaryPathFormula.h | 1 + src/logic/BinaryStateFormula.cpp | 4 +++ src/logic/BinaryStateFormula.h | 1 + src/logic/BooleanLiteralFormula.cpp | 4 +++ src/logic/BooleanLiteralFormula.h | 1 + src/logic/BoundedUntilFormula.cpp | 4 +++ src/logic/BoundedUntilFormula.h | 1 + src/logic/ConditionalPathFormula.cpp | 14 +++++++- src/logic/ConditionalPathFormula.h | 8 ++++- src/logic/CumulativeRewardFormula.cpp | 4 +++ src/logic/CumulativeRewardFormula.h | 1 + src/logic/EventuallyFormula.cpp | 10 ++++-- src/logic/EventuallyFormula.h | 5 ++- src/logic/ExpectedTimeOperatorFormula.cpp | 4 +++ src/logic/ExpectedTimeOperatorFormula.h | 1 + src/logic/Formula.cpp | 32 +++++++++++++++++++ src/logic/Formula.h | 8 +++++ src/logic/InstantaneousRewardFormula.cpp | 4 +++ src/logic/InstantaneousRewardFormula.h | 1 + src/logic/LongRunAverageOperatorFormula.cpp | 4 +++ src/logic/LongRunAverageOperatorFormula.h | 1 + src/logic/LongRunAverageRewardFormula.cpp | 4 +++ src/logic/LongRunAverageRewardFormula.h | 1 + src/logic/ProbabilityOperatorFormula.cpp | 4 +++ src/logic/ProbabilityOperatorFormula.h | 1 + src/logic/RewardOperatorFormula.cpp | 5 ++- src/logic/RewardOperatorFormula.h | 2 +- src/logic/UnaryPathFormula.cpp | 4 +++ src/logic/UnaryPathFormula.h | 1 + src/logic/UnaryStateFormula.cpp | 4 +++ src/logic/UnaryStateFormula.h | 1 + .../csl/HybridCtmcCslModelChecker.cpp | 2 +- src/parser/FormulaParser.cpp | 28 ++++++++-------- 38 files changed, 159 insertions(+), 25 deletions(-) diff --git a/src/logic/AtomicExpressionFormula.cpp b/src/logic/AtomicExpressionFormula.cpp index 6747d2ab5..35c7149b0 100644 --- a/src/logic/AtomicExpressionFormula.cpp +++ b/src/logic/AtomicExpressionFormula.cpp @@ -13,6 +13,10 @@ namespace storm { bool AtomicExpressionFormula::isPctlStateFormula() const { return true; } + + bool AtomicExpressionFormula::isPctlWithConditionalStateFormula() const { + return true; + } bool AtomicExpressionFormula::isLtlFormula() const { return true; diff --git a/src/logic/AtomicExpressionFormula.h b/src/logic/AtomicExpressionFormula.h index f054c9e42..2b2e36dd5 100644 --- a/src/logic/AtomicExpressionFormula.h +++ b/src/logic/AtomicExpressionFormula.h @@ -16,6 +16,7 @@ namespace storm { virtual bool isAtomicExpressionFormula() const override; virtual bool isPctlStateFormula() const override; + virtual bool isPctlWithConditionalStateFormula() const override; virtual bool isLtlFormula() const override; virtual bool isPropositionalFormula() const override; diff --git a/src/logic/AtomicLabelFormula.cpp b/src/logic/AtomicLabelFormula.cpp index 0555ff56a..36c00eb23 100644 --- a/src/logic/AtomicLabelFormula.cpp +++ b/src/logic/AtomicLabelFormula.cpp @@ -14,6 +14,10 @@ namespace storm { return true; } + bool AtomicLabelFormula::isPctlWithConditionalStateFormula() const { + return true; + } + bool AtomicLabelFormula::isLtlFormula() const { return true; } diff --git a/src/logic/AtomicLabelFormula.h b/src/logic/AtomicLabelFormula.h index 8cd2f51f1..3d326c211 100644 --- a/src/logic/AtomicLabelFormula.h +++ b/src/logic/AtomicLabelFormula.h @@ -18,6 +18,7 @@ namespace storm { virtual bool isAtomicLabelFormula() const override; virtual bool isPctlStateFormula() const override; + virtual bool isPctlWithConditionalStateFormula() const override; virtual bool isLtlFormula() const override; virtual bool isPropositionalFormula() const override; diff --git a/src/logic/BinaryPathFormula.cpp b/src/logic/BinaryPathFormula.cpp index 949dbf378..5075894c4 100644 --- a/src/logic/BinaryPathFormula.cpp +++ b/src/logic/BinaryPathFormula.cpp @@ -14,6 +14,10 @@ namespace storm { return this->getLeftSubformula().isPctlStateFormula() && this->getRightSubformula().isPctlStateFormula(); } + bool BinaryPathFormula::isPctlWithConditionalPathFormula() const { + return this->getLeftSubformula().isPctlWithConditionalPathFormula() && this->getRightSubformula().isPctlWithConditionalPathFormula(); + } + bool BinaryPathFormula::isCslPathFormula() const { return this->getLeftSubformula().isCslStateFormula() && this->getRightSubformula().isCslStateFormula(); } diff --git a/src/logic/BinaryPathFormula.h b/src/logic/BinaryPathFormula.h index 928d21728..14d162926 100644 --- a/src/logic/BinaryPathFormula.h +++ b/src/logic/BinaryPathFormula.h @@ -18,6 +18,7 @@ namespace storm { virtual bool isBinaryPathFormula() const override; virtual bool isPctlPathFormula() const override; + virtual bool isPctlWithConditionalPathFormula() const override; virtual bool isCslPathFormula() const override; virtual bool isLtlFormula() const override; virtual bool containsBoundedUntilFormula() const override; diff --git a/src/logic/BinaryStateFormula.cpp b/src/logic/BinaryStateFormula.cpp index 6993707ad..bcaa2d39b 100644 --- a/src/logic/BinaryStateFormula.cpp +++ b/src/logic/BinaryStateFormula.cpp @@ -13,6 +13,10 @@ namespace storm { bool BinaryStateFormula::isPctlStateFormula() const { return this->getLeftSubformula().isPctlStateFormula() && this->getRightSubformula().isPctlStateFormula(); } + + bool BinaryStateFormula::isPctlWithConditionalStateFormula() const { + return this->getLeftSubformula().isPctlWithConditionalStateFormula() && this->getRightSubformula().isPctlWithConditionalStateFormula(); + } bool BinaryStateFormula::isCslStateFormula() const { return this->getLeftSubformula().isCslStateFormula() && this->getRightSubformula().isCslStateFormula(); diff --git a/src/logic/BinaryStateFormula.h b/src/logic/BinaryStateFormula.h index a0fcbc9d1..c259aa759 100644 --- a/src/logic/BinaryStateFormula.h +++ b/src/logic/BinaryStateFormula.h @@ -16,6 +16,7 @@ namespace storm { virtual bool isBinaryStateFormula() const override; virtual bool isPctlStateFormula() const override; + virtual bool isPctlWithConditionalStateFormula() const override; virtual bool isCslStateFormula() const override; virtual bool isLtlFormula() const override; virtual bool containsBoundedUntilFormula() const override; diff --git a/src/logic/BooleanLiteralFormula.cpp b/src/logic/BooleanLiteralFormula.cpp index aa78a6772..d021bbc64 100644 --- a/src/logic/BooleanLiteralFormula.cpp +++ b/src/logic/BooleanLiteralFormula.cpp @@ -18,6 +18,10 @@ namespace storm { return true; } + bool BooleanLiteralFormula::isPctlWithConditionalStateFormula() const { + return true; + } + bool BooleanLiteralFormula::isLtlFormula() const { return true; } diff --git a/src/logic/BooleanLiteralFormula.h b/src/logic/BooleanLiteralFormula.h index d8df08651..1283fde71 100644 --- a/src/logic/BooleanLiteralFormula.h +++ b/src/logic/BooleanLiteralFormula.h @@ -18,6 +18,7 @@ namespace storm { virtual bool isFalseFormula() const override; virtual bool isPctlStateFormula() const override; + virtual bool isPctlWithConditionalStateFormula() const override; virtual bool isLtlFormula() const override; virtual bool isPropositionalFormula() const override; diff --git a/src/logic/BoundedUntilFormula.cpp b/src/logic/BoundedUntilFormula.cpp index 7c29c579b..9a1f867e1 100644 --- a/src/logic/BoundedUntilFormula.cpp +++ b/src/logic/BoundedUntilFormula.cpp @@ -38,6 +38,10 @@ namespace storm { return this->hasDiscreteTimeBound() && this->getLeftSubformula().isPctlStateFormula() && this->getRightSubformula().isPctlStateFormula(); } + bool BoundedUntilFormula::isPctlWithConditionalPathFormula() const { + return this->hasDiscreteTimeBound() && this->getLeftSubformula().isPctlWithConditionalStateFormula() && this->getRightSubformula().isPctlWithConditionalStateFormula(); + } + bool BoundedUntilFormula::isCslPathFormula() const { return this->getLeftSubformula().isCslStateFormula() && this->getRightSubformula().isCslStateFormula(); } diff --git a/src/logic/BoundedUntilFormula.h b/src/logic/BoundedUntilFormula.h index 7da7e70f6..bc14d8def 100644 --- a/src/logic/BoundedUntilFormula.h +++ b/src/logic/BoundedUntilFormula.h @@ -23,6 +23,7 @@ namespace storm { uint_fast64_t getDiscreteTimeBound() const; virtual bool isValidProbabilityPathFormula() const override; + virtual bool isPctlWithConditionalPathFormula() const override; virtual bool isPctlPathFormula() const override; virtual bool isCslPathFormula() const override; diff --git a/src/logic/ConditionalPathFormula.cpp b/src/logic/ConditionalPathFormula.cpp index 8ef461e35..676a83185 100644 --- a/src/logic/ConditionalPathFormula.cpp +++ b/src/logic/ConditionalPathFormula.cpp @@ -2,7 +2,7 @@ namespace storm { namespace logic { - ConditionalPathFormula::ConditionalPathFormula(std::shared_ptr<Formula const> const& leftSubformula, std::shared_ptr<Formula const> const& rightSubformula) : BinaryPathFormula(leftSubformula, rightSubformula) { + ConditionalPathFormula::ConditionalPathFormula(std::shared_ptr<Formula const> const& leftSubformula, std::shared_ptr<Formula const> const& rightSubformula, bool isRewardFormula) : BinaryPathFormula(leftSubformula, rightSubformula), isRewardFormula(isRewardFormula) { // Intentionally left empty. } @@ -14,6 +14,18 @@ namespace storm { return true; } + bool ConditionalPathFormula::isPctlWithConditionalPathFormula() const { + return this->getLeftSubformula().isPctlPathFormula() && this->getRightSubformula().isPctlPathFormula(); + } + + bool ConditionalPathFormula::isRewardPathFormula() const { + return this->isRewardFormula && this->isValidRewardPathFormula(); + } + + bool ConditionalPathFormula::isValidRewardPathFormula() const { + return this->getLeftSubformula().isRewardPathFormula() && !this->getLeftSubformula().isConditionalPathFormula() && this->getRightSubformula().isPctlPathFormula(); + } + std::shared_ptr<Formula> ConditionalPathFormula::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const { return std::make_shared<ConditionalPathFormula>(this->getLeftSubformula().substitute(substitution), this->getRightSubformula().substitute(substitution)); } diff --git a/src/logic/ConditionalPathFormula.h b/src/logic/ConditionalPathFormula.h index a3e12e20f..94053606b 100644 --- a/src/logic/ConditionalPathFormula.h +++ b/src/logic/ConditionalPathFormula.h @@ -7,18 +7,24 @@ namespace storm { namespace logic { class ConditionalPathFormula : public BinaryPathFormula { public: - ConditionalPathFormula(std::shared_ptr<Formula const> const& leftSubformula, std::shared_ptr<Formula const> const& rightSubformula); + ConditionalPathFormula(std::shared_ptr<Formula const> const& leftSubformula, std::shared_ptr<Formula const> const& rightSubformula, bool isRewardFormula = false); virtual ~ConditionalPathFormula() { // Intentionally left empty. } + virtual bool isPctlWithConditionalPathFormula() const override; + virtual bool isRewardPathFormula() const override; virtual bool isConditionalPathFormula() const override; virtual bool isValidProbabilityPathFormula() const override; + virtual bool isValidRewardPathFormula() const override; virtual std::ostream& writeToStream(std::ostream& out) const override; virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override; + + private: + bool isRewardFormula; }; } } diff --git a/src/logic/CumulativeRewardFormula.cpp b/src/logic/CumulativeRewardFormula.cpp index 3f53c2e9d..2a00c04f3 100644 --- a/src/logic/CumulativeRewardFormula.cpp +++ b/src/logic/CumulativeRewardFormula.cpp @@ -10,6 +10,10 @@ namespace storm { // Intentionally left empty. } + bool CumulativeRewardFormula::isRewardPathFormula() const { + return true; + } + bool CumulativeRewardFormula::isCumulativeRewardFormula() const { return true; } diff --git a/src/logic/CumulativeRewardFormula.h b/src/logic/CumulativeRewardFormula.h index 4ebf08cd4..0192a8a49 100644 --- a/src/logic/CumulativeRewardFormula.h +++ b/src/logic/CumulativeRewardFormula.h @@ -17,6 +17,7 @@ namespace storm { // Intentionally left empty. } + virtual bool isRewardPathFormula() const override; virtual bool isCumulativeRewardFormula() const override; virtual bool isValidRewardPathFormula() const override; diff --git a/src/logic/EventuallyFormula.cpp b/src/logic/EventuallyFormula.cpp index a25d12b33..8b09281cd 100644 --- a/src/logic/EventuallyFormula.cpp +++ b/src/logic/EventuallyFormula.cpp @@ -2,7 +2,7 @@ namespace storm { namespace logic { - EventuallyFormula::EventuallyFormula(std::shared_ptr<Formula const> const& subformula) : UnaryPathFormula(subformula) { + EventuallyFormula::EventuallyFormula(std::shared_ptr<Formula const> const& subformula, bool isRewardFormula) : UnaryPathFormula(subformula), isRewardFormula(isRewardFormula) { // Intentionally left empty. } @@ -10,12 +10,16 @@ namespace storm { return true; } + bool EventuallyFormula::isRewardPathFormula() const { + return isRewardFormula; + } + bool EventuallyFormula::isValidProbabilityPathFormula() const { - return true; + return !isRewardFormula; } bool EventuallyFormula::isValidRewardPathFormula() const { - return true; + return isRewardFormula; } std::shared_ptr<Formula> EventuallyFormula::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const { diff --git a/src/logic/EventuallyFormula.h b/src/logic/EventuallyFormula.h index a488eb443..3b121d320 100644 --- a/src/logic/EventuallyFormula.h +++ b/src/logic/EventuallyFormula.h @@ -7,13 +7,14 @@ namespace storm { namespace logic { class EventuallyFormula : public UnaryPathFormula { public: - EventuallyFormula(std::shared_ptr<Formula const> const& subformula); + EventuallyFormula(std::shared_ptr<Formula const> const& subformula, bool isRewardFormula = false); virtual ~EventuallyFormula() { // Intentionally left empty. } virtual bool isEventuallyFormula() const override; + virtual bool isRewardPathFormula() const override; virtual bool isValidProbabilityPathFormula() const override; virtual bool isValidRewardPathFormula() const override; @@ -21,6 +22,8 @@ namespace storm { virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override; + private: + bool isRewardFormula; }; } } diff --git a/src/logic/ExpectedTimeOperatorFormula.cpp b/src/logic/ExpectedTimeOperatorFormula.cpp index ed21be228..8165710a1 100644 --- a/src/logic/ExpectedTimeOperatorFormula.cpp +++ b/src/logic/ExpectedTimeOperatorFormula.cpp @@ -26,6 +26,10 @@ namespace storm { return this->getSubformula().isPctlStateFormula(); } + bool ExpectedTimeOperatorFormula::isPctlWithConditionalStateFormula() const { + return this->getSubformula().isPctlWithConditionalStateFormula(); + } + bool ExpectedTimeOperatorFormula::containsProbabilityOperator() const { return this->getSubformula().containsProbabilityOperator(); } diff --git a/src/logic/ExpectedTimeOperatorFormula.h b/src/logic/ExpectedTimeOperatorFormula.h index 5702610c2..162fb39f8 100644 --- a/src/logic/ExpectedTimeOperatorFormula.h +++ b/src/logic/ExpectedTimeOperatorFormula.h @@ -20,6 +20,7 @@ namespace storm { virtual bool isExpectedTimeOperatorFormula() const override; virtual bool isPctlStateFormula() const override; + virtual bool isPctlWithConditionalStateFormula() const override; virtual bool containsProbabilityOperator() const override; virtual bool containsNestedProbabilityOperators() const override; diff --git a/src/logic/Formula.cpp b/src/logic/Formula.cpp index e3fa84c74..9f9151b84 100644 --- a/src/logic/Formula.cpp +++ b/src/logic/Formula.cpp @@ -111,6 +111,22 @@ namespace storm { return false; } + bool Formula::isPctlFormula() const { + return this->isPctlStateFormula() || this->isPctlPathFormula(); + } + + bool Formula::isPctlWithConditionalFormula() const { + return this->isPctlWithConditionalStateFormula() || this->isPctlWithConditionalPathFormula(); + } + + bool Formula::isRewardFormula() const { + return this->isRewardStateFormula() || this->isRewardPathFormula(); + } + + bool Formula::isCslFormula() const { + return this->isCslStateFormula() || this->isCslPathFormula(); + } + bool Formula::isPctlPathFormula() const { return false; } @@ -119,6 +135,14 @@ namespace storm { return false; } + bool Formula::isPctlWithConditionalPathFormula() const { + return false; + } + + bool Formula::isPctlWithConditionalStateFormula() const { + return false; + } + bool Formula::isCslPathFormula() const { return this->isPctlPathFormula(); } @@ -127,6 +151,14 @@ namespace storm { return this->isPctlStateFormula(); } + bool Formula::isRewardPathFormula() const { + return false; + } + + bool Formula::isRewardStateFormula() const { + return false; + } + bool Formula::isPltlFormula() const { return false; } diff --git a/src/logic/Formula.h b/src/logic/Formula.h index 2ea234449..cf4333eb4 100644 --- a/src/logic/Formula.h +++ b/src/logic/Formula.h @@ -79,10 +79,18 @@ namespace storm { virtual bool isRewardOperatorFormula() const; virtual bool isOperatorFormula() const; + bool isPctlFormula() const; + bool isPctlWithConditionalFormula() const; + bool isRewardFormula() const; + bool isCslFormula() const; virtual bool isPctlPathFormula() const; virtual bool isPctlStateFormula() const; + virtual bool isPctlWithConditionalPathFormula() const; + virtual bool isPctlWithConditionalStateFormula() const; virtual bool isCslPathFormula() const; virtual bool isCslStateFormula() const; + virtual bool isRewardPathFormula() const; + virtual bool isRewardStateFormula() const; virtual bool isPltlFormula() const; virtual bool isLtlFormula() const; virtual bool isPropositionalFormula() const; diff --git a/src/logic/InstantaneousRewardFormula.cpp b/src/logic/InstantaneousRewardFormula.cpp index 77efb5705..7289f18e9 100644 --- a/src/logic/InstantaneousRewardFormula.cpp +++ b/src/logic/InstantaneousRewardFormula.cpp @@ -18,6 +18,10 @@ namespace storm { return true; } + bool InstantaneousRewardFormula::isRewardPathFormula() const { + return true; + } + bool InstantaneousRewardFormula::hasDiscreteTimeBound() const { return timeBound.which() == 0; } diff --git a/src/logic/InstantaneousRewardFormula.h b/src/logic/InstantaneousRewardFormula.h index c895c5b39..967f03a2b 100644 --- a/src/logic/InstantaneousRewardFormula.h +++ b/src/logic/InstantaneousRewardFormula.h @@ -17,6 +17,7 @@ namespace storm { // Intentionally left empty. } + virtual bool isRewardPathFormula() const override; virtual bool isInstantaneousRewardFormula() const override; virtual bool isValidRewardPathFormula() const override; diff --git a/src/logic/LongRunAverageOperatorFormula.cpp b/src/logic/LongRunAverageOperatorFormula.cpp index cfeb30692..1563dc67e 100644 --- a/src/logic/LongRunAverageOperatorFormula.cpp +++ b/src/logic/LongRunAverageOperatorFormula.cpp @@ -26,6 +26,10 @@ namespace storm { return this->getSubformula().isPctlStateFormula(); } + bool LongRunAverageOperatorFormula::isPctlWithConditionalStateFormula() const { + return this->getSubformula().isPctlWithConditionalStateFormula(); + } + bool LongRunAverageOperatorFormula::containsProbabilityOperator() const { return this->getSubformula().containsProbabilityOperator(); } diff --git a/src/logic/LongRunAverageOperatorFormula.h b/src/logic/LongRunAverageOperatorFormula.h index 89e119f48..85eb9f969 100644 --- a/src/logic/LongRunAverageOperatorFormula.h +++ b/src/logic/LongRunAverageOperatorFormula.h @@ -20,6 +20,7 @@ namespace storm { virtual bool isLongRunAverageOperatorFormula() const override; virtual bool isPctlStateFormula() const override; + virtual bool isPctlWithConditionalStateFormula() const override; virtual bool containsProbabilityOperator() const override; virtual bool containsNestedProbabilityOperators() const override; diff --git a/src/logic/LongRunAverageRewardFormula.cpp b/src/logic/LongRunAverageRewardFormula.cpp index 7bc064c1e..9d9dc898d 100644 --- a/src/logic/LongRunAverageRewardFormula.cpp +++ b/src/logic/LongRunAverageRewardFormula.cpp @@ -14,6 +14,10 @@ namespace storm { return true; } + bool LongRunAverageRewardFormula::isRewardPathFormula() const { + return true; + } + std::shared_ptr<Formula> LongRunAverageRewardFormula::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const { return std::shared_ptr<Formula>(new LongRunAverageRewardFormula()); } diff --git a/src/logic/LongRunAverageRewardFormula.h b/src/logic/LongRunAverageRewardFormula.h index aa4d3f424..929a6f3c8 100644 --- a/src/logic/LongRunAverageRewardFormula.h +++ b/src/logic/LongRunAverageRewardFormula.h @@ -13,6 +13,7 @@ namespace storm { // Intentionally left empty. } + virtual bool isRewardPathFormula() const override; virtual bool isLongRunAverageRewardFormula() const override; virtual bool isValidRewardPathFormula() const override; diff --git a/src/logic/ProbabilityOperatorFormula.cpp b/src/logic/ProbabilityOperatorFormula.cpp index 1f4615556..cb584b034 100644 --- a/src/logic/ProbabilityOperatorFormula.cpp +++ b/src/logic/ProbabilityOperatorFormula.cpp @@ -26,6 +26,10 @@ namespace storm { return this->getSubformula().isPctlPathFormula(); } + bool ProbabilityOperatorFormula::isPctlWithConditionalStateFormula() const { + return this->getSubformula().isPctlWithConditionalPathFormula(); + } + bool ProbabilityOperatorFormula::isCslStateFormula() const { return this->getSubformula().isCslPathFormula(); } diff --git a/src/logic/ProbabilityOperatorFormula.h b/src/logic/ProbabilityOperatorFormula.h index 8bae11548..163e05f58 100644 --- a/src/logic/ProbabilityOperatorFormula.h +++ b/src/logic/ProbabilityOperatorFormula.h @@ -18,6 +18,7 @@ namespace storm { } virtual bool isPctlStateFormula() const override; + virtual bool isPctlWithConditionalStateFormula() const override; virtual bool isCslStateFormula() const override; virtual bool isPltlFormula() const override; virtual bool containsProbabilityOperator() const override; diff --git a/src/logic/RewardOperatorFormula.cpp b/src/logic/RewardOperatorFormula.cpp index 1e5390830..0eea0eedc 100644 --- a/src/logic/RewardOperatorFormula.cpp +++ b/src/logic/RewardOperatorFormula.cpp @@ -22,9 +22,8 @@ namespace storm { return true; } - bool RewardOperatorFormula::isPctlStateFormula() const { - Formula const& subformula = this->getSubformula(); - return subformula.isEventuallyFormula() || subformula.isCumulativeRewardFormula() || subformula.isInstantaneousRewardFormula(); + bool RewardOperatorFormula::isRewardStateFormula() const { + return this->getSubformula().isRewardPathFormula(); } bool RewardOperatorFormula::containsRewardOperator() const { diff --git a/src/logic/RewardOperatorFormula.h b/src/logic/RewardOperatorFormula.h index 9e90ef01f..0cbfe955e 100644 --- a/src/logic/RewardOperatorFormula.h +++ b/src/logic/RewardOperatorFormula.h @@ -19,8 +19,8 @@ namespace storm { } virtual bool isRewardOperatorFormula() const override; + virtual bool isRewardStateFormula() const override; - virtual bool isPctlStateFormula() const override; virtual bool containsRewardOperator() const override; virtual bool containsNestedRewardOperators() const override; diff --git a/src/logic/UnaryPathFormula.cpp b/src/logic/UnaryPathFormula.cpp index d961f1612..01ccadde8 100644 --- a/src/logic/UnaryPathFormula.cpp +++ b/src/logic/UnaryPathFormula.cpp @@ -14,6 +14,10 @@ namespace storm { return this->getSubformula().isPctlStateFormula(); } + bool UnaryPathFormula::isPctlWithConditionalPathFormula() const { + return this->getSubformula().isPctlWithConditionalStateFormula(); + } + bool UnaryPathFormula::isLtlFormula() const { return this->getSubformula().isLtlFormula(); } diff --git a/src/logic/UnaryPathFormula.h b/src/logic/UnaryPathFormula.h index 8d168585c..be60edbd9 100644 --- a/src/logic/UnaryPathFormula.h +++ b/src/logic/UnaryPathFormula.h @@ -18,6 +18,7 @@ namespace storm { virtual bool isUnaryPathFormula() const override; virtual bool isPctlPathFormula() const override; + virtual bool isPctlWithConditionalPathFormula() const override; virtual bool isLtlFormula() const override; virtual bool containsBoundedUntilFormula() const override; virtual bool containsNextFormula() const override; diff --git a/src/logic/UnaryStateFormula.cpp b/src/logic/UnaryStateFormula.cpp index 4bf651aa1..a57b86b1e 100644 --- a/src/logic/UnaryStateFormula.cpp +++ b/src/logic/UnaryStateFormula.cpp @@ -18,6 +18,10 @@ namespace storm { return this->getSubformula().isPctlStateFormula(); } + bool UnaryStateFormula::isPctlWithConditionalStateFormula() const { + return this->getSubformula().isPctlWithConditionalStateFormula(); + } + bool UnaryStateFormula::isLtlFormula() const { return this->getSubformula().isLtlFormula(); } diff --git a/src/logic/UnaryStateFormula.h b/src/logic/UnaryStateFormula.h index 745687e6b..8b5539a88 100644 --- a/src/logic/UnaryStateFormula.h +++ b/src/logic/UnaryStateFormula.h @@ -16,6 +16,7 @@ namespace storm { virtual bool isUnaryStateFormula() const override; virtual bool isPropositionalFormula() const override; + virtual bool isPctlWithConditionalStateFormula() const override; virtual bool isPctlStateFormula() const override; virtual bool isLtlFormula() const override; virtual bool containsBoundedUntilFormula() const override; diff --git a/src/modelchecker/csl/HybridCtmcCslModelChecker.cpp b/src/modelchecker/csl/HybridCtmcCslModelChecker.cpp index 412ab836c..c6b7c9d1e 100644 --- a/src/modelchecker/csl/HybridCtmcCslModelChecker.cpp +++ b/src/modelchecker/csl/HybridCtmcCslModelChecker.cpp @@ -25,7 +25,7 @@ namespace storm { template<storm::dd::DdType DdType, class ValueType> bool HybridCtmcCslModelChecker<DdType, ValueType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const { storm::logic::Formula const& formula = checkTask.getFormula(); - return formula.isCslStateFormula() || formula.isCslPathFormula(); + return formula.isCslFormula() || formula.isRewardFormula(); } template<storm::dd::DdType DdType, class ValueType> diff --git a/src/parser/FormulaParser.cpp b/src/parser/FormulaParser.cpp index 4bf036e4f..1298b3fa2 100644 --- a/src/parser/FormulaParser.cpp +++ b/src/parser/FormulaParser.cpp @@ -120,8 +120,8 @@ namespace storm { qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> expressionFormula; qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), qi::locals<bool>, Skipper> booleanLiteralFormula; - qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> conditionalFormula; - qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> eventuallyFormula; + qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(bool), Skipper> conditionalFormula; + qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(bool), Skipper> eventuallyFormula; qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> nextFormula; qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> globallyFormula; qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> untilFormula; @@ -142,11 +142,11 @@ namespace storm { std::shared_ptr<storm::logic::Formula> createAtomicExpressionFormula(storm::expressions::Expression const& expression) const; std::shared_ptr<storm::logic::Formula> createBooleanLiteralFormula(bool literal) const; std::shared_ptr<storm::logic::Formula> createAtomicLabelFormula(std::string const& label) const; - std::shared_ptr<storm::logic::Formula> createEventuallyFormula(boost::optional<boost::variant<std::pair<double, double>, uint_fast64_t>> const& timeBound, std::shared_ptr<storm::logic::Formula> const& subformula) const; + std::shared_ptr<storm::logic::Formula> createEventuallyFormula(boost::optional<boost::variant<std::pair<double, double>, uint_fast64_t>> const& timeBound, bool reward, std::shared_ptr<storm::logic::Formula> const& subformula) const; std::shared_ptr<storm::logic::Formula> createGloballyFormula(std::shared_ptr<storm::logic::Formula> const& subformula) const; std::shared_ptr<storm::logic::Formula> createNextFormula(std::shared_ptr<storm::logic::Formula> const& subformula) const; std::shared_ptr<storm::logic::Formula> createUntilFormula(std::shared_ptr<storm::logic::Formula> const& leftSubformula, boost::optional<boost::variant<std::pair<double, double>, uint_fast64_t>> const& timeBound, std::shared_ptr<storm::logic::Formula> const& rightSubformula); - std::shared_ptr<storm::logic::Formula> createConditionalFormula(std::shared_ptr<storm::logic::Formula> const& leftSubformula, std::shared_ptr<storm::logic::Formula> const& rightSubformula) const; + std::shared_ptr<storm::logic::Formula> createConditionalFormula(std::shared_ptr<storm::logic::Formula> const& leftSubformula, std::shared_ptr<storm::logic::Formula> const& rightSubformula, bool reward) const; std::pair<boost::optional<storm::OptimizationDirection>, boost::optional<storm::logic::Bound<double>>> createOperatorInformation(boost::optional<storm::OptimizationDirection> const& optimizationDirection, boost::optional<storm::logic::ComparisonType> const& comparisonType, boost::optional<double> const& threshold) const; std::shared_ptr<storm::logic::Formula> createLongRunAverageOperatorFormula(std::pair<boost::optional<storm::OptimizationDirection>, boost::optional<storm::logic::Bound<double>>> const& operatorInformation, std::shared_ptr<storm::logic::Formula> const& subformula) const; std::shared_ptr<storm::logic::Formula> createRewardOperatorFormula(boost::optional<std::string> const& rewardModelName, std::pair<boost::optional<storm::OptimizationDirection>, boost::optional<storm::logic::Bound<double>>> const& operatorInformation, std::shared_ptr<storm::logic::Formula> const& subformula) const; @@ -253,7 +253,7 @@ namespace storm { cumulativeRewardFormula = (qi::lit("C<=") >> strict_double)[qi::_val = phoenix::bind(&FormulaParserGrammar::createCumulativeRewardFormula, phoenix::ref(*this), qi::_1)] | (qi::lit("C<=") > qi::uint_)[qi::_val = phoenix::bind(&FormulaParserGrammar::createCumulativeRewardFormula, phoenix::ref(*this), qi::_1)]; cumulativeRewardFormula.name("cumulative reward formula"); - rewardPathFormula = eventuallyFormula | cumulativeRewardFormula | instantaneousRewardFormula | longRunAverageRewardFormula | conditionalFormula; + rewardPathFormula = eventuallyFormula(true) | cumulativeRewardFormula | instantaneousRewardFormula | longRunAverageRewardFormula | conditionalFormula(true); rewardPathFormula.name("reward path formula"); expressionFormula = expressionParser[qi::_val = phoenix::bind(&FormulaParserGrammar::createAtomicExpressionFormula, phoenix::ref(*this), qi::_1)]; @@ -277,7 +277,7 @@ namespace storm { notStateFormula = (-unaryBooleanOperator_ >> atomicStateFormula)[qi::_val = phoenix::bind(&FormulaParserGrammar::createUnaryBooleanStateFormula, phoenix::ref(*this), qi::_2, qi::_1)]; notStateFormula.name("negation formula"); - eventuallyFormula = (qi::lit("F") >> -timeBound >> pathFormulaWithoutUntil)[qi::_val = phoenix::bind(&FormulaParserGrammar::createEventuallyFormula, phoenix::ref(*this), qi::_1, qi::_2)]; + eventuallyFormula = (qi::lit("F") >> -timeBound >> pathFormulaWithoutUntil)[qi::_val = phoenix::bind(&FormulaParserGrammar::createEventuallyFormula, phoenix::ref(*this), qi::_1, qi::_r1, qi::_2)]; eventuallyFormula.name("eventually formula"); globallyFormula = (qi::lit("G") >> pathFormulaWithoutUntil)[qi::_val = phoenix::bind(&FormulaParserGrammar::createGloballyFormula, phoenix::ref(*this), qi::_1)]; @@ -286,19 +286,19 @@ namespace storm { nextFormula = (qi::lit("X") >> pathFormulaWithoutUntil)[qi::_val = phoenix::bind(&FormulaParserGrammar::createNextFormula, phoenix::ref(*this), qi::_1)]; nextFormula.name("next formula"); - pathFormulaWithoutUntil = eventuallyFormula | globallyFormula | nextFormula | stateFormula; + pathFormulaWithoutUntil = eventuallyFormula(false) | globallyFormula | nextFormula | stateFormula; pathFormulaWithoutUntil.name("path formula"); untilFormula = pathFormulaWithoutUntil[qi::_val = qi::_1] >> *(qi::lit("U") >> -timeBound >> pathFormulaWithoutUntil)[qi::_val = phoenix::bind(&FormulaParserGrammar::createUntilFormula, phoenix::ref(*this), qi::_val, qi::_1, qi::_2)]; untilFormula.name("until formula"); - conditionalFormula = untilFormula[qi::_val = qi::_1] >> *(qi::lit("||") >> untilFormula)[qi::_val = phoenix::bind(&FormulaParserGrammar::createConditionalFormula, phoenix::ref(*this), qi::_val, qi::_1)]; + conditionalFormula = untilFormula[qi::_val = qi::_1] >> *(qi::lit("||") >> untilFormula)[qi::_val = phoenix::bind(&FormulaParserGrammar::createConditionalFormula, phoenix::ref(*this), qi::_val, qi::_1, qi::_r1)]; conditionalFormula.name("conditional formula"); timeBound = (qi::lit("[") > qi::double_ > qi::lit(",") > qi::double_ > qi::lit("]"))[qi::_val = phoenix::construct<std::pair<double, double>>(qi::_1, qi::_2)] | (qi::lit("<=") >> strict_double)[qi::_val = phoenix::construct<std::pair<double, double>>(0, qi::_1)] | (qi::lit("<=") > qi::uint_)[qi::_val = qi::_1]; timeBound.name("time bound"); - pathFormula = conditionalFormula; + pathFormula = conditionalFormula(false); pathFormula.name("path formula"); operatorInformation = (-optimalityOperator_[qi::_a = qi::_1] >> ((relationalOperator_[qi::_b = qi::_1] > qi::double_[qi::_c = qi::_1]) | (qi::lit("=") > qi::lit("?"))))[qi::_val = phoenix::bind(&FormulaParserGrammar::createOperatorInformation, phoenix::ref(*this), qi::_a, qi::_b, qi::_c)]; @@ -313,7 +313,7 @@ namespace storm { rewardOperator = (qi::lit("R") > -rewardModelName > operatorInformation > qi::lit("[") > rewardPathFormula > qi::lit("]"))[qi::_val = phoenix::bind(&FormulaParserGrammar::createRewardOperatorFormula, phoenix::ref(*this), qi::_1, qi::_2, qi::_3)]; rewardOperator.name("reward operator"); - expectedTimeOperator = (qi::lit("ET") > operatorInformation > qi::lit("[") > eventuallyFormula > qi::lit("]"))[qi::_val = phoenix::bind(&FormulaParserGrammar::createExpectedTimeOperatorFormula, phoenix::ref(*this), qi::_1, qi::_2)]; + expectedTimeOperator = (qi::lit("ET") > operatorInformation > qi::lit("[") > eventuallyFormula(true) > qi::lit("]"))[qi::_val = phoenix::bind(&FormulaParserGrammar::createExpectedTimeOperatorFormula, phoenix::ref(*this), qi::_1, qi::_2)]; expectedTimeOperator.name("expected time operator"); probabilityOperator = (qi::lit("P") > operatorInformation > qi::lit("[") > pathFormula > qi::lit("]"))[qi::_val = phoenix::bind(&FormulaParserGrammar::createProbabilityOperatorFormula, phoenix::ref(*this), qi::_1, qi::_2)]; @@ -422,7 +422,7 @@ namespace storm { return std::shared_ptr<storm::logic::Formula>(new storm::logic::AtomicLabelFormula(label)); } - std::shared_ptr<storm::logic::Formula> FormulaParserGrammar::createEventuallyFormula(boost::optional<boost::variant<std::pair<double, double>, uint_fast64_t>> const& timeBound, std::shared_ptr<storm::logic::Formula> const& subformula) const { + std::shared_ptr<storm::logic::Formula> FormulaParserGrammar::createEventuallyFormula(boost::optional<boost::variant<std::pair<double, double>, uint_fast64_t>> const& timeBound, bool reward, std::shared_ptr<storm::logic::Formula> const& subformula) const { if (timeBound) { if (timeBound.get().which() == 0) { std::pair<double, double> const& bounds = boost::get<std::pair<double, double>>(timeBound.get()); @@ -431,7 +431,7 @@ namespace storm { return std::shared_ptr<storm::logic::Formula>(new storm::logic::BoundedUntilFormula(createBooleanLiteralFormula(true), subformula, static_cast<uint_fast64_t>(boost::get<uint_fast64_t>(timeBound.get())))); } } else { - return std::shared_ptr<storm::logic::Formula>(new storm::logic::EventuallyFormula(subformula)); + return std::shared_ptr<storm::logic::Formula>(new storm::logic::EventuallyFormula(subformula, reward)); } } @@ -456,8 +456,8 @@ namespace storm { } } - std::shared_ptr<storm::logic::Formula> FormulaParserGrammar::createConditionalFormula(std::shared_ptr<storm::logic::Formula> const& leftSubformula, std::shared_ptr<storm::logic::Formula> const& rightSubformula) const { - return std::shared_ptr<storm::logic::Formula>(new storm::logic::ConditionalPathFormula(leftSubformula, rightSubformula)); + std::shared_ptr<storm::logic::Formula> FormulaParserGrammar::createConditionalFormula(std::shared_ptr<storm::logic::Formula> const& leftSubformula, std::shared_ptr<storm::logic::Formula> const& rightSubformula, bool reward) const { + return std::shared_ptr<storm::logic::Formula>(new storm::logic::ConditionalPathFormula(leftSubformula, rightSubformula, reward)); } std::pair<boost::optional<storm::OptimizationDirection>, boost::optional<storm::logic::Bound<double>>> FormulaParserGrammar::createOperatorInformation(boost::optional<storm::OptimizationDirection> const& optimizationDirection, boost::optional<storm::logic::ComparisonType> const& comparisonType, boost::optional<double> const& threshold) const { From 2604df54ec2077a45353df7baed7e521c5f96c9f Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Wed, 17 Feb 2016 18:40:56 +0100 Subject: [PATCH 03/23] more refactoring of formula classes: in particular fragment checking Former-commit-id: 544c5f953fc496f4fce8f002270fa0c0380992dc --- src/builder/DdPrismModelBuilder.cpp | 6 +- src/builder/ExplicitPrismModelBuilder.cpp | 6 +- src/logic/AtomicExpressionFormula.cpp | 18 +- src/logic/AtomicExpressionFormula.h | 5 +- src/logic/AtomicLabelFormula.cpp | 18 +- src/logic/AtomicLabelFormula.h | 5 +- src/logic/BinaryBooleanStateFormula.cpp | 6 +- src/logic/BinaryBooleanStateFormula.h | 2 +- src/logic/BinaryPathFormula.cpp | 42 +--- src/logic/BinaryPathFormula.h | 11 -- src/logic/BinaryStateFormula.cpp | 42 +--- src/logic/BinaryStateFormula.h | 11 -- src/logic/BooleanLiteralFormula.cpp | 26 +-- src/logic/BooleanLiteralFormula.h | 7 +- src/logic/BoundedUntilFormula.cpp | 26 +-- src/logic/BoundedUntilFormula.h | 9 +- src/logic/ConditionalFormula.cpp | 42 ++++ src/logic/ConditionalFormula.h | 38 ++++ src/logic/ConditionalPathFormula.cpp | 40 ---- src/logic/ConditionalPathFormula.h | 32 --- src/logic/CumulativeRewardFormula.cpp | 10 +- src/logic/CumulativeRewardFormula.h | 7 +- src/logic/EventuallyFormula.cpp | 28 ++- src/logic/EventuallyFormula.h | 14 +- src/logic/ExpectedTimeOperatorFormula.cpp | 18 +- src/logic/ExpectedTimeOperatorFormula.h | 9 +- src/logic/Formula.cpp | 108 ++-------- src/logic/Formula.h | 107 ++++------ src/logic/FormulaVisitor.h | 36 ++++ src/logic/Formulas.h | 2 +- src/logic/FormulasForwardDeclarations.h | 36 ++++ src/logic/FragmentChecker.cpp | 118 +++++++++++ src/logic/FragmentChecker.h | 39 ++++ src/logic/FragmentSpecification.cpp | 209 ++++++++++++++++++++ src/logic/FragmentSpecification.h | 112 +++++++++++ src/logic/GloballyFormula.cpp | 8 +- src/logic/GloballyFormula.h | 4 +- src/logic/InstantaneousRewardFormula.cpp | 8 +- src/logic/InstantaneousRewardFormula.h | 6 +- src/logic/LongRunAverageOperatorFormula.cpp | 18 +- src/logic/LongRunAverageOperatorFormula.h | 5 +- src/logic/LongRunAverageRewardFormula.cpp | 8 +- src/logic/LongRunAverageRewardFormula.h | 5 +- src/logic/NextFormula.cpp | 8 +- src/logic/NextFormula.h | 4 +- src/logic/ProbabilityOperatorFormula.cpp | 28 +-- src/logic/ProbabilityOperatorFormula.h | 9 +- src/logic/RewardOperatorFormula.cpp | 18 +- src/logic/RewardOperatorFormula.h | 6 +- src/logic/UnaryBooleanStateFormula.cpp | 6 + src/logic/UnaryBooleanStateFormula.h | 2 + src/logic/UnaryPathFormula.cpp | 38 +--- src/logic/UnaryPathFormula.h | 10 - src/logic/UnaryStateFormula.cpp | 42 +--- src/logic/UnaryStateFormula.h | 11 +- src/logic/UntilFormula.cpp | 8 +- src/logic/UntilFormula.h | 4 +- src/modelchecker/AbstractModelChecker.cpp | 20 +- src/modelchecker/AbstractModelChecker.h | 3 +- src/modelchecker/CheckTask.h | 31 +-- 60 files changed, 874 insertions(+), 681 deletions(-) create mode 100644 src/logic/ConditionalFormula.cpp create mode 100644 src/logic/ConditionalFormula.h delete mode 100644 src/logic/ConditionalPathFormula.cpp delete mode 100644 src/logic/ConditionalPathFormula.h create mode 100644 src/logic/FormulaVisitor.h create mode 100644 src/logic/FormulasForwardDeclarations.h create mode 100644 src/logic/FragmentChecker.cpp create mode 100644 src/logic/FragmentChecker.h create mode 100644 src/logic/FragmentSpecification.cpp create mode 100644 src/logic/FragmentSpecification.h diff --git a/src/builder/DdPrismModelBuilder.cpp b/src/builder/DdPrismModelBuilder.cpp index 18a156e08..e265f70c5 100644 --- a/src/builder/DdPrismModelBuilder.cpp +++ b/src/builder/DdPrismModelBuilder.cpp @@ -227,10 +227,8 @@ namespace storm { // If we are not required to build all reward models, we determine the reward models we need to build. if (!buildAllRewardModels) { - if (formula.containsRewardOperator()) { - std::set<std::string> referencedRewardModels = formula.getReferencedRewardModels(); - rewardModelsToBuild.insert(referencedRewardModels.begin(), referencedRewardModels.end()); - } + std::set<std::string> referencedRewardModels = formula.getReferencedRewardModels(); + rewardModelsToBuild.insert(referencedRewardModels.begin(), referencedRewardModels.end()); } // Extract all the labels used in the formula. diff --git a/src/builder/ExplicitPrismModelBuilder.cpp b/src/builder/ExplicitPrismModelBuilder.cpp index d345d9f05..d7c2f6293 100644 --- a/src/builder/ExplicitPrismModelBuilder.cpp +++ b/src/builder/ExplicitPrismModelBuilder.cpp @@ -185,10 +185,8 @@ namespace storm { // If we are not required to build all reward models, we determine the reward models we need to build. if (!buildAllRewardModels) { - if (formula.containsRewardOperator()) { - std::set<std::string> referencedRewardModels = formula.getReferencedRewardModels(); - rewardModelsToBuild.insert(referencedRewardModels.begin(), referencedRewardModels.end()); - } + std::set<std::string> referencedRewardModels = formula.getReferencedRewardModels(); + rewardModelsToBuild.insert(referencedRewardModels.begin(), referencedRewardModels.end()); } // Extract all the labels used in the formula. diff --git a/src/logic/AtomicExpressionFormula.cpp b/src/logic/AtomicExpressionFormula.cpp index 35c7149b0..5f8f0f509 100644 --- a/src/logic/AtomicExpressionFormula.cpp +++ b/src/logic/AtomicExpressionFormula.cpp @@ -1,5 +1,7 @@ #include "src/logic/AtomicExpressionFormula.h" +#include "src/logic/FormulaVisitor.h" + namespace storm { namespace logic { AtomicExpressionFormula::AtomicExpressionFormula(storm::expressions::Expression const& expression) : expression(expression) { @@ -10,22 +12,10 @@ namespace storm { return true; } - bool AtomicExpressionFormula::isPctlStateFormula() const { - return true; + boost::any AtomicExpressionFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const { + return visitor.visit(*this, data); } - bool AtomicExpressionFormula::isPctlWithConditionalStateFormula() const { - return true; - } - - bool AtomicExpressionFormula::isLtlFormula() const { - return true; - } - - bool AtomicExpressionFormula::isPropositionalFormula() const { - return true; - } - storm::expressions::Expression const& AtomicExpressionFormula::getExpression() const { return expression; } diff --git a/src/logic/AtomicExpressionFormula.h b/src/logic/AtomicExpressionFormula.h index 2b2e36dd5..12636475d 100644 --- a/src/logic/AtomicExpressionFormula.h +++ b/src/logic/AtomicExpressionFormula.h @@ -15,10 +15,7 @@ namespace storm { virtual bool isAtomicExpressionFormula() const override; - virtual bool isPctlStateFormula() const override; - virtual bool isPctlWithConditionalStateFormula() const override; - virtual bool isLtlFormula() const override; - virtual bool isPropositionalFormula() const override; + virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override; storm::expressions::Expression const& getExpression() const; diff --git a/src/logic/AtomicLabelFormula.cpp b/src/logic/AtomicLabelFormula.cpp index 36c00eb23..19a5f673f 100644 --- a/src/logic/AtomicLabelFormula.cpp +++ b/src/logic/AtomicLabelFormula.cpp @@ -1,5 +1,7 @@ #include "src/logic/AtomicLabelFormula.h" +#include "src/logic/FormulaVisitor.h" + namespace storm { namespace logic { AtomicLabelFormula::AtomicLabelFormula(std::string const& label) : label(label) { @@ -10,20 +12,8 @@ namespace storm { return true; } - bool AtomicLabelFormula::isPctlStateFormula() const { - return true; - } - - bool AtomicLabelFormula::isPctlWithConditionalStateFormula() const { - return true; - } - - bool AtomicLabelFormula::isLtlFormula() const { - return true; - } - - bool AtomicLabelFormula::isPropositionalFormula() const { - return true; + boost::any AtomicLabelFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const { + return visitor.visit(*this, data); } std::string const& AtomicLabelFormula::getLabel() const { diff --git a/src/logic/AtomicLabelFormula.h b/src/logic/AtomicLabelFormula.h index 3d326c211..795704305 100644 --- a/src/logic/AtomicLabelFormula.h +++ b/src/logic/AtomicLabelFormula.h @@ -17,10 +17,7 @@ namespace storm { virtual bool isAtomicLabelFormula() const override; - virtual bool isPctlStateFormula() const override; - virtual bool isPctlWithConditionalStateFormula() const override; - virtual bool isLtlFormula() const override; - virtual bool isPropositionalFormula() const override; + virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override; std::string const& getLabel() const; diff --git a/src/logic/BinaryBooleanStateFormula.cpp b/src/logic/BinaryBooleanStateFormula.cpp index 521869129..180ea12c1 100644 --- a/src/logic/BinaryBooleanStateFormula.cpp +++ b/src/logic/BinaryBooleanStateFormula.cpp @@ -1,5 +1,7 @@ #include "src/logic/BinaryBooleanStateFormula.h" +#include "src/logic/FormulaVisitor.h" + namespace storm { namespace logic { BinaryBooleanStateFormula::BinaryBooleanStateFormula(OperatorType operatorType, std::shared_ptr<Formula const> const& leftSubformula, std::shared_ptr<Formula const> const& rightSubformula) : BinaryStateFormula(leftSubformula, rightSubformula), operatorType(operatorType) { @@ -10,8 +12,8 @@ namespace storm { return true; } - bool BinaryBooleanStateFormula::isPropositionalFormula() const { - return this->getLeftSubformula().isPropositionalFormula() && this->getRightSubformula().isPropositionalFormula(); + boost::any BinaryBooleanStateFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const { + return visitor.visit(*this, data); } BinaryBooleanStateFormula::OperatorType BinaryBooleanStateFormula::getOperator() const { diff --git a/src/logic/BinaryBooleanStateFormula.h b/src/logic/BinaryBooleanStateFormula.h index 23a330ae0..6956e56c6 100644 --- a/src/logic/BinaryBooleanStateFormula.h +++ b/src/logic/BinaryBooleanStateFormula.h @@ -19,7 +19,7 @@ namespace storm { virtual bool isBinaryBooleanStateFormula() const override; - virtual bool isPropositionalFormula() const override; + virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override; OperatorType getOperator() const; diff --git a/src/logic/BinaryPathFormula.cpp b/src/logic/BinaryPathFormula.cpp index 5075894c4..4e028d567 100644 --- a/src/logic/BinaryPathFormula.cpp +++ b/src/logic/BinaryPathFormula.cpp @@ -9,47 +9,7 @@ namespace storm { bool BinaryPathFormula::isBinaryPathFormula() const { return true; } - - bool BinaryPathFormula::isPctlPathFormula() const { - return this->getLeftSubformula().isPctlStateFormula() && this->getRightSubformula().isPctlStateFormula(); - } - - bool BinaryPathFormula::isPctlWithConditionalPathFormula() const { - return this->getLeftSubformula().isPctlWithConditionalPathFormula() && this->getRightSubformula().isPctlWithConditionalPathFormula(); - } - - bool BinaryPathFormula::isCslPathFormula() const { - return this->getLeftSubformula().isCslStateFormula() && this->getRightSubformula().isCslStateFormula(); - } - - bool BinaryPathFormula::isLtlFormula() const { - return this->getLeftSubformula().isLtlFormula() && this->getRightSubformula().isLtlFormula(); - } - - bool BinaryPathFormula::containsBoundedUntilFormula() const { - return this->getLeftSubformula().containsBoundedUntilFormula() || this->getRightSubformula().containsBoundedUntilFormula(); - } - - bool BinaryPathFormula::containsNextFormula() const { - return this->getLeftSubformula().containsNextFormula() || this->getRightSubformula().containsNextFormula(); - } - - bool BinaryPathFormula::containsProbabilityOperator() const { - return this->getLeftSubformula().containsProbabilityOperator() || this->getRightSubformula().containsProbabilityOperator(); - } - - bool BinaryPathFormula::containsNestedProbabilityOperators() const { - return this->getLeftSubformula().containsNestedProbabilityOperators() || this->getRightSubformula().containsNestedProbabilityOperators(); - } - - bool BinaryPathFormula::containsRewardOperator() const { - return this->getLeftSubformula().containsRewardOperator() || this->getRightSubformula().containsRewardOperator(); - } - - bool BinaryPathFormula::containsNestedRewardOperators() const { - return this->getLeftSubformula().containsNestedRewardOperators() || this->getRightSubformula().containsNestedRewardOperators(); - } - + Formula const& BinaryPathFormula::getLeftSubformula() const { return *leftSubformula; } diff --git a/src/logic/BinaryPathFormula.h b/src/logic/BinaryPathFormula.h index 14d162926..fe0526bee 100644 --- a/src/logic/BinaryPathFormula.h +++ b/src/logic/BinaryPathFormula.h @@ -17,17 +17,6 @@ namespace storm { virtual bool isBinaryPathFormula() const override; - virtual bool isPctlPathFormula() const override; - virtual bool isPctlWithConditionalPathFormula() const override; - virtual bool isCslPathFormula() const override; - virtual bool isLtlFormula() const override; - virtual bool containsBoundedUntilFormula() const override; - virtual bool containsNextFormula() const override; - virtual bool containsProbabilityOperator() const override; - virtual bool containsNestedProbabilityOperators() const override; - virtual bool containsRewardOperator() const override; - virtual bool containsNestedRewardOperators() const override; - Formula const& getLeftSubformula() const; Formula const& getRightSubformula() const; diff --git a/src/logic/BinaryStateFormula.cpp b/src/logic/BinaryStateFormula.cpp index bcaa2d39b..9fcdad992 100644 --- a/src/logic/BinaryStateFormula.cpp +++ b/src/logic/BinaryStateFormula.cpp @@ -9,47 +9,7 @@ namespace storm { bool BinaryStateFormula::isBinaryStateFormula() const { return true; } - - bool BinaryStateFormula::isPctlStateFormula() const { - return this->getLeftSubformula().isPctlStateFormula() && this->getRightSubformula().isPctlStateFormula(); - } - - bool BinaryStateFormula::isPctlWithConditionalStateFormula() const { - return this->getLeftSubformula().isPctlWithConditionalStateFormula() && this->getRightSubformula().isPctlWithConditionalStateFormula(); - } - - bool BinaryStateFormula::isCslStateFormula() const { - return this->getLeftSubformula().isCslStateFormula() && this->getRightSubformula().isCslStateFormula(); - } - - bool BinaryStateFormula::isLtlFormula() const { - return this->getLeftSubformula().isLtlFormula() && this->getRightSubformula().isLtlFormula(); - } - - bool BinaryStateFormula::containsBoundedUntilFormula() const { - return this->getLeftSubformula().containsBoundedUntilFormula() || this->getRightSubformula().containsBoundedUntilFormula(); - } - - bool BinaryStateFormula::containsNextFormula() const { - return this->getLeftSubformula().containsNextFormula() || this->getRightSubformula().containsNextFormula(); - } - - bool BinaryStateFormula::containsProbabilityOperator() const { - return this->getLeftSubformula().containsProbabilityOperator() || this->getRightSubformula().containsProbabilityOperator(); - } - - bool BinaryStateFormula::containsNestedProbabilityOperators() const { - return this->getLeftSubformula().containsNestedProbabilityOperators() || this->getRightSubformula().containsNestedProbabilityOperators(); - } - - bool BinaryStateFormula::containsRewardOperator() const { - return this->getLeftSubformula().containsRewardOperator() || this->getRightSubformula().containsRewardOperator(); - } - - bool BinaryStateFormula::containsNestedRewardOperators() const { - return this->containsNestedRewardOperators() || this->getRightSubformula().containsNestedRewardOperators(); - } - + Formula const& BinaryStateFormula::getLeftSubformula() const { return *leftSubformula; } diff --git a/src/logic/BinaryStateFormula.h b/src/logic/BinaryStateFormula.h index c259aa759..3820097ca 100644 --- a/src/logic/BinaryStateFormula.h +++ b/src/logic/BinaryStateFormula.h @@ -15,17 +15,6 @@ namespace storm { virtual bool isBinaryStateFormula() const override; - virtual bool isPctlStateFormula() const override; - virtual bool isPctlWithConditionalStateFormula() const override; - virtual bool isCslStateFormula() const override; - virtual bool isLtlFormula() const override; - virtual bool containsBoundedUntilFormula() const override; - virtual bool containsNextFormula() const override; - virtual bool containsProbabilityOperator() const override; - virtual bool containsNestedProbabilityOperators() const override; - virtual bool containsRewardOperator() const override; - virtual bool containsNestedRewardOperators() const override; - Formula const& getLeftSubformula() const; Formula const& getRightSubformula() const; diff --git a/src/logic/BooleanLiteralFormula.cpp b/src/logic/BooleanLiteralFormula.cpp index d021bbc64..897fbf377 100644 --- a/src/logic/BooleanLiteralFormula.cpp +++ b/src/logic/BooleanLiteralFormula.cpp @@ -1,11 +1,17 @@ #include "src/logic/BooleanLiteralFormula.h" +#include "src/logic/FormulaVisitor.h" + namespace storm { namespace logic { BooleanLiteralFormula::BooleanLiteralFormula(bool value) : value(value) { // Intenionally left empty. } + bool BooleanLiteralFormula::isBooleanLiteralFormula() const { + return true; + } + bool BooleanLiteralFormula::isTrueFormula() const { return value; } @@ -14,24 +20,8 @@ namespace storm { return !value; } - bool BooleanLiteralFormula::isPctlStateFormula() const { - return true; - } - - bool BooleanLiteralFormula::isPctlWithConditionalStateFormula() const { - return true; - } - - bool BooleanLiteralFormula::isLtlFormula() const { - return true; - } - - bool BooleanLiteralFormula::isPropositionalFormula() const { - return true; - } - - bool BooleanLiteralFormula::isBooleanLiteralFormula() const { - return true; + boost::any BooleanLiteralFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const { + return visitor.visit(*this, data); } std::shared_ptr<Formula> BooleanLiteralFormula::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const { diff --git a/src/logic/BooleanLiteralFormula.h b/src/logic/BooleanLiteralFormula.h index 1283fde71..405044600 100644 --- a/src/logic/BooleanLiteralFormula.h +++ b/src/logic/BooleanLiteralFormula.h @@ -16,11 +16,8 @@ namespace storm { virtual bool isBooleanLiteralFormula() const override; virtual bool isTrueFormula() const override; virtual bool isFalseFormula() const override; - - virtual bool isPctlStateFormula() const override; - virtual bool isPctlWithConditionalStateFormula() const override; - virtual bool isLtlFormula() const override; - virtual bool isPropositionalFormula() const override; + + virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override; virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override; diff --git a/src/logic/BoundedUntilFormula.cpp b/src/logic/BoundedUntilFormula.cpp index 9a1f867e1..8f3e73286 100644 --- a/src/logic/BoundedUntilFormula.cpp +++ b/src/logic/BoundedUntilFormula.cpp @@ -3,6 +3,8 @@ #include "src/utility/macros.h" #include "src/exceptions/InvalidArgumentException.h" +#include "src/logic/FormulaVisitor.h" + namespace storm { namespace logic { BoundedUntilFormula::BoundedUntilFormula(std::shared_ptr<Formula const> const& leftSubformula, std::shared_ptr<Formula const> const& rightSubformula, double lowerBound, double upperBound) : BinaryPathFormula(leftSubformula, rightSubformula), bounds(std::make_pair(lowerBound, upperBound)) { @@ -22,30 +24,18 @@ namespace storm { return true; } - bool BoundedUntilFormula::containsBoundedUntilFormula() const { + bool BoundedUntilFormula::isProbabilityPathFormula() const { return true; } + boost::any BoundedUntilFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const { + return visitor.visit(*this, data); + } + bool BoundedUntilFormula::hasDiscreteTimeBound() const { return bounds.which() == 0; } - - bool BoundedUntilFormula::isValidProbabilityPathFormula() const { - return true; - } - - bool BoundedUntilFormula::isPctlPathFormula() const { - return this->hasDiscreteTimeBound() && this->getLeftSubformula().isPctlStateFormula() && this->getRightSubformula().isPctlStateFormula(); - } - - bool BoundedUntilFormula::isPctlWithConditionalPathFormula() const { - return this->hasDiscreteTimeBound() && this->getLeftSubformula().isPctlWithConditionalStateFormula() && this->getRightSubformula().isPctlWithConditionalStateFormula(); - } - - bool BoundedUntilFormula::isCslPathFormula() const { - return this->getLeftSubformula().isCslStateFormula() && this->getRightSubformula().isCslStateFormula(); - } - + std::pair<double, double> const& BoundedUntilFormula::getIntervalBounds() const { return boost::get<std::pair<double, double>>(bounds); } diff --git a/src/logic/BoundedUntilFormula.h b/src/logic/BoundedUntilFormula.h index bc14d8def..222bab142 100644 --- a/src/logic/BoundedUntilFormula.h +++ b/src/logic/BoundedUntilFormula.h @@ -15,17 +15,14 @@ namespace storm { virtual bool isBoundedUntilFormula() const override; - virtual bool containsBoundedUntilFormula() const override; + virtual bool isProbabilityPathFormula() const override; + + virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override; bool hasDiscreteTimeBound() const; std::pair<double, double> const& getIntervalBounds() const; uint_fast64_t getDiscreteTimeBound() const; - - virtual bool isValidProbabilityPathFormula() const override; - virtual bool isPctlWithConditionalPathFormula() const override; - virtual bool isPctlPathFormula() const override; - virtual bool isCslPathFormula() const override; virtual std::ostream& writeToStream(std::ostream& out) const override; diff --git a/src/logic/ConditionalFormula.cpp b/src/logic/ConditionalFormula.cpp new file mode 100644 index 000000000..2b63fd941 --- /dev/null +++ b/src/logic/ConditionalFormula.cpp @@ -0,0 +1,42 @@ +#include "src/logic/ConditionalFormula.h" + +#include "src/logic/FormulaVisitor.h" + +namespace storm { + namespace logic { + ConditionalFormula::ConditionalFormula(std::shared_ptr<Formula const> const& subformula, std::shared_ptr<Formula const> const& conditionFormula, Context context) : subformula(subformula), conditionFormula(conditionFormula), context(context) { + // Intentionally left empty. + } + + Formula const& ConditionalFormula::getSubformula() const { + return *subformula; + } + + Formula const& ConditionalFormula::getConditionFormula() const { + return *conditionFormula; + } + + bool ConditionalFormula::isConditionalProbabilityFormula() const { + return context == Context::Probability; + } + + bool ConditionalFormula::isConditionalRewardFormula() const { + return context == Context::Reward; + } + + boost::any ConditionalFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const { + return visitor.visit(*this, data); + } + + std::shared_ptr<Formula> ConditionalFormula::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const { + return std::make_shared<ConditionalFormula>(this->getSubformula().substitute(substitution), this->getConditionFormula().substitute(substitution)); + } + + std::ostream& ConditionalFormula::writeToStream(std::ostream& out) const { + this->getSubformula().writeToStream(out); + out << " || "; + this->getConditionFormula().writeToStream(out); + return out; + } + } +} \ No newline at end of file diff --git a/src/logic/ConditionalFormula.h b/src/logic/ConditionalFormula.h new file mode 100644 index 000000000..d7b4dc7cd --- /dev/null +++ b/src/logic/ConditionalFormula.h @@ -0,0 +1,38 @@ +#ifndef STORM_LOGIC_CONDITIONALFORMULA_H_ +#define STORM_LOGIC_CONDITIONALFORMULA_H_ + +#include "src/logic/BinaryPathFormula.h" + +namespace storm { + namespace logic { + class ConditionalFormula : public Formula { + public: + enum class Context { Probability, Reward }; + + ConditionalFormula(std::shared_ptr<Formula const> const& subformula, std::shared_ptr<Formula const> const& conditionFormula, Context context = Context::Probability); + + virtual ~ConditionalFormula() { + // Intentionally left empty. + } + + Formula const& getSubformula() const; + Formula const& getConditionFormula() const; + + virtual bool isConditionalProbabilityFormula() const override; + virtual bool isConditionalRewardFormula() const override; + + virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override; + + virtual std::ostream& writeToStream(std::ostream& out) const override; + + virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override; + + private: + std::shared_ptr<Formula const> subformula; + std::shared_ptr<Formula const> conditionFormula; + Context context; + }; + } +} + +#endif /* STORM_LOGIC_CONDITIONALFORMULA_H_ */ \ No newline at end of file diff --git a/src/logic/ConditionalPathFormula.cpp b/src/logic/ConditionalPathFormula.cpp deleted file mode 100644 index 676a83185..000000000 --- a/src/logic/ConditionalPathFormula.cpp +++ /dev/null @@ -1,40 +0,0 @@ -#include "src/logic/ConditionalPathFormula.h" - -namespace storm { - namespace logic { - ConditionalPathFormula::ConditionalPathFormula(std::shared_ptr<Formula const> const& leftSubformula, std::shared_ptr<Formula const> const& rightSubformula, bool isRewardFormula) : BinaryPathFormula(leftSubformula, rightSubformula), isRewardFormula(isRewardFormula) { - // Intentionally left empty. - } - - bool ConditionalPathFormula::isConditionalPathFormula() const { - return true; - } - - bool ConditionalPathFormula::isValidProbabilityPathFormula() const { - return true; - } - - bool ConditionalPathFormula::isPctlWithConditionalPathFormula() const { - return this->getLeftSubformula().isPctlPathFormula() && this->getRightSubformula().isPctlPathFormula(); - } - - bool ConditionalPathFormula::isRewardPathFormula() const { - return this->isRewardFormula && this->isValidRewardPathFormula(); - } - - bool ConditionalPathFormula::isValidRewardPathFormula() const { - return this->getLeftSubformula().isRewardPathFormula() && !this->getLeftSubformula().isConditionalPathFormula() && this->getRightSubformula().isPctlPathFormula(); - } - - std::shared_ptr<Formula> ConditionalPathFormula::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const { - return std::make_shared<ConditionalPathFormula>(this->getLeftSubformula().substitute(substitution), this->getRightSubformula().substitute(substitution)); - } - - std::ostream& ConditionalPathFormula::writeToStream(std::ostream& out) const { - this->getLeftSubformula().writeToStream(out); - out << " || "; - this->getRightSubformula().writeToStream(out); - return out; - } - } -} \ No newline at end of file diff --git a/src/logic/ConditionalPathFormula.h b/src/logic/ConditionalPathFormula.h deleted file mode 100644 index 94053606b..000000000 --- a/src/logic/ConditionalPathFormula.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef STORM_LOGIC_CONDITIONALPATHFORMULA_H_ -#define STORM_LOGIC_CONDITIONALPATHFORMULA_H_ - -#include "src/logic/BinaryPathFormula.h" - -namespace storm { - namespace logic { - class ConditionalPathFormula : public BinaryPathFormula { - public: - ConditionalPathFormula(std::shared_ptr<Formula const> const& leftSubformula, std::shared_ptr<Formula const> const& rightSubformula, bool isRewardFormula = false); - - virtual ~ConditionalPathFormula() { - // Intentionally left empty. - } - - virtual bool isPctlWithConditionalPathFormula() const override; - virtual bool isRewardPathFormula() const override; - virtual bool isConditionalPathFormula() const override; - virtual bool isValidProbabilityPathFormula() const override; - virtual bool isValidRewardPathFormula() const override; - - virtual std::ostream& writeToStream(std::ostream& out) const override; - - virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override; - - private: - bool isRewardFormula; - }; - } -} - -#endif /* STORM_LOGIC_CONDITIONALPATHFORMULA_H_ */ \ No newline at end of file diff --git a/src/logic/CumulativeRewardFormula.cpp b/src/logic/CumulativeRewardFormula.cpp index 2a00c04f3..d8318164d 100644 --- a/src/logic/CumulativeRewardFormula.cpp +++ b/src/logic/CumulativeRewardFormula.cpp @@ -1,5 +1,7 @@ #include "src/logic/CumulativeRewardFormula.h" +#include "src/logic/FormulaVisitor.h" + namespace storm { namespace logic { CumulativeRewardFormula::CumulativeRewardFormula(uint_fast64_t timeBound) : timeBound(timeBound) { @@ -10,16 +12,16 @@ namespace storm { // Intentionally left empty. } - bool CumulativeRewardFormula::isRewardPathFormula() const { + bool CumulativeRewardFormula::isCumulativeRewardFormula() const { return true; } - bool CumulativeRewardFormula::isCumulativeRewardFormula() const { + bool CumulativeRewardFormula::isRewardPathFormula() const { return true; } - bool CumulativeRewardFormula::isValidRewardPathFormula() const { - return true; + boost::any CumulativeRewardFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const { + return visitor.visit(*this, data); } bool CumulativeRewardFormula::hasDiscreteTimeBound() const { diff --git a/src/logic/CumulativeRewardFormula.h b/src/logic/CumulativeRewardFormula.h index 0192a8a49..6a5e8c035 100644 --- a/src/logic/CumulativeRewardFormula.h +++ b/src/logic/CumulativeRewardFormula.h @@ -16,10 +16,11 @@ namespace storm { virtual ~CumulativeRewardFormula() { // Intentionally left empty. } - - virtual bool isRewardPathFormula() const override; + virtual bool isCumulativeRewardFormula() const override; - virtual bool isValidRewardPathFormula() const override; + virtual bool isRewardPathFormula() const override; + + virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override; virtual std::ostream& writeToStream(std::ostream& out) const override; diff --git a/src/logic/EventuallyFormula.cpp b/src/logic/EventuallyFormula.cpp index 8b09281cd..3d2e6fb57 100644 --- a/src/logic/EventuallyFormula.cpp +++ b/src/logic/EventuallyFormula.cpp @@ -1,25 +1,39 @@ #include "src/logic/EventuallyFormula.h" +#include "src/logic/FormulaVisitor.h" + namespace storm { namespace logic { - EventuallyFormula::EventuallyFormula(std::shared_ptr<Formula const> const& subformula, bool isRewardFormula) : UnaryPathFormula(subformula), isRewardFormula(isRewardFormula) { + EventuallyFormula::EventuallyFormula(std::shared_ptr<Formula const> const& subformula, Context context) : UnaryPathFormula(subformula), context(context) { // Intentionally left empty. } bool EventuallyFormula::isEventuallyFormula() const { - return true; + return context == Context::Probability; + } + + bool EventuallyFormula::isReachabilityRewardFormula() const { + return context == Context::Reward; + } + + bool EventuallyFormula::isReachbilityExpectedTimeFormula() const { + return context == Context::ExpectedTime; + } + + bool EventuallyFormula::isProbabilityPathFormula() const { + return this->isEventuallyFormula(); } bool EventuallyFormula::isRewardPathFormula() const { - return isRewardFormula; + return this->isReachabilityRewardFormula(); } - bool EventuallyFormula::isValidProbabilityPathFormula() const { - return !isRewardFormula; + bool EventuallyFormula::isExpectedTimePathFormula() const { + return this->isReachbilityExpectedTimeFormula(); } - bool EventuallyFormula::isValidRewardPathFormula() const { - return isRewardFormula; + boost::any EventuallyFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const { + return visitor.visit(*this, data); } std::shared_ptr<Formula> EventuallyFormula::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const { diff --git a/src/logic/EventuallyFormula.h b/src/logic/EventuallyFormula.h index 3b121d320..d7a81fa83 100644 --- a/src/logic/EventuallyFormula.h +++ b/src/logic/EventuallyFormula.h @@ -7,23 +7,29 @@ namespace storm { namespace logic { class EventuallyFormula : public UnaryPathFormula { public: - EventuallyFormula(std::shared_ptr<Formula const> const& subformula, bool isRewardFormula = false); + enum class Context { Probability, Reward, ExpectedTime }; + + EventuallyFormula(std::shared_ptr<Formula const> const& subformula, Context context = Context::Probability); virtual ~EventuallyFormula() { // Intentionally left empty. } virtual bool isEventuallyFormula() const override; + virtual bool isReachabilityRewardFormula() const override; + virtual bool isReachbilityExpectedTimeFormula() const override; + virtual bool isProbabilityPathFormula() const override; virtual bool isRewardPathFormula() const override; - virtual bool isValidProbabilityPathFormula() const override; - virtual bool isValidRewardPathFormula() const override; + virtual bool isExpectedTimePathFormula() const override; + + virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override; virtual std::ostream& writeToStream(std::ostream& out) const override; virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override; private: - bool isRewardFormula; + Context context; }; } } diff --git a/src/logic/ExpectedTimeOperatorFormula.cpp b/src/logic/ExpectedTimeOperatorFormula.cpp index 8165710a1..5dc8161ae 100644 --- a/src/logic/ExpectedTimeOperatorFormula.cpp +++ b/src/logic/ExpectedTimeOperatorFormula.cpp @@ -1,5 +1,7 @@ #include "src/logic/ExpectedTimeOperatorFormula.h" +#include "src/logic/FormulaVisitor.h" + namespace storm { namespace logic { ExpectedTimeOperatorFormula::ExpectedTimeOperatorFormula(std::shared_ptr<Formula const> const& subformula) : ExpectedTimeOperatorFormula(boost::none, boost::none, subformula) { @@ -22,20 +24,8 @@ namespace storm { return true; } - bool ExpectedTimeOperatorFormula::isPctlStateFormula() const { - return this->getSubformula().isPctlStateFormula(); - } - - bool ExpectedTimeOperatorFormula::isPctlWithConditionalStateFormula() const { - return this->getSubformula().isPctlWithConditionalStateFormula(); - } - - bool ExpectedTimeOperatorFormula::containsProbabilityOperator() const { - return this->getSubformula().containsProbabilityOperator(); - } - - bool ExpectedTimeOperatorFormula::containsNestedProbabilityOperators() const { - return this->getSubformula().containsNestedProbabilityOperators(); + boost::any ExpectedTimeOperatorFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const { + return visitor.visit(*this, data); } ExpectedTimeOperatorFormula::ExpectedTimeOperatorFormula(boost::optional<OptimizationDirection> optimalityType, boost::optional<Bound<double>> bound, std::shared_ptr<Formula const> const& subformula) : OperatorFormula(optimalityType, bound, subformula) { diff --git a/src/logic/ExpectedTimeOperatorFormula.h b/src/logic/ExpectedTimeOperatorFormula.h index 162fb39f8..5e1925b44 100644 --- a/src/logic/ExpectedTimeOperatorFormula.h +++ b/src/logic/ExpectedTimeOperatorFormula.h @@ -3,6 +3,8 @@ #include "src/logic/OperatorFormula.h" +#include "src/logic/FormulaVisitor.h" + namespace storm { namespace logic { class ExpectedTimeOperatorFormula : public OperatorFormula { @@ -18,11 +20,8 @@ namespace storm { } virtual bool isExpectedTimeOperatorFormula() const override; - - virtual bool isPctlStateFormula() const override; - virtual bool isPctlWithConditionalStateFormula() const override; - virtual bool containsProbabilityOperator() const override; - virtual bool containsNestedProbabilityOperators() const override; + + virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override; virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override; diff --git a/src/logic/Formula.cpp b/src/logic/Formula.cpp index 9f9151b84..6270d5664 100644 --- a/src/logic/Formula.cpp +++ b/src/logic/Formula.cpp @@ -71,135 +71,63 @@ namespace storm { return false; } - bool Formula::isConditionalPathFormula() const { + bool Formula::isConditionalProbabilityFormula() const { return false; } - bool Formula::isNextFormula() const { - return false; - } - - bool Formula::isLongRunAverageOperatorFormula() const { - return false; - } - - bool Formula::isExpectedTimeOperatorFormula() const { - return false; - } - - bool Formula::isCumulativeRewardFormula() const { - return false; - } - - bool Formula::isInstantaneousRewardFormula() const { - return false; - } - - bool Formula::isLongRunAverageRewardFormula() const { - return false; - } - - bool Formula::isProbabilityOperatorFormula() const { - return false; - } - - bool Formula::isRewardOperatorFormula() const { - return false; - } - - bool Formula::isOperatorFormula() const { + bool Formula::isConditionalRewardFormula() const { return false; } - bool Formula::isPctlFormula() const { - return this->isPctlStateFormula() || this->isPctlPathFormula(); - } - - bool Formula::isPctlWithConditionalFormula() const { - return this->isPctlWithConditionalStateFormula() || this->isPctlWithConditionalPathFormula(); - } - - bool Formula::isRewardFormula() const { - return this->isRewardStateFormula() || this->isRewardPathFormula(); - } - - bool Formula::isCslFormula() const { - return this->isCslStateFormula() || this->isCslPathFormula(); - } - - bool Formula::isPctlPathFormula() const { - return false; - } - - bool Formula::isPctlStateFormula() const { - return false; - } - - bool Formula::isPctlWithConditionalPathFormula() const { - return false; - } - - bool Formula::isPctlWithConditionalStateFormula() const { + bool Formula::isProbabilityPathFormula() const { return false; } - bool Formula::isCslPathFormula() const { - return this->isPctlPathFormula(); - } - - bool Formula::isCslStateFormula() const { - return this->isPctlStateFormula(); - } - bool Formula::isRewardPathFormula() const { return false; } - bool Formula::isRewardStateFormula() const { + bool Formula::isExpectedTimePathFormula() const { return false; } - bool Formula::isPltlFormula() const { - return false; - } - - bool Formula::isLtlFormula() const { + bool Formula::isNextFormula() const { return false; } - bool Formula::isPropositionalFormula() const { + bool Formula::isLongRunAverageOperatorFormula() const { return false; } - bool Formula::isValidProbabilityPathFormula() const { + bool Formula::isExpectedTimeOperatorFormula() const { return false; } - bool Formula::isValidRewardPathFormula() const { + bool Formula::isCumulativeRewardFormula() const { return false; } - bool Formula::containsBoundedUntilFormula() const { + bool Formula::isInstantaneousRewardFormula() const { return false; } - bool Formula::containsNextFormula() const { + bool Formula::isLongRunAverageRewardFormula() const { return false; } - bool Formula::containsProbabilityOperator() const { + bool Formula::isReachbilityExpectedTimeFormula() const { return false; } - bool Formula::containsNestedProbabilityOperators() const { + bool Formula::isProbabilityOperatorFormula() const { return false; } - bool Formula::containsRewardOperator() const { + bool Formula::isRewardOperatorFormula() const { return false; } - bool Formula::containsNestedRewardOperators() const { + bool Formula::isOperatorFormula() const { return false; } @@ -239,12 +167,12 @@ namespace storm { return dynamic_cast<UnaryStateFormula const&>(*this); } - ConditionalPathFormula& Formula::asConditionalPathFormula() { - return dynamic_cast<ConditionalPathFormula&>(*this); + ConditionalFormula& Formula::asConditionalFormula() { + return dynamic_cast<ConditionalFormula&>(*this); } - ConditionalPathFormula const& Formula::asConditionalPathFormula() const { - return dynamic_cast<ConditionalPathFormula const&>(*this); + ConditionalFormula const& Formula::asConditionalFormula() const { + return dynamic_cast<ConditionalFormula const&>(*this); } BinaryBooleanStateFormula& Formula::asBinaryBooleanStateFormula() { diff --git a/src/logic/Formula.h b/src/logic/Formula.h index cf4333eb4..ae879fce6 100644 --- a/src/logic/Formula.h +++ b/src/logic/Formula.h @@ -6,37 +6,18 @@ #include <iostream> #include <set> +#include <boost/any.hpp> + #include "src/storage/expressions/Variable.h" #include "src/storage/expressions/Expression.h" +#include "src/logic/FormulasForwardDeclarations.h" + namespace storm { namespace logic { - // Forward-declare all formula classes. - class PathFormula; - class StateFormula; - class BinaryStateFormula; - class UnaryStateFormula; - class BinaryBooleanStateFormula; - class UnaryBooleanStateFormula; - class BooleanLiteralFormula; - class AtomicExpressionFormula; - class AtomicLabelFormula; - class UntilFormula; - class BoundedUntilFormula; - class EventuallyFormula; - class GloballyFormula; - class BinaryPathFormula; - class UnaryPathFormula; - class ConditionalPathFormula; - class NextFormula; - class LongRunAverageOperatorFormula; - class ExpectedTimeOperatorFormula; - class CumulativeRewardFormula; - class InstantaneousRewardFormula; - class LongRunAverageRewardFormula; - class ProbabilityOperatorFormula; - class RewardOperatorFormula; - class OperatorFormula; + + // Forward-declare visitor for accept() method. + class FormulaVisitor; // Also foward-declare base model checker class. class ModelChecker; @@ -49,59 +30,57 @@ namespace storm { }; friend std::ostream& operator<<(std::ostream& out, Formula const& formula); - - // Methods for querying the exact formula type. + + // Basic formula types. virtual bool isPathFormula() const; virtual bool isStateFormula() const; - virtual bool isBinaryStateFormula() const; - virtual bool isUnaryStateFormula() const; + virtual bool isConditionalProbabilityFormula() const; + virtual bool isConditionalRewardFormula() const; + + virtual bool isProbabilityPathFormula() const; + virtual bool isRewardPathFormula() const; + virtual bool isExpectedTimePathFormula() const; + virtual bool isBinaryBooleanStateFormula() const; virtual bool isUnaryBooleanStateFormula() const; + + // Operator formulas. + virtual bool isOperatorFormula() const; + virtual bool isLongRunAverageOperatorFormula() const; + virtual bool isExpectedTimeOperatorFormula() const; + virtual bool isProbabilityOperatorFormula() const; + virtual bool isRewardOperatorFormula() const; + + // Atomic state formulas. virtual bool isBooleanLiteralFormula() const; virtual bool isTrueFormula() const; virtual bool isFalseFormula() const; virtual bool isAtomicExpressionFormula() const; virtual bool isAtomicLabelFormula() const; + + // Probability path formulas. + virtual bool isNextFormula() const; virtual bool isUntilFormula() const; virtual bool isBoundedUntilFormula() const; virtual bool isEventuallyFormula() const; virtual bool isGloballyFormula() const; - virtual bool isBinaryPathFormula() const; - virtual bool isUnaryPathFormula() const; - virtual bool isConditionalPathFormula() const; - virtual bool isNextFormula() const; - virtual bool isLongRunAverageOperatorFormula() const; - virtual bool isExpectedTimeOperatorFormula() const; + + // Reward formulas. virtual bool isCumulativeRewardFormula() const; virtual bool isInstantaneousRewardFormula() const; + virtual bool isReachabilityRewardFormula() const; virtual bool isLongRunAverageRewardFormula() const; - virtual bool isProbabilityOperatorFormula() const; - virtual bool isRewardOperatorFormula() const; - virtual bool isOperatorFormula() const; + + // Expected time formulas. + virtual bool isReachbilityExpectedTimeFormula() const; + + // Type checks for abstract intermediate classes. + virtual bool isBinaryPathFormula() const; + virtual bool isBinaryStateFormula() const; + virtual bool isUnaryPathFormula() const; + virtual bool isUnaryStateFormula() const; - bool isPctlFormula() const; - bool isPctlWithConditionalFormula() const; - bool isRewardFormula() const; - bool isCslFormula() const; - virtual bool isPctlPathFormula() const; - virtual bool isPctlStateFormula() const; - virtual bool isPctlWithConditionalPathFormula() const; - virtual bool isPctlWithConditionalStateFormula() const; - virtual bool isCslPathFormula() const; - virtual bool isCslStateFormula() const; - virtual bool isRewardPathFormula() const; - virtual bool isRewardStateFormula() const; - virtual bool isPltlFormula() const; - virtual bool isLtlFormula() const; - virtual bool isPropositionalFormula() const; - virtual bool isValidProbabilityPathFormula() const; - virtual bool isValidRewardPathFormula() const; - virtual bool containsBoundedUntilFormula() const; - virtual bool containsNextFormula() const; - virtual bool containsProbabilityOperator() const; - virtual bool containsNestedProbabilityOperators() const; - virtual bool containsRewardOperator() const; - virtual bool containsNestedRewardOperators() const; + virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const = 0; static std::shared_ptr<Formula const> getTrueFormula(); @@ -150,8 +129,8 @@ namespace storm { UnaryPathFormula& asUnaryPathFormula(); UnaryPathFormula const& asUnaryPathFormula() const; - ConditionalPathFormula& asConditionalPathFormula(); - ConditionalPathFormula const& asConditionalPathFormula() const; + ConditionalFormula& asConditionalFormula(); + ConditionalFormula const& asConditionalFormula() const; NextFormula& asNextFormula(); NextFormula const& asNextFormula() const; diff --git a/src/logic/FormulaVisitor.h b/src/logic/FormulaVisitor.h new file mode 100644 index 000000000..a2e5b1a4f --- /dev/null +++ b/src/logic/FormulaVisitor.h @@ -0,0 +1,36 @@ +#ifndef STORM_LOGIC_FORMULAVISITOR_H_ +#define STORM_LOGIC_FORMULAVISITOR_H_ + +#include <boost/any.hpp> + +#include "src/logic/FormulasForwardDeclarations.h" + +namespace storm { + namespace logic { + + class FormulaVisitor { + public: + virtual boost::any visit(AtomicExpressionFormula const& f, boost::any const& data) const = 0; + virtual boost::any visit(AtomicLabelFormula const& f, boost::any const& data) const = 0; + virtual boost::any visit(BinaryBooleanStateFormula const& f, boost::any const& data) const = 0; + virtual boost::any visit(BooleanLiteralFormula const& f, boost::any const& data) const = 0; + virtual boost::any visit(BoundedUntilFormula const& f, boost::any const& data) const = 0; + virtual boost::any visit(ConditionalFormula const& f, boost::any const& data) const = 0; + virtual boost::any visit(CumulativeRewardFormula const& f, boost::any const& data) const = 0; + virtual boost::any visit(EventuallyFormula const& f, boost::any const& data) const = 0; + virtual boost::any visit(ExpectedTimeOperatorFormula const& f, boost::any const& data) const = 0; + virtual boost::any visit(GloballyFormula const& f, boost::any const& data) const = 0; + virtual boost::any visit(InstantaneousRewardFormula const& f, boost::any const& data) const = 0; + virtual boost::any visit(LongRunAverageOperatorFormula const& f, boost::any const& data) const = 0; + virtual boost::any visit(LongRunAverageRewardFormula const& f, boost::any const& data) const = 0; + virtual boost::any visit(NextFormula const& f, boost::any const& data) const = 0; + virtual boost::any visit(ProbabilityOperatorFormula const& f, boost::any const& data) const = 0; + virtual boost::any visit(RewardOperatorFormula const& f, boost::any const& data) const = 0; + virtual boost::any visit(UnaryBooleanStateFormula const& f, boost::any const& data) const = 0; + virtual boost::any visit(UntilFormula const& f, boost::any const& data) const = 0; + }; + + } +} + +#endif /* STORM_LOGIC_FORMULAVISITOR_H_ */ \ No newline at end of file diff --git a/src/logic/Formulas.h b/src/logic/Formulas.h index 7da9321c6..a5218eeb8 100644 --- a/src/logic/Formulas.h +++ b/src/logic/Formulas.h @@ -23,7 +23,7 @@ #include "src/logic/UnaryPathFormula.h" #include "src/logic/UnaryStateFormula.h" #include "src/logic/UntilFormula.h" -#include "src/logic/ConditionalPathFormula.h" +#include "src/logic/ConditionalFormula.h" #include "src/logic/ProbabilityOperatorFormula.h" #include "src/logic/RewardOperatorFormula.h" #include "src/logic/ComparisonType.h" \ No newline at end of file diff --git a/src/logic/FormulasForwardDeclarations.h b/src/logic/FormulasForwardDeclarations.h new file mode 100644 index 000000000..13b4c326c --- /dev/null +++ b/src/logic/FormulasForwardDeclarations.h @@ -0,0 +1,36 @@ +#ifndef STORM_LOGIC_FORMULASFORWARDDECLARATIONS_H_ +#define STORM_LOGIC_FORMULASFORWARDDECLARATIONS_H_ + +namespace storm { + namespace logic { + // Forward-declare all formula classes. + class Formula; + class AtomicExpressionFormula; + class AtomicLabelFormula; + class BinaryBooleanStateFormula; + class BinaryPathFormula; + class BinaryStateFormula; + class BooleanLiteralFormula; + class BoundedUntilFormula; + class ConditionalFormula; + class CumulativeRewardFormula; + class EventuallyFormula; + class ExpectedTimeOperatorFormula; + class GloballyFormula; + class InstantaneousRewardFormula; + class LongRunAverageOperatorFormula; + class LongRunAverageRewardFormula; + class NextFormula; + class OperatorFormula; + class PathFormula; + class ProbabilityOperatorFormula; + class RewardOperatorFormula; + class StateFormula; + class UnaryBooleanStateFormula; + class UnaryPathFormula; + class UnaryStateFormula; + class UntilFormula; + } +} + +#endif /* STORM_LOGIC_FORMULASFORWARDDECLARATIONS_H_ */ \ No newline at end of file diff --git a/src/logic/FragmentChecker.cpp b/src/logic/FragmentChecker.cpp new file mode 100644 index 000000000..d94056f58 --- /dev/null +++ b/src/logic/FragmentChecker.cpp @@ -0,0 +1,118 @@ +#include "src/logic/FragmentChecker.h" + +#include "src/logic/Formulas.h" + +namespace storm { + namespace logic { + bool FragmentChecker::conformsToSpecification(Formula const& f, FragmentSpecification const& specification) const { + boost::any result = f.accept(*this, specification); + return boost::any_cast<bool>(result); + } + + boost::any FragmentChecker::visit(AtomicExpressionFormula const& f, boost::any const& data) const { + FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data); + return specification.areAtomicExpressionFormulasAllowed(); + } + + boost::any FragmentChecker::visit(AtomicLabelFormula const& f, boost::any const& data) const { + FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data); + return specification.areAtomicLabelFormulasAllowed(); + } + + boost::any FragmentChecker::visit(BinaryBooleanStateFormula const& f, boost::any const& data) const { + FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data); + bool result = specification.areBinaryBooleanStateFormulasAllowed(); + result = result && boost::any_cast<bool>(f.getLeftSubformula().accept(*this, specification)); + result = result && boost::any_cast<bool>(f.getRightSubformula().accept(*this, specification)); + return result; + } + + boost::any FragmentChecker::visit(BooleanLiteralFormula const& f, boost::any const& data) const { + FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data); + return specification.areBooleanLiteralFormulasAllowed(); + } + + boost::any FragmentChecker::visit(BoundedUntilFormula const& f, boost::any const& data) const { + FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data); + bool result = specification.areBoundedUntilFormulasAllowed(); + result = result && boost::any_cast<bool>(f.getLeftSubformula().accept(*this, data)); + result = result && boost::any_cast<bool>(f.getRightSubformula().accept(*this, data)); + return result; + } + + boost::any FragmentChecker::visit(ConditionalFormula const& f, boost::any const& data) const { + FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data); + bool result = true; + if (f.isConditionalProbabilityFormula()) { + result &= specification.areConditionalProbabilityFormulasAllowed(); + } else if (f.Formula::isConditionalRewardFormula()) { + result &= specification.areConditionalRewardFormulasFormulasAllowed(); + } + result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, data)); + result = result && boost::any_cast<bool>(f.getConditionFormula().accept(*this, data)); + return result; + } + + boost::any FragmentChecker::visit(CumulativeRewardFormula const& f, boost::any const& data) const { + FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data); + return specification.areCumulativeRewardFormulasAllowed(); + } + + boost::any FragmentChecker::visit(EventuallyFormula const& f, boost::any const& data) const { + FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data); + bool result = specification.areEventuallyFormulasAllowed(); + result && boost::any_cast<bool>(f.getSubformula().accept(*this, data)); + return result; + } + + boost::any FragmentChecker::visit(ExpectedTimeOperatorFormula const& f, boost::any const& data) const { + FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data); + return specification.areExpectedTimeOperatorsAllowed(); + } + + boost::any FragmentChecker::visit(GloballyFormula const& f, boost::any const& data) const { + FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data); + return specification.areGloballyFormulasAllowed(); + } + + boost::any FragmentChecker::visit(InstantaneousRewardFormula const& f, boost::any const& data) const { + FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data); + return specification.areInstantaneousRewardFormulasAllowed(); + } + + boost::any FragmentChecker::visit(LongRunAverageOperatorFormula const& f, boost::any const& data) const { + FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data); + return specification.areLongRunAverageOperatorsAllowed(); + } + + boost::any FragmentChecker::visit(LongRunAverageRewardFormula const& f, boost::any const& data) const { + FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data); + return specification.areLongRunAverageRewardFormulasAllowed(); + } + + boost::any FragmentChecker::visit(NextFormula const& f, boost::any const& data) const { + FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data); + return specification.areNextFormulasAllowed(); + } + + boost::any FragmentChecker::visit(ProbabilityOperatorFormula const& f, boost::any const& data) const { + FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data); + return specification.areProbabilityOperatorsAllowed(); + } + + boost::any FragmentChecker::visit(RewardOperatorFormula const& f, boost::any const& data) const { + FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data); + return specification.areRewardOperatorsAllowed(); + } + + boost::any FragmentChecker::visit(UnaryBooleanStateFormula const& f, boost::any const& data) const { + FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data); + return specification.areUnaryBooleanStateFormulasAllowed(); + } + + boost::any FragmentChecker::visit(UntilFormula const& f, boost::any const& data) const { + FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data); + return specification.areUntilFormulasAllowed(); + } + } +} \ No newline at end of file diff --git a/src/logic/FragmentChecker.h b/src/logic/FragmentChecker.h new file mode 100644 index 000000000..3d22390e6 --- /dev/null +++ b/src/logic/FragmentChecker.h @@ -0,0 +1,39 @@ +#ifndef STORM_LOGIC_FRAGMENTCHECKER_H_ +#define STORM_LOGIC_FRAGMENTCHECKER_H_ + +#include "src/logic/FormulaVisitor.h" + +#include "src/logic/FragmentSpecification.h" + +namespace storm { + namespace logic { + + class FragmentChecker : public FormulaVisitor { + public: + bool conformsToSpecification(Formula const& f, FragmentSpecification const& specification) const; + + virtual boost::any visit(AtomicExpressionFormula const& f, boost::any const& data) const override; + virtual boost::any visit(AtomicLabelFormula const& f, boost::any const& data) const override; + virtual boost::any visit(BinaryBooleanStateFormula const& f, boost::any const& data) const override; + virtual boost::any visit(BooleanLiteralFormula const& f, boost::any const& data) const override; + virtual boost::any visit(BoundedUntilFormula const& f, boost::any const& data) const override; + virtual boost::any visit(ConditionalFormula const& f, boost::any const& data) const override; + virtual boost::any visit(CumulativeRewardFormula const& f, boost::any const& data) const override; + virtual boost::any visit(EventuallyFormula const& f, boost::any const& data) const override; + virtual boost::any visit(ExpectedTimeOperatorFormula const& f, boost::any const& data) const override; + virtual boost::any visit(GloballyFormula const& f, boost::any const& data) const override; + virtual boost::any visit(InstantaneousRewardFormula const& f, boost::any const& data) const override; + virtual boost::any visit(LongRunAverageOperatorFormula const& f, boost::any const& data) const override; + virtual boost::any visit(LongRunAverageRewardFormula const& f, boost::any const& data) const override; + virtual boost::any visit(NextFormula const& f, boost::any const& data) const override; + virtual boost::any visit(ProbabilityOperatorFormula const& f, boost::any const& data) const override; + virtual boost::any visit(RewardOperatorFormula const& f, boost::any const& data) const override; + virtual boost::any visit(UnaryBooleanStateFormula const& f, boost::any const& data) const override; + virtual boost::any visit(UntilFormula const& f, boost::any const& data) const override; + }; + + } +} + + +#endif /* STORM_LOGIC_FRAGMENTCHECKER_H_ */ \ No newline at end of file diff --git a/src/logic/FragmentSpecification.cpp b/src/logic/FragmentSpecification.cpp new file mode 100644 index 000000000..eeb697582 --- /dev/null +++ b/src/logic/FragmentSpecification.cpp @@ -0,0 +1,209 @@ +#include "src/logic/FragmentSpecification.h" + +namespace storm { + namespace logic { + + FragmentSpecification FragmentSpecification::copy() const { + return FragmentSpecification(*this); + } + + bool FragmentSpecification::areProbabilityOperatorsAllowed() const { + return probabilityOperator; + } + + FragmentSpecification& FragmentSpecification::setProbabilityOperatorsAllowed(bool newValue) { + this->probabilityOperator = newValue; + return *this; + } + + bool FragmentSpecification::areRewardOperatorsAllowed() const { + return rewardOperator; + } + + FragmentSpecification& FragmentSpecification::setRewardOperatorsAllowed(bool newValue) { + this->rewardOperator = newValue; + return *this; + } + + bool FragmentSpecification::areExpectedTimeOperatorsAllowed() const { + return expectedTimeOperator; + } + + FragmentSpecification& FragmentSpecification::setExpectedTimeOperatorsAllowed(bool newValue) { + this->expectedTimeOperator = newValue; + return *this; + } + + bool FragmentSpecification::areLongRunAverageOperatorsAllowed() const { + return longRunAverageOperator; + } + + FragmentSpecification& FragmentSpecification::setLongRunAverageOperatorsAllowed(bool newValue) { + this->longRunAverageOperator = newValue; + return *this; + } + + bool FragmentSpecification::areGloballyFormulasAllowed() const { + return globallyFormula; + } + + FragmentSpecification& FragmentSpecification::setGloballyFormulasAllowed(bool newValue) { + this->globallyFormula = newValue; + return *this; + } + + bool FragmentSpecification::areEventuallyFormulasAllowed() const { + return eventuallyFormula; + } + + FragmentSpecification& FragmentSpecification::setEventuallyFormulasAllowed(bool newValue) { + this->eventuallyFormula = newValue; + return *this; + } + + bool FragmentSpecification::areNextFormulasAllowed() const { + return nextFormula; + } + + FragmentSpecification& FragmentSpecification::setNextFormulasAllowed(bool newValue) { + this->nextFormula = newValue; + return *this; + } + + bool FragmentSpecification::areUntilFormulasAllowed() const { + return untilFormula; + } + + FragmentSpecification& FragmentSpecification::setUntilFormulasAllowed(bool newValue) { + this->untilFormula = newValue; + return *this; + } + + bool FragmentSpecification::areBoundedUntilFormulasAllowed() const { + return boundedUntilFormula; + } + + FragmentSpecification& FragmentSpecification::setBoundedUntilFormulasAllowed(bool newValue) { + this->boundedUntilFormula = newValue; + return *this; + } + + bool FragmentSpecification::areAtomicExpressionFormulasAllowed() const { + return atomicExpressionFormula; + } + + FragmentSpecification& FragmentSpecification::setAtomicExpressionFormulasAllowed(bool newValue) { + this->atomicExpressionFormula = newValue; + return *this; + } + + bool FragmentSpecification::areAtomicLabelFormulasAllowed() const { + return atomicLabelFormula; + } + + FragmentSpecification& FragmentSpecification::setAtomicLabelFormulasAllowed(bool newValue) { + this->atomicLabelFormula = newValue; + return *this; + } + + bool FragmentSpecification::areBooleanLiteralFormulasAllowed() const { + return booleanLiteralFormula; + } + + FragmentSpecification& FragmentSpecification::setBooleanLiteralFormulasAllowed(bool newValue) { + this->booleanLiteralFormula = newValue; + return *this; + } + + bool FragmentSpecification::areUnaryBooleanStateFormulasAllowed() const { + return unaryBooleanStateFormula; + } + + FragmentSpecification& FragmentSpecification::setUnaryBooleanStateFormulasAllowed(bool newValue) { + this->unaryBooleanStateFormula = newValue; + return *this; + } + + bool FragmentSpecification::areBinaryBooleanStateFormulasAllowed() const { + return binaryBooleanStateFormula; + } + + FragmentSpecification& FragmentSpecification::setBinaryBooleanStateFormulasAllowed(bool newValue) { + this->binaryBooleanStateFormula = newValue; + return *this; + } + + bool FragmentSpecification::areCumulativeRewardFormulasAllowed() const { + return cumulativeRewardFormula; + } + + FragmentSpecification& FragmentSpecification::setCumulativeRewardFormulasAllowed(bool newValue) { + this->cumulativeRewardFormula = newValue; + return *this; + } + + bool FragmentSpecification::areInstantaneousRewardFormulasAllowed() const { + return instantaneousRewardFormula; + } + + FragmentSpecification& FragmentSpecification::setInstantaneousFormulasAllowed(bool newValue) { + this->instantaneousRewardFormula = newValue; + return *this; + } + + bool FragmentSpecification::areReachabilityRewardFormulasAllowed() const { + return reachabilityRewardFormula; + } + + FragmentSpecification& FragmentSpecification::setReachabilityRewardFormulasAllowed(bool newValue) { + this->reachabilityRewardFormula = newValue; + return *this; + } + + bool FragmentSpecification::areLongRunAverageRewardFormulasAllowed() const { + return longRunAverageRewardFormula; + } + + FragmentSpecification& FragmentSpecification::setLongRunAverageRewardFormulasAllowed(bool newValue) { + this->longRunAverageRewardFormula = newValue; + return *this; + } + + bool FragmentSpecification::areConditionalProbabilityFormulasAllowed() const { + return conditionalProbabilityFormula; + } + + FragmentSpecification& FragmentSpecification::setConditionalProbabilityFormulasAllowed(bool newValue) { + this->conditionalProbabilityFormula = newValue; + return *this; + } + + bool FragmentSpecification::areConditionalRewardFormulasFormulasAllowed() const { + return conditionalRewardFormula; + } + + FragmentSpecification& FragmentSpecification::setConditionalRewardFormulasAllowed(bool newValue) { + this->conditionalRewardFormula = newValue; + return *this; + } + + bool FragmentSpecification::areReachbilityExpectedTimeFormulasAllowed() const { + return reachabilityExpectedTimeFormula; + } + + FragmentSpecification& FragmentSpecification::setReachbilityExpectedTimeFormulasAllowed(bool newValue) { + this->reachabilityExpectedTimeFormula = newValue; + return *this; + } + + bool FragmentSpecification::areNestedOperatorsAllowed() const { + return this->nestedOperators; + } + + FragmentSpecification& FragmentSpecification::setNestedOperatorsAllowed(bool newValue) { + this->nestedOperators = newValue; + return *this; + } + + } +} \ No newline at end of file diff --git a/src/logic/FragmentSpecification.h b/src/logic/FragmentSpecification.h new file mode 100644 index 000000000..91099703f --- /dev/null +++ b/src/logic/FragmentSpecification.h @@ -0,0 +1,112 @@ +#ifndef STORM_LOGIC_FRAGMENTSPECIFICATION_H_ +#define STORM_LOGIC_FRAGMENTSPECIFICATION_H_ + +namespace storm { + namespace logic { + class FragmentSpecification { + public: + FragmentSpecification copy() const; + + bool areProbabilityOperatorsAllowed() const; + FragmentSpecification& setProbabilityOperatorsAllowed(bool newValue); + + bool areRewardOperatorsAllowed() const; + FragmentSpecification& setRewardOperatorsAllowed(bool newValue); + + bool areExpectedTimeOperatorsAllowed() const; + FragmentSpecification& setExpectedTimeOperatorsAllowed(bool newValue); + + bool areLongRunAverageOperatorsAllowed() const; + FragmentSpecification& setLongRunAverageOperatorsAllowed(bool newValue); + + bool areGloballyFormulasAllowed() const; + FragmentSpecification& setGloballyFormulasAllowed(bool newValue); + + bool areEventuallyFormulasAllowed() const; + FragmentSpecification& setEventuallyFormulasAllowed(bool newValue); + + bool areNextFormulasAllowed() const; + FragmentSpecification& setNextFormulasAllowed(bool newValue); + + bool areUntilFormulasAllowed() const; + FragmentSpecification& setUntilFormulasAllowed(bool newValue); + + bool areBoundedUntilFormulasAllowed() const; + FragmentSpecification& setBoundedUntilFormulasAllowed(bool newValue); + + bool areAtomicExpressionFormulasAllowed() const; + FragmentSpecification& setAtomicExpressionFormulasAllowed(bool newValue); + + bool areAtomicLabelFormulasAllowed() const; + FragmentSpecification& setAtomicLabelFormulasAllowed(bool newValue); + + bool areBooleanLiteralFormulasAllowed() const; + FragmentSpecification& setBooleanLiteralFormulasAllowed(bool newValue); + + bool areUnaryBooleanStateFormulasAllowed() const; + FragmentSpecification& setUnaryBooleanStateFormulasAllowed(bool newValue); + + bool areBinaryBooleanStateFormulasAllowed() const; + FragmentSpecification& setBinaryBooleanStateFormulasAllowed(bool newValue); + + bool areCumulativeRewardFormulasAllowed() const; + FragmentSpecification& setCumulativeRewardFormulasAllowed(bool newValue); + + bool areInstantaneousRewardFormulasAllowed() const; + FragmentSpecification& setInstantaneousFormulasAllowed(bool newValue); + + bool areReachabilityRewardFormulasAllowed() const; + FragmentSpecification& setReachabilityRewardFormulasAllowed(bool newValue); + + bool areLongRunAverageRewardFormulasAllowed() const; + FragmentSpecification& setLongRunAverageRewardFormulasAllowed(bool newValue); + + bool areConditionalProbabilityFormulasAllowed() const; + FragmentSpecification& setConditionalProbabilityFormulasAllowed(bool newValue); + + bool areConditionalRewardFormulasFormulasAllowed() const; + FragmentSpecification& setConditionalRewardFormulasAllowed(bool newValue); + + bool areReachbilityExpectedTimeFormulasAllowed() const; + FragmentSpecification& setReachbilityExpectedTimeFormulasAllowed(bool newValue); + + bool areNestedOperatorsAllowed() const; + FragmentSpecification& setNestedOperatorsAllowed(bool newValue); + + private: + // Flags that indicate whether it is legal to see such a formula. + bool probabilityOperator; + bool rewardOperator; + bool expectedTimeOperator; + bool longRunAverageOperator; + + bool globallyFormula; + bool eventuallyFormula; + bool nextFormula; + bool untilFormula; + bool boundedUntilFormula; + + bool atomicExpressionFormula; + bool atomicLabelFormula; + bool booleanLiteralFormula; + bool unaryBooleanStateFormula; + bool binaryBooleanStateFormula; + + bool cumulativeRewardFormula; + bool instantaneousRewardFormula; + bool reachabilityRewardFormula; + bool longRunAverageRewardFormula; + + bool conditionalProbabilityFormula; + bool conditionalRewardFormula; + + bool reachabilityExpectedTimeFormula; + + // Members that indicate certain restrictions. + bool nestedOperators; + + }; + } +} + +#endif /* STORM_LOGIC_FRAGMENTSPECIFICATION_H_ */ \ No newline at end of file diff --git a/src/logic/GloballyFormula.cpp b/src/logic/GloballyFormula.cpp index 5ddfd8feb..df33f0b52 100644 --- a/src/logic/GloballyFormula.cpp +++ b/src/logic/GloballyFormula.cpp @@ -1,5 +1,7 @@ #include "src/logic/GloballyFormula.h" +#include "src/logic/FormulaVisitor.h" + namespace storm { namespace logic { GloballyFormula::GloballyFormula(std::shared_ptr<Formula const> const& subformula) : UnaryPathFormula(subformula) { @@ -10,9 +12,13 @@ namespace storm { return true; } - bool GloballyFormula::isValidProbabilityPathFormula() const { + bool GloballyFormula::isProbabilityPathFormula() const { return true; } + + boost::any GloballyFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const { + return visitor.visit(*this, data); + } std::shared_ptr<Formula> GloballyFormula::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const { return std::make_shared<GloballyFormula>(this->getSubformula().substitute(substitution)); diff --git a/src/logic/GloballyFormula.h b/src/logic/GloballyFormula.h index e3fc82f2d..011c61de9 100644 --- a/src/logic/GloballyFormula.h +++ b/src/logic/GloballyFormula.h @@ -14,7 +14,9 @@ namespace storm { } virtual bool isGloballyFormula() const override; - virtual bool isValidProbabilityPathFormula() const override; + virtual bool isProbabilityPathFormula() const override; + + virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override; virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override; diff --git a/src/logic/InstantaneousRewardFormula.cpp b/src/logic/InstantaneousRewardFormula.cpp index 7289f18e9..4f1f65429 100644 --- a/src/logic/InstantaneousRewardFormula.cpp +++ b/src/logic/InstantaneousRewardFormula.cpp @@ -1,5 +1,7 @@ #include "src/logic/InstantaneousRewardFormula.h" +#include "src/logic/FormulaVisitor.h" + namespace storm { namespace logic { InstantaneousRewardFormula::InstantaneousRewardFormula(uint_fast64_t timeBound) : timeBound(timeBound) { @@ -14,12 +16,12 @@ namespace storm { return true; } - bool InstantaneousRewardFormula::isValidRewardPathFormula() const { + bool InstantaneousRewardFormula::isRewardPathFormula() const { return true; } - bool InstantaneousRewardFormula::isRewardPathFormula() const { - return true; + boost::any InstantaneousRewardFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const { + return visitor.visit(*this, data); } bool InstantaneousRewardFormula::hasDiscreteTimeBound() const { diff --git a/src/logic/InstantaneousRewardFormula.h b/src/logic/InstantaneousRewardFormula.h index 967f03a2b..069bf21bd 100644 --- a/src/logic/InstantaneousRewardFormula.h +++ b/src/logic/InstantaneousRewardFormula.h @@ -17,10 +17,12 @@ namespace storm { // Intentionally left empty. } - virtual bool isRewardPathFormula() const override; virtual bool isInstantaneousRewardFormula() const override; - virtual bool isValidRewardPathFormula() const override; + virtual bool isRewardPathFormula() const override; + + virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override; + virtual std::ostream& writeToStream(std::ostream& out) const override; bool hasDiscreteTimeBound() const; diff --git a/src/logic/LongRunAverageOperatorFormula.cpp b/src/logic/LongRunAverageOperatorFormula.cpp index 1563dc67e..c9d781905 100644 --- a/src/logic/LongRunAverageOperatorFormula.cpp +++ b/src/logic/LongRunAverageOperatorFormula.cpp @@ -1,5 +1,7 @@ #include "src/logic/LongRunAverageOperatorFormula.h" +#include "src/logic/FormulaVisitor.h" + namespace storm { namespace logic { LongRunAverageOperatorFormula::LongRunAverageOperatorFormula(std::shared_ptr<Formula const> const& subformula) : LongRunAverageOperatorFormula(boost::none, boost::none, subformula) { @@ -22,20 +24,8 @@ namespace storm { return true; } - bool LongRunAverageOperatorFormula::isPctlStateFormula() const { - return this->getSubformula().isPctlStateFormula(); - } - - bool LongRunAverageOperatorFormula::isPctlWithConditionalStateFormula() const { - return this->getSubformula().isPctlWithConditionalStateFormula(); - } - - bool LongRunAverageOperatorFormula::containsProbabilityOperator() const { - return this->getSubformula().containsProbabilityOperator(); - } - - bool LongRunAverageOperatorFormula::containsNestedProbabilityOperators() const { - return this->getSubformula().containsNestedProbabilityOperators(); + boost::any LongRunAverageOperatorFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const { + return visitor.visit(*this, data); } LongRunAverageOperatorFormula::LongRunAverageOperatorFormula(boost::optional<OptimizationDirection> optimalityType, boost::optional<Bound<double>> bound, std::shared_ptr<Formula const> const& subformula) : OperatorFormula(optimalityType, bound, subformula) { diff --git a/src/logic/LongRunAverageOperatorFormula.h b/src/logic/LongRunAverageOperatorFormula.h index 85eb9f969..d4a785b80 100644 --- a/src/logic/LongRunAverageOperatorFormula.h +++ b/src/logic/LongRunAverageOperatorFormula.h @@ -19,10 +19,7 @@ namespace storm { virtual bool isLongRunAverageOperatorFormula() const override; - virtual bool isPctlStateFormula() const override; - virtual bool isPctlWithConditionalStateFormula() const override; - virtual bool containsProbabilityOperator() const override; - virtual bool containsNestedProbabilityOperators() const override; + virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override; virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override; diff --git a/src/logic/LongRunAverageRewardFormula.cpp b/src/logic/LongRunAverageRewardFormula.cpp index 9d9dc898d..30bfd7ba9 100644 --- a/src/logic/LongRunAverageRewardFormula.cpp +++ b/src/logic/LongRunAverageRewardFormula.cpp @@ -1,5 +1,7 @@ #include "src/logic/LongRunAverageRewardFormula.h" +#include "src/logic/FormulaVisitor.h" + namespace storm { namespace logic { LongRunAverageRewardFormula::LongRunAverageRewardFormula() { @@ -10,12 +12,12 @@ namespace storm { return true; } - bool LongRunAverageRewardFormula::isValidRewardPathFormula() const { + bool LongRunAverageRewardFormula::isRewardPathFormula() const { return true; } - bool LongRunAverageRewardFormula::isRewardPathFormula() const { - return true; + boost::any LongRunAverageRewardFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const { + return visitor.visit(*this, data); } std::shared_ptr<Formula> LongRunAverageRewardFormula::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const { diff --git a/src/logic/LongRunAverageRewardFormula.h b/src/logic/LongRunAverageRewardFormula.h index 929a6f3c8..3dfea465e 100644 --- a/src/logic/LongRunAverageRewardFormula.h +++ b/src/logic/LongRunAverageRewardFormula.h @@ -13,9 +13,10 @@ namespace storm { // Intentionally left empty. } - virtual bool isRewardPathFormula() const override; virtual bool isLongRunAverageRewardFormula() const override; - virtual bool isValidRewardPathFormula() const override; + virtual bool isRewardPathFormula() const override; + + virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override; virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override; diff --git a/src/logic/NextFormula.cpp b/src/logic/NextFormula.cpp index b7400eb7d..e73171a95 100644 --- a/src/logic/NextFormula.cpp +++ b/src/logic/NextFormula.cpp @@ -1,5 +1,7 @@ #include "src/logic/NextFormula.h" +#include "src/logic/FormulaVisitor.h" + namespace storm { namespace logic { NextFormula::NextFormula(std::shared_ptr<Formula const> const& subformula) : UnaryPathFormula(subformula) { @@ -10,12 +12,12 @@ namespace storm { return true; } - bool NextFormula::isValidProbabilityPathFormula() const { + bool NextFormula::isProbabilityPathFormula() const { return true; } - bool NextFormula::containsNextFormula() const { - return true; + boost::any NextFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const { + return visitor.visit(*this, data); } std::shared_ptr<Formula> NextFormula::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const { diff --git a/src/logic/NextFormula.h b/src/logic/NextFormula.h index f0de43cc6..bade60456 100644 --- a/src/logic/NextFormula.h +++ b/src/logic/NextFormula.h @@ -14,9 +14,9 @@ namespace storm { } virtual bool isNextFormula() const override; - virtual bool isValidProbabilityPathFormula() const override; + virtual bool isProbabilityPathFormula() const override; - virtual bool containsNextFormula() const override; + virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override; virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override; diff --git a/src/logic/ProbabilityOperatorFormula.cpp b/src/logic/ProbabilityOperatorFormula.cpp index cb584b034..09680cbc5 100644 --- a/src/logic/ProbabilityOperatorFormula.cpp +++ b/src/logic/ProbabilityOperatorFormula.cpp @@ -1,5 +1,7 @@ #include "src/logic/ProbabilityOperatorFormula.h" +#include "src/logic/FormulaVisitor.h" + namespace storm { namespace logic { ProbabilityOperatorFormula::ProbabilityOperatorFormula(std::shared_ptr<Formula const> const& subformula) : ProbabilityOperatorFormula(boost::none, boost::none, subformula) { @@ -22,30 +24,10 @@ namespace storm { return true; } - bool ProbabilityOperatorFormula::isPctlStateFormula() const { - return this->getSubformula().isPctlPathFormula(); - } - - bool ProbabilityOperatorFormula::isPctlWithConditionalStateFormula() const { - return this->getSubformula().isPctlWithConditionalPathFormula(); - } - - bool ProbabilityOperatorFormula::isCslStateFormula() const { - return this->getSubformula().isCslPathFormula(); - } - - bool ProbabilityOperatorFormula::isPltlFormula() const { - return this->getSubformula().isLtlFormula(); + boost::any ProbabilityOperatorFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const { + return visitor.visit(*this, data); } - - bool ProbabilityOperatorFormula::containsProbabilityOperator() const { - return true; - } - - bool ProbabilityOperatorFormula::containsNestedProbabilityOperators() const { - return this->getSubformula().containsProbabilityOperator(); - } - + ProbabilityOperatorFormula::ProbabilityOperatorFormula(boost::optional<OptimizationDirection> optimalityType, boost::optional<Bound<double>> bound, std::shared_ptr<Formula const> const& subformula) : OperatorFormula(optimalityType, bound, subformula) { // Intentionally left empty. } diff --git a/src/logic/ProbabilityOperatorFormula.h b/src/logic/ProbabilityOperatorFormula.h index 163e05f58..1172247d0 100644 --- a/src/logic/ProbabilityOperatorFormula.h +++ b/src/logic/ProbabilityOperatorFormula.h @@ -17,14 +17,9 @@ namespace storm { // Intentionally left empty. } - virtual bool isPctlStateFormula() const override; - virtual bool isPctlWithConditionalStateFormula() const override; - virtual bool isCslStateFormula() const override; - virtual bool isPltlFormula() const override; - virtual bool containsProbabilityOperator() const override; - virtual bool containsNestedProbabilityOperators() const override; - virtual bool isProbabilityOperatorFormula() const override; + + virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override; virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override; diff --git a/src/logic/RewardOperatorFormula.cpp b/src/logic/RewardOperatorFormula.cpp index 0eea0eedc..0e025c208 100644 --- a/src/logic/RewardOperatorFormula.cpp +++ b/src/logic/RewardOperatorFormula.cpp @@ -1,5 +1,7 @@ #include "src/logic/RewardOperatorFormula.h" +#include "src/logic/FormulaVisitor.h" + namespace storm { namespace logic { RewardOperatorFormula::RewardOperatorFormula(boost::optional<std::string> const& rewardModelName, std::shared_ptr<Formula const> const& subformula) : RewardOperatorFormula(rewardModelName, boost::none, boost::none, subformula) { @@ -22,20 +24,8 @@ namespace storm { return true; } - bool RewardOperatorFormula::isRewardStateFormula() const { - return this->getSubformula().isRewardPathFormula(); - } - - bool RewardOperatorFormula::containsRewardOperator() const { - return true; - } - - bool RewardOperatorFormula::containsNestedRewardOperators() const { - return this->getSubformula().containsRewardOperator(); - } - - bool RewardOperatorFormula::hasRewardModelName() const { - return static_cast<bool>(this->rewardModelName); + boost::any RewardOperatorFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const { + return visitor.visit(*this, data); } std::string const& RewardOperatorFormula::getRewardModelName() const { diff --git a/src/logic/RewardOperatorFormula.h b/src/logic/RewardOperatorFormula.h index 0cbfe955e..6bcf015d8 100644 --- a/src/logic/RewardOperatorFormula.h +++ b/src/logic/RewardOperatorFormula.h @@ -19,11 +19,9 @@ namespace storm { } virtual bool isRewardOperatorFormula() const override; - virtual bool isRewardStateFormula() const override; - virtual bool containsRewardOperator() const override; - virtual bool containsNestedRewardOperators() const override; - + virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override; + virtual void gatherReferencedRewardModels(std::set<std::string>& referencedRewardModels) const override; virtual std::ostream& writeToStream(std::ostream& out) const override; diff --git a/src/logic/UnaryBooleanStateFormula.cpp b/src/logic/UnaryBooleanStateFormula.cpp index ec9a4ff0a..6d4f9ecdd 100644 --- a/src/logic/UnaryBooleanStateFormula.cpp +++ b/src/logic/UnaryBooleanStateFormula.cpp @@ -1,5 +1,7 @@ #include "src/logic/UnaryBooleanStateFormula.h" +#include "src/logic/FormulaVisitor.h" + namespace storm { namespace logic { UnaryBooleanStateFormula::UnaryBooleanStateFormula(OperatorType operatorType, std::shared_ptr<Formula const> const& subformula) : UnaryStateFormula(subformula), operatorType(operatorType) { @@ -9,6 +11,10 @@ namespace storm { bool UnaryBooleanStateFormula::isUnaryBooleanStateFormula() const { return true; } + + boost::any UnaryBooleanStateFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const { + return visitor.visit(*this, data); + } UnaryBooleanStateFormula::OperatorType UnaryBooleanStateFormula::getOperator() const { return operatorType; diff --git a/src/logic/UnaryBooleanStateFormula.h b/src/logic/UnaryBooleanStateFormula.h index fa0a83023..93d45f862 100644 --- a/src/logic/UnaryBooleanStateFormula.h +++ b/src/logic/UnaryBooleanStateFormula.h @@ -17,6 +17,8 @@ namespace storm { virtual bool isUnaryBooleanStateFormula() const override; + virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override; + OperatorType getOperator() const; virtual bool isNot() const; diff --git a/src/logic/UnaryPathFormula.cpp b/src/logic/UnaryPathFormula.cpp index 01ccadde8..3e0cdaebc 100644 --- a/src/logic/UnaryPathFormula.cpp +++ b/src/logic/UnaryPathFormula.cpp @@ -9,43 +9,7 @@ namespace storm { bool UnaryPathFormula::isUnaryPathFormula() const { return true; } - - bool UnaryPathFormula::isPctlPathFormula() const { - return this->getSubformula().isPctlStateFormula(); - } - - bool UnaryPathFormula::isPctlWithConditionalPathFormula() const { - return this->getSubformula().isPctlWithConditionalStateFormula(); - } - - bool UnaryPathFormula::isLtlFormula() const { - return this->getSubformula().isLtlFormula(); - } - - bool UnaryPathFormula::containsBoundedUntilFormula() const { - return this->getSubformula().containsBoundedUntilFormula(); - } - - bool UnaryPathFormula::containsNextFormula() const { - return this->getSubformula().containsNextFormula(); - } - - bool UnaryPathFormula::containsProbabilityOperator() const { - return this->getSubformula().containsProbabilityOperator(); - } - - bool UnaryPathFormula::containsNestedProbabilityOperators() const { - return this->getSubformula().containsNestedProbabilityOperators(); - } - - bool UnaryPathFormula::containsRewardOperator() const { - return this->getSubformula().containsRewardOperator(); - } - - bool UnaryPathFormula::containsNestedRewardOperators() const { - return this->getSubformula().containsNestedRewardOperators(); - } - + Formula const& UnaryPathFormula::getSubformula() const { return *subformula; } diff --git a/src/logic/UnaryPathFormula.h b/src/logic/UnaryPathFormula.h index be60edbd9..3ea27d8f5 100644 --- a/src/logic/UnaryPathFormula.h +++ b/src/logic/UnaryPathFormula.h @@ -17,16 +17,6 @@ namespace storm { virtual bool isUnaryPathFormula() const override; - virtual bool isPctlPathFormula() const override; - virtual bool isPctlWithConditionalPathFormula() const override; - virtual bool isLtlFormula() const override; - virtual bool containsBoundedUntilFormula() const override; - virtual bool containsNextFormula() const override; - virtual bool containsProbabilityOperator() const override; - virtual bool containsNestedProbabilityOperators() const override; - virtual bool containsRewardOperator() const override; - virtual bool containsNestedRewardOperators() const override; - Formula const& getSubformula() const; virtual void gatherAtomicExpressionFormulas(std::vector<std::shared_ptr<AtomicExpressionFormula const>>& atomicExpressionFormulas) const override; diff --git a/src/logic/UnaryStateFormula.cpp b/src/logic/UnaryStateFormula.cpp index a57b86b1e..e99c77057 100644 --- a/src/logic/UnaryStateFormula.cpp +++ b/src/logic/UnaryStateFormula.cpp @@ -1,5 +1,7 @@ #include "src/logic/UnaryStateFormula.h" +#include "src/logic/FormulaVisitor.h" + namespace storm { namespace logic { UnaryStateFormula::UnaryStateFormula(std::shared_ptr<Formula const> subformula) : subformula(subformula) { @@ -10,44 +12,8 @@ namespace storm { return true; } - bool UnaryStateFormula::isPropositionalFormula() const { - return this->getSubformula().isPropositionalFormula(); - } - - bool UnaryStateFormula::isPctlStateFormula() const { - return this->getSubformula().isPctlStateFormula(); - } - - bool UnaryStateFormula::isPctlWithConditionalStateFormula() const { - return this->getSubformula().isPctlWithConditionalStateFormula(); - } - - bool UnaryStateFormula::isLtlFormula() const { - return this->getSubformula().isLtlFormula(); - } - - bool UnaryStateFormula::containsBoundedUntilFormula() const { - return this->getSubformula().containsBoundedUntilFormula(); - } - - bool UnaryStateFormula::containsNextFormula() const { - return this->getSubformula().containsNextFormula(); - } - - bool UnaryStateFormula::containsProbabilityOperator() const { - return getSubformula().containsProbabilityOperator(); - } - - bool UnaryStateFormula::containsNestedProbabilityOperators() const { - return getSubformula().containsNestedProbabilityOperators(); - } - - bool UnaryStateFormula::containsRewardOperator() const { - return this->getSubformula().containsRewardOperator(); - } - - bool UnaryStateFormula::containsNestedRewardOperators() const { - return this->getSubformula().containsNestedRewardOperators(); + boost::any UnaryStateFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const { + return visitor.visit(*this, data); } Formula const& UnaryStateFormula::getSubformula() const { diff --git a/src/logic/UnaryStateFormula.h b/src/logic/UnaryStateFormula.h index 8b5539a88..1dcf00023 100644 --- a/src/logic/UnaryStateFormula.h +++ b/src/logic/UnaryStateFormula.h @@ -15,16 +15,7 @@ namespace storm { virtual bool isUnaryStateFormula() const override; - virtual bool isPropositionalFormula() const override; - virtual bool isPctlWithConditionalStateFormula() const override; - virtual bool isPctlStateFormula() const override; - virtual bool isLtlFormula() const override; - virtual bool containsBoundedUntilFormula() const override; - virtual bool containsNextFormula() const override; - virtual bool containsProbabilityOperator() const override; - virtual bool containsNestedProbabilityOperators() const override; - virtual bool containsRewardOperator() const override; - virtual bool containsNestedRewardOperators() const override; + virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override; Formula const& getSubformula() const; diff --git a/src/logic/UntilFormula.cpp b/src/logic/UntilFormula.cpp index b15f3743f..a00eae77d 100644 --- a/src/logic/UntilFormula.cpp +++ b/src/logic/UntilFormula.cpp @@ -1,5 +1,7 @@ #include "src/logic/UntilFormula.h" +#include "src/logic/FormulaVisitor.h" + namespace storm { namespace logic { UntilFormula::UntilFormula(std::shared_ptr<Formula const> const& leftSubformula, std::shared_ptr<Formula const> const& rightSubformula) : BinaryPathFormula(leftSubformula, rightSubformula) { @@ -10,10 +12,14 @@ namespace storm { return true; } - bool UntilFormula::isValidProbabilityPathFormula() const { + bool UntilFormula::isProbabilityPathFormula() const { return true; } + boost::any UntilFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const { + return visitor.visit(*this, data); + } + std::shared_ptr<Formula> UntilFormula::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const { return std::make_shared<UntilFormula>(this->getLeftSubformula().substitute(substitution), this->getRightSubformula().substitute(substitution)); } diff --git a/src/logic/UntilFormula.h b/src/logic/UntilFormula.h index 87ceef806..887d39b45 100644 --- a/src/logic/UntilFormula.h +++ b/src/logic/UntilFormula.h @@ -14,8 +14,10 @@ namespace storm { } virtual bool isUntilFormula() const override; - virtual bool isValidProbabilityPathFormula() const override; + virtual bool isProbabilityPathFormula() const override; + virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override; + virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override; virtual std::ostream& writeToStream(std::ostream& out) const override; diff --git a/src/modelchecker/AbstractModelChecker.cpp b/src/modelchecker/AbstractModelChecker.cpp index 56a65b39e..e7fabdec1 100644 --- a/src/modelchecker/AbstractModelChecker.cpp +++ b/src/modelchecker/AbstractModelChecker.cpp @@ -17,11 +17,15 @@ namespace storm { if (formula.isStateFormula()) { return this->checkStateFormula(checkTask.substituteFormula(formula.asStateFormula())); } else if (formula.isPathFormula()) { - if (checkTask.computeProbabilities()) { + if (formula.isProbabilityPathFormula()) { return this->computeProbabilities(checkTask.substituteFormula(formula.asPathFormula())); - } else if (checkTask.computeRewards()) { + } else if (formula.isRewardPathFormula()) { return this->computeRewards(checkTask.substituteFormula(formula.asPathFormula())); } + } else if (formula.isConditionalProbabilityFormula()) { + return this->computeConditionalProbabilities(checkTask.substituteFormula(formula.asConditionalFormula())); + } else if (formula.isConditionalRewardFormula()) { + return this->computeConditionalRewards(checkTask.substituteFormula(formula.asConditionalFormula())); } STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "The given formula '" << formula << "' is invalid."); } @@ -30,8 +34,6 @@ namespace storm { storm::logic::PathFormula const& pathFormula = checkTask.getFormula(); if (pathFormula.isBoundedUntilFormula()) { return this->computeBoundedUntilProbabilities(checkTask.substituteFormula(pathFormula.asBoundedUntilFormula())); - } else if (pathFormula.isConditionalPathFormula()) { - return this->computeConditionalProbabilities(checkTask.substituteFormula(pathFormula.asConditionalPathFormula())); } else if (pathFormula.isEventuallyFormula()) { return this->computeEventuallyProbabilities(checkTask.substituteFormula(pathFormula.asEventuallyFormula())); } else if (pathFormula.isGloballyFormula()) { @@ -48,7 +50,7 @@ namespace storm { STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "This model checker does not support the formula: " << checkTask.getFormula() << "."); } - std::unique_ptr<CheckResult> AbstractModelChecker::computeConditionalProbabilities(CheckTask<storm::logic::ConditionalPathFormula> const& checkTask) { + std::unique_ptr<CheckResult> AbstractModelChecker::computeConditionalProbabilities(CheckTask<storm::logic::ConditionalFormula> const& checkTask) { STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "This model checker does not support the formula: " << checkTask.getFormula() << "."); } @@ -84,6 +86,10 @@ namespace storm { STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "The given formula '" << rewardPathFormula << "' is invalid."); } + std::unique_ptr<CheckResult> AbstractModelChecker::computeConditionalRewards(CheckTask<storm::logic::ConditionalFormula> const& checkTask) { + STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "This model checker does not support the formula: " << checkTask.getFormula() << "."); + } + std::unique_ptr<CheckResult> AbstractModelChecker::computeCumulativeRewards(CheckTask<storm::logic::CumulativeRewardFormula> const& checkTask) { STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "This model checker does not support the formula: " << checkTask.getFormula() << "."); } @@ -171,8 +177,6 @@ namespace storm { std::unique_ptr<CheckResult> AbstractModelChecker::checkProbabilityOperatorFormula(CheckTask<storm::logic::ProbabilityOperatorFormula> const& checkTask) { storm::logic::ProbabilityOperatorFormula const& stateFormula = checkTask.getFormula(); - STORM_LOG_THROW(stateFormula.getSubformula().isValidProbabilityPathFormula(), storm::exceptions::InvalidArgumentException, "The given formula is invalid."); - std::unique_ptr<CheckResult> result = this->computeProbabilities(checkTask.substituteFormula(stateFormula.getSubformula().asPathFormula())); if (stateFormula.hasBound()) { @@ -185,8 +189,6 @@ namespace storm { std::unique_ptr<CheckResult> AbstractModelChecker::checkRewardOperatorFormula(CheckTask<storm::logic::RewardOperatorFormula> const& checkTask) { storm::logic::RewardOperatorFormula const& stateFormula = checkTask.getFormula(); - STORM_LOG_THROW(stateFormula.getSubformula().isValidRewardPathFormula(), storm::exceptions::InvalidArgumentException, "The given formula is invalid."); - std::unique_ptr<CheckResult> result = this->computeRewards(checkTask.substituteFormula(stateFormula.getSubformula().asPathFormula())); if (checkTask.isBoundSet()) { diff --git a/src/modelchecker/AbstractModelChecker.h b/src/modelchecker/AbstractModelChecker.h index f827c99ff..c79302808 100644 --- a/src/modelchecker/AbstractModelChecker.h +++ b/src/modelchecker/AbstractModelChecker.h @@ -36,8 +36,8 @@ namespace storm { // The methods to compute probabilities for path formulas. virtual std::unique_ptr<CheckResult> computeProbabilities(CheckTask<storm::logic::PathFormula> const& checkTask); + virtual std::unique_ptr<CheckResult> computeConditionalProbabilities(CheckTask<storm::logic::ConditionalFormula> const& checkTask); virtual std::unique_ptr<CheckResult> computeBoundedUntilProbabilities(CheckTask<storm::logic::BoundedUntilFormula> const& checkTask); - virtual std::unique_ptr<CheckResult> computeConditionalProbabilities(CheckTask<storm::logic::ConditionalPathFormula> const& checkTask); virtual std::unique_ptr<CheckResult> computeEventuallyProbabilities(CheckTask<storm::logic::EventuallyFormula> const& checkTask); virtual std::unique_ptr<CheckResult> computeGloballyProbabilities(CheckTask<storm::logic::GloballyFormula> const& checkTask); virtual std::unique_ptr<CheckResult> computeNextProbabilities(CheckTask<storm::logic::NextFormula> const& checkTask); @@ -45,6 +45,7 @@ namespace storm { // The methods to compute the rewards for path formulas. virtual std::unique_ptr<CheckResult> computeRewards(CheckTask<storm::logic::PathFormula> const& checkTask); + virtual std::unique_ptr<CheckResult> computeConditionalRewards(CheckTask<storm::logic::ConditionalFormula> const& checkTask); virtual std::unique_ptr<CheckResult> computeCumulativeRewards(CheckTask<storm::logic::CumulativeRewardFormula> const& checkTask); virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(CheckTask<storm::logic::InstantaneousRewardFormula> const& checkTask); virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask); diff --git a/src/modelchecker/CheckTask.h b/src/modelchecker/CheckTask.h index a780ef168..8693f09f2 100644 --- a/src/modelchecker/CheckTask.h +++ b/src/modelchecker/CheckTask.h @@ -63,8 +63,6 @@ namespace storm { } } } else if (formula.isRewardOperatorFormula()) { - this->checkType = CheckType::Rewards; - storm::logic::RewardOperatorFormula const& rewardOperatorFormula = formula.asRewardOperatorFormula(); this->rewardModel = rewardOperatorFormula.getOptionalRewardModelName(); @@ -82,7 +80,7 @@ namespace storm { */ template<typename NewFormulaType> CheckTask<NewFormulaType, ValueType> substituteFormula(NewFormulaType const& newFormula) const { - return CheckTask<NewFormulaType, ValueType>(newFormula, this->checkType, this->optimizationDirection, this->rewardModel, this->onlyInitialStatesRelevant, this->bound, this->qualitative, this->produceSchedulers); + return CheckTask<NewFormulaType, ValueType>(newFormula, this->optimizationDirection, this->rewardModel, this->onlyInitialStatesRelevant, this->bound, this->qualitative, this->produceSchedulers); } /*! @@ -91,27 +89,6 @@ namespace storm { FormulaType const& getFormula() const { return formula.get(); } - - /*! - * Retrieves whether probabilities are to be computed. - */ - bool computeProbabilities() const { - return checkType == CheckType::Probabilities; - } - - /*! - * Retrieves whether rewards are to be computed. - */ - bool computeRewards() const { - return checkType == CheckType::Rewards; - } - - /*! - * Retrieves the type of this task. - */ - CheckType getCheckType() const { - return checkType; - } /*! * Retrieves whether an optimization direction was set. @@ -211,7 +188,6 @@ namespace storm { * Creates a task object with the given options. * * @param formula The formula to attach to the task. - * @param checkType The type of task: whether to compute probabilities or rewards. * @param optimizationDirection If set, the probabilities will be minimized/maximized. * @param rewardModelName If given, the checking has to be done wrt. to this reward model. * @param onlyInitialStatesRelevant If set to true, the model checker may decide to only compute the values @@ -222,16 +198,13 @@ namespace storm { * @param produceSchedulers If supported by the model checker and the model formalism, schedulers to achieve * a value will be produced if this flag is set. */ - CheckTask(std::reference_wrapper<FormulaType const> const& formula, CheckType checkType, boost::optional<storm::OptimizationDirection> const& optimizationDirection, boost::optional<std::string> const& rewardModel, bool onlyInitialStatesRelevant, boost::optional<storm::logic::Bound<ValueType>> const& bound, bool qualitative, bool produceSchedulers) : formula(formula), checkType(checkType), optimizationDirection(optimizationDirection), rewardModel(rewardModel), onlyInitialStatesRelevant(onlyInitialStatesRelevant), bound(bound), qualitative(qualitative), produceSchedulers(produceSchedulers) { + CheckTask(std::reference_wrapper<FormulaType const> const& formula, boost::optional<storm::OptimizationDirection> const& optimizationDirection, boost::optional<std::string> const& rewardModel, bool onlyInitialStatesRelevant, boost::optional<storm::logic::Bound<ValueType>> const& bound, bool qualitative, bool produceSchedulers) : formula(formula), optimizationDirection(optimizationDirection), rewardModel(rewardModel), onlyInitialStatesRelevant(onlyInitialStatesRelevant), bound(bound), qualitative(qualitative), produceSchedulers(produceSchedulers) { // Intentionally left empty. } // The formula that is to be checked. std::reference_wrapper<FormulaType const> formula; - // A type indicating whether probabilities or rewards are to be computed. - CheckType checkType; - // If set, the probabilities will be minimized/maximized. boost::optional<storm::OptimizationDirection> optimizationDirection; From dc8a5b11e0df6ff5238f8abd906cf85ed41989ae Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Thu, 18 Feb 2016 18:04:15 +0100 Subject: [PATCH 04/23] more refactoring regarding fragment checking Former-commit-id: fd335f6f8edd73577910525ff03134d0121aba21 --- src/logic/Formula.cpp | 17 ++ src/logic/Formula.h | 12 +- src/logic/FormulaInformation.cpp | 46 +++++ src/logic/FormulaInformation.h | 29 +++ src/logic/FormulaInformationVisitor.cpp | 85 +++++++++ src/logic/FormulaInformationVisitor.h | 38 ++++ src/logic/FragmentChecker.cpp | 165 +++++++++++++----- src/logic/FragmentSpecification.cpp | 148 ++++++++++++++++ src/logic/FragmentSpecification.h | 43 ++++- src/logic/RewardOperatorFormula.cpp | 4 + src/logic/UnaryStateFormula.cpp | 4 - src/logic/UnaryStateFormula.h | 2 - .../csl/HybridCtmcCslModelChecker.cpp | 4 +- .../csl/SparseCtmcCslModelChecker.cpp | 4 +- .../SparseMarkovAutomatonCslModelChecker.cpp | 6 +- .../prctl/HybridDtmcPrctlModelChecker.cpp | 4 +- .../prctl/HybridMdpPrctlModelChecker.cpp | 13 +- .../prctl/SparseDtmcPrctlModelChecker.cpp | 31 +--- .../prctl/SparseDtmcPrctlModelChecker.h | 2 +- .../prctl/SparseMdpPrctlModelChecker.cpp | 31 +--- .../prctl/SparseMdpPrctlModelChecker.h | 2 +- .../prctl/SymbolicDtmcPrctlModelChecker.cpp | 14 +- .../prctl/SymbolicMdpPrctlModelChecker.cpp | 13 +- .../SparsePropositionalModelChecker.cpp | 4 +- .../SymbolicPropositionalModelChecker.cpp | 4 +- .../SparseDtmcEliminationModelChecker.cpp | 58 ++---- .../SparseDtmcEliminationModelChecker.h | 2 +- src/parser/FormulaParser.cpp | 24 +-- .../BisimulationDecomposition.cpp | 21 ++- test/functional/logic/FragmentCheckerTest.cpp | 14 ++ test/functional/parser/FormulaParserTest.cpp | 11 +- 31 files changed, 653 insertions(+), 202 deletions(-) create mode 100644 src/logic/FormulaInformation.cpp create mode 100644 src/logic/FormulaInformation.h create mode 100644 src/logic/FormulaInformationVisitor.cpp create mode 100644 src/logic/FormulaInformationVisitor.h create mode 100644 test/functional/logic/FragmentCheckerTest.cpp diff --git a/src/logic/Formula.cpp b/src/logic/Formula.cpp index 6270d5664..d682d02aa 100644 --- a/src/logic/Formula.cpp +++ b/src/logic/Formula.cpp @@ -1,6 +1,9 @@ #include "src/logic/Formulas.h" #include <sstream> +#include "src/logic/FragmentChecker.h" +#include "src/logic/FormulaInformationVisitor.h" + namespace storm { namespace logic { bool Formula::isPathFormula() const { @@ -111,6 +114,10 @@ namespace storm { return false; } + bool Formula::isReachabilityRewardFormula() const { + return false; + } + bool Formula::isLongRunAverageRewardFormula() const { return false; } @@ -131,6 +138,16 @@ namespace storm { return false; } + bool Formula::isInFragment(FragmentSpecification const& fragment) const { + FragmentChecker checker; + return checker.conformsToSpecification(*this, fragment); + } + + FormulaInformation Formula::info() const { + FormulaInformationVisitor visitor; + return visitor.getInformation(*this); + } + std::shared_ptr<Formula const> Formula::getTrueFormula() { return std::shared_ptr<Formula const>(new BooleanLiteralFormula(true)); } diff --git a/src/logic/Formula.h b/src/logic/Formula.h index ae879fce6..f2e06bc0b 100644 --- a/src/logic/Formula.h +++ b/src/logic/Formula.h @@ -19,8 +19,11 @@ namespace storm { // Forward-declare visitor for accept() method. class FormulaVisitor; - // Also foward-declare base model checker class. - class ModelChecker; + // Forward-declare fragment specification for isInFragment() method. + class FragmentSpecification; + + // Forward-declare formula information class for info() method. + class FormulaInformation; class Formula : public std::enable_shared_from_this<Formula const> { public: @@ -80,7 +83,10 @@ namespace storm { virtual bool isUnaryPathFormula() const; virtual bool isUnaryStateFormula() const; - virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const = 0; + bool isInFragment(FragmentSpecification const& fragment) const; + FormulaInformation info() const; + + virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data = boost::any()) const = 0; static std::shared_ptr<Formula const> getTrueFormula(); diff --git a/src/logic/FormulaInformation.cpp b/src/logic/FormulaInformation.cpp new file mode 100644 index 000000000..b49f4a23b --- /dev/null +++ b/src/logic/FormulaInformation.cpp @@ -0,0 +1,46 @@ +#include "src/logic/FormulaInformation.h" + +namespace storm { + namespace logic { + FormulaInformation::FormulaInformation() { + this->mContainsRewardOperator = false; + this->mContainsNextFormula = false; + this->mContainsBoundedUntilFormula = false; + } + + bool FormulaInformation::containsRewardOperator() const { + return this->mContainsRewardOperator; + } + + bool FormulaInformation::containsNextFormula() const { + return this->mContainsNextFormula; + } + + bool FormulaInformation::containsBoundedUntilFormula() const { + return this-mContainsBoundedUntilFormula; + } + + FormulaInformation FormulaInformation::join(FormulaInformation const& other) { + FormulaInformation result; + result.mContainsRewardOperator = this->containsRewardOperator() || other.containsRewardOperator(); + result.mContainsNextFormula = this->containsNextFormula() || other.containsNextFormula(); + result.mContainsBoundedUntilFormula = this->containsBoundedUntilFormula() || other.containsBoundedUntilFormula(); + return result; + } + + FormulaInformation& FormulaInformation::setContainsRewardOperator(bool newValue) { + this->mContainsRewardOperator = newValue; + return *this; + } + + FormulaInformation& FormulaInformation::setContainsNextFormula(bool newValue) { + this->mContainsNextFormula = newValue; + return *this; + } + + FormulaInformation& FormulaInformation::setContainsBoundedUntilFormula(bool newValue) { + this->mContainsBoundedUntilFormula = newValue; + return *this; + } + } +} \ No newline at end of file diff --git a/src/logic/FormulaInformation.h b/src/logic/FormulaInformation.h new file mode 100644 index 000000000..53269696c --- /dev/null +++ b/src/logic/FormulaInformation.h @@ -0,0 +1,29 @@ +#ifndef STORM_LOGIC_FORMULAINFORMATION_H_ +#define STORM_LOGIC_FORMULAINFORMATION_H_ + +namespace storm { + namespace logic { + + class FormulaInformation { + public: + FormulaInformation(); + bool containsRewardOperator() const; + bool containsNextFormula() const; + bool containsBoundedUntilFormula() const; + + FormulaInformation join(FormulaInformation const& other); + + FormulaInformation& setContainsRewardOperator(bool newValue = true); + FormulaInformation& setContainsNextFormula(bool newValue = true); + FormulaInformation& setContainsBoundedUntilFormula(bool newValue = true); + + private: + bool mContainsRewardOperator; + bool mContainsNextFormula; + bool mContainsBoundedUntilFormula; + }; + + } +} + +#endif /* STORM_LOGIC_FORMULAINFORMATION_H_ */ \ No newline at end of file diff --git a/src/logic/FormulaInformationVisitor.cpp b/src/logic/FormulaInformationVisitor.cpp new file mode 100644 index 000000000..f8ef57f92 --- /dev/null +++ b/src/logic/FormulaInformationVisitor.cpp @@ -0,0 +1,85 @@ +#include "src/logic/FormulaInformationVisitor.h" + +#include "src/logic/Formulas.h" + +namespace storm { + namespace logic { + FormulaInformation FormulaInformationVisitor::getInformation(Formula const& f) const { + boost::any result = f.accept(*this, boost::any()); + return boost::any_cast<FormulaInformation>(result); + } + + boost::any FormulaInformationVisitor::visit(AtomicExpressionFormula const& f, boost::any const& data) const { + return FormulaInformation(); + } + + boost::any FormulaInformationVisitor::visit(AtomicLabelFormula const& f, boost::any const& data) const { + return FormulaInformation(); + } + + boost::any FormulaInformationVisitor::visit(BinaryBooleanStateFormula const& f, boost::any const& data) const { + return FormulaInformation(); + } + + boost::any FormulaInformationVisitor::visit(BooleanLiteralFormula const& f, boost::any const& data) const { + return FormulaInformation(); + } + + boost::any FormulaInformationVisitor::visit(BoundedUntilFormula const& f, boost::any const& data) const { + return boost::any_cast<FormulaInformation>(f.getLeftSubformula().accept(*this)).join(boost::any_cast<FormulaInformation>(f.getRightSubformula().accept(*this))).setContainsBoundedUntilFormula(); + } + + boost::any FormulaInformationVisitor::visit(ConditionalFormula const& f, boost::any const& data) const { + return boost::any_cast<FormulaInformation>(f.getSubformula().accept(*this)).join(boost::any_cast<FormulaInformation>(f.getConditionFormula().accept(*this))); + } + + boost::any FormulaInformationVisitor::visit(CumulativeRewardFormula const& f, boost::any const& data) const { + return FormulaInformation(); + } + + boost::any FormulaInformationVisitor::visit(EventuallyFormula const& f, boost::any const& data) const { + return f.getSubformula().accept(*this); + } + + boost::any FormulaInformationVisitor::visit(ExpectedTimeOperatorFormula const& f, boost::any const& data) const { + return f.getSubformula().accept(*this); + } + + boost::any FormulaInformationVisitor::visit(GloballyFormula const& f, boost::any const& data) const { + return f.getSubformula().accept(*this); + } + + boost::any FormulaInformationVisitor::visit(InstantaneousRewardFormula const& f, boost::any const& data) const { + return FormulaInformation(); + } + + boost::any FormulaInformationVisitor::visit(LongRunAverageOperatorFormula const& f, boost::any const& data) const { + return f.getSubformula().accept(*this); + } + + boost::any FormulaInformationVisitor::visit(LongRunAverageRewardFormula const& f, boost::any const& data) const { + return FormulaInformation(); + } + + boost::any FormulaInformationVisitor::visit(NextFormula const& f, boost::any const& data) const { + return boost::any_cast<FormulaInformation>(f.getSubformula().accept(*this)).setContainsNextFormula(); + } + + boost::any FormulaInformationVisitor::visit(ProbabilityOperatorFormula const& f, boost::any const& data) const { + return f.getSubformula().accept(*this); + } + + boost::any FormulaInformationVisitor::visit(RewardOperatorFormula const& f, boost::any const& data) const { + return boost::any_cast<FormulaInformation>(f.getSubformula().accept(*this)).setContainsRewardOperator(); + } + + boost::any FormulaInformationVisitor::visit(UnaryBooleanStateFormula const& f, boost::any const& data) const { + return f.getSubformula().accept(*this); + } + + boost::any FormulaInformationVisitor::visit(UntilFormula const& f, boost::any const& data) const { + return boost::any_cast<FormulaInformation>(f.getLeftSubformula().accept(*this)).join(boost::any_cast<FormulaInformation>(f.getRightSubformula().accept(*this))); + } + + } +} \ No newline at end of file diff --git a/src/logic/FormulaInformationVisitor.h b/src/logic/FormulaInformationVisitor.h new file mode 100644 index 000000000..2e2cc0d6d --- /dev/null +++ b/src/logic/FormulaInformationVisitor.h @@ -0,0 +1,38 @@ +#ifndef STORM_LOGIC_FORMULAINFORMATIONVISITOR_H_ +#define STORM_LOGIC_FORMULAINFORMATIONVISITOR_H_ + +#include "src/logic/FormulaVisitor.h" +#include "src/logic/FormulaInformation.h" + +namespace storm { + namespace logic { + + class FormulaInformationVisitor : public FormulaVisitor { + public: + FormulaInformation getInformation(Formula const& f) const; + + virtual boost::any visit(AtomicExpressionFormula const& f, boost::any const& data) const override; + virtual boost::any visit(AtomicLabelFormula const& f, boost::any const& data) const override; + virtual boost::any visit(BinaryBooleanStateFormula const& f, boost::any const& data) const override; + virtual boost::any visit(BooleanLiteralFormula const& f, boost::any const& data) const override; + virtual boost::any visit(BoundedUntilFormula const& f, boost::any const& data) const override; + virtual boost::any visit(ConditionalFormula const& f, boost::any const& data) const override; + virtual boost::any visit(CumulativeRewardFormula const& f, boost::any const& data) const override; + virtual boost::any visit(EventuallyFormula const& f, boost::any const& data) const override; + virtual boost::any visit(ExpectedTimeOperatorFormula const& f, boost::any const& data) const override; + virtual boost::any visit(GloballyFormula const& f, boost::any const& data) const override; + virtual boost::any visit(InstantaneousRewardFormula const& f, boost::any const& data) const override; + virtual boost::any visit(LongRunAverageOperatorFormula const& f, boost::any const& data) const override; + virtual boost::any visit(LongRunAverageRewardFormula const& f, boost::any const& data) const override; + virtual boost::any visit(NextFormula const& f, boost::any const& data) const override; + virtual boost::any visit(ProbabilityOperatorFormula const& f, boost::any const& data) const override; + virtual boost::any visit(RewardOperatorFormula const& f, boost::any const& data) const override; + virtual boost::any visit(UnaryBooleanStateFormula const& f, boost::any const& data) const override; + virtual boost::any visit(UntilFormula const& f, boost::any const& data) const override; + }; + + } +} + + +#endif /* STORM_LOGIC_FORMULAINFORMATIONVISITOR_H_ */ \ No newline at end of file diff --git a/src/logic/FragmentChecker.cpp b/src/logic/FragmentChecker.cpp index d94056f58..405b75a27 100644 --- a/src/logic/FragmentChecker.cpp +++ b/src/logic/FragmentChecker.cpp @@ -4,49 +4,75 @@ namespace storm { namespace logic { + class InheritedInformation { + public: + InheritedInformation(FragmentSpecification const& fragmentSpecification) : fragmentSpecification(fragmentSpecification) { + // Intentionally left empty. + } + + FragmentSpecification const& getSpecification() const { + return fragmentSpecification; + } + + private: + FragmentSpecification const& fragmentSpecification; + }; + bool FragmentChecker::conformsToSpecification(Formula const& f, FragmentSpecification const& specification) const { - boost::any result = f.accept(*this, specification); + boost::any result = f.accept(*this, InheritedInformation(specification)); return boost::any_cast<bool>(result); } boost::any FragmentChecker::visit(AtomicExpressionFormula const& f, boost::any const& data) const { - FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data); - return specification.areAtomicExpressionFormulasAllowed(); + InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data); + return inherited.getSpecification().areAtomicExpressionFormulasAllowed(); } boost::any FragmentChecker::visit(AtomicLabelFormula const& f, boost::any const& data) const { - FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data); - return specification.areAtomicLabelFormulasAllowed(); + InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data); + return inherited.getSpecification().areAtomicLabelFormulasAllowed(); } boost::any FragmentChecker::visit(BinaryBooleanStateFormula const& f, boost::any const& data) const { - FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data); - bool result = specification.areBinaryBooleanStateFormulasAllowed(); - result = result && boost::any_cast<bool>(f.getLeftSubformula().accept(*this, specification)); - result = result && boost::any_cast<bool>(f.getRightSubformula().accept(*this, specification)); + InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data); + bool result = inherited.getSpecification().areBinaryBooleanStateFormulasAllowed(); + result = result && boost::any_cast<bool>(f.getLeftSubformula().accept(*this, data)); + result = result && boost::any_cast<bool>(f.getRightSubformula().accept(*this, data)); return result; } boost::any FragmentChecker::visit(BooleanLiteralFormula const& f, boost::any const& data) const { - FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data); - return specification.areBooleanLiteralFormulasAllowed(); + InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data); + return inherited.getSpecification().areBooleanLiteralFormulasAllowed(); } boost::any FragmentChecker::visit(BoundedUntilFormula const& f, boost::any const& data) const { - FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data); - bool result = specification.areBoundedUntilFormulasAllowed(); + InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data); + bool result = inherited.getSpecification().areBoundedUntilFormulasAllowed(); + if (!inherited.getSpecification().areNestedPathFormulasAllowed()) { + result = result && !f.getLeftSubformula().isPathFormula(); + result = result && !f.getRightSubformula().isPathFormula(); + } + if (f.hasDiscreteTimeBound()) { + result = result && inherited.getSpecification().areStepBoundedUntilFormulasAllowed(); + } else { + result = result && inherited.getSpecification().areTimeBoundedUntilFormulasAllowed(); + } result = result && boost::any_cast<bool>(f.getLeftSubformula().accept(*this, data)); result = result && boost::any_cast<bool>(f.getRightSubformula().accept(*this, data)); return result; } boost::any FragmentChecker::visit(ConditionalFormula const& f, boost::any const& data) const { - FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data); + InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data); bool result = true; if (f.isConditionalProbabilityFormula()) { - result &= specification.areConditionalProbabilityFormulasAllowed(); + result = result && inherited.getSpecification().areConditionalProbabilityFormulasAllowed(); } else if (f.Formula::isConditionalRewardFormula()) { - result &= specification.areConditionalRewardFormulasFormulasAllowed(); + result = result && inherited.getSpecification().areConditionalRewardFormulasFormulasAllowed(); + } + if (inherited.getSpecification().areOnlyEventuallyFormuluasInConditionalFormulasAllowed()) { + result = result && f.getSubformula().isEventuallyFormula() && f.getConditionFormula().isEventuallyFormula(); } result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, data)); result = result && boost::any_cast<bool>(f.getConditionFormula().accept(*this, data)); @@ -54,65 +80,124 @@ namespace storm { } boost::any FragmentChecker::visit(CumulativeRewardFormula const& f, boost::any const& data) const { - FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data); - return specification.areCumulativeRewardFormulasAllowed(); + InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data); + return inherited.getSpecification().areCumulativeRewardFormulasAllowed(); } boost::any FragmentChecker::visit(EventuallyFormula const& f, boost::any const& data) const { - FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data); - bool result = specification.areEventuallyFormulasAllowed(); + InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data); + bool result = true; + if (f.isEventuallyFormula()) { + result = inherited.getSpecification().areEventuallyFormulasAllowed(); + if (!inherited.getSpecification().areNestedPathFormulasAllowed()) { + result = result && !f.getSubformula().isPathFormula(); + } + } else if (f.isReachabilityRewardFormula()) { + result = result && inherited.getSpecification().areReachabilityRewardFormulasAllowed(); + result = result && f.getSubformula().isStateFormula(); + } else if (f.isReachbilityExpectedTimeFormula()) { + result = result && inherited.getSpecification().areReachbilityExpectedTimeFormulasAllowed(); + result = result && f.getSubformula().isStateFormula(); + } result && boost::any_cast<bool>(f.getSubformula().accept(*this, data)); return result; } boost::any FragmentChecker::visit(ExpectedTimeOperatorFormula const& f, boost::any const& data) const { - FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data); - return specification.areExpectedTimeOperatorsAllowed(); + InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data); + bool result = inherited.getSpecification().areExpectedTimeOperatorsAllowed(); + result = result && f.getSubformula().isExpectedTimePathFormula(); + if (!inherited.getSpecification().areNestedOperatorsAllowed()) { + result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, inherited.getSpecification().copy().setOperatorsAllowed(false))); + } else { + result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, data)); + } + return result; } boost::any FragmentChecker::visit(GloballyFormula const& f, boost::any const& data) const { - FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data); - return specification.areGloballyFormulasAllowed(); + InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data); + bool result = inherited.getSpecification().areGloballyFormulasAllowed(); + if (!inherited.getSpecification().areNestedPathFormulasAllowed()) { + result = result && !f.getSubformula().isPathFormula(); + } + result && boost::any_cast<bool>(f.getSubformula().accept(*this, data)); + return result; } boost::any FragmentChecker::visit(InstantaneousRewardFormula const& f, boost::any const& data) const { - FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data); - return specification.areInstantaneousRewardFormulasAllowed(); + InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data); + return inherited.getSpecification().areInstantaneousRewardFormulasAllowed(); } boost::any FragmentChecker::visit(LongRunAverageOperatorFormula const& f, boost::any const& data) const { - FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data); - return specification.areLongRunAverageOperatorsAllowed(); + InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data); + bool result = inherited.getSpecification().areLongRunAverageOperatorsAllowed(); + result = result && f.getSubformula().isStateFormula(); + if (!inherited.getSpecification().areNestedOperatorsAllowed()) { + result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, inherited.getSpecification().copy().setOperatorsAllowed(false))); + } else { + result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, data)); + } + return result; } boost::any FragmentChecker::visit(LongRunAverageRewardFormula const& f, boost::any const& data) const { - FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data); - return specification.areLongRunAverageRewardFormulasAllowed(); + InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data); + return inherited.getSpecification().areLongRunAverageRewardFormulasAllowed(); } boost::any FragmentChecker::visit(NextFormula const& f, boost::any const& data) const { - FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data); - return specification.areNextFormulasAllowed(); + InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data); + bool result = inherited.getSpecification().areNextFormulasAllowed(); + if (!inherited.getSpecification().areNestedPathFormulasAllowed()) { + result = result && !f.getSubformula().isPathFormula(); + } + result && boost::any_cast<bool>(f.getSubformula().accept(*this, data)); + return result; } boost::any FragmentChecker::visit(ProbabilityOperatorFormula const& f, boost::any const& data) const { - FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data); - return specification.areProbabilityOperatorsAllowed(); + InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data); + bool result = inherited.getSpecification().areProbabilityOperatorsAllowed(); + result = result && f.getSubformula().isProbabilityPathFormula(); + if (!inherited.getSpecification().areNestedOperatorsAllowed()) { + result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, inherited.getSpecification().copy().setOperatorsAllowed(false))); + } else { + result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, data)); + } + return result; } boost::any FragmentChecker::visit(RewardOperatorFormula const& f, boost::any const& data) const { - FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data); - return specification.areRewardOperatorsAllowed(); + InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data); + bool result = inherited.getSpecification().areRewardOperatorsAllowed(); + result = result && f.getSubformula().isRewardPathFormula(); + if (!inherited.getSpecification().areNestedOperatorsAllowed()) { + result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, inherited.getSpecification().copy().setOperatorsAllowed(false))); + } else { + result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, data)); + } + return result; } boost::any FragmentChecker::visit(UnaryBooleanStateFormula const& f, boost::any const& data) const { - FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data); - return specification.areUnaryBooleanStateFormulasAllowed(); + InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data); + bool result = inherited.getSpecification().areUnaryBooleanStateFormulasAllowed(); + result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, data)); + return result; } boost::any FragmentChecker::visit(UntilFormula const& f, boost::any const& data) const { - FragmentSpecification const& specification = boost::any_cast<FragmentSpecification const&>(data); - return specification.areUntilFormulasAllowed(); + InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data); + bool result = inherited.getSpecification().areUntilFormulasAllowed(); + if (!inherited.getSpecification().areNestedPathFormulasAllowed()) { + result = result && !f.getLeftSubformula().isPathFormula(); + result = result && !f.getRightSubformula().isPathFormula(); + } + result = result && boost::any_cast<bool>(f.getLeftSubformula().accept(*this, data)); + result = result && boost::any_cast<bool>(f.getRightSubformula().accept(*this, data)); + return result; } } } \ No newline at end of file diff --git a/src/logic/FragmentSpecification.cpp b/src/logic/FragmentSpecification.cpp index eeb697582..d8c02a18e 100644 --- a/src/logic/FragmentSpecification.cpp +++ b/src/logic/FragmentSpecification.cpp @@ -3,6 +3,99 @@ namespace storm { namespace logic { + FragmentSpecification propositional() { + FragmentSpecification propositional; + + propositional.setBooleanLiteralFormulasAllowed(true); + propositional.setBinaryBooleanStateFormulasAllowed(true); + propositional.setUnaryBooleanStateFormulasAllowed(true); + propositional.setAtomicExpressionFormulasAllowed(true); + propositional.setAtomicLabelFormulasAllowed(true); + + return propositional; + } + + FragmentSpecification pctl() { + FragmentSpecification pctl = propositional(); + + pctl.setProbabilityOperatorsAllowed(true); + pctl.setGloballyFormulasAllowed(true); + pctl.setEventuallyFormulasAllowed(true); + pctl.setNextFormulasAllowed(true); + pctl.setUntilFormulasAllowed(true); + pctl.setBoundedUntilFormulasAllowed(true); + pctl.setStepBoundedUntilFormulasAllowed(true); + + return pctl; + } + + FragmentSpecification prctl() { + FragmentSpecification prctl = pctl(); + + prctl.setRewardOperatorsAllowed(true); + prctl.setCumulativeRewardFormulasAllowed(true); + prctl.setInstantaneousFormulasAllowed(true); + prctl.setReachabilityRewardFormulasAllowed(true); + prctl.setLongRunAverageOperatorsAllowed(true); + + return prctl; + } + + FragmentSpecification csl() { + FragmentSpecification csl = pctl(); + + csl.setTimeBoundedUntilFormulasAllowed(true); + + return csl; + } + + FragmentSpecification csrl() { + FragmentSpecification csrl; + + csrl.setRewardOperatorsAllowed(true); + csrl.setCumulativeRewardFormulasAllowed(true); + csrl.setInstantaneousFormulasAllowed(true); + csrl.setReachabilityRewardFormulasAllowed(true); + csrl.setLongRunAverageOperatorsAllowed(true); + + return csrl; + } + + FragmentSpecification::FragmentSpecification() { + probabilityOperator = false; + rewardOperator = false; + expectedTimeOperator = false; + longRunAverageOperator = false; + + globallyFormula = false; + eventuallyFormula = false; + nextFormula = false; + untilFormula = false; + boundedUntilFormula = false; + + atomicExpressionFormula = false; + atomicLabelFormula = false; + booleanLiteralFormula = false; + unaryBooleanStateFormula = false; + binaryBooleanStateFormula = false; + + cumulativeRewardFormula = false; + instantaneousRewardFormula = false; + reachabilityRewardFormula = false; + longRunAverageRewardFormula = false; + + conditionalProbabilityFormula = false; + conditionalRewardFormula = false; + + reachabilityExpectedTimeFormula = false; + + nestedOperators = true; + nestedPathFormulas = false; + onlyEventuallyFormuluasInConditionalFormulas = true; + stepBoundedUntilFormulas = false; + timeBoundedUntilFormulas = false; + } + FragmentSpecification FragmentSpecification::copy() const { return FragmentSpecification(*this); } @@ -205,5 +298,60 @@ namespace storm { return *this; } + bool FragmentSpecification::areNestedPathFormulasAllowed() const { + return this->nestedPathFormulas; + } + + FragmentSpecification& FragmentSpecification::setNestedPathFormulasAllowed(bool newValue) { + this->nestedPathFormulas = newValue; + return *this; + } + + bool FragmentSpecification::areOnlyEventuallyFormuluasInConditionalFormulasAllowed() const { + return this->onlyEventuallyFormuluasInConditionalFormulas; + } + + FragmentSpecification& FragmentSpecification::setOnlyEventuallyFormuluasInConditionalFormulasAllowed(bool newValue) { + this->onlyEventuallyFormuluasInConditionalFormulas = newValue; + return *this; + } + + bool FragmentSpecification::areStepBoundedUntilFormulasAllowed() const { + return this->stepBoundedUntilFormulas; + } + + FragmentSpecification& FragmentSpecification::setStepBoundedUntilFormulasAllowed(bool newValue) { + this->stepBoundedUntilFormulas = newValue; + return *this; + } + + bool FragmentSpecification::areTimeBoundedUntilFormulasAllowed() const { + return this->timeBoundedUntilFormulas; + } + + FragmentSpecification& FragmentSpecification::setTimeBoundedUntilFormulasAllowed(bool newValue) { + this->timeBoundedUntilFormulas = newValue; + return *this; + } + + FragmentSpecification& FragmentSpecification::setOperatorsAllowed(bool newValue) { + this->setProbabilityOperatorsAllowed(newValue); + this->setRewardOperatorsAllowed(newValue); + this->setLongRunAverageOperatorsAllowed(newValue); + this->setExpectedTimeOperatorsAllowed(newValue); + return *this; + } + + FragmentSpecification& FragmentSpecification::setExpectedTimeAllowed(bool newValue) { + this->setExpectedTimeOperatorsAllowed(newValue); + this->setReachbilityExpectedTimeFormulasAllowed(newValue); + return *this; + } + + FragmentSpecification& FragmentSpecification::setLongRunAverageProbabilitiesAllowed(bool newValue) { + this->setLongRunAverageOperatorsAllowed(newValue); + return *this; + } + } } \ No newline at end of file diff --git a/src/logic/FragmentSpecification.h b/src/logic/FragmentSpecification.h index 91099703f..1bd46f4f7 100644 --- a/src/logic/FragmentSpecification.h +++ b/src/logic/FragmentSpecification.h @@ -5,6 +5,12 @@ namespace storm { namespace logic { class FragmentSpecification { public: + FragmentSpecification(); + FragmentSpecification(FragmentSpecification const& other) = default; + FragmentSpecification(FragmentSpecification&& other) = default; + FragmentSpecification& operator=(FragmentSpecification const& other) = default; + FragmentSpecification& operator=(FragmentSpecification&& other) = default; + FragmentSpecification copy() const; bool areProbabilityOperatorsAllowed() const; @@ -73,6 +79,22 @@ namespace storm { bool areNestedOperatorsAllowed() const; FragmentSpecification& setNestedOperatorsAllowed(bool newValue); + bool areNestedPathFormulasAllowed() const; + FragmentSpecification& setNestedPathFormulasAllowed(bool newValue); + + bool areOnlyEventuallyFormuluasInConditionalFormulasAllowed() const; + FragmentSpecification& setOnlyEventuallyFormuluasInConditionalFormulasAllowed(bool newValue); + + bool areStepBoundedUntilFormulasAllowed() const; + FragmentSpecification& setStepBoundedUntilFormulasAllowed(bool newValue); + + bool areTimeBoundedUntilFormulasAllowed() const; + FragmentSpecification& setTimeBoundedUntilFormulasAllowed(bool newValue); + + FragmentSpecification& setOperatorsAllowed(bool newValue); + FragmentSpecification& setExpectedTimeAllowed(bool newValue); + FragmentSpecification& setLongRunAverageProbabilitiesAllowed(bool newValue); + private: // Flags that indicate whether it is legal to see such a formula. bool probabilityOperator; @@ -104,8 +126,27 @@ namespace storm { // Members that indicate certain restrictions. bool nestedOperators; - + bool nestedPathFormulas; + bool onlyEventuallyFormuluasInConditionalFormulas; + bool stepBoundedUntilFormulas; + bool timeBoundedUntilFormulas; }; + + // Propositional. + FragmentSpecification propositional(); + + // Regular PCTL. + FragmentSpecification pctl(); + + // PCTL + cumulative, instantaneous, reachability and long-run rewards. + FragmentSpecification prctl(); + + // Regular CSL. + FragmentSpecification csl(); + + // CSL + cumulative, instantaneous, reachability and long-run rewards. + FragmentSpecification csrl(); + } } diff --git a/src/logic/RewardOperatorFormula.cpp b/src/logic/RewardOperatorFormula.cpp index 0e025c208..711f78789 100644 --- a/src/logic/RewardOperatorFormula.cpp +++ b/src/logic/RewardOperatorFormula.cpp @@ -32,6 +32,10 @@ namespace storm { return this->rewardModelName.get(); } + bool RewardOperatorFormula::hasRewardModelName() const { + return static_cast<bool>(rewardModelName); + } + boost::optional<std::string> const& RewardOperatorFormula::getOptionalRewardModelName() const { return this->rewardModelName; } diff --git a/src/logic/UnaryStateFormula.cpp b/src/logic/UnaryStateFormula.cpp index e99c77057..3ff75a0e1 100644 --- a/src/logic/UnaryStateFormula.cpp +++ b/src/logic/UnaryStateFormula.cpp @@ -12,10 +12,6 @@ namespace storm { return true; } - boost::any UnaryStateFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const { - return visitor.visit(*this, data); - } - Formula const& UnaryStateFormula::getSubformula() const { return *subformula; } diff --git a/src/logic/UnaryStateFormula.h b/src/logic/UnaryStateFormula.h index 1dcf00023..29149ebc8 100644 --- a/src/logic/UnaryStateFormula.h +++ b/src/logic/UnaryStateFormula.h @@ -14,8 +14,6 @@ namespace storm { } virtual bool isUnaryStateFormula() const override; - - virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override; Formula const& getSubformula() const; diff --git a/src/modelchecker/csl/HybridCtmcCslModelChecker.cpp b/src/modelchecker/csl/HybridCtmcCslModelChecker.cpp index c6b7c9d1e..a08d7a6b1 100644 --- a/src/modelchecker/csl/HybridCtmcCslModelChecker.cpp +++ b/src/modelchecker/csl/HybridCtmcCslModelChecker.cpp @@ -10,6 +10,8 @@ #include "src/storage/dd/Add.h" #include "src/storage/dd/Bdd.h" +#include "src/logic/FragmentSpecification.h" + namespace storm { namespace modelchecker { template<storm::dd::DdType DdType, class ValueType> @@ -25,7 +27,7 @@ namespace storm { template<storm::dd::DdType DdType, class ValueType> bool HybridCtmcCslModelChecker<DdType, ValueType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const { storm::logic::Formula const& formula = checkTask.getFormula(); - return formula.isCslFormula() || formula.isRewardFormula(); + return formula.isInFragment(storm::logic::csrl().setGloballyFormulasAllowed(false).setLongRunAverageRewardFormulasAllowed(false).setLongRunAverageProbabilitiesAllowed(true)); } template<storm::dd::DdType DdType, class ValueType> diff --git a/src/modelchecker/csl/SparseCtmcCslModelChecker.cpp b/src/modelchecker/csl/SparseCtmcCslModelChecker.cpp index e91547e81..ee545cb27 100644 --- a/src/modelchecker/csl/SparseCtmcCslModelChecker.cpp +++ b/src/modelchecker/csl/SparseCtmcCslModelChecker.cpp @@ -13,6 +13,8 @@ #include "src/modelchecker/results/ExplicitQualitativeCheckResult.h" #include "src/modelchecker/results/ExplicitQuantitativeCheckResult.h" +#include "src/logic/FragmentSpecification.h" + #include "src/exceptions/InvalidStateException.h" #include "src/exceptions/InvalidPropertyException.h" #include "src/exceptions/NotImplementedException.h" @@ -32,7 +34,7 @@ namespace storm { template <typename SparseCtmcModelType> bool SparseCtmcCslModelChecker<SparseCtmcModelType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const { storm::logic::Formula const& formula = checkTask.getFormula(); - return formula.isCslStateFormula() || formula.isCslPathFormula(); + return formula.isInFragment(storm::logic::csrl().setGloballyFormulasAllowed(false).setLongRunAverageRewardFormulasAllowed(false).setLongRunAverageProbabilitiesAllowed(true)); } template <typename SparseCtmcModelType> diff --git a/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.cpp b/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.cpp index b5966bf4c..9892eb530 100644 --- a/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.cpp +++ b/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.cpp @@ -12,6 +12,8 @@ #include "src/modelchecker/results/ExplicitQualitativeCheckResult.h" #include "src/modelchecker/results/ExplicitQuantitativeCheckResult.h" +#include "src/logic/FragmentSpecification.h" + #include "src/exceptions/InvalidPropertyException.h" #include "src/exceptions/NotImplementedException.h" @@ -30,7 +32,9 @@ namespace storm { template<typename SparseMarkovAutomatonModelType> bool SparseMarkovAutomatonCslModelChecker<SparseMarkovAutomatonModelType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const { storm::logic::Formula const& formula = checkTask.getFormula(); - return formula.isCslStateFormula() || formula.isCslPathFormula(); + storm::logic::FragmentSpecification fragment = storm::logic::csl().setGloballyFormulasAllowed(false).setNextFormulasAllowed(false).setReachabilityRewardFormulasAllowed(true); + fragment.setExpectedTimeAllowed(true).setLongRunAverageProbabilitiesAllowed(true); + return formula.isInFragment(fragment); } template<typename SparseMarkovAutomatonModelType> diff --git a/src/modelchecker/prctl/HybridDtmcPrctlModelChecker.cpp b/src/modelchecker/prctl/HybridDtmcPrctlModelChecker.cpp index b9b0bec0a..31628f4ed 100644 --- a/src/modelchecker/prctl/HybridDtmcPrctlModelChecker.cpp +++ b/src/modelchecker/prctl/HybridDtmcPrctlModelChecker.cpp @@ -17,6 +17,8 @@ #include "src/modelchecker/results/SymbolicQuantitativeCheckResult.h" #include "src/modelchecker/results/HybridQuantitativeCheckResult.h" +#include "src/logic/FragmentSpecification.h" + #include "src/exceptions/InvalidStateException.h" #include "src/exceptions/InvalidPropertyException.h" #include "src/exceptions/InvalidArgumentException.h" @@ -36,7 +38,7 @@ namespace storm { template<storm::dd::DdType DdType, typename ValueType> bool HybridDtmcPrctlModelChecker<DdType, ValueType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const { storm::logic::Formula const& formula = checkTask.getFormula(); - return formula.isPctlStateFormula() || formula.isPctlPathFormula(); + return formula.isInFragment(storm::logic::prctl().setLongRunAverageRewardFormulasAllowed(false).setLongRunAverageProbabilitiesAllowed(true)); } template<storm::dd::DdType DdType, typename ValueType> diff --git a/src/modelchecker/prctl/HybridMdpPrctlModelChecker.cpp b/src/modelchecker/prctl/HybridMdpPrctlModelChecker.cpp index cd39e8c62..f79bbb933 100644 --- a/src/modelchecker/prctl/HybridMdpPrctlModelChecker.cpp +++ b/src/modelchecker/prctl/HybridMdpPrctlModelChecker.cpp @@ -8,6 +8,8 @@ #include "src/modelchecker/results/SymbolicQualitativeCheckResult.h" #include "src/modelchecker/results/SymbolicQuantitativeCheckResult.h" +#include "src/logic/FragmentSpecification.h" + #include "src/solver/MinMaxLinearEquationSolver.h" #include "src/settings/modules/GeneralSettings.h" @@ -30,16 +32,7 @@ namespace storm { template<storm::dd::DdType DdType, typename ValueType> bool HybridMdpPrctlModelChecker<DdType, ValueType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const { storm::logic::Formula const& formula = checkTask.getFormula(); - if (formula.isPctlStateFormula() || formula.isPctlPathFormula()) { - return true; - } - if (formula.isProbabilityOperatorFormula()) { - return this->canHandle(checkTask.substituteFormula(formula.asProbabilityOperatorFormula().getSubformula())); - } - if (formula.isGloballyFormula()) { - return true; - } - return false; + return formula.isInFragment(storm::logic::prctl().setLongRunAverageRewardFormulasAllowed(false)); } template<storm::dd::DdType DdType, typename ValueType> diff --git a/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.cpp b/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.cpp index dce8a8138..df7f1ee9a 100644 --- a/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.cpp +++ b/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.cpp @@ -11,6 +11,8 @@ #include "src/modelchecker/prctl/helper/SparseDtmcPrctlHelper.h" #include "src/modelchecker/csl/helper/SparseCtmcCslHelper.h" +#include "src/logic/FragmentSpecification.h" + #include "src/models/sparse/StandardRewardModel.h" #include "src/settings/modules/GeneralSettings.h" @@ -34,22 +36,7 @@ namespace storm { template<typename SparseDtmcModelType> bool SparseDtmcPrctlModelChecker<SparseDtmcModelType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const { storm::logic::Formula const& formula = checkTask.getFormula(); - if (formula.isPctlStateFormula() || formula.isPctlPathFormula()) { - return true; - } - if (formula.isGloballyFormula()) { - return true; - } - if (formula.isProbabilityOperatorFormula()) { - return this->canHandle(checkTask.substituteFormula(formula.asProbabilityOperatorFormula().getSubformula())); - } - if (formula.isConditionalPathFormula()) { - storm::logic::ConditionalPathFormula const& conditionalPathFormula = formula.asConditionalPathFormula(); - if (conditionalPathFormula.getLeftSubformula().isEventuallyFormula() && conditionalPathFormula.getRightSubformula().isEventuallyFormula()) { - return this->canHandle(conditionalPathFormula.getLeftSubformula()) && this->canHandle(conditionalPathFormula.getRightSubformula()); - } - } - return false; + return formula.isInFragment(storm::logic::prctl().setLongRunAverageRewardFormulasAllowed(false).setLongRunAverageProbabilitiesAllowed(true).setConditionalProbabilityFormulasAllowed(true).setOnlyEventuallyFormuluasInConditionalFormulasAllowed(true)); } template<typename SparseDtmcModelType> @@ -129,13 +116,13 @@ namespace storm { } template<typename SparseDtmcModelType> - std::unique_ptr<CheckResult> SparseDtmcPrctlModelChecker<SparseDtmcModelType>::computeConditionalProbabilities(CheckTask<storm::logic::ConditionalPathFormula> const& checkTask) { - storm::logic::ConditionalPathFormula const& pathFormula = checkTask.getFormula(); - STORM_LOG_THROW(pathFormula.getLeftSubformula().isEventuallyFormula(), storm::exceptions::InvalidPropertyException, "Illegal conditional probability formula."); - STORM_LOG_THROW(pathFormula.getRightSubformula().isEventuallyFormula(), storm::exceptions::InvalidPropertyException, "Illegal conditional probability formula."); + std::unique_ptr<CheckResult> SparseDtmcPrctlModelChecker<SparseDtmcModelType>::computeConditionalProbabilities(CheckTask<storm::logic::ConditionalFormula> const& checkTask) { + storm::logic::ConditionalFormula const& conditionalFormula = checkTask.getFormula(); + STORM_LOG_THROW(conditionalFormula.getSubformula().isEventuallyFormula(), storm::exceptions::InvalidPropertyException, "Illegal conditional probability formula."); + STORM_LOG_THROW(conditionalFormula.getConditionFormula().isEventuallyFormula(), storm::exceptions::InvalidPropertyException, "Illegal conditional probability formula."); - std::unique_ptr<CheckResult> leftResultPointer = this->check(pathFormula.getLeftSubformula().asEventuallyFormula().getSubformula()); - std::unique_ptr<CheckResult> rightResultPointer = this->check(pathFormula.getRightSubformula().asEventuallyFormula().getSubformula()); + std::unique_ptr<CheckResult> leftResultPointer = this->check(conditionalFormula.getSubformula().asEventuallyFormula().getSubformula()); + std::unique_ptr<CheckResult> rightResultPointer = this->check(conditionalFormula.getConditionFormula().asEventuallyFormula().getSubformula()); ExplicitQualitativeCheckResult const& leftResult = leftResultPointer->asExplicitQualitativeCheckResult(); ExplicitQualitativeCheckResult const& rightResult = rightResultPointer->asExplicitQualitativeCheckResult(); diff --git a/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h b/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h index acc7d9283..264f1725d 100644 --- a/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h +++ b/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h @@ -24,7 +24,7 @@ namespace storm { virtual std::unique_ptr<CheckResult> computeNextProbabilities(CheckTask<storm::logic::NextFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeUntilProbabilities(CheckTask<storm::logic::UntilFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeGloballyProbabilities(CheckTask<storm::logic::GloballyFormula> const& checkTask) override; - virtual std::unique_ptr<CheckResult> computeConditionalProbabilities(CheckTask<storm::logic::ConditionalPathFormula> const& checkTask) override; + virtual std::unique_ptr<CheckResult> computeConditionalProbabilities(CheckTask<storm::logic::ConditionalFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeCumulativeRewards(CheckTask<storm::logic::CumulativeRewardFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(CheckTask<storm::logic::InstantaneousRewardFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) override; diff --git a/src/modelchecker/prctl/SparseMdpPrctlModelChecker.cpp b/src/modelchecker/prctl/SparseMdpPrctlModelChecker.cpp index a7a56a890..614522e01 100644 --- a/src/modelchecker/prctl/SparseMdpPrctlModelChecker.cpp +++ b/src/modelchecker/prctl/SparseMdpPrctlModelChecker.cpp @@ -8,6 +8,8 @@ #include "src/modelchecker/results/ExplicitQualitativeCheckResult.h" #include "src/modelchecker/results/ExplicitQuantitativeCheckResult.h" +#include "src/logic/FragmentSpecification.h" + #include "src/models/sparse/StandardRewardModel.h" #include "src/modelchecker/prctl/helper/SparseMdpPrctlHelper.h" @@ -39,22 +41,7 @@ namespace storm { template<typename SparseMdpModelType> bool SparseMdpPrctlModelChecker<SparseMdpModelType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const { storm::logic::Formula const& formula = checkTask.getFormula(); - if (formula.isPctlStateFormula() || formula.isPctlPathFormula()) { - return true; - } - if (formula.isProbabilityOperatorFormula()) { - return this->canHandle(checkTask.substituteFormula(formula.asProbabilityOperatorFormula().getSubformula())); - } - if (formula.isGloballyFormula()) { - return true; - } - if (formula.isConditionalPathFormula()) { - storm::logic::ConditionalPathFormula const& conditionalPathFormula = formula.asConditionalPathFormula(); - if (conditionalPathFormula.getLeftSubformula().isEventuallyFormula() && conditionalPathFormula.getRightSubformula().isEventuallyFormula()) { - return this->canHandle(conditionalPathFormula.getLeftSubformula()) && this->canHandle(conditionalPathFormula.getRightSubformula()); - } - } - return false; + return formula.isInFragment(storm::logic::prctl().setLongRunAverageRewardFormulasAllowed(false).setLongRunAverageProbabilitiesAllowed(true).setConditionalProbabilityFormulasAllowed(true).setOnlyEventuallyFormuluasInConditionalFormulasAllowed(true)); } template<typename SparseMdpModelType> @@ -106,15 +93,15 @@ namespace storm { } template<typename SparseMdpModelType> - std::unique_ptr<CheckResult> SparseMdpPrctlModelChecker<SparseMdpModelType>::computeConditionalProbabilities(CheckTask<storm::logic::ConditionalPathFormula> const& checkTask) { - storm::logic::ConditionalPathFormula const& pathFormula = checkTask.getFormula(); + std::unique_ptr<CheckResult> SparseMdpPrctlModelChecker<SparseMdpModelType>::computeConditionalProbabilities(CheckTask<storm::logic::ConditionalFormula> const& checkTask) { + storm::logic::ConditionalFormula const& conditionalFormula = checkTask.getFormula(); STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidArgumentException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); STORM_LOG_THROW(this->getModel().getInitialStates().getNumberOfSetBits() == 1, storm::exceptions::InvalidPropertyException, "Cannot compute conditional probabilities on MDPs with more than one initial state."); - STORM_LOG_THROW(pathFormula.getLeftSubformula().isEventuallyFormula(), storm::exceptions::InvalidPropertyException, "Illegal conditional probability formula."); - STORM_LOG_THROW(pathFormula.getRightSubformula().isEventuallyFormula(), storm::exceptions::InvalidPropertyException, "Illegal conditional probability formula."); + STORM_LOG_THROW(conditionalFormula.getSubformula().isEventuallyFormula(), storm::exceptions::InvalidPropertyException, "Illegal conditional probability formula."); + STORM_LOG_THROW(conditionalFormula.getConditionFormula().isEventuallyFormula(), storm::exceptions::InvalidPropertyException, "Illegal conditional probability formula."); - std::unique_ptr<CheckResult> leftResultPointer = this->check(pathFormula.getLeftSubformula().asEventuallyFormula().getSubformula()); - std::unique_ptr<CheckResult> rightResultPointer = this->check(pathFormula.getRightSubformula().asEventuallyFormula().getSubformula()); + std::unique_ptr<CheckResult> leftResultPointer = this->check(conditionalFormula.getSubformula().asEventuallyFormula().getSubformula()); + std::unique_ptr<CheckResult> rightResultPointer = this->check(conditionalFormula.getConditionFormula().asEventuallyFormula().getSubformula()); ExplicitQualitativeCheckResult const& leftResult = leftResultPointer->asExplicitQualitativeCheckResult(); ExplicitQualitativeCheckResult const& rightResult = rightResultPointer->asExplicitQualitativeCheckResult(); diff --git a/src/modelchecker/prctl/SparseMdpPrctlModelChecker.h b/src/modelchecker/prctl/SparseMdpPrctlModelChecker.h index 37cd6ef5b..b08c9abc5 100644 --- a/src/modelchecker/prctl/SparseMdpPrctlModelChecker.h +++ b/src/modelchecker/prctl/SparseMdpPrctlModelChecker.h @@ -22,7 +22,7 @@ namespace storm { virtual std::unique_ptr<CheckResult> computeNextProbabilities(CheckTask<storm::logic::NextFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeUntilProbabilities(CheckTask<storm::logic::UntilFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeGloballyProbabilities(CheckTask<storm::logic::GloballyFormula> const& checkTask) override; - virtual std::unique_ptr<CheckResult> computeConditionalProbabilities(CheckTask<storm::logic::ConditionalPathFormula> const& checkTask) override; + virtual std::unique_ptr<CheckResult> computeConditionalProbabilities(CheckTask<storm::logic::ConditionalFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeCumulativeRewards(CheckTask<storm::logic::CumulativeRewardFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(CheckTask<storm::logic::InstantaneousRewardFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) override; diff --git a/src/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.cpp b/src/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.cpp index 2394a3176..311ef7590 100644 --- a/src/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.cpp +++ b/src/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.cpp @@ -10,6 +10,9 @@ #include "src/modelchecker/results/SymbolicQualitativeCheckResult.h" #include "src/modelchecker/results/SymbolicQuantitativeCheckResult.h" + +#include "src/logic/FragmentSpecification.h" + #include "src/solver/SymbolicLinearEquationSolver.h" #include "src/settings/modules/GeneralSettings.h" @@ -32,16 +35,7 @@ namespace storm { template<storm::dd::DdType DdType, typename ValueType> bool SymbolicDtmcPrctlModelChecker<DdType, ValueType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const { storm::logic::Formula const& formula = checkTask.getFormula(); - if (formula.isPctlStateFormula() || formula.isPctlPathFormula()) { - return true; - } - if (formula.isProbabilityOperatorFormula()) { - return this->canHandle(checkTask.substituteFormula(formula.asProbabilityOperatorFormula().getSubformula())); - } - if (formula.isGloballyFormula()) { - return true; - } - return false; + return formula.isInFragment(storm::logic::prctl().setLongRunAverageRewardFormulasAllowed(false)); } template<storm::dd::DdType DdType, typename ValueType> diff --git a/src/modelchecker/prctl/SymbolicMdpPrctlModelChecker.cpp b/src/modelchecker/prctl/SymbolicMdpPrctlModelChecker.cpp index 9b74594dc..d6a3554e3 100644 --- a/src/modelchecker/prctl/SymbolicMdpPrctlModelChecker.cpp +++ b/src/modelchecker/prctl/SymbolicMdpPrctlModelChecker.cpp @@ -5,6 +5,8 @@ #include "src/modelchecker/results/SymbolicQualitativeCheckResult.h" #include "src/modelchecker/results/SymbolicQuantitativeCheckResult.h" +#include "src/logic/FragmentSpecification.h" + #include "src/models/symbolic/StandardRewardModel.h" #include "src/utility/macros.h" @@ -32,16 +34,7 @@ namespace storm { template<storm::dd::DdType DdType, typename ValueType> bool SymbolicMdpPrctlModelChecker<DdType, ValueType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const { storm::logic::Formula const& formula = checkTask.getFormula(); - if (formula.isPctlStateFormula() || formula.isPctlPathFormula()) { - return true; - } - if (formula.isProbabilityOperatorFormula()) { - return this->canHandle(checkTask.substituteFormula(formula.asProbabilityOperatorFormula().getSubformula())); - } - if (formula.isGloballyFormula()) { - return true; - } - return false; + return formula.isInFragment(storm::logic::prctl().setLongRunAverageRewardFormulasAllowed(false)); } template<storm::dd::DdType DdType, typename ValueType> diff --git a/src/modelchecker/propositional/SparsePropositionalModelChecker.cpp b/src/modelchecker/propositional/SparsePropositionalModelChecker.cpp index f56843aef..aa947c8cb 100644 --- a/src/modelchecker/propositional/SparsePropositionalModelChecker.cpp +++ b/src/modelchecker/propositional/SparsePropositionalModelChecker.cpp @@ -10,6 +10,8 @@ #include "src/modelchecker/results/ExplicitQualitativeCheckResult.h" +#include "src/logic/FragmentSpecification.h" + #include "src/utility/macros.h" #include "src/exceptions/InvalidPropertyException.h" @@ -23,7 +25,7 @@ namespace storm { template<typename SparseModelType> bool SparsePropositionalModelChecker<SparseModelType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const { storm::logic::Formula const& formula = checkTask.getFormula(); - return formula.isPropositionalFormula(); + return formula.isInFragment(storm::logic::propositional()); } template<typename SparseModelType> diff --git a/src/modelchecker/propositional/SymbolicPropositionalModelChecker.cpp b/src/modelchecker/propositional/SymbolicPropositionalModelChecker.cpp index 943ecf7db..eee71e3c8 100644 --- a/src/modelchecker/propositional/SymbolicPropositionalModelChecker.cpp +++ b/src/modelchecker/propositional/SymbolicPropositionalModelChecker.cpp @@ -10,6 +10,8 @@ #include "src/modelchecker/results/SymbolicQualitativeCheckResult.h" +#include "src/logic/FragmentSpecification.h" + #include "src/utility/macros.h" #include "src/exceptions/InvalidPropertyException.h" @@ -23,7 +25,7 @@ namespace storm { template<storm::dd::DdType Type, typename ValueType> bool SymbolicPropositionalModelChecker<Type, ValueType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const { storm::logic::Formula const& formula = checkTask.getFormula(); - return formula.isPropositionalFormula(); + return formula.isInFragment(storm::logic::propositional()); } template<storm::dd::DdType Type, typename ValueType> diff --git a/src/modelchecker/reachability/SparseDtmcEliminationModelChecker.cpp b/src/modelchecker/reachability/SparseDtmcEliminationModelChecker.cpp index 98afe49a1..7022b92c8 100644 --- a/src/modelchecker/reachability/SparseDtmcEliminationModelChecker.cpp +++ b/src/modelchecker/reachability/SparseDtmcEliminationModelChecker.cpp @@ -16,6 +16,8 @@ #include "src/modelchecker/results/ExplicitQualitativeCheckResult.h" #include "src/modelchecker/results/ExplicitQuantitativeCheckResult.h" +#include "src/logic/FragmentSpecification.h" + #include "src/utility/graph.h" #include "src/utility/vector.h" #include "src/utility/macros.h" @@ -82,45 +84,9 @@ namespace storm { template<typename SparseDtmcModelType> bool SparseDtmcEliminationModelChecker<SparseDtmcModelType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const { storm::logic::Formula const& formula = checkTask.getFormula(); - if (formula.isProbabilityOperatorFormula()) { - return this->canHandle(checkTask.substituteFormula(formula.asProbabilityOperatorFormula().getSubformula())); - } else if (formula.isRewardOperatorFormula()) { - return this->canHandle(checkTask.substituteFormula(formula.asRewardOperatorFormula().getSubformula())); - } else if (formula.isUntilFormula() || formula.isEventuallyFormula()) { - if (formula.isUntilFormula()) { - storm::logic::UntilFormula const& untilFormula = formula.asUntilFormula(); - if (untilFormula.getLeftSubformula().isPropositionalFormula() && untilFormula.getRightSubformula().isPropositionalFormula()) { - return true; - } - } else if (formula.isEventuallyFormula()) { - storm::logic::EventuallyFormula const& eventuallyFormula = formula.asEventuallyFormula(); - if (eventuallyFormula.getSubformula().isPropositionalFormula()) { - return true; - } - } - } else if (formula.isBoundedUntilFormula()) { - storm::logic::BoundedUntilFormula const& boundedUntilFormula = formula.asBoundedUntilFormula(); - if (boundedUntilFormula.getLeftSubformula().isPropositionalFormula() && boundedUntilFormula.getRightSubformula().isPropositionalFormula()) { - return true; - } - } else if (formula.isConditionalPathFormula()) { - storm::logic::ConditionalPathFormula const& conditionalPathFormula = formula.asConditionalPathFormula(); - if (conditionalPathFormula.getLeftSubformula().isEventuallyFormula() && conditionalPathFormula.getRightSubformula().isEventuallyFormula()) { - return this->canHandle(conditionalPathFormula.getLeftSubformula()) && this->canHandle(conditionalPathFormula.getRightSubformula()); - } - } else if (formula.isLongRunAverageOperatorFormula()) { - storm::logic::LongRunAverageOperatorFormula const& longRunAverageOperatorFormula = formula.asLongRunAverageOperatorFormula(); - if (longRunAverageOperatorFormula.getSubformula().isPropositionalFormula()) { - return true; - } - } else if (formula.isLongRunAverageRewardFormula()) { - return true; - } - - else if (formula.isPropositionalFormula()) { - return true; - } - return false; + storm::logic::FragmentSpecification fragment = storm::logic::prctl().setCumulativeRewardFormulasAllowed(false).setInstantaneousFormulasAllowed(false); + fragment.setNestedOperatorsAllowed(false).setLongRunAverageProbabilitiesAllowed(true).setConditionalProbabilityFormulasAllowed(true).setOnlyEventuallyFormuluasInConditionalFormulasAllowed(true); + return formula.isInFragment(fragment); } template<typename SparseDtmcModelType> @@ -646,15 +612,15 @@ namespace storm { } template<typename SparseDtmcModelType> - std::unique_ptr<CheckResult> SparseDtmcEliminationModelChecker<SparseDtmcModelType>::computeConditionalProbabilities(CheckTask<storm::logic::ConditionalPathFormula> const& checkTask) { - storm::logic::ConditionalPathFormula const& pathFormula = checkTask.getFormula(); + std::unique_ptr<CheckResult> SparseDtmcEliminationModelChecker<SparseDtmcModelType>::computeConditionalProbabilities(CheckTask<storm::logic::ConditionalFormula> const& checkTask) { + storm::logic::ConditionalFormula const& conditionalFormula = checkTask.getFormula(); // Retrieve the appropriate bitvectors by model checking the subformulas. - STORM_LOG_THROW(pathFormula.getLeftSubformula().isEventuallyFormula(), storm::exceptions::InvalidPropertyException, "Expected 'eventually' formula."); - STORM_LOG_THROW(pathFormula.getRightSubformula().isEventuallyFormula(), storm::exceptions::InvalidPropertyException, "Expected 'eventually' formula."); + STORM_LOG_THROW(conditionalFormula.getSubformula().isEventuallyFormula(), storm::exceptions::InvalidPropertyException, "Expected 'eventually' formula."); + STORM_LOG_THROW(conditionalFormula.getConditionFormula().isEventuallyFormula(), storm::exceptions::InvalidPropertyException, "Expected 'eventually' formula."); - std::unique_ptr<CheckResult> leftResultPointer = this->check(pathFormula.getLeftSubformula().asEventuallyFormula().getSubformula()); - std::unique_ptr<CheckResult> rightResultPointer = this->check(pathFormula.getRightSubformula().asEventuallyFormula().getSubformula()); + std::unique_ptr<CheckResult> leftResultPointer = this->check(conditionalFormula.getSubformula().asEventuallyFormula().getSubformula()); + std::unique_ptr<CheckResult> rightResultPointer = this->check(conditionalFormula.getConditionFormula().asEventuallyFormula().getSubformula()); storm::storage::BitVector phiStates = leftResultPointer->asExplicitQualitativeCheckResult().getTruthValuesVector(); storm::storage::BitVector psiStates = rightResultPointer->asExplicitQualitativeCheckResult().getTruthValuesVector(); storm::storage::BitVector trueStates(this->getModel().getNumberOfStates(), true); @@ -680,7 +646,7 @@ namespace storm { if (this->getModel().getInitialStates().isSubsetOf(statesWithProbability1)) { STORM_LOG_INFO("The condition holds with probability 1, so the regular reachability probability is computed."); std::shared_ptr<storm::logic::BooleanLiteralFormula> trueFormula = std::make_shared<storm::logic::BooleanLiteralFormula>(true); - std::shared_ptr<storm::logic::UntilFormula> untilFormula = std::make_shared<storm::logic::UntilFormula>(trueFormula, pathFormula.getLeftSubformula().asSharedPointer()); + std::shared_ptr<storm::logic::UntilFormula> untilFormula = std::make_shared<storm::logic::UntilFormula>(trueFormula, conditionalFormula.getSubformula().asSharedPointer()); return this->computeUntilProbabilities(*untilFormula); } diff --git a/src/modelchecker/reachability/SparseDtmcEliminationModelChecker.h b/src/modelchecker/reachability/SparseDtmcEliminationModelChecker.h index af5b464be..8b86e1dd9 100644 --- a/src/modelchecker/reachability/SparseDtmcEliminationModelChecker.h +++ b/src/modelchecker/reachability/SparseDtmcEliminationModelChecker.h @@ -28,7 +28,7 @@ namespace storm { virtual std::unique_ptr<CheckResult> computeUntilProbabilities(CheckTask<storm::logic::UntilFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeLongRunAverageRewards(CheckTask<storm::logic::LongRunAverageRewardFormula> const& checkTask) override; - virtual std::unique_ptr<CheckResult> computeConditionalProbabilities(CheckTask<storm::logic::ConditionalPathFormula> const& checkTask) override; + virtual std::unique_ptr<CheckResult> computeConditionalProbabilities(CheckTask<storm::logic::ConditionalFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeLongRunAverageProbabilities(CheckTask<storm::logic::StateFormula> const& checkTask) override; private: diff --git a/src/parser/FormulaParser.cpp b/src/parser/FormulaParser.cpp index 1298b3fa2..983f64cae 100644 --- a/src/parser/FormulaParser.cpp +++ b/src/parser/FormulaParser.cpp @@ -120,8 +120,8 @@ namespace storm { qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> expressionFormula; qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), qi::locals<bool>, Skipper> booleanLiteralFormula; - qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(bool), Skipper> conditionalFormula; - qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(bool), Skipper> eventuallyFormula; + qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(storm::logic::ConditionalFormula::Context), Skipper> conditionalFormula; + qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(storm::logic::EventuallyFormula::Context), Skipper> eventuallyFormula; qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> nextFormula; qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> globallyFormula; qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> untilFormula; @@ -142,11 +142,11 @@ namespace storm { std::shared_ptr<storm::logic::Formula> createAtomicExpressionFormula(storm::expressions::Expression const& expression) const; std::shared_ptr<storm::logic::Formula> createBooleanLiteralFormula(bool literal) const; std::shared_ptr<storm::logic::Formula> createAtomicLabelFormula(std::string const& label) const; - std::shared_ptr<storm::logic::Formula> createEventuallyFormula(boost::optional<boost::variant<std::pair<double, double>, uint_fast64_t>> const& timeBound, bool reward, std::shared_ptr<storm::logic::Formula> const& subformula) const; + std::shared_ptr<storm::logic::Formula> createEventuallyFormula(boost::optional<boost::variant<std::pair<double, double>, uint_fast64_t>> const& timeBound, storm::logic::EventuallyFormula::Context context, std::shared_ptr<storm::logic::Formula> const& subformula) const; std::shared_ptr<storm::logic::Formula> createGloballyFormula(std::shared_ptr<storm::logic::Formula> const& subformula) const; std::shared_ptr<storm::logic::Formula> createNextFormula(std::shared_ptr<storm::logic::Formula> const& subformula) const; std::shared_ptr<storm::logic::Formula> createUntilFormula(std::shared_ptr<storm::logic::Formula> const& leftSubformula, boost::optional<boost::variant<std::pair<double, double>, uint_fast64_t>> const& timeBound, std::shared_ptr<storm::logic::Formula> const& rightSubformula); - std::shared_ptr<storm::logic::Formula> createConditionalFormula(std::shared_ptr<storm::logic::Formula> const& leftSubformula, std::shared_ptr<storm::logic::Formula> const& rightSubformula, bool reward) const; + std::shared_ptr<storm::logic::Formula> createConditionalFormula(std::shared_ptr<storm::logic::Formula> const& leftSubformula, std::shared_ptr<storm::logic::Formula> const& rightSubformula, storm::logic::ConditionalFormula::Context context) const; std::pair<boost::optional<storm::OptimizationDirection>, boost::optional<storm::logic::Bound<double>>> createOperatorInformation(boost::optional<storm::OptimizationDirection> const& optimizationDirection, boost::optional<storm::logic::ComparisonType> const& comparisonType, boost::optional<double> const& threshold) const; std::shared_ptr<storm::logic::Formula> createLongRunAverageOperatorFormula(std::pair<boost::optional<storm::OptimizationDirection>, boost::optional<storm::logic::Bound<double>>> const& operatorInformation, std::shared_ptr<storm::logic::Formula> const& subformula) const; std::shared_ptr<storm::logic::Formula> createRewardOperatorFormula(boost::optional<std::string> const& rewardModelName, std::pair<boost::optional<storm::OptimizationDirection>, boost::optional<storm::logic::Bound<double>>> const& operatorInformation, std::shared_ptr<storm::logic::Formula> const& subformula) const; @@ -253,7 +253,7 @@ namespace storm { cumulativeRewardFormula = (qi::lit("C<=") >> strict_double)[qi::_val = phoenix::bind(&FormulaParserGrammar::createCumulativeRewardFormula, phoenix::ref(*this), qi::_1)] | (qi::lit("C<=") > qi::uint_)[qi::_val = phoenix::bind(&FormulaParserGrammar::createCumulativeRewardFormula, phoenix::ref(*this), qi::_1)]; cumulativeRewardFormula.name("cumulative reward formula"); - rewardPathFormula = eventuallyFormula(true) | cumulativeRewardFormula | instantaneousRewardFormula | longRunAverageRewardFormula | conditionalFormula(true); + rewardPathFormula = eventuallyFormula(storm::logic::EventuallyFormula::Context::Reward) | cumulativeRewardFormula | instantaneousRewardFormula | longRunAverageRewardFormula | conditionalFormula(storm::logic::ConditionalFormula::Context::Reward); rewardPathFormula.name("reward path formula"); expressionFormula = expressionParser[qi::_val = phoenix::bind(&FormulaParserGrammar::createAtomicExpressionFormula, phoenix::ref(*this), qi::_1)]; @@ -286,7 +286,7 @@ namespace storm { nextFormula = (qi::lit("X") >> pathFormulaWithoutUntil)[qi::_val = phoenix::bind(&FormulaParserGrammar::createNextFormula, phoenix::ref(*this), qi::_1)]; nextFormula.name("next formula"); - pathFormulaWithoutUntil = eventuallyFormula(false) | globallyFormula | nextFormula | stateFormula; + pathFormulaWithoutUntil = eventuallyFormula(storm::logic::EventuallyFormula::Context::Probability) | globallyFormula | nextFormula | stateFormula; pathFormulaWithoutUntil.name("path formula"); untilFormula = pathFormulaWithoutUntil[qi::_val = qi::_1] >> *(qi::lit("U") >> -timeBound >> pathFormulaWithoutUntil)[qi::_val = phoenix::bind(&FormulaParserGrammar::createUntilFormula, phoenix::ref(*this), qi::_val, qi::_1, qi::_2)]; @@ -298,7 +298,7 @@ namespace storm { timeBound = (qi::lit("[") > qi::double_ > qi::lit(",") > qi::double_ > qi::lit("]"))[qi::_val = phoenix::construct<std::pair<double, double>>(qi::_1, qi::_2)] | (qi::lit("<=") >> strict_double)[qi::_val = phoenix::construct<std::pair<double, double>>(0, qi::_1)] | (qi::lit("<=") > qi::uint_)[qi::_val = qi::_1]; timeBound.name("time bound"); - pathFormula = conditionalFormula(false); + pathFormula = conditionalFormula(storm::logic::ConditionalFormula::Context::Probability); pathFormula.name("path formula"); operatorInformation = (-optimalityOperator_[qi::_a = qi::_1] >> ((relationalOperator_[qi::_b = qi::_1] > qi::double_[qi::_c = qi::_1]) | (qi::lit("=") > qi::lit("?"))))[qi::_val = phoenix::bind(&FormulaParserGrammar::createOperatorInformation, phoenix::ref(*this), qi::_a, qi::_b, qi::_c)]; @@ -313,7 +313,7 @@ namespace storm { rewardOperator = (qi::lit("R") > -rewardModelName > operatorInformation > qi::lit("[") > rewardPathFormula > qi::lit("]"))[qi::_val = phoenix::bind(&FormulaParserGrammar::createRewardOperatorFormula, phoenix::ref(*this), qi::_1, qi::_2, qi::_3)]; rewardOperator.name("reward operator"); - expectedTimeOperator = (qi::lit("ET") > operatorInformation > qi::lit("[") > eventuallyFormula(true) > qi::lit("]"))[qi::_val = phoenix::bind(&FormulaParserGrammar::createExpectedTimeOperatorFormula, phoenix::ref(*this), qi::_1, qi::_2)]; + expectedTimeOperator = (qi::lit("ET") > operatorInformation > qi::lit("[") > eventuallyFormula(storm::logic::EventuallyFormula::Context::ExpectedTime) > qi::lit("]"))[qi::_val = phoenix::bind(&FormulaParserGrammar::createExpectedTimeOperatorFormula, phoenix::ref(*this), qi::_1, qi::_2)]; expectedTimeOperator.name("expected time operator"); probabilityOperator = (qi::lit("P") > operatorInformation > qi::lit("[") > pathFormula > qi::lit("]"))[qi::_val = phoenix::bind(&FormulaParserGrammar::createProbabilityOperatorFormula, phoenix::ref(*this), qi::_1, qi::_2)]; @@ -422,7 +422,7 @@ namespace storm { return std::shared_ptr<storm::logic::Formula>(new storm::logic::AtomicLabelFormula(label)); } - std::shared_ptr<storm::logic::Formula> FormulaParserGrammar::createEventuallyFormula(boost::optional<boost::variant<std::pair<double, double>, uint_fast64_t>> const& timeBound, bool reward, std::shared_ptr<storm::logic::Formula> const& subformula) const { + std::shared_ptr<storm::logic::Formula> FormulaParserGrammar::createEventuallyFormula(boost::optional<boost::variant<std::pair<double, double>, uint_fast64_t>> const& timeBound, storm::logic::EventuallyFormula::Context context, std::shared_ptr<storm::logic::Formula> const& subformula) const { if (timeBound) { if (timeBound.get().which() == 0) { std::pair<double, double> const& bounds = boost::get<std::pair<double, double>>(timeBound.get()); @@ -431,7 +431,7 @@ namespace storm { return std::shared_ptr<storm::logic::Formula>(new storm::logic::BoundedUntilFormula(createBooleanLiteralFormula(true), subformula, static_cast<uint_fast64_t>(boost::get<uint_fast64_t>(timeBound.get())))); } } else { - return std::shared_ptr<storm::logic::Formula>(new storm::logic::EventuallyFormula(subformula, reward)); + return std::shared_ptr<storm::logic::Formula>(new storm::logic::EventuallyFormula(subformula, context)); } } @@ -456,8 +456,8 @@ namespace storm { } } - std::shared_ptr<storm::logic::Formula> FormulaParserGrammar::createConditionalFormula(std::shared_ptr<storm::logic::Formula> const& leftSubformula, std::shared_ptr<storm::logic::Formula> const& rightSubformula, bool reward) const { - return std::shared_ptr<storm::logic::Formula>(new storm::logic::ConditionalPathFormula(leftSubformula, rightSubformula, reward)); + std::shared_ptr<storm::logic::Formula> FormulaParserGrammar::createConditionalFormula(std::shared_ptr<storm::logic::Formula> const& leftSubformula, std::shared_ptr<storm::logic::Formula> const& rightSubformula, storm::logic::ConditionalFormula::Context context) const { + return std::shared_ptr<storm::logic::Formula>(new storm::logic::ConditionalFormula(leftSubformula, rightSubformula, context)); } std::pair<boost::optional<storm::OptimizationDirection>, boost::optional<storm::logic::Bound<double>>> FormulaParserGrammar::createOperatorInformation(boost::optional<storm::OptimizationDirection> const& optimizationDirection, boost::optional<storm::logic::ComparisonType> const& comparisonType, boost::optional<double> const& threshold) const { diff --git a/src/storage/bisimulation/BisimulationDecomposition.cpp b/src/storage/bisimulation/BisimulationDecomposition.cpp index 902a69288..aedd4a998 100644 --- a/src/storage/bisimulation/BisimulationDecomposition.cpp +++ b/src/storage/bisimulation/BisimulationDecomposition.cpp @@ -15,6 +15,9 @@ #include "src/settings/SettingsManager.h" #include "src/settings/modules/GeneralSettings.h" +#include "src/logic/FormulaInformation.h" +#include "src/logic/FragmentSpecification.h" + #include "src/utility/macros.h" #include "src/exceptions/IllegalFunctionCallException.h" #include "src/exceptions/InvalidOptionException.h" @@ -55,11 +58,14 @@ namespace storm { phiStates = boost::none; psiStates = boost::none; + // Retrieve information about formula. + storm::logic::FormulaInformation info = formula.info(); + // Preserve rewards if necessary. - keepRewards = keepRewards || formula.containsRewardOperator(); + keepRewards = keepRewards || info.containsRewardOperator(); // Preserve bounded properties if necessary. - bounded = bounded || (formula.containsBoundedUntilFormula() || formula.containsNextFormula()); + bounded = bounded || (info.containsBoundedUntilFormula() || info.containsNextFormula()); // Compute the relevant labels and expressions. this->addToRespectedAtomicPropositions(formula.getAtomicExpressionFormulas(), formula.getAtomicLabelFormulas()); @@ -67,10 +73,13 @@ namespace storm { template<typename ModelType, typename BlockDataType> void BisimulationDecomposition<ModelType, BlockDataType>::Options::preserveSingleFormula(ModelType const& model, storm::logic::Formula const& formula) { - keepRewards = formula.containsRewardOperator(); + // Retrieve information about formula. + storm::logic::FormulaInformation info = formula.info(); + + keepRewards = info.containsRewardOperator(); // We need to preserve bounded properties iff the formula contains a bounded until or a next subformula. - bounded = formula.containsBoundedUntilFormula() || formula.containsNextFormula(); + bounded = info.containsBoundedUntilFormula() || info.containsNextFormula(); // Compute the relevant labels and expressions. this->addToRespectedAtomicPropositions(formula.getAtomicExpressionFormulas(), formula.getAtomicLabelFormulas()); @@ -114,12 +123,12 @@ namespace storm { if (newFormula->isUntilFormula()) { leftSubformula = newFormula->asUntilFormula().getLeftSubformula().asSharedPointer(); rightSubformula = newFormula->asUntilFormula().getRightSubformula().asSharedPointer(); - if (leftSubformula->isPropositionalFormula() && rightSubformula->isPropositionalFormula()) { + if (leftSubformula->isInFragment(storm::logic::propositional()) && rightSubformula->isInFragment(storm::logic::propositional())) { measureDrivenInitialPartition = true; } } else if (newFormula->isEventuallyFormula()) { rightSubformula = newFormula->asEventuallyFormula().getSubformula().asSharedPointer(); - if (rightSubformula->isPropositionalFormula()) { + if (rightSubformula->isInFragment(storm::logic::propositional())) { measureDrivenInitialPartition = true; } } diff --git a/test/functional/logic/FragmentCheckerTest.cpp b/test/functional/logic/FragmentCheckerTest.cpp new file mode 100644 index 000000000..6f21467af --- /dev/null +++ b/test/functional/logic/FragmentCheckerTest.cpp @@ -0,0 +1,14 @@ +#include "gtest/gtest.h" +#include "storm-config.h" +#include "src/parser/FormulaParser.h" +#include "src/logic/FragmentSpecification.h" +#include "src/exceptions/WrongFormatException.h" + +TEST(FragmentCheckerTest, PctlTest) { + storm::parser::FormulaParser formulaParser; + + std::string input = "\"label\""; + std::shared_ptr<const storm::logic::Formula> formula(nullptr); + ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString(input)); + +} diff --git a/test/functional/parser/FormulaParserTest.cpp b/test/functional/parser/FormulaParserTest.cpp index 15f116125..a3d78632b 100644 --- a/test/functional/parser/FormulaParserTest.cpp +++ b/test/functional/parser/FormulaParserTest.cpp @@ -1,6 +1,7 @@ #include "gtest/gtest.h" #include "storm-config.h" #include "src/parser/FormulaParser.h" +#include "src/logic/FragmentSpecification.h" #include "src/exceptions/WrongFormatException.h" TEST(FormulaParserTest, LabelTest) { @@ -20,7 +21,7 @@ TEST(FormulaParserTest, ComplexLabelTest) { std::shared_ptr<const storm::logic::Formula> formula(nullptr); ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString(input)); - EXPECT_TRUE(formula->isPropositionalFormula()); + EXPECT_TRUE(formula->isInFragment(storm::logic::propositional())); EXPECT_TRUE(formula->isBinaryBooleanStateFormula()); } @@ -35,7 +36,7 @@ TEST(FormulaParserTest, ExpressionTest) { std::shared_ptr<const storm::logic::Formula> formula(nullptr); ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString(input)); - EXPECT_TRUE(formula->isPropositionalFormula()); + EXPECT_TRUE(formula->isInFragment(storm::logic::propositional())); EXPECT_TRUE(formula->isUnaryBooleanStateFormula()); } @@ -50,11 +51,11 @@ TEST(FormulaParserTest, LabelAndExpressionTest) { std::shared_ptr<const storm::logic::Formula> formula(nullptr); ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString(input)); - EXPECT_TRUE(formula->isPropositionalFormula()); + EXPECT_TRUE(formula->isInFragment(storm::logic::propositional())); input = "x | y > 3 | !\"a\""; ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString(input)); - EXPECT_TRUE(formula->isPropositionalFormula()); + EXPECT_TRUE(formula->isInFragment(storm::logic::propositional())); } TEST(FormulaParserTest, ProbabilityOperatorTest) { @@ -98,7 +99,7 @@ TEST(FormulaParserTest, ConditionalProbabilityTest) { EXPECT_TRUE(formula->isProbabilityOperatorFormula()); storm::logic::ProbabilityOperatorFormula const& probFormula = formula->asProbabilityOperatorFormula(); - EXPECT_TRUE(probFormula.getSubformula().isConditionalPathFormula()); + EXPECT_TRUE(probFormula.getSubformula().isConditionalProbabilityFormula()); } TEST(FormulaParserTest, NestedPathFormulaTest) { From 7b643fe16675791ac9dade7f1f8f6f4de8678cc9 Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Thu, 18 Feb 2016 23:15:35 +0100 Subject: [PATCH 05/23] tests working again Former-commit-id: 58e97ea35b1062d75258347875558a44574ac829 --- src/logic/FormulaInformation.cpp | 2 +- src/logic/FormulaInformation.h | 5 +++ src/logic/FragmentChecker.cpp | 12 +++---- src/logic/FragmentSpecification.cpp | 4 ++- src/modelchecker/AbstractModelChecker.cpp | 34 ++++++++++--------- src/modelchecker/AbstractModelChecker.h | 2 +- .../bisimulation/BisimulationDecomposition.h | 8 +---- 7 files changed, 35 insertions(+), 32 deletions(-) diff --git a/src/logic/FormulaInformation.cpp b/src/logic/FormulaInformation.cpp index b49f4a23b..3cbca1323 100644 --- a/src/logic/FormulaInformation.cpp +++ b/src/logic/FormulaInformation.cpp @@ -17,7 +17,7 @@ namespace storm { } bool FormulaInformation::containsBoundedUntilFormula() const { - return this-mContainsBoundedUntilFormula; + return this->mContainsBoundedUntilFormula; } FormulaInformation FormulaInformation::join(FormulaInformation const& other) { diff --git a/src/logic/FormulaInformation.h b/src/logic/FormulaInformation.h index 53269696c..6dfc90b8e 100644 --- a/src/logic/FormulaInformation.h +++ b/src/logic/FormulaInformation.h @@ -7,6 +7,11 @@ namespace storm { class FormulaInformation { public: FormulaInformation(); + FormulaInformation(FormulaInformation const& other) = default; + FormulaInformation(FormulaInformation&& other) = default; + FormulaInformation& operator=(FormulaInformation const& other) = default; + FormulaInformation& operator=(FormulaInformation&& other) = default; + bool containsRewardOperator() const; bool containsNextFormula() const; bool containsBoundedUntilFormula() const; diff --git a/src/logic/FragmentChecker.cpp b/src/logic/FragmentChecker.cpp index 405b75a27..8e701cedd 100644 --- a/src/logic/FragmentChecker.cpp +++ b/src/logic/FragmentChecker.cpp @@ -99,7 +99,7 @@ namespace storm { result = result && inherited.getSpecification().areReachbilityExpectedTimeFormulasAllowed(); result = result && f.getSubformula().isStateFormula(); } - result && boost::any_cast<bool>(f.getSubformula().accept(*this, data)); + result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, data)); return result; } @@ -108,7 +108,7 @@ namespace storm { bool result = inherited.getSpecification().areExpectedTimeOperatorsAllowed(); result = result && f.getSubformula().isExpectedTimePathFormula(); if (!inherited.getSpecification().areNestedOperatorsAllowed()) { - result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, inherited.getSpecification().copy().setOperatorsAllowed(false))); + result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, InheritedInformation(inherited.getSpecification().copy().setOperatorsAllowed(false)))); } else { result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, data)); } @@ -135,7 +135,7 @@ namespace storm { bool result = inherited.getSpecification().areLongRunAverageOperatorsAllowed(); result = result && f.getSubformula().isStateFormula(); if (!inherited.getSpecification().areNestedOperatorsAllowed()) { - result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, inherited.getSpecification().copy().setOperatorsAllowed(false))); + result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, InheritedInformation(inherited.getSpecification().copy().setOperatorsAllowed(false)))); } else { result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, data)); } @@ -160,9 +160,9 @@ namespace storm { boost::any FragmentChecker::visit(ProbabilityOperatorFormula const& f, boost::any const& data) const { InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data); bool result = inherited.getSpecification().areProbabilityOperatorsAllowed(); - result = result && f.getSubformula().isProbabilityPathFormula(); + result = result && (f.getSubformula().isProbabilityPathFormula() || f.getSubformula().isConditionalProbabilityFormula()); if (!inherited.getSpecification().areNestedOperatorsAllowed()) { - result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, inherited.getSpecification().copy().setOperatorsAllowed(false))); + result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, InheritedInformation(inherited.getSpecification().copy().setOperatorsAllowed(false)))); } else { result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, data)); } @@ -174,7 +174,7 @@ namespace storm { bool result = inherited.getSpecification().areRewardOperatorsAllowed(); result = result && f.getSubformula().isRewardPathFormula(); if (!inherited.getSpecification().areNestedOperatorsAllowed()) { - result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, inherited.getSpecification().copy().setOperatorsAllowed(false))); + result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, InheritedInformation(inherited.getSpecification().copy().setOperatorsAllowed(false)))); } else { result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, data)); } diff --git a/src/logic/FragmentSpecification.cpp b/src/logic/FragmentSpecification.cpp index d8c02a18e..378fe3a88 100644 --- a/src/logic/FragmentSpecification.cpp +++ b/src/logic/FragmentSpecification.cpp @@ -1,5 +1,7 @@ #include "src/logic/FragmentSpecification.h" +#include <iostream> + namespace storm { namespace logic { @@ -50,7 +52,7 @@ namespace storm { } FragmentSpecification csrl() { - FragmentSpecification csrl; + FragmentSpecification csrl = csl(); csrl.setRewardOperatorsAllowed(true); csrl.setCumulativeRewardFormulasAllowed(true); diff --git a/src/modelchecker/AbstractModelChecker.cpp b/src/modelchecker/AbstractModelChecker.cpp index e7fabdec1..8f7a7b2f5 100644 --- a/src/modelchecker/AbstractModelChecker.cpp +++ b/src/modelchecker/AbstractModelChecker.cpp @@ -18,7 +18,7 @@ namespace storm { return this->checkStateFormula(checkTask.substituteFormula(formula.asStateFormula())); } else if (formula.isPathFormula()) { if (formula.isProbabilityPathFormula()) { - return this->computeProbabilities(checkTask.substituteFormula(formula.asPathFormula())); + return this->computeProbabilities(checkTask); } else if (formula.isRewardPathFormula()) { return this->computeRewards(checkTask.substituteFormula(formula.asPathFormula())); } @@ -30,20 +30,22 @@ namespace storm { STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "The given formula '" << formula << "' is invalid."); } - std::unique_ptr<CheckResult> AbstractModelChecker::computeProbabilities(CheckTask<storm::logic::PathFormula> const& checkTask) { - storm::logic::PathFormula const& pathFormula = checkTask.getFormula(); - if (pathFormula.isBoundedUntilFormula()) { - return this->computeBoundedUntilProbabilities(checkTask.substituteFormula(pathFormula.asBoundedUntilFormula())); - } else if (pathFormula.isEventuallyFormula()) { - return this->computeEventuallyProbabilities(checkTask.substituteFormula(pathFormula.asEventuallyFormula())); - } else if (pathFormula.isGloballyFormula()) { - return this->computeGloballyProbabilities(checkTask.substituteFormula(pathFormula.asGloballyFormula())); - } else if (pathFormula.isUntilFormula()) { - return this->computeUntilProbabilities(checkTask.substituteFormula(pathFormula.asUntilFormula())); - } else if (pathFormula.isNextFormula()) { - return this->computeNextProbabilities(checkTask.substituteFormula(pathFormula.asNextFormula())); + std::unique_ptr<CheckResult> AbstractModelChecker::computeProbabilities(CheckTask<storm::logic::Formula> const& checkTask) { + storm::logic::Formula const& formula = checkTask.getFormula(); + if (formula.isBoundedUntilFormula()) { + return this->computeBoundedUntilProbabilities(checkTask.substituteFormula(formula.asBoundedUntilFormula())); + } else if (formula.isEventuallyFormula()) { + return this->computeEventuallyProbabilities(checkTask.substituteFormula(formula.asEventuallyFormula())); + } else if (formula.isGloballyFormula()) { + return this->computeGloballyProbabilities(checkTask.substituteFormula(formula.asGloballyFormula())); + } else if (formula.isUntilFormula()) { + return this->computeUntilProbabilities(checkTask.substituteFormula(formula.asUntilFormula())); + } else if (formula.isNextFormula()) { + return this->computeNextProbabilities(checkTask.substituteFormula(formula.asNextFormula())); + } else if (formula.isConditionalProbabilityFormula()) { + return this->computeConditionalProbabilities(checkTask.substituteFormula(formula.asConditionalFormula())); } - STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "The given formula '" << pathFormula << "' is invalid."); + STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "The given formula '" << formula << "' is invalid."); } std::unique_ptr<CheckResult> AbstractModelChecker::computeBoundedUntilProbabilities(CheckTask<storm::logic::BoundedUntilFormula> const& checkTask) { @@ -78,7 +80,7 @@ namespace storm { return this->computeCumulativeRewards(checkTask.substituteFormula(rewardPathFormula.asCumulativeRewardFormula())); } else if (rewardPathFormula.isInstantaneousRewardFormula()) { return this->computeInstantaneousRewards(checkTask.substituteFormula(rewardPathFormula.asInstantaneousRewardFormula())); - } else if (rewardPathFormula.isEventuallyFormula()) { + } else if (rewardPathFormula.isReachabilityRewardFormula()) { return this->computeReachabilityRewards(checkTask.substituteFormula(rewardPathFormula.asEventuallyFormula())); } else if (rewardPathFormula.isLongRunAverageRewardFormula()) { return this->computeLongRunAverageRewards(checkTask.substituteFormula(rewardPathFormula.asLongRunAverageRewardFormula())); @@ -177,7 +179,7 @@ namespace storm { std::unique_ptr<CheckResult> AbstractModelChecker::checkProbabilityOperatorFormula(CheckTask<storm::logic::ProbabilityOperatorFormula> const& checkTask) { storm::logic::ProbabilityOperatorFormula const& stateFormula = checkTask.getFormula(); - std::unique_ptr<CheckResult> result = this->computeProbabilities(checkTask.substituteFormula(stateFormula.getSubformula().asPathFormula())); + std::unique_ptr<CheckResult> result = this->computeProbabilities(checkTask.substituteFormula(stateFormula.getSubformula())); if (stateFormula.hasBound()) { STORM_LOG_THROW(result->isQuantitative(), storm::exceptions::InvalidOperationException, "Unable to perform comparison operation on non-quantitative result."); diff --git a/src/modelchecker/AbstractModelChecker.h b/src/modelchecker/AbstractModelChecker.h index c79302808..fc7fe2fdd 100644 --- a/src/modelchecker/AbstractModelChecker.h +++ b/src/modelchecker/AbstractModelChecker.h @@ -35,7 +35,7 @@ namespace storm { virtual std::unique_ptr<CheckResult> check(CheckTask<storm::logic::Formula> const& checkTask); // The methods to compute probabilities for path formulas. - virtual std::unique_ptr<CheckResult> computeProbabilities(CheckTask<storm::logic::PathFormula> const& checkTask); + virtual std::unique_ptr<CheckResult> computeProbabilities(CheckTask<storm::logic::Formula> const& checkTask); virtual std::unique_ptr<CheckResult> computeConditionalProbabilities(CheckTask<storm::logic::ConditionalFormula> const& checkTask); virtual std::unique_ptr<CheckResult> computeBoundedUntilProbabilities(CheckTask<storm::logic::BoundedUntilFormula> const& checkTask); virtual std::unique_ptr<CheckResult> computeEventuallyProbabilities(CheckTask<storm::logic::EventuallyFormula> const& checkTask); diff --git a/src/storage/bisimulation/BisimulationDecomposition.h b/src/storage/bisimulation/BisimulationDecomposition.h index 420d528c9..dc1c73261 100644 --- a/src/storage/bisimulation/BisimulationDecomposition.h +++ b/src/storage/bisimulation/BisimulationDecomposition.h @@ -139,10 +139,7 @@ namespace storm { private: boost::optional<OptimizationDirection> optimalityType; - - - - + /// A flag that indicates whether or not the state-rewards of the model are to be respected (and should /// be kept in the quotient model, if one is built). bool keepRewards; @@ -154,9 +151,6 @@ namespace storm { /// when computing strong bisimulation equivalence. bool bounded; - - - /*! * Sets the options under the assumption that the given formula is the only one that is to be checked. * From e40cc6511778cb5478de35bdcc17df6a0149f560 Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Fri, 19 Feb 2016 11:08:41 +0100 Subject: [PATCH 06/23] added tests for fragment checker Former-commit-id: 2de76ee5a5e149f52f0c0956addfb4597abea2e0 --- src/parser/FormulaParser.cpp | 3 +- test/functional/logic/FragmentCheckerTest.cpp | 128 +++++++++++++++++- 2 files changed, 124 insertions(+), 7 deletions(-) diff --git a/src/parser/FormulaParser.cpp b/src/parser/FormulaParser.cpp index 983f64cae..ae7d8e0f7 100644 --- a/src/parser/FormulaParser.cpp +++ b/src/parser/FormulaParser.cpp @@ -351,10 +351,9 @@ namespace storm { debug(labelFormula); debug(expressionFormula); debug(rewardPathFormula); - debug(reachabilityRewardFormula); debug(cumulativeRewardFormula); debug(instantaneousRewardFormula); - */ + */ // Enable error reporting. qi::on_error<qi::fail>(start, handler(qi::_1, qi::_2, qi::_3, qi::_4)); diff --git a/test/functional/logic/FragmentCheckerTest.cpp b/test/functional/logic/FragmentCheckerTest.cpp index 6f21467af..bb5d358c9 100644 --- a/test/functional/logic/FragmentCheckerTest.cpp +++ b/test/functional/logic/FragmentCheckerTest.cpp @@ -1,14 +1,132 @@ #include "gtest/gtest.h" #include "storm-config.h" #include "src/parser/FormulaParser.h" -#include "src/logic/FragmentSpecification.h" +#include "src/logic/FragmentChecker.h" #include "src/exceptions/WrongFormatException.h" -TEST(FragmentCheckerTest, PctlTest) { +TEST(FragmentCheckerTest, Propositional) { + storm::logic::FragmentChecker checker; + storm::logic::FragmentSpecification prop = storm::logic::propositional(); + + storm::parser::FormulaParser formulaParser; + std::shared_ptr<const storm::logic::Formula> formula; + + ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("\"label\"")); + EXPECT_TRUE(checker.conformsToSpecification(*formula, prop)); + + ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("true")); + EXPECT_TRUE(checker.conformsToSpecification(*formula, prop)); + + ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("true | \"label\"")); + EXPECT_TRUE(checker.conformsToSpecification(*formula, prop)); + + ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("!true")); + EXPECT_TRUE(checker.conformsToSpecification(*formula, prop)); + + ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("true")); + EXPECT_TRUE(checker.conformsToSpecification(*formula, prop)); + + ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("P=? [F true]")); + EXPECT_FALSE(checker.conformsToSpecification(*formula, prop)); + + ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("false | P>0.5 [G \"label\"]")); + EXPECT_FALSE(checker.conformsToSpecification(*formula, prop)); + + ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("P=? [F \"label\"]")); + EXPECT_FALSE(checker.conformsToSpecification(*formula, prop)); +} + +TEST(FragmentCheckerTest, Pctl) { + storm::logic::FragmentChecker checker; + storm::logic::FragmentSpecification pctl = storm::logic::pctl(); + + storm::parser::FormulaParser formulaParser; + std::shared_ptr<const storm::logic::Formula> formula; + + ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("\"label\"")); + EXPECT_TRUE(checker.conformsToSpecification(*formula, pctl)); + + ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("P=? [F \"label\"]")); + EXPECT_TRUE(checker.conformsToSpecification(*formula, pctl)); + + ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("P=? [F P=? [F \"label\"]]")); + EXPECT_TRUE(checker.conformsToSpecification(*formula, pctl)); + + ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("R=? [F \"label\"]")); + EXPECT_FALSE(checker.conformsToSpecification(*formula, pctl)); +} + +TEST(FragmentCheckerTest, Prctl) { + storm::logic::FragmentChecker checker; + storm::logic::FragmentSpecification prctl = storm::logic::prctl(); + + storm::parser::FormulaParser formulaParser; + std::shared_ptr<const storm::logic::Formula> formula; + + ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("\"label\"")); + EXPECT_TRUE(checker.conformsToSpecification(*formula, prctl)); + + ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("P=? [F \"label\"]")); + EXPECT_TRUE(checker.conformsToSpecification(*formula, prctl)); + + ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("P=? [F P=? [F \"label\"]]")); + EXPECT_TRUE(checker.conformsToSpecification(*formula, prctl)); + + ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("R=? [F \"label\"]")); + EXPECT_TRUE(checker.conformsToSpecification(*formula, prctl)); + + ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("R=? [C<=3]")); + EXPECT_TRUE(checker.conformsToSpecification(*formula, prctl)); + + ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("P=? [F[0,1] \"label\"]")); + EXPECT_FALSE(checker.conformsToSpecification(*formula, prctl)); +} + +TEST(FragmentCheckerTest, Csl) { + storm::logic::FragmentChecker checker; + storm::logic::FragmentSpecification csl = storm::logic::csl(); + + storm::parser::FormulaParser formulaParser; + std::shared_ptr<const storm::logic::Formula> formula; + + ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("\"label\"")); + EXPECT_TRUE(checker.conformsToSpecification(*formula, csl)); + + ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("P=? [F \"label\"]")); + EXPECT_TRUE(checker.conformsToSpecification(*formula, csl)); + + ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("P=? [F P=? [F \"label\"]]")); + EXPECT_TRUE(checker.conformsToSpecification(*formula, csl)); + + ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("R=? [F \"label\"]")); + EXPECT_FALSE(checker.conformsToSpecification(*formula, csl)); + + ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("P=? [F[0,1] \"label\"]")); + EXPECT_TRUE(checker.conformsToSpecification(*formula, csl)); +} + +TEST(FragmentCheckerTest, Csrl) { + storm::logic::FragmentChecker checker; + storm::logic::FragmentSpecification csrl = storm::logic::csrl(); + storm::parser::FormulaParser formulaParser; + std::shared_ptr<const storm::logic::Formula> formula; + + ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("\"label\"")); + EXPECT_TRUE(checker.conformsToSpecification(*formula, csrl)); + + ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("P=? [F \"label\"]")); + EXPECT_TRUE(checker.conformsToSpecification(*formula, csrl)); + + ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("P=? [F P=? [F \"label\"]]")); + EXPECT_TRUE(checker.conformsToSpecification(*formula, csrl)); + + ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("R=? [F \"label\"]")); + EXPECT_TRUE(checker.conformsToSpecification(*formula, csrl)); - std::string input = "\"label\""; - std::shared_ptr<const storm::logic::Formula> formula(nullptr); - ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString(input)); + ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("R=? [C<=3]")); + EXPECT_TRUE(checker.conformsToSpecification(*formula, csrl)); + ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString("P=? [F[0,1] \"label\"]")); + EXPECT_TRUE(checker.conformsToSpecification(*formula, csrl)); } From b46ee5425eadb46ca170371f4b2042ce7761bf20 Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Fri, 19 Feb 2016 17:00:41 +0100 Subject: [PATCH 07/23] started to implement conditional rewards for dtmcs Former-commit-id: 0400ea21ef9c3f1854895b9602a7a91854276d95 --- src/logic/ConditionalFormula.cpp | 29 ++++- src/logic/ConditionalFormula.h | 9 +- src/logic/EventuallyFormula.cpp | 16 ++- src/logic/EventuallyFormula.h | 9 +- src/logic/Formula.cpp | 10 +- src/logic/Formula.h | 5 +- src/logic/FormulaContext.h | 12 ++ src/logic/FragmentChecker.cpp | 10 +- src/modelchecker/AbstractModelChecker.cpp | 28 ++-- src/modelchecker/AbstractModelChecker.h | 2 +- .../prctl/SparseDtmcPrctlModelChecker.cpp | 17 ++- .../prctl/SparseDtmcPrctlModelChecker.h | 6 +- .../prctl/helper/SparseDtmcPrctlHelper.cpp | 120 ++++++++++++++---- .../prctl/helper/SparseDtmcPrctlHelper.h | 12 ++ src/parser/FormulaParser.cpp | 46 +++---- 15 files changed, 238 insertions(+), 93 deletions(-) create mode 100644 src/logic/FormulaContext.h diff --git a/src/logic/ConditionalFormula.cpp b/src/logic/ConditionalFormula.cpp index 2b63fd941..af3e1d95b 100644 --- a/src/logic/ConditionalFormula.cpp +++ b/src/logic/ConditionalFormula.cpp @@ -1,11 +1,13 @@ #include "src/logic/ConditionalFormula.h" - #include "src/logic/FormulaVisitor.h" +#include "src/utility/macros.h" +#include "src/exceptions/InvalidPropertyException.h" + namespace storm { namespace logic { - ConditionalFormula::ConditionalFormula(std::shared_ptr<Formula const> const& subformula, std::shared_ptr<Formula const> const& conditionFormula, Context context) : subformula(subformula), conditionFormula(conditionFormula), context(context) { - // Intentionally left empty. + ConditionalFormula::ConditionalFormula(std::shared_ptr<Formula const> const& subformula, std::shared_ptr<Formula const> const& conditionFormula, FormulaContext context) : subformula(subformula), conditionFormula(conditionFormula), context(context) { + STORM_LOG_THROW(context == FormulaContext::Probability || context == FormulaContext::Reward, storm::exceptions::InvalidPropertyException, "Invalid context for formula."); } Formula const& ConditionalFormula::getSubformula() const { @@ -17,11 +19,11 @@ namespace storm { } bool ConditionalFormula::isConditionalProbabilityFormula() const { - return context == Context::Probability; + return context == FormulaContext::Probability; } bool ConditionalFormula::isConditionalRewardFormula() const { - return context == Context::Reward; + return context == FormulaContext::Reward; } boost::any ConditionalFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const { @@ -29,7 +31,22 @@ namespace storm { } std::shared_ptr<Formula> ConditionalFormula::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const { - return std::make_shared<ConditionalFormula>(this->getSubformula().substitute(substitution), this->getConditionFormula().substitute(substitution)); + return std::make_shared<ConditionalFormula>(this->getSubformula().substitute(substitution), this->getConditionFormula().substitute(substitution), context); + } + + void ConditionalFormula::gatherAtomicExpressionFormulas(std::vector<std::shared_ptr<AtomicExpressionFormula const>>& atomicExpressionFormulas) const { + this->getSubformula().gatherAtomicExpressionFormulas(atomicExpressionFormulas); + this->getConditionFormula().gatherAtomicExpressionFormulas(atomicExpressionFormulas); + } + + void ConditionalFormula::gatherAtomicLabelFormulas(std::vector<std::shared_ptr<AtomicLabelFormula const>>& atomicLabelFormulas) const { + this->getSubformula().gatherAtomicLabelFormulas(atomicLabelFormulas); + this->getConditionFormula().gatherAtomicLabelFormulas(atomicLabelFormulas); + } + + void ConditionalFormula::gatherReferencedRewardModels(std::set<std::string>& referencedRewardModels) const { + this->getSubformula().gatherReferencedRewardModels(referencedRewardModels); + this->getConditionFormula().gatherReferencedRewardModels(referencedRewardModels); } std::ostream& ConditionalFormula::writeToStream(std::ostream& out) const { diff --git a/src/logic/ConditionalFormula.h b/src/logic/ConditionalFormula.h index d7b4dc7cd..fc6b61655 100644 --- a/src/logic/ConditionalFormula.h +++ b/src/logic/ConditionalFormula.h @@ -2,6 +2,7 @@ #define STORM_LOGIC_CONDITIONALFORMULA_H_ #include "src/logic/BinaryPathFormula.h" +#include "src/logic/FormulaContext.h" namespace storm { namespace logic { @@ -9,7 +10,7 @@ namespace storm { public: enum class Context { Probability, Reward }; - ConditionalFormula(std::shared_ptr<Formula const> const& subformula, std::shared_ptr<Formula const> const& conditionFormula, Context context = Context::Probability); + ConditionalFormula(std::shared_ptr<Formula const> const& subformula, std::shared_ptr<Formula const> const& conditionFormula, FormulaContext context = FormulaContext::Probability); virtual ~ConditionalFormula() { // Intentionally left empty. @@ -27,10 +28,14 @@ namespace storm { virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override; + virtual void gatherAtomicExpressionFormulas(std::vector<std::shared_ptr<AtomicExpressionFormula const>>& atomicExpressionFormulas) const override; + virtual void gatherAtomicLabelFormulas(std::vector<std::shared_ptr<AtomicLabelFormula const>>& atomicLabelFormulas) const override; + virtual void gatherReferencedRewardModels(std::set<std::string>& referencedRewardModels) const override; + private: std::shared_ptr<Formula const> subformula; std::shared_ptr<Formula const> conditionFormula; - Context context; + FormulaContext context; }; } } diff --git a/src/logic/EventuallyFormula.cpp b/src/logic/EventuallyFormula.cpp index 3d2e6fb57..71ff4ac54 100644 --- a/src/logic/EventuallyFormula.cpp +++ b/src/logic/EventuallyFormula.cpp @@ -1,23 +1,25 @@ #include "src/logic/EventuallyFormula.h" - #include "src/logic/FormulaVisitor.h" +#include "src/utility/macros.h" +#include "src/exceptions/InvalidPropertyException.h" + namespace storm { namespace logic { - EventuallyFormula::EventuallyFormula(std::shared_ptr<Formula const> const& subformula, Context context) : UnaryPathFormula(subformula), context(context) { - // Intentionally left empty. + EventuallyFormula::EventuallyFormula(std::shared_ptr<Formula const> const& subformula, FormulaContext context) : UnaryPathFormula(subformula), context(context) { + STORM_LOG_THROW(context == FormulaContext::Probability || context == FormulaContext::Reward || context == FormulaContext::ExpectedTime, storm::exceptions::InvalidPropertyException, "Invalid context for formula."); } bool EventuallyFormula::isEventuallyFormula() const { - return context == Context::Probability; + return context == FormulaContext::Probability; } bool EventuallyFormula::isReachabilityRewardFormula() const { - return context == Context::Reward; + return context == FormulaContext::Reward; } bool EventuallyFormula::isReachbilityExpectedTimeFormula() const { - return context == Context::ExpectedTime; + return context == FormulaContext::ExpectedTime; } bool EventuallyFormula::isProbabilityPathFormula() const { @@ -37,7 +39,7 @@ namespace storm { } std::shared_ptr<Formula> EventuallyFormula::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const { - return std::make_shared<EventuallyFormula>(this->getSubformula().substitute(substitution)); + return std::make_shared<EventuallyFormula>(this->getSubformula().substitute(substitution), context); } std::ostream& EventuallyFormula::writeToStream(std::ostream& out) const { diff --git a/src/logic/EventuallyFormula.h b/src/logic/EventuallyFormula.h index d7a81fa83..5a0070a16 100644 --- a/src/logic/EventuallyFormula.h +++ b/src/logic/EventuallyFormula.h @@ -2,14 +2,13 @@ #define STORM_LOGIC_EVENTUALLYFORMULA_H_ #include "src/logic/UnaryPathFormula.h" +#include "src/logic/FormulaContext.h" namespace storm { namespace logic { class EventuallyFormula : public UnaryPathFormula { - public: - enum class Context { Probability, Reward, ExpectedTime }; - - EventuallyFormula(std::shared_ptr<Formula const> const& subformula, Context context = Context::Probability); + public: + EventuallyFormula(std::shared_ptr<Formula const> const& subformula, FormulaContext context = FormulaContext::Probability); virtual ~EventuallyFormula() { // Intentionally left empty. @@ -29,7 +28,7 @@ namespace storm { virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override; private: - Context context; + FormulaContext context; }; } } diff --git a/src/logic/Formula.cpp b/src/logic/Formula.cpp index d682d02aa..6c7084f53 100644 --- a/src/logic/Formula.cpp +++ b/src/logic/Formula.cpp @@ -256,6 +256,14 @@ namespace storm { return dynamic_cast<EventuallyFormula const&>(*this); } + EventuallyFormula& Formula::asReachabilityRewardFormula() { + return dynamic_cast<EventuallyFormula&>(*this); + } + + EventuallyFormula const& Formula::asReachabilityRewardFormula() const { + return dynamic_cast<EventuallyFormula const&>(*this); + } + GloballyFormula& Formula::asGloballyFormula() { return dynamic_cast<GloballyFormula&>(*this); } @@ -382,7 +390,7 @@ namespace storm { return; } - void Formula::gatherAtomicLabelFormulas(std::vector<std::shared_ptr<AtomicLabelFormula const>>& atomicExpressionFormulas) const { + void Formula::gatherAtomicLabelFormulas(std::vector<std::shared_ptr<AtomicLabelFormula const>>& atomicLabelFormulas) const { return; } diff --git a/src/logic/Formula.h b/src/logic/Formula.h index f2e06bc0b..7d77de7b3 100644 --- a/src/logic/Formula.h +++ b/src/logic/Formula.h @@ -126,6 +126,9 @@ namespace storm { EventuallyFormula& asEventuallyFormula(); EventuallyFormula const& asEventuallyFormula() const; + EventuallyFormula& asReachabilityRewardFormula(); + EventuallyFormula const& asReachabilityRewardFormula() const; + GloballyFormula& asGloballyFormula(); GloballyFormula const& asGloballyFormula() const; @@ -178,7 +181,7 @@ namespace storm { virtual std::ostream& writeToStream(std::ostream& out) const = 0; virtual void gatherAtomicExpressionFormulas(std::vector<std::shared_ptr<AtomicExpressionFormula const>>& atomicExpressionFormulas) const; - virtual void gatherAtomicLabelFormulas(std::vector<std::shared_ptr<AtomicLabelFormula const>>& atomicExpressionFormulas) const; + virtual void gatherAtomicLabelFormulas(std::vector<std::shared_ptr<AtomicLabelFormula const>>& atomicLabelFormulas) const; virtual void gatherReferencedRewardModels(std::set<std::string>& referencedRewardModels) const; private: diff --git a/src/logic/FormulaContext.h b/src/logic/FormulaContext.h new file mode 100644 index 000000000..41113cb8d --- /dev/null +++ b/src/logic/FormulaContext.h @@ -0,0 +1,12 @@ +#ifndef STORM_LOGIC_FORMULACONTEXT_H_ +#define STORM_LOGIC_FORMULACONTEXT_H_ + +namespace storm { + namespace logic { + + enum class FormulaContext { Undefined, Probability, Reward, LongRunAverage, ExpectedTime }; + + } +} + +#endif /* STORM_LOGIC_FORMULACONTEXT_H_ */ \ No newline at end of file diff --git a/src/logic/FragmentChecker.cpp b/src/logic/FragmentChecker.cpp index 8e701cedd..6bf03ddb7 100644 --- a/src/logic/FragmentChecker.cpp +++ b/src/logic/FragmentChecker.cpp @@ -68,11 +68,15 @@ namespace storm { bool result = true; if (f.isConditionalProbabilityFormula()) { result = result && inherited.getSpecification().areConditionalProbabilityFormulasAllowed(); - } else if (f.Formula::isConditionalRewardFormula()) { + } else if (f.isConditionalRewardFormula()) { result = result && inherited.getSpecification().areConditionalRewardFormulasFormulasAllowed(); } if (inherited.getSpecification().areOnlyEventuallyFormuluasInConditionalFormulasAllowed()) { - result = result && f.getSubformula().isEventuallyFormula() && f.getConditionFormula().isEventuallyFormula(); + if (f.isConditionalProbabilityFormula()) { + result = result && f.getSubformula().isEventuallyFormula() && f.getConditionFormula().isEventuallyFormula(); + } else if (f.isConditionalRewardFormula()) { + result = result && f.getSubformula().isReachabilityRewardFormula() && f.getConditionFormula().isEventuallyFormula(); + } } result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, data)); result = result && boost::any_cast<bool>(f.getConditionFormula().accept(*this, data)); @@ -172,7 +176,7 @@ namespace storm { boost::any FragmentChecker::visit(RewardOperatorFormula const& f, boost::any const& data) const { InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data); bool result = inherited.getSpecification().areRewardOperatorsAllowed(); - result = result && f.getSubformula().isRewardPathFormula(); + result = result && (f.getSubformula().isRewardPathFormula() || f.getSubformula().isConditionalRewardFormula()); if (!inherited.getSpecification().areNestedOperatorsAllowed()) { result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, InheritedInformation(inherited.getSpecification().copy().setOperatorsAllowed(false)))); } else { diff --git a/src/modelchecker/AbstractModelChecker.cpp b/src/modelchecker/AbstractModelChecker.cpp index 8f7a7b2f5..ebd760d2e 100644 --- a/src/modelchecker/AbstractModelChecker.cpp +++ b/src/modelchecker/AbstractModelChecker.cpp @@ -20,7 +20,7 @@ namespace storm { if (formula.isProbabilityPathFormula()) { return this->computeProbabilities(checkTask); } else if (formula.isRewardPathFormula()) { - return this->computeRewards(checkTask.substituteFormula(formula.asPathFormula())); + return this->computeRewards(checkTask); } } else if (formula.isConditionalProbabilityFormula()) { return this->computeConditionalProbabilities(checkTask.substituteFormula(formula.asConditionalFormula())); @@ -74,18 +74,20 @@ namespace storm { STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "This model checker does not support the formula: " << checkTask.getFormula() << "."); } - std::unique_ptr<CheckResult> AbstractModelChecker::computeRewards(CheckTask<storm::logic::PathFormula> const& checkTask) { - storm::logic::PathFormula const& rewardPathFormula = checkTask.getFormula(); - if (rewardPathFormula.isCumulativeRewardFormula()) { - return this->computeCumulativeRewards(checkTask.substituteFormula(rewardPathFormula.asCumulativeRewardFormula())); - } else if (rewardPathFormula.isInstantaneousRewardFormula()) { - return this->computeInstantaneousRewards(checkTask.substituteFormula(rewardPathFormula.asInstantaneousRewardFormula())); - } else if (rewardPathFormula.isReachabilityRewardFormula()) { - return this->computeReachabilityRewards(checkTask.substituteFormula(rewardPathFormula.asEventuallyFormula())); - } else if (rewardPathFormula.isLongRunAverageRewardFormula()) { - return this->computeLongRunAverageRewards(checkTask.substituteFormula(rewardPathFormula.asLongRunAverageRewardFormula())); + std::unique_ptr<CheckResult> AbstractModelChecker::computeRewards(CheckTask<storm::logic::Formula> const& checkTask) { + storm::logic::Formula const& rewardFormula = checkTask.getFormula(); + if (rewardFormula.isCumulativeRewardFormula()) { + return this->computeCumulativeRewards(checkTask.substituteFormula(rewardFormula.asCumulativeRewardFormula())); + } else if (rewardFormula.isInstantaneousRewardFormula()) { + return this->computeInstantaneousRewards(checkTask.substituteFormula(rewardFormula.asInstantaneousRewardFormula())); + } else if (rewardFormula.isReachabilityRewardFormula()) { + return this->computeReachabilityRewards(checkTask.substituteFormula(rewardFormula.asEventuallyFormula())); + } else if (rewardFormula.isLongRunAverageRewardFormula()) { + return this->computeLongRunAverageRewards(checkTask.substituteFormula(rewardFormula.asLongRunAverageRewardFormula())); + } else if (rewardFormula.isConditionalRewardFormula()) { + return this->computeConditionalRewards(checkTask.substituteFormula(rewardFormula.asConditionalFormula())); } - STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "The given formula '" << rewardPathFormula << "' is invalid."); + STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "The given formula '" << rewardFormula << "' is invalid."); } std::unique_ptr<CheckResult> AbstractModelChecker::computeConditionalRewards(CheckTask<storm::logic::ConditionalFormula> const& checkTask) { @@ -191,7 +193,7 @@ namespace storm { std::unique_ptr<CheckResult> AbstractModelChecker::checkRewardOperatorFormula(CheckTask<storm::logic::RewardOperatorFormula> const& checkTask) { storm::logic::RewardOperatorFormula const& stateFormula = checkTask.getFormula(); - std::unique_ptr<CheckResult> result = this->computeRewards(checkTask.substituteFormula(stateFormula.getSubformula().asPathFormula())); + std::unique_ptr<CheckResult> result = this->computeRewards(checkTask.substituteFormula(stateFormula.getSubformula())); if (checkTask.isBoundSet()) { STORM_LOG_THROW(result->isQuantitative(), storm::exceptions::InvalidOperationException, "Unable to perform comparison operation on non-quantitative result."); diff --git a/src/modelchecker/AbstractModelChecker.h b/src/modelchecker/AbstractModelChecker.h index fc7fe2fdd..90562659b 100644 --- a/src/modelchecker/AbstractModelChecker.h +++ b/src/modelchecker/AbstractModelChecker.h @@ -44,7 +44,7 @@ namespace storm { virtual std::unique_ptr<CheckResult> computeUntilProbabilities(CheckTask<storm::logic::UntilFormula> const& checkTask); // The methods to compute the rewards for path formulas. - virtual std::unique_ptr<CheckResult> computeRewards(CheckTask<storm::logic::PathFormula> const& checkTask); + virtual std::unique_ptr<CheckResult> computeRewards(CheckTask<storm::logic::Formula> const& checkTask); virtual std::unique_ptr<CheckResult> computeConditionalRewards(CheckTask<storm::logic::ConditionalFormula> const& checkTask); virtual std::unique_ptr<CheckResult> computeCumulativeRewards(CheckTask<storm::logic::CumulativeRewardFormula> const& checkTask); virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(CheckTask<storm::logic::InstantaneousRewardFormula> const& checkTask); diff --git a/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.cpp b/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.cpp index df7f1ee9a..b21d509ec 100644 --- a/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.cpp +++ b/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.cpp @@ -36,7 +36,7 @@ namespace storm { template<typename SparseDtmcModelType> bool SparseDtmcPrctlModelChecker<SparseDtmcModelType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const { storm::logic::Formula const& formula = checkTask.getFormula(); - return formula.isInFragment(storm::logic::prctl().setLongRunAverageRewardFormulasAllowed(false).setLongRunAverageProbabilitiesAllowed(true).setConditionalProbabilityFormulasAllowed(true).setOnlyEventuallyFormuluasInConditionalFormulasAllowed(true)); + return formula.isInFragment(storm::logic::prctl().setLongRunAverageRewardFormulasAllowed(false).setLongRunAverageProbabilitiesAllowed(true).setConditionalProbabilityFormulasAllowed(true).setConditionalRewardFormulasAllowed(true).setOnlyEventuallyFormuluasInConditionalFormulasAllowed(true)); } template<typename SparseDtmcModelType> @@ -130,6 +130,21 @@ namespace storm { return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); } + template<typename SparseDtmcModelType> + std::unique_ptr<CheckResult> SparseDtmcPrctlModelChecker<SparseDtmcModelType>::computeConditionalRewards(CheckTask<storm::logic::ConditionalFormula> const& checkTask) { + storm::logic::ConditionalFormula const& conditionalFormula = checkTask.getFormula(); + STORM_LOG_THROW(conditionalFormula.getSubformula().isReachabilityRewardFormula(), storm::exceptions::InvalidPropertyException, "Illegal conditional probability formula."); + STORM_LOG_THROW(conditionalFormula.getConditionFormula().isEventuallyFormula(), storm::exceptions::InvalidPropertyException, "Illegal conditional probability formula."); + + std::unique_ptr<CheckResult> leftResultPointer = this->check(conditionalFormula.getSubformula().asReachabilityRewardFormula().getSubformula()); + std::unique_ptr<CheckResult> rightResultPointer = this->check(conditionalFormula.getConditionFormula().asEventuallyFormula().getSubformula()); + ExplicitQualitativeCheckResult const& leftResult = leftResultPointer->asExplicitQualitativeCheckResult(); + ExplicitQualitativeCheckResult const& rightResult = rightResultPointer->asExplicitQualitativeCheckResult(); + + std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeConditionalRewards(this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *linearEquationSolverFactory); + return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); + } + template class SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<double>>; } } \ No newline at end of file diff --git a/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h b/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h index 264f1725d..bdfbe5509 100644 --- a/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h +++ b/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h @@ -25,11 +25,13 @@ namespace storm { virtual std::unique_ptr<CheckResult> computeUntilProbabilities(CheckTask<storm::logic::UntilFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeGloballyProbabilities(CheckTask<storm::logic::GloballyFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeConditionalProbabilities(CheckTask<storm::logic::ConditionalFormula> const& checkTask) override; + virtual std::unique_ptr<CheckResult> computeLongRunAverageProbabilities(CheckTask<storm::logic::StateFormula> const& checkTask) override; + virtual std::unique_ptr<CheckResult> computeCumulativeRewards(CheckTask<storm::logic::CumulativeRewardFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(CheckTask<storm::logic::InstantaneousRewardFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) override; - virtual std::unique_ptr<CheckResult> computeLongRunAverageProbabilities(CheckTask<storm::logic::StateFormula> const& checkTask) override; - + virtual std::unique_ptr<CheckResult> computeConditionalRewards(CheckTask<storm::logic::ConditionalFormula> const& checkTask) override; + private: // An object that is used for retrieving linear equation solvers. std::unique_ptr<storm::utility::solver::LinearEquationSolverFactory<ValueType>> linearEquationSolverFactory; diff --git a/src/modelchecker/prctl/helper/SparseDtmcPrctlHelper.cpp b/src/modelchecker/prctl/helper/SparseDtmcPrctlHelper.cpp index b1401cd8a..2be798889 100644 --- a/src/modelchecker/prctl/helper/SparseDtmcPrctlHelper.cpp +++ b/src/modelchecker/prctl/helper/SparseDtmcPrctlHelper.cpp @@ -46,7 +46,7 @@ namespace storm { return result; } - + template<typename ValueType, typename RewardModelType> std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeUntilProbabilities(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { // We need to identify the states which have to be taken out of the matrix, i.e. @@ -154,7 +154,7 @@ namespace storm { return result; } - + template<typename ValueType, typename RewardModelType> std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeReachabilityRewards(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { return computeReachabilityRewards(transitionMatrix, backwardTransitions, [&] (uint_fast64_t numberOfRows, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& maybeStates) { return rewardModel.getTotalRewardVector(numberOfRows, transitionMatrix, maybeStates); }, targetStates, qualitative, linearEquationSolverFactory); @@ -170,7 +170,7 @@ namespace storm { }, targetStates, qualitative, linearEquationSolverFactory); } - + template<typename ValueType, typename RewardModelType> std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeReachabilityRewards(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::function<std::vector<ValueType>(uint_fast64_t, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const&)> const& totalStateRewardVectorGetter, storm::storage::BitVector const& targetStates, bool qualitative, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { @@ -222,23 +222,26 @@ namespace storm { return result; } - + template<typename ValueType, typename RewardModelType> std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeLongRunAverageProbabilities(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& psiStates, bool qualitative, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { return SparseCtmcCslHelper<ValueType>::computeLongRunAverageProbabilities(transitionMatrix, psiStates, nullptr, qualitative, linearEquationSolverFactory); } template<typename ValueType, typename RewardModelType> - std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeConditionalProbabilities(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates, bool qualitative, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { - std::vector<ValueType> probabilitiesToReachConditionStates = computeUntilProbabilities(transitionMatrix, backwardTransitions, storm::storage::BitVector(transitionMatrix.getRowCount(), true), conditionStates, false, linearEquationSolverFactory); + typename SparseDtmcPrctlHelper<ValueType, RewardModelType>::BaierTransformedModel SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeBaierTransformation(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates, boost::optional<std::vector<ValueType>> const& stateRewards, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + + BaierTransformedModel result; // Start by computing all 'before' states, i.e. the states for which the conditional probability is defined. - storm::storage::BitVector beforeStates(targetStates.size(), true); + std::vector<ValueType> probabilitiesToReachConditionStates = computeUntilProbabilities(transitionMatrix, backwardTransitions, storm::storage::BitVector(transitionMatrix.getRowCount(), true), conditionStates, false, linearEquationSolverFactory); + + result.beforeStates = storm::storage::BitVector(targetStates.size(), true); uint_fast64_t state = 0; uint_fast64_t beforeStateIndex = 0; for (auto const& value : probabilitiesToReachConditionStates) { if (value == storm::utility::zero<ValueType>()) { - beforeStates.set(state, false); + result.beforeStates.set(state, false); } else { probabilitiesToReachConditionStates[beforeStateIndex] = value; ++beforeStateIndex; @@ -246,35 +249,33 @@ namespace storm { ++state; } probabilitiesToReachConditionStates.resize(beforeStateIndex); - - // If there were any before states, we can compute their conditional probabilities. If not, the result - // is undefined for all states. - std::vector<ValueType> result(transitionMatrix.getRowCount(), storm::utility::infinity<ValueType>()); + if (targetStates.empty()) { - storm::utility::vector::setVectorValues(result, beforeStates, storm::utility::zero<ValueType>()); - } else if (!beforeStates.empty()) { + result.noTargetStates = true; + return result; + } else if (!result.beforeStates.empty()) { // If there are some states for which the conditional probability is defined and there are some // states that can reach the target states without visiting condition states first, we need to // do more work. - + // First, compute the relevant states and some offsets. storm::storage::BitVector allStates(targetStates.size(), true); - std::vector<uint_fast64_t> numberOfBeforeStatesUpToState = beforeStates.getNumberOfSetBitsBeforeIndices(); + std::vector<uint_fast64_t> numberOfBeforeStatesUpToState = result.beforeStates.getNumberOfSetBitsBeforeIndices(); storm::storage::BitVector statesWithProbabilityGreater0 = storm::utility::graph::performProbGreater0(backwardTransitions, allStates, targetStates); statesWithProbabilityGreater0 &= storm::utility::graph::getReachableStates(transitionMatrix, conditionStates, allStates, targetStates); - uint_fast64_t normalStatesOffset = beforeStates.getNumberOfSetBits(); + uint_fast64_t normalStatesOffset = result.beforeStates.getNumberOfSetBits(); std::vector<uint_fast64_t> numberOfNormalStatesUpToState = statesWithProbabilityGreater0.getNumberOfSetBitsBeforeIndices(); // All transitions going to states with probability zero, need to be redirected to a deadlock state. bool addDeadlockState = false; uint_fast64_t deadlockState = normalStatesOffset + statesWithProbabilityGreater0.getNumberOfSetBits(); - + // Now, we create the matrix of 'before' and 'normal' states. storm::storage::SparseMatrixBuilder<ValueType> builder; // Start by creating the transitions of the 'before' states. uint_fast64_t currentRow = 0; - for (auto beforeState : beforeStates) { + for (auto beforeState : result.beforeStates) { if (conditionStates.get(beforeState)) { // For condition states, we move to the 'normal' states. ValueType zeroProbability = storm::utility::zero<ValueType>(); @@ -291,7 +292,7 @@ namespace storm { } else { // For non-condition states, we scale the probabilities going to other before states. for (auto const& successorEntry : transitionMatrix.getRow(beforeState)) { - if (beforeStates.get(successorEntry.getColumn())) { + if (result.beforeStates.get(successorEntry.getColumn())) { builder.addNextValue(currentRow, numberOfBeforeStatesUpToState[successorEntry.getColumn()], successorEntry.getValue() * probabilitiesToReachConditionStates[numberOfBeforeStatesUpToState[successorEntry.getColumn()]] / probabilitiesToReachConditionStates[currentRow]); } } @@ -320,21 +321,84 @@ namespace storm { } // Build the new transition matrix and the new targets. - storm::storage::SparseMatrix<ValueType> newTransitionMatrix = builder.build(); - storm::storage::BitVector newTargetStates = targetStates % beforeStates; - newTargetStates.resize(newTransitionMatrix.getRowCount()); + result.transitionMatrix = builder.build(); + storm::storage::BitVector newTargetStates = targetStates % result.beforeStates; + newTargetStates.resize(result.transitionMatrix.get().getRowCount()); for (auto state : targetStates % statesWithProbabilityGreater0) { newTargetStates.set(normalStatesOffset + state, true); } + result.targetStates = std::move(newTargetStates); + + // If a reward model was given, we need to compute the rewards for the transformed model. + if (stateRewards) { + std::vector<ValueType> newStateRewards(result.beforeStates.getNumberOfSetBits()); + storm::utility::vector::selectVectorValues(newStateRewards, result.beforeStates, stateRewards.get()); + + newStateRewards.reserve(newStateRewards.size() + statesWithProbabilityGreater0.getNumberOfSetBits() + 1); + for (auto state : statesWithProbabilityGreater0) { + newStateRewards.push_back(stateRewards.get()[state]); + } + // Add a zero reward to the deadlock state. + newStateRewards.push_back(storm::utility::zero<ValueType>()); + result.stateRewards = std::move(newStateRewards); + } - // Finally, compute the conditional probabiltities by a reachability query. - std::vector<ValueType> conditionalProbabilities = computeUntilProbabilities(newTransitionMatrix, newTransitionMatrix.transpose(), storm::storage::BitVector(newTransitionMatrix.getRowCount(), true), newTargetStates, qualitative, linearEquationSolverFactory); - storm::utility::vector::setVectorValues(result, beforeStates, conditionalProbabilities); } - + return result; } - + + template<typename ValueType, typename RewardModelType> + std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeConditionalProbabilities(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates, bool qualitative, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + + // Prepare result vector. + std::vector<ValueType> result(transitionMatrix.getRowCount(), storm::utility::infinity<ValueType>()); + + if (!conditionStates.empty()) { + BaierTransformedModel transformedModel = computeBaierTransformation(transitionMatrix, backwardTransitions, targetStates, conditionStates, boost::none, linearEquationSolverFactory); + + if (transformedModel.noTargetStates) { + storm::utility::vector::setVectorValues(result, transformedModel.beforeStates, storm::utility::zero<ValueType>()); + } else { + // At this point, we do not need to check whether there are 'before' states, since the condition + // states were non-empty so there is at least one state with a positive probability of satisfying + // the condition. + + // Now compute reachability probabilities in the transformed model. + storm::storage::SparseMatrix<ValueType> const& newTransitionMatrix = transformedModel.transitionMatrix.get(); + std::vector<ValueType> conditionalProbabilities = computeUntilProbabilities(newTransitionMatrix, newTransitionMatrix.transpose(), storm::storage::BitVector(newTransitionMatrix.getRowCount(), true), transformedModel.targetStates.get(), qualitative, linearEquationSolverFactory); + storm::utility::vector::setVectorValues(result, transformedModel.beforeStates, conditionalProbabilities); + } + } + + return result; + } + + template<typename ValueType, typename RewardModelType> + std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeConditionalRewards(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel, storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates, bool qualitative, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + // Prepare result vector. + std::vector<ValueType> result(transitionMatrix.getRowCount(), storm::utility::infinity<ValueType>()); + + if (!conditionStates.empty()) { + BaierTransformedModel transformedModel = computeBaierTransformation(transitionMatrix, backwardTransitions, targetStates, conditionStates, rewardModel.getTotalRewardVector(transitionMatrix), linearEquationSolverFactory); + + if (transformedModel.noTargetStates) { + storm::utility::vector::setVectorValues(result, transformedModel.beforeStates, storm::utility::zero<ValueType>()); + } else { + // At this point, we do not need to check whether there are 'before' states, since the condition + // states were non-empty so there is at least one state with a positive probability of satisfying + // the condition. + + // Now compute reachability probabilities in the transformed model. + storm::storage::SparseMatrix<ValueType> const& newTransitionMatrix = transformedModel.transitionMatrix.get(); + std::vector<ValueType> conditionalProbabilities = computeUntilProbabilities(newTransitionMatrix, newTransitionMatrix.transpose(), storm::storage::BitVector(newTransitionMatrix.getRowCount(), true), transformedModel.targetStates.get(), qualitative, linearEquationSolverFactory); + storm::utility::vector::setVectorValues(result, transformedModel.beforeStates, conditionalProbabilities); + } + } + + return result; + } + template class SparseDtmcPrctlHelper<double>; } } diff --git a/src/modelchecker/prctl/helper/SparseDtmcPrctlHelper.h b/src/modelchecker/prctl/helper/SparseDtmcPrctlHelper.h index d1414dbce..637c30cb5 100644 --- a/src/modelchecker/prctl/helper/SparseDtmcPrctlHelper.h +++ b/src/modelchecker/prctl/helper/SparseDtmcPrctlHelper.h @@ -39,8 +39,20 @@ namespace storm { static std::vector<ValueType> computeConditionalProbabilities(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates, bool qualitative, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::vector<ValueType> computeConditionalRewards(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel, storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates, bool qualitative, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + private: static std::vector<ValueType> computeReachabilityRewards(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::function<std::vector<ValueType>(uint_fast64_t, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const&)> const& totalStateRewardVectorGetter, storm::storage::BitVector const& targetStates, bool qualitative, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + + struct BaierTransformedModel { + storm::storage::BitVector beforeStates; + boost::optional<storm::storage::SparseMatrix<ValueType>> transitionMatrix; + boost::optional<storm::storage::BitVector> targetStates; + boost::optional<std::vector<ValueType>> stateRewards; + bool noTargetStates; + }; + + static BaierTransformedModel computeBaierTransformation(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates, boost::optional<std::vector<ValueType>> const& stateRewards, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); }; } diff --git a/src/parser/FormulaParser.cpp b/src/parser/FormulaParser.cpp index ae7d8e0f7..d8fa100c8 100644 --- a/src/parser/FormulaParser.cpp +++ b/src/parser/FormulaParser.cpp @@ -105,8 +105,8 @@ namespace storm { qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> simpleFormula; qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> stateFormula; - qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> pathFormula; - qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> pathFormulaWithoutUntil; + qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(storm::logic::FormulaContext), Skipper> pathFormula; + qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(storm::logic::FormulaContext), Skipper> pathFormulaWithoutUntil; qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> simplePathFormula; qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> atomicStateFormula; qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> operatorFormula; @@ -120,11 +120,11 @@ namespace storm { qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> expressionFormula; qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), qi::locals<bool>, Skipper> booleanLiteralFormula; - qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(storm::logic::ConditionalFormula::Context), Skipper> conditionalFormula; - qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(storm::logic::EventuallyFormula::Context), Skipper> eventuallyFormula; - qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> nextFormula; - qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> globallyFormula; - qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> untilFormula; + qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(storm::logic::FormulaContext), Skipper> conditionalFormula; + qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(storm::logic::FormulaContext), Skipper> eventuallyFormula; + qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(storm::logic::FormulaContext), Skipper> nextFormula; + qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(storm::logic::FormulaContext), Skipper> globallyFormula; + qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(storm::logic::FormulaContext), Skipper> untilFormula; qi::rule<Iterator, boost::variant<std::pair<double, double>, uint_fast64_t>(), Skipper> timeBound; qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> rewardPathFormula; @@ -142,11 +142,11 @@ namespace storm { std::shared_ptr<storm::logic::Formula> createAtomicExpressionFormula(storm::expressions::Expression const& expression) const; std::shared_ptr<storm::logic::Formula> createBooleanLiteralFormula(bool literal) const; std::shared_ptr<storm::logic::Formula> createAtomicLabelFormula(std::string const& label) const; - std::shared_ptr<storm::logic::Formula> createEventuallyFormula(boost::optional<boost::variant<std::pair<double, double>, uint_fast64_t>> const& timeBound, storm::logic::EventuallyFormula::Context context, std::shared_ptr<storm::logic::Formula> const& subformula) const; + std::shared_ptr<storm::logic::Formula> createEventuallyFormula(boost::optional<boost::variant<std::pair<double, double>, uint_fast64_t>> const& timeBound, storm::logic::FormulaContext context, std::shared_ptr<storm::logic::Formula> const& subformula) const; std::shared_ptr<storm::logic::Formula> createGloballyFormula(std::shared_ptr<storm::logic::Formula> const& subformula) const; std::shared_ptr<storm::logic::Formula> createNextFormula(std::shared_ptr<storm::logic::Formula> const& subformula) const; std::shared_ptr<storm::logic::Formula> createUntilFormula(std::shared_ptr<storm::logic::Formula> const& leftSubformula, boost::optional<boost::variant<std::pair<double, double>, uint_fast64_t>> const& timeBound, std::shared_ptr<storm::logic::Formula> const& rightSubformula); - std::shared_ptr<storm::logic::Formula> createConditionalFormula(std::shared_ptr<storm::logic::Formula> const& leftSubformula, std::shared_ptr<storm::logic::Formula> const& rightSubformula, storm::logic::ConditionalFormula::Context context) const; + std::shared_ptr<storm::logic::Formula> createConditionalFormula(std::shared_ptr<storm::logic::Formula> const& leftSubformula, std::shared_ptr<storm::logic::Formula> const& rightSubformula, storm::logic::FormulaContext context) const; std::pair<boost::optional<storm::OptimizationDirection>, boost::optional<storm::logic::Bound<double>>> createOperatorInformation(boost::optional<storm::OptimizationDirection> const& optimizationDirection, boost::optional<storm::logic::ComparisonType> const& comparisonType, boost::optional<double> const& threshold) const; std::shared_ptr<storm::logic::Formula> createLongRunAverageOperatorFormula(std::pair<boost::optional<storm::OptimizationDirection>, boost::optional<storm::logic::Bound<double>>> const& operatorInformation, std::shared_ptr<storm::logic::Formula> const& subformula) const; std::shared_ptr<storm::logic::Formula> createRewardOperatorFormula(boost::optional<std::string> const& rewardModelName, std::pair<boost::optional<storm::OptimizationDirection>, boost::optional<storm::logic::Bound<double>>> const& operatorInformation, std::shared_ptr<storm::logic::Formula> const& subformula) const; @@ -253,7 +253,7 @@ namespace storm { cumulativeRewardFormula = (qi::lit("C<=") >> strict_double)[qi::_val = phoenix::bind(&FormulaParserGrammar::createCumulativeRewardFormula, phoenix::ref(*this), qi::_1)] | (qi::lit("C<=") > qi::uint_)[qi::_val = phoenix::bind(&FormulaParserGrammar::createCumulativeRewardFormula, phoenix::ref(*this), qi::_1)]; cumulativeRewardFormula.name("cumulative reward formula"); - rewardPathFormula = eventuallyFormula(storm::logic::EventuallyFormula::Context::Reward) | cumulativeRewardFormula | instantaneousRewardFormula | longRunAverageRewardFormula | conditionalFormula(storm::logic::ConditionalFormula::Context::Reward); + rewardPathFormula = conditionalFormula(storm::logic::FormulaContext::Reward) | eventuallyFormula(storm::logic::FormulaContext::Reward) | cumulativeRewardFormula | instantaneousRewardFormula | longRunAverageRewardFormula; rewardPathFormula.name("reward path formula"); expressionFormula = expressionParser[qi::_val = phoenix::bind(&FormulaParserGrammar::createAtomicExpressionFormula, phoenix::ref(*this), qi::_1)]; @@ -277,28 +277,28 @@ namespace storm { notStateFormula = (-unaryBooleanOperator_ >> atomicStateFormula)[qi::_val = phoenix::bind(&FormulaParserGrammar::createUnaryBooleanStateFormula, phoenix::ref(*this), qi::_2, qi::_1)]; notStateFormula.name("negation formula"); - eventuallyFormula = (qi::lit("F") >> -timeBound >> pathFormulaWithoutUntil)[qi::_val = phoenix::bind(&FormulaParserGrammar::createEventuallyFormula, phoenix::ref(*this), qi::_1, qi::_r1, qi::_2)]; + eventuallyFormula = (qi::lit("F") >> -timeBound >> pathFormulaWithoutUntil(qi::_r1))[qi::_val = phoenix::bind(&FormulaParserGrammar::createEventuallyFormula, phoenix::ref(*this), qi::_1, qi::_r1, qi::_2)]; eventuallyFormula.name("eventually formula"); - globallyFormula = (qi::lit("G") >> pathFormulaWithoutUntil)[qi::_val = phoenix::bind(&FormulaParserGrammar::createGloballyFormula, phoenix::ref(*this), qi::_1)]; + globallyFormula = (qi::lit("G") >> pathFormulaWithoutUntil(qi::_r1))[qi::_val = phoenix::bind(&FormulaParserGrammar::createGloballyFormula, phoenix::ref(*this), qi::_1)]; globallyFormula.name("globally formula"); - nextFormula = (qi::lit("X") >> pathFormulaWithoutUntil)[qi::_val = phoenix::bind(&FormulaParserGrammar::createNextFormula, phoenix::ref(*this), qi::_1)]; + nextFormula = (qi::lit("X") >> pathFormulaWithoutUntil(qi::_r1))[qi::_val = phoenix::bind(&FormulaParserGrammar::createNextFormula, phoenix::ref(*this), qi::_1)]; nextFormula.name("next formula"); - pathFormulaWithoutUntil = eventuallyFormula(storm::logic::EventuallyFormula::Context::Probability) | globallyFormula | nextFormula | stateFormula; + pathFormulaWithoutUntil = eventuallyFormula(qi::_r1) | globallyFormula(qi::_r1) | nextFormula(qi::_r1) | stateFormula; pathFormulaWithoutUntil.name("path formula"); - untilFormula = pathFormulaWithoutUntil[qi::_val = qi::_1] >> *(qi::lit("U") >> -timeBound >> pathFormulaWithoutUntil)[qi::_val = phoenix::bind(&FormulaParserGrammar::createUntilFormula, phoenix::ref(*this), qi::_val, qi::_1, qi::_2)]; + untilFormula = pathFormulaWithoutUntil(qi::_r1)[qi::_val = qi::_1] >> *(qi::lit("U") >> -timeBound >> pathFormulaWithoutUntil(qi::_r1))[qi::_val = phoenix::bind(&FormulaParserGrammar::createUntilFormula, phoenix::ref(*this), qi::_val, qi::_1, qi::_2)]; untilFormula.name("until formula"); - conditionalFormula = untilFormula[qi::_val = qi::_1] >> *(qi::lit("||") >> untilFormula)[qi::_val = phoenix::bind(&FormulaParserGrammar::createConditionalFormula, phoenix::ref(*this), qi::_val, qi::_1, qi::_r1)]; + conditionalFormula = untilFormula(qi::_r1)[qi::_val = qi::_1] >> *(qi::lit("||") >> untilFormula(storm::logic::FormulaContext::Probability))[qi::_val = phoenix::bind(&FormulaParserGrammar::createConditionalFormula, phoenix::ref(*this), qi::_val, qi::_1, qi::_r1)]; conditionalFormula.name("conditional formula"); timeBound = (qi::lit("[") > qi::double_ > qi::lit(",") > qi::double_ > qi::lit("]"))[qi::_val = phoenix::construct<std::pair<double, double>>(qi::_1, qi::_2)] | (qi::lit("<=") >> strict_double)[qi::_val = phoenix::construct<std::pair<double, double>>(0, qi::_1)] | (qi::lit("<=") > qi::uint_)[qi::_val = qi::_1]; timeBound.name("time bound"); - pathFormula = conditionalFormula(storm::logic::ConditionalFormula::Context::Probability); + pathFormula = conditionalFormula(qi::_r1); pathFormula.name("path formula"); operatorInformation = (-optimalityOperator_[qi::_a = qi::_1] >> ((relationalOperator_[qi::_b = qi::_1] > qi::double_[qi::_c = qi::_1]) | (qi::lit("=") > qi::lit("?"))))[qi::_val = phoenix::bind(&FormulaParserGrammar::createOperatorInformation, phoenix::ref(*this), qi::_a, qi::_b, qi::_c)]; @@ -313,10 +313,10 @@ namespace storm { rewardOperator = (qi::lit("R") > -rewardModelName > operatorInformation > qi::lit("[") > rewardPathFormula > qi::lit("]"))[qi::_val = phoenix::bind(&FormulaParserGrammar::createRewardOperatorFormula, phoenix::ref(*this), qi::_1, qi::_2, qi::_3)]; rewardOperator.name("reward operator"); - expectedTimeOperator = (qi::lit("ET") > operatorInformation > qi::lit("[") > eventuallyFormula(storm::logic::EventuallyFormula::Context::ExpectedTime) > qi::lit("]"))[qi::_val = phoenix::bind(&FormulaParserGrammar::createExpectedTimeOperatorFormula, phoenix::ref(*this), qi::_1, qi::_2)]; + expectedTimeOperator = (qi::lit("ET") > operatorInformation > qi::lit("[") > eventuallyFormula(storm::logic::FormulaContext::ExpectedTime) > qi::lit("]"))[qi::_val = phoenix::bind(&FormulaParserGrammar::createExpectedTimeOperatorFormula, phoenix::ref(*this), qi::_1, qi::_2)]; expectedTimeOperator.name("expected time operator"); - probabilityOperator = (qi::lit("P") > operatorInformation > qi::lit("[") > pathFormula > qi::lit("]"))[qi::_val = phoenix::bind(&FormulaParserGrammar::createProbabilityOperatorFormula, phoenix::ref(*this), qi::_1, qi::_2)]; + probabilityOperator = (qi::lit("P") > operatorInformation > qi::lit("[") > pathFormula(storm::logic::FormulaContext::Probability) > qi::lit("]"))[qi::_val = phoenix::bind(&FormulaParserGrammar::createProbabilityOperatorFormula, phoenix::ref(*this), qi::_1, qi::_2)]; probabilityOperator.name("probability operator"); andStateFormula = notStateFormula[qi::_val = qi::_1] >> *(qi::lit("&") >> notStateFormula)[qi::_val = phoenix::bind(&FormulaParserGrammar::createBinaryBooleanStateFormula, phoenix::ref(*this), qi::_val, qi::_1, storm::logic::BinaryBooleanStateFormula::OperatorType::And)]; @@ -342,10 +342,10 @@ namespace storm { debug(longRunAverageOperator); debug(pathFormulaWithoutUntil); debug(pathFormula); - debug(conditionalFormula); +// debug(conditionalFormula); debug(nextFormula); debug(globallyFormula); - debug(eventuallyFormula); +// debug(eventuallyFormula); debug(atomicStateFormula); debug(booleanLiteralFormula); debug(labelFormula); @@ -421,7 +421,7 @@ namespace storm { return std::shared_ptr<storm::logic::Formula>(new storm::logic::AtomicLabelFormula(label)); } - std::shared_ptr<storm::logic::Formula> FormulaParserGrammar::createEventuallyFormula(boost::optional<boost::variant<std::pair<double, double>, uint_fast64_t>> const& timeBound, storm::logic::EventuallyFormula::Context context, std::shared_ptr<storm::logic::Formula> const& subformula) const { + std::shared_ptr<storm::logic::Formula> FormulaParserGrammar::createEventuallyFormula(boost::optional<boost::variant<std::pair<double, double>, uint_fast64_t>> const& timeBound, storm::logic::FormulaContext context, std::shared_ptr<storm::logic::Formula> const& subformula) const { if (timeBound) { if (timeBound.get().which() == 0) { std::pair<double, double> const& bounds = boost::get<std::pair<double, double>>(timeBound.get()); @@ -455,7 +455,7 @@ namespace storm { } } - std::shared_ptr<storm::logic::Formula> FormulaParserGrammar::createConditionalFormula(std::shared_ptr<storm::logic::Formula> const& leftSubformula, std::shared_ptr<storm::logic::Formula> const& rightSubformula, storm::logic::ConditionalFormula::Context context) const { + std::shared_ptr<storm::logic::Formula> FormulaParserGrammar::createConditionalFormula(std::shared_ptr<storm::logic::Formula> const& leftSubformula, std::shared_ptr<storm::logic::Formula> const& rightSubformula, storm::logic::FormulaContext context) const { return std::shared_ptr<storm::logic::Formula>(new storm::logic::ConditionalFormula(leftSubformula, rightSubformula, context)); } From 0156b1276485e7acf60a74c25cc89a070b2ab6a3 Mon Sep 17 00:00:00 2001 From: Mavo <matthias.volk@rwth-aachen.de> Date: Fri, 19 Feb 2016 17:36:35 +0100 Subject: [PATCH 08/23] Fixed compile problem under gcc Former-commit-id: f5d40795e99f9d40698b8787f2409f6735a1c2f8 --- src/builder/ExplicitDFTModelBuilder.h | 4 ++-- src/storage/BitVectorHashMap.cpp | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/builder/ExplicitDFTModelBuilder.h b/src/builder/ExplicitDFTModelBuilder.h index 522f2375c..a64efaddd 100644 --- a/src/builder/ExplicitDFTModelBuilder.h +++ b/src/builder/ExplicitDFTModelBuilder.h @@ -50,7 +50,7 @@ namespace storm { storm::storage::DFT<ValueType> const& mDft; std::shared_ptr<storm::storage::DFTStateGenerationInfo> mStateGenerationInfo; - storm::storage::BitVectorHashMap<size_t> mStates; + storm::storage::BitVectorHashMap<uint32_t> mStates; size_t newIndex = 0; public: @@ -71,4 +71,4 @@ namespace storm { } } -#endif /* EXPLICITDFTMODELBUILDER_H */ \ No newline at end of file +#endif /* EXPLICITDFTMODELBUILDER_H */ diff --git a/src/storage/BitVectorHashMap.cpp b/src/storage/BitVectorHashMap.cpp index 4d6238350..9237dfde3 100644 --- a/src/storage/BitVectorHashMap.cpp +++ b/src/storage/BitVectorHashMap.cpp @@ -240,6 +240,5 @@ namespace storm { template class BitVectorHashMap<uint_fast64_t>; template class BitVectorHashMap<uint32_t>; - template class BitVectorHashMap<size_t>; } } From b3483211ff47b7f5ca7a559e274cb6c4cdfe96b4 Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Fri, 19 Feb 2016 19:41:16 +0100 Subject: [PATCH 09/23] alpha version of conditional rewards for dtmc Former-commit-id: 1adfb3d405ffb6b2332dc5a71e4238e85dfe7ec5 --- src/modelchecker/prctl/helper/SparseDtmcPrctlHelper.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modelchecker/prctl/helper/SparseDtmcPrctlHelper.cpp b/src/modelchecker/prctl/helper/SparseDtmcPrctlHelper.cpp index 2be798889..9e1b6ef14 100644 --- a/src/modelchecker/prctl/helper/SparseDtmcPrctlHelper.cpp +++ b/src/modelchecker/prctl/helper/SparseDtmcPrctlHelper.cpp @@ -391,8 +391,8 @@ namespace storm { // Now compute reachability probabilities in the transformed model. storm::storage::SparseMatrix<ValueType> const& newTransitionMatrix = transformedModel.transitionMatrix.get(); - std::vector<ValueType> conditionalProbabilities = computeUntilProbabilities(newTransitionMatrix, newTransitionMatrix.transpose(), storm::storage::BitVector(newTransitionMatrix.getRowCount(), true), transformedModel.targetStates.get(), qualitative, linearEquationSolverFactory); - storm::utility::vector::setVectorValues(result, transformedModel.beforeStates, conditionalProbabilities); + std::vector<ValueType> conditionalRewards = computeReachabilityRewards(newTransitionMatrix, newTransitionMatrix.transpose(), transformedModel.stateRewards.get(), transformedModel.targetStates.get(), qualitative, linearEquationSolverFactory); + storm::utility::vector::setVectorValues(result, transformedModel.beforeStates, conditionalRewards); } } From 5ce72a85cef4d643d6c380a455dcf80e1802444d Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Fri, 19 Feb 2016 20:04:11 +0100 Subject: [PATCH 10/23] added small test for conditional probability and conditional rewards Former-commit-id: 891d99eea61311d88087da1dfbc825ea00ea0995 --- .../GmmxxDtmcPrctlModelCheckerTest.cpp | 47 +++++++++++++++++-- .../modelchecker/test_conditional.pm | 18 +++++++ 2 files changed, 62 insertions(+), 3 deletions(-) create mode 100644 test/functional/modelchecker/test_conditional.pm diff --git a/test/functional/modelchecker/GmmxxDtmcPrctlModelCheckerTest.cpp b/test/functional/modelchecker/GmmxxDtmcPrctlModelCheckerTest.cpp index 7999da353..1e131c335 100644 --- a/test/functional/modelchecker/GmmxxDtmcPrctlModelCheckerTest.cpp +++ b/test/functional/modelchecker/GmmxxDtmcPrctlModelCheckerTest.cpp @@ -13,6 +13,8 @@ #include "src/settings/modules/NativeEquationSolverSettings.h" #include "src/settings/SettingMemento.h" #include "src/parser/AutoParser.h" +#include "src/parser/PrismParser.h" +#include "src/builder/ExplicitPrismModelBuilder.h" TEST(GmmxxDtmcPrctlModelCheckerTest, Die) { std::shared_ptr<storm::models::sparse::Model<double>> abstractModel = storm::parser::AutoParser<>::parseModel(STORM_CPP_BASE_PATH "/examples/dtmc/die/die.tra", STORM_CPP_BASE_PATH "/examples/dtmc/die/die.lab", "", STORM_CPP_BASE_PATH "/examples/dtmc/die/die.coin_flips.trans.rew"); @@ -214,7 +216,7 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, LRASingleBscc) { TEST(GmmxxDtmcPrctlModelCheckerTest, LRA) { storm::storage::SparseMatrixBuilder<double> matrixBuilder; - std::shared_ptr<storm::models::sparse::Dtmc<double>> mdp; + std::shared_ptr<storm::models::sparse::Dtmc<double>> dtmc; // A parser that we use for conveniently constructing the formulas. storm::parser::FormulaParser formulaParser; @@ -260,9 +262,9 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, LRA) { ap.addLabelToState("a", 13); ap.addLabelToState("a", 14); - mdp.reset(new storm::models::sparse::Dtmc<double>(transitionMatrix, ap)); + dtmc.reset(new storm::models::sparse::Dtmc<double>(transitionMatrix, ap)); - storm::modelchecker::SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<double>> checker(*mdp, std::unique_ptr<storm::utility::solver::LinearEquationSolverFactory<double>>(new storm::utility::solver::GmmxxLinearEquationSolverFactory<double>())); + storm::modelchecker::SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<double>> checker(*dtmc, std::unique_ptr<storm::utility::solver::LinearEquationSolverFactory<double>>(new storm::utility::solver::GmmxxLinearEquationSolverFactory<double>())); std::shared_ptr<const storm::logic::Formula> formula = formulaParser.parseSingleFormulaFromString("LRA=? [\"a\"]"); @@ -278,3 +280,42 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, LRA) { EXPECT_NEAR(0.3 / 3., quantitativeResult1[14], storm::settings::nativeEquationSolverSettings().getPrecision()); } } + +TEST(GmmxxDtmcPrctlModelCheckerTest, Conditional) { + storm::prism::Program program = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/test_conditional.pm"); + + std::shared_ptr<storm::models::sparse::Model<double>> model = storm::builder::ExplicitPrismModelBuilder<double>().translateProgram(program); + ASSERT_TRUE(model->getType() == storm::models::ModelType::Dtmc); + ASSERT_EQ(4ul, model->getNumberOfStates()); + ASSERT_EQ(5ul, model->getNumberOfTransitions()); + + std::shared_ptr<storm::models::sparse::Dtmc<double>> dtmc = model->as<storm::models::sparse::Dtmc<double>>(); + + storm::modelchecker::SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<double>> checker(*dtmc, std::unique_ptr<storm::utility::solver::LinearEquationSolverFactory<double>>(new storm::utility::solver::GmmxxLinearEquationSolverFactory<double>())); + + // A parser that we use for conveniently constructing the formulas. + storm::parser::FormulaParser formulaParser; + std::shared_ptr<const storm::logic::Formula> formula = formulaParser.parseSingleFormulaFromString("P=? [F \"target\"]"); + + std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(*formula); + storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult1 = result->asExplicitQuantitativeCheckResult<double>(); + EXPECT_NEAR(0.5, quantitativeResult1[0], storm::settings::nativeEquationSolverSettings().getPrecision()); + + formula = formulaParser.parseSingleFormulaFromString("P=? [F \"target\" || F \"condition\"]"); + + result = checker.check(*formula); + storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult2 = result->asExplicitQuantitativeCheckResult<double>(); + EXPECT_NEAR(storm::utility::one<double>(), quantitativeResult2[0], storm::settings::nativeEquationSolverSettings().getPrecision()); + + formula = formulaParser.parseSingleFormulaFromString("R=? [F \"target\"]"); + + result = checker.check(*formula); + storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult3 = result->asExplicitQuantitativeCheckResult<double>(); + EXPECT_EQ(storm::utility::infinity<double>(), quantitativeResult3[0]); + + formula = formulaParser.parseSingleFormulaFromString("R=? [F \"target\" || F \"condition\"]"); + + result = checker.check(*formula); + storm::modelchecker::ExplicitQuantitativeCheckResult<double>& quantitativeResult4 = result->asExplicitQuantitativeCheckResult<double>(); + EXPECT_NEAR(storm::utility::one<double>(), quantitativeResult4[0], storm::settings::nativeEquationSolverSettings().getPrecision()); +} diff --git a/test/functional/modelchecker/test_conditional.pm b/test/functional/modelchecker/test_conditional.pm new file mode 100644 index 000000000..57b8ba44c --- /dev/null +++ b/test/functional/modelchecker/test_conditional.pm @@ -0,0 +1,18 @@ +dtmc + +module test + s : [0 .. 3] init 0; + + [] s=0 -> 0.5 : (s'=1) + 0.5 : (s'=2); + [] s=1 -> 1 : true; + [] s=2 -> 1 : (s'=3); + [] s=3 -> 1 : true; + +endmodule + +rewards + s=2 : 1; +endrewards + +label "condition" = s=2; +label "target" = s=3; From 211994bff9f69ddcc86ccb5f91fa6f11458586d4 Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Sun, 21 Feb 2016 21:35:09 +0100 Subject: [PATCH 11/23] removed debug output Former-commit-id: 915be7778b54e3f9a93a792b4f184eff83a0d957 --- src/storage/dd/cudd/InternalCuddAdd.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/storage/dd/cudd/InternalCuddAdd.cpp b/src/storage/dd/cudd/InternalCuddAdd.cpp index e30fd71e6..0925b4f58 100644 --- a/src/storage/dd/cudd/InternalCuddAdd.cpp +++ b/src/storage/dd/cudd/InternalCuddAdd.cpp @@ -230,7 +230,6 @@ namespace storm { if (numberOfDdVariables == 0) { return 0; } - std::cout << "num dd vars: " << numberOfDdVariables << std::endl; return static_cast<uint_fast64_t>(this->getCuddAdd().CountMinterm(static_cast<int>(numberOfDdVariables))); } From 08bed3657998244156ce5f7772876e9922b8c99f Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Wed, 24 Feb 2016 17:31:18 +0100 Subject: [PATCH 12/23] fixed an issue in performance tests and renamed all remaining LOG4CPLUS macro invocations to that of storm Former-commit-id: 8536943978e7313a9f9834d3f790973b7868e204 --- src/adapters/GmmxxAdapter.h | 4 +- src/counterexamples/GenerateCounterexample.h | 28 +++---- .../MILPMinimalLabelSetGenerator.h | 44 +++++----- .../PathBasedSubsystemGenerator.h | 42 +++++----- .../SMTMinimalCommandSetGenerator.h | 84 +++++++++---------- .../prctl/helper/SparseMdpPrctlHelper.cpp | 14 ++-- src/models/sparse/Dtmc.cpp | 6 +- .../AtomicPropositionLabelingParser.cpp | 14 ++-- src/parser/AutoParser.cpp | 2 +- .../DeterministicSparseTransitionParser.cpp | 32 +++---- src/parser/MappedFile.cpp | 14 ++-- src/parser/MarkovAutomatonParser.cpp | 2 +- .../MarkovAutomatonSparseTransitionParser.cpp | 20 ++--- ...NondeterministicSparseTransitionParser.cpp | 28 +++---- src/parser/SparseChoiceLabelingParser.cpp | 2 +- src/parser/SparseStateRewardParser.cpp | 8 +- src/solver/GmmxxLinearEquationSolver.cpp | 12 +-- .../GmmxxMinMaxLinearEquationSolver.cpp | 8 +- src/solver/GurobiLpSolver.cpp | 6 +- .../NativeMinMaxLinearEquationSolver.cpp | 8 +- .../TopologicalMinMaxLinearEquationSolver.cpp | 36 ++++---- src/utility/ErrorHandling.h | 12 +-- src/utility/cstring.cpp | 8 +- src/utility/graph.cpp | 6 +- .../GmmxxDtmcPrctModelCheckerTest.cpp | 2 +- .../NativeDtmcPrctlModelCheckerTest.cpp | 2 +- 26 files changed, 222 insertions(+), 222 deletions(-) diff --git a/src/adapters/GmmxxAdapter.h b/src/adapters/GmmxxAdapter.h index 320e57021..df81b46f7 100644 --- a/src/adapters/GmmxxAdapter.h +++ b/src/adapters/GmmxxAdapter.h @@ -34,7 +34,7 @@ public: template<class T> static std::unique_ptr<gmm::csr_matrix<T>> toGmmxxSparseMatrix(storm::storage::SparseMatrix<T> const& matrix) { uint_fast64_t realNonZeros = matrix.getEntryCount(); - LOG4CPLUS_DEBUG(logger, "Converting matrix with " << realNonZeros << " non-zeros to gmm++ format."); + STORM_LOG_DEBUG("Converting matrix with " << realNonZeros << " non-zeros to gmm++ format."); // Prepare the resulting matrix. std::unique_ptr<gmm::csr_matrix<T>> result(new gmm::csr_matrix<T>(matrix.getRowCount(), matrix.getColumnCount())); @@ -58,7 +58,7 @@ public: std::swap(result->ir, columns); std::swap(result->pr, values); - LOG4CPLUS_DEBUG(logger, "Done converting matrix to gmm++ format."); + STORM_LOG_DEBUG("Done converting matrix to gmm++ format."); return result; } diff --git a/src/counterexamples/GenerateCounterexample.h b/src/counterexamples/GenerateCounterexample.h index b111e16a8..f3b0e7ada 100644 --- a/src/counterexamples/GenerateCounterexample.h +++ b/src/counterexamples/GenerateCounterexample.h @@ -24,20 +24,20 @@ * @param parser An AutoParser to get the model from. */ void generateCounterExample(std::shared_ptr<storm::models::sparse::Model<double>> model) { - LOG4CPLUS_INFO(logger, "Starting counterexample generation."); - LOG4CPLUS_INFO(logger, "Testing inputs..."); + STORM_LOG_INFO("Starting counterexample generation."); + STORM_LOG_INFO("Testing inputs..."); storm::settings::SettingsManager* s = storm::settings::SettingsManager::getInstance(); // First test output directory. std::string outPath = s->getOptionByLongName("counterExample").getArgument(0).getValueAsString(); if(outPath.back() != '/' && outPath.back() != '\\') { - LOG4CPLUS_ERROR(logger, "The output path is not valid."); + STORM_LOG_ERROR("The output path is not valid."); return; } std::ofstream testFile(outPath + "test.dot"); if(testFile.fail()) { - LOG4CPLUS_ERROR(logger, "The output path is not valid."); + STORM_LOG_ERROR("The output path is not valid."); return; } testFile.close(); @@ -45,7 +45,7 @@ // Differentiate between model types. if(model->getType() != storm::models::DTMC) { - LOG4CPLUS_ERROR(logger, "Counterexample generation for the selected model type is not supported."); + STORM_LOG_ERROR("Counterexample generation for the selected model type is not supported."); return; } @@ -53,21 +53,21 @@ // Note that the ownership of the object referenced by dtmc lies at the main function. // Thus, it must not be deleted. storm::models::Dtmc<double> dtmc = *(model->as<storm::models::Dtmc<double>>()); - LOG4CPLUS_INFO(logger, "Model is a DTMC."); + STORM_LOG_INFO("Model is a DTMC."); // Get specified PRCTL formulas. if(!s->isSet("prctl")) { - LOG4CPLUS_ERROR(logger, "No PRCTL formula file specified."); + STORM_LOG_ERROR("No PRCTL formula file specified."); return; } std::string const chosenPrctlFile = s->getOptionByLongName("prctl").getArgument(0).getValueAsString(); - LOG4CPLUS_INFO(logger, "Parsing prctl file: " << chosenPrctlFile << "."); + STORM_LOG_INFO("Parsing prctl file: " << chosenPrctlFile << "."); std::list<std::shared_ptr<storm::properties::prctl::PrctlFilter<double>>> formulaList = storm::parser::PrctlFileParser::parsePrctlFile(chosenPrctlFile); // Test for each formula if a counterexample can be generated for it. if(formulaList.size() == 0) { - LOG4CPLUS_ERROR(logger, "No PRCTL formula found."); + STORM_LOG_ERROR("No PRCTL formula found."); return; } @@ -94,7 +94,7 @@ // First check if it is a formula type for which a counterexample can be generated. if (std::dynamic_pointer_cast<storm::properties::prctl::AbstractStateFormula<double>>(formula->getChild()).get() == nullptr) { - LOG4CPLUS_ERROR(logger, "Unexpected kind of formula. Expected a state formula."); + STORM_LOG_ERROR("Unexpected kind of formula. Expected a state formula."); continue; } @@ -102,9 +102,9 @@ // Do some output std::cout << "Generating counterexample for formula " << fIndex << ":" << std::endl; - LOG4CPLUS_INFO(logger, "Generating counterexample for formula " + std::to_string(fIndex) + ": "); + STORM_LOG_INFO("Generating counterexample for formula " + std::to_string(fIndex) + ": "); std::cout << "\t" << formula->toString() << "\n" << std::endl; - LOG4CPLUS_INFO(logger, formula->toString()); + STORM_LOG_INFO(formula->toString()); // Now check if the model does not satisfy the formula. // That is if there is at least one initial state of the model that does not. @@ -117,14 +117,14 @@ if((result & dtmc.getInitialStates()).getNumberOfSetBits() == dtmc.getInitialStates().getNumberOfSetBits()) { std::cout << "Formula is satisfied. Can not generate counterexample.\n\n" << std::endl; - LOG4CPLUS_INFO(logger, "Formula is satisfied. Can not generate counterexample."); + STORM_LOG_INFO("Formula is satisfied. Can not generate counterexample."); continue; } // Generate counterexample storm::models::Dtmc<double> counterExample = storm::counterexamples::PathBasedSubsystemGenerator<double>::computeCriticalSubsystem(dtmc, stateForm); - LOG4CPLUS_INFO(logger, "Found counterexample."); + STORM_LOG_INFO("Found counterexample."); // Output counterexample // Do standard output diff --git a/src/counterexamples/MILPMinimalLabelSetGenerator.h b/src/counterexamples/MILPMinimalLabelSetGenerator.h index 87f02c668..ffc398e34 100644 --- a/src/counterexamples/MILPMinimalLabelSetGenerator.h +++ b/src/counterexamples/MILPMinimalLabelSetGenerator.h @@ -98,10 +98,10 @@ namespace storm { result.relevantStates &= ~psiStates; result.problematicStates = storm::utility::graph::performProb0E(labeledMdp.getTransitionMatrix(), labeledMdp.getNondeterministicChoiceIndices(), labeledMdp.getBackwardTransitions(), phiStates, psiStates); result.problematicStates &= result.relevantStates; - LOG4CPLUS_DEBUG(logger, "Found " << phiStates.getNumberOfSetBits() << " filter states."); - LOG4CPLUS_DEBUG(logger, "Found " << psiStates.getNumberOfSetBits() << " target states."); - LOG4CPLUS_DEBUG(logger, "Found " << result.relevantStates.getNumberOfSetBits() << " relevant states."); - LOG4CPLUS_DEBUG(logger, "Found " << result.problematicStates.getNumberOfSetBits() << " problematic states."); + STORM_LOG_DEBUG("Found " << phiStates.getNumberOfSetBits() << " filter states."); + STORM_LOG_DEBUG("Found " << psiStates.getNumberOfSetBits() << " target states."); + STORM_LOG_DEBUG("Found " << result.relevantStates.getNumberOfSetBits() << " relevant states."); + STORM_LOG_DEBUG("Found " << result.problematicStates.getNumberOfSetBits() << " problematic states."); return result; } @@ -158,7 +158,7 @@ namespace storm { // Finally, determine the set of labels that are known to be taken. result.knownLabels = storm::utility::counterexamples::getGuaranteedLabelSet(labeledMdp, psiStates, result.allRelevantLabels); - LOG4CPLUS_DEBUG(logger, "Found " << result.allRelevantLabels.size() << " relevant labels and " << result.knownLabels.size() << " known labels."); + STORM_LOG_DEBUG("Found " << result.allRelevantLabels.size() << " relevant labels and " << result.knownLabels.size() << " known labels."); return result; } @@ -364,47 +364,47 @@ namespace storm { std::pair<std::unordered_map<uint_fast64_t, storm::expressions::Variable>, uint_fast64_t> labelVariableResult = createLabelVariables(solver, choiceInformation.allRelevantLabels); result.labelToVariableMap = std::move(labelVariableResult.first); result.numberOfVariables += labelVariableResult.second; - LOG4CPLUS_DEBUG(logger, "Created variables for labels."); + STORM_LOG_DEBUG("Created variables for labels."); // Create scheduler variables for relevant states and their actions. std::pair<std::unordered_map<uint_fast64_t, std::list<storm::expressions::Variable>>, uint_fast64_t> schedulerVariableResult = createSchedulerVariables(solver, stateInformation, choiceInformation); result.stateToChoiceVariablesMap = std::move(schedulerVariableResult.first); result.numberOfVariables += schedulerVariableResult.second; - LOG4CPLUS_DEBUG(logger, "Created variables for nondeterministic choices."); + STORM_LOG_DEBUG("Created variables for nondeterministic choices."); // Create scheduler variables for nondeterministically choosing an initial state. std::pair<std::unordered_map<uint_fast64_t, storm::expressions::Variable>, uint_fast64_t> initialChoiceVariableResult = createInitialChoiceVariables(solver, labeledMdp, stateInformation); result.initialStateToChoiceVariableMap = std::move(initialChoiceVariableResult.first); result.numberOfVariables += initialChoiceVariableResult.second; - LOG4CPLUS_DEBUG(logger, "Created variables for the nondeterministic choice of the initial state."); + STORM_LOG_DEBUG("Created variables for the nondeterministic choice of the initial state."); // Create variables for probabilities for all relevant states. std::pair<std::unordered_map<uint_fast64_t, storm::expressions::Variable>, uint_fast64_t> probabilityVariableResult = createProbabilityVariables(solver, stateInformation); result.stateToProbabilityVariableMap = std::move(probabilityVariableResult.first); result.numberOfVariables += probabilityVariableResult.second; - LOG4CPLUS_DEBUG(logger, "Created variables for the reachability probabilities."); + STORM_LOG_DEBUG("Created variables for the reachability probabilities."); // Create a probability variable for a virtual initial state that nondeterministically chooses one of the system's real initial states as its target state. std::pair<storm::expressions::Variable, uint_fast64_t> virtualInitialStateVariableResult = createVirtualInitialStateVariable(solver); result.virtualInitialStateVariable = virtualInitialStateVariableResult.first; result.numberOfVariables += virtualInitialStateVariableResult.second; - LOG4CPLUS_DEBUG(logger, "Created variables for the virtual initial state."); + STORM_LOG_DEBUG("Created variables for the virtual initial state."); // Create variables for problematic states. std::pair<std::unordered_map<uint_fast64_t, storm::expressions::Variable>, uint_fast64_t> problematicStateVariableResult = createProblematicStateVariables(solver, labeledMdp, stateInformation, choiceInformation); result.problematicStateToVariableMap = std::move(problematicStateVariableResult.first); result.numberOfVariables += problematicStateVariableResult.second; - LOG4CPLUS_DEBUG(logger, "Created variables for the problematic states."); + STORM_LOG_DEBUG("Created variables for the problematic states."); // Create variables for problematic choices. std::pair<std::unordered_map<std::pair<uint_fast64_t, uint_fast64_t>, storm::expressions::Variable, PairHash>, uint_fast64_t> problematicTransitionVariableResult = createProblematicChoiceVariables(solver, labeledMdp, stateInformation, choiceInformation); result.problematicTransitionToVariableMap = problematicTransitionVariableResult.first; result.numberOfVariables += problematicTransitionVariableResult.second; - LOG4CPLUS_DEBUG(logger, "Created variables for the problematic choices."); + STORM_LOG_DEBUG("Created variables for the problematic choices."); // Finally, we need to update the model to make the new variables usable. solver.update(); - LOG4CPLUS_INFO(logger, "Successfully created " << result.numberOfVariables << " MILP variables."); + STORM_LOG_INFO("Successfully created " << result.numberOfVariables << " MILP variables."); // Finally, return variable information struct. return result; @@ -816,43 +816,43 @@ namespace storm { static void buildConstraintSystem(storm::solver::LpSolver& solver, storm::models::sparse::Mdp<T> const& labeledMdp, storm::storage::BitVector const& psiStates, StateInformation const& stateInformation, ChoiceInformation const& choiceInformation, VariableInformation const& variableInformation, double probabilityThreshold, bool strictBound, bool includeSchedulerCuts = false) { // Assert that the reachability probability in the subsystem exceeds the given threshold. uint_fast64_t numberOfConstraints = assertProbabilityGreaterThanThreshold(solver, labeledMdp, variableInformation, probabilityThreshold, strictBound); - LOG4CPLUS_DEBUG(logger, "Asserted that reachability probability exceeds threshold."); + STORM_LOG_DEBUG("Asserted that reachability probability exceeds threshold."); // Add constraints that assert the policy takes at most one action in each state. numberOfConstraints += assertValidPolicy(solver, stateInformation, variableInformation); - LOG4CPLUS_DEBUG(logger, "Asserted that policy is valid."); + STORM_LOG_DEBUG("Asserted that policy is valid."); // Add constraints that assert the labels that belong to some taken choices are taken as well. numberOfConstraints += assertChoicesImplyLabels(solver, labeledMdp, stateInformation, choiceInformation, variableInformation); - LOG4CPLUS_DEBUG(logger, "Asserted that labels implied by choices are taken."); + STORM_LOG_DEBUG("Asserted that labels implied by choices are taken."); // Add constraints that encode that the reachability probability from states which do not pick any action // is zero. numberOfConstraints += assertZeroProbabilityWithoutChoice(solver, stateInformation, choiceInformation, variableInformation); - LOG4CPLUS_DEBUG(logger, "Asserted that reachability probability is zero if no choice is taken."); + STORM_LOG_DEBUG("Asserted that reachability probability is zero if no choice is taken."); // Add constraints that encode the reachability probabilities for states. numberOfConstraints += assertReachabilityProbabilities(solver, labeledMdp, psiStates, stateInformation, choiceInformation, variableInformation); - LOG4CPLUS_DEBUG(logger, "Asserted constraints for reachability probabilities."); + STORM_LOG_DEBUG("Asserted constraints for reachability probabilities."); // Add constraints that ensure the reachability of an unproblematic state from each problematic state. numberOfConstraints += assertUnproblematicStateReachable(solver, labeledMdp, stateInformation, choiceInformation, variableInformation); - LOG4CPLUS_DEBUG(logger, "Asserted that unproblematic state reachable from problematic states."); + STORM_LOG_DEBUG("Asserted that unproblematic state reachable from problematic states."); // Add constraints that express that certain labels are already known to be taken. numberOfConstraints += assertKnownLabels(solver, labeledMdp, psiStates, choiceInformation, variableInformation); - LOG4CPLUS_DEBUG(logger, "Asserted known labels are taken."); + STORM_LOG_DEBUG("Asserted known labels are taken."); // If required, assert additional constraints that reduce the number of possible policies. if (includeSchedulerCuts) { numberOfConstraints += assertSchedulerCuts(solver, labeledMdp, psiStates, stateInformation, choiceInformation, variableInformation); - LOG4CPLUS_DEBUG(logger, "Asserted scheduler cuts."); + STORM_LOG_DEBUG("Asserted scheduler cuts."); } // Finally, we can tell the solver to incorporate the latest changes. solver.update(); - LOG4CPLUS_INFO(logger, "Successfully created " << numberOfConstraints << " MILP constraints."); + STORM_LOG_INFO("Successfully created " << numberOfConstraints << " MILP constraints."); } /*! diff --git a/src/counterexamples/PathBasedSubsystemGenerator.h b/src/counterexamples/PathBasedSubsystemGenerator.h index 465ee5608..6061e9449 100644 --- a/src/counterexamples/PathBasedSubsystemGenerator.h +++ b/src/counterexamples/PathBasedSubsystemGenerator.h @@ -100,7 +100,7 @@ public: } } - LOG4CPLUS_DEBUG(logger, "Initialized."); + STORM_LOG_DEBUG("Initialized."); //Now find the shortest distances to all states while(!activeSet.empty()) { @@ -151,7 +151,7 @@ public: } } - LOG4CPLUS_DEBUG(logger, "Discovery done."); + STORM_LOG_DEBUG("Discovery done."); } /*! @@ -215,7 +215,7 @@ public: } } - LOG4CPLUS_DEBUG(logger, "Initialized."); + STORM_LOG_DEBUG("Initialized."); //Now find the shortest distances to all states while(!activeSet.empty()) { @@ -269,7 +269,7 @@ public: } } - LOG4CPLUS_DEBUG(logger, "Discovery done."); + STORM_LOG_DEBUG("Discovery done."); } /*! @@ -324,7 +324,7 @@ public: if(distances[bestIndex].second == (T) -1){ shortestPath.push_back(bestIndex); probability = (T) 0; - LOG4CPLUS_DEBUG(logger, "Terminal state not viable!"); + STORM_LOG_DEBUG("Terminal state not viable!"); return; } @@ -338,8 +338,8 @@ public: bestIndex = distances[bestIndex].first; } - LOG4CPLUS_DEBUG(logger, "Found best state: " << bestIndex); - LOG4CPLUS_DEBUG(logger, "Value: " << bestValue); + STORM_LOG_DEBUG("Found best state: " << bestIndex); + STORM_LOG_DEBUG("Value: " << bestValue); shortestPath.push_back(bestIndex); bestIndex = distances[bestIndex].first; @@ -382,9 +382,9 @@ public: //------------------------------------------------------------- #ifdef BENCHMARK - LOG4CPLUS_INFO(logger, "Formula: " << stateFormula.toString()); + STORM_LOG_INFO("Formula: " << stateFormula.toString()); #endif - LOG4CPLUS_INFO(logger, "Start finding critical subsystem."); + STORM_LOG_INFO("Start finding critical subsystem."); // make model checker // TODO: Implement and use generic Model Checker factory. @@ -397,7 +397,7 @@ public: std::shared_ptr<storm::properties::prctl::ProbabilisticBoundOperator<T>> boundOperator = std::dynamic_pointer_cast<storm::properties::prctl::ProbabilisticBoundOperator<T>>(stateFormula); if(boundOperator == nullptr){ - LOG4CPLUS_ERROR(logger, "No path bound operator at formula root."); + STORM_LOG_ERROR("No path bound operator at formula root."); return model.getSubDtmc(subSys); } T bound = boundOperator->getBound(); @@ -440,7 +440,7 @@ public: targetStates = until->getRight()->check(modelCheck); } else { - LOG4CPLUS_ERROR(logger, "Strange path formula. Can't decipher."); + STORM_LOG_ERROR("Strange path formula. Can't decipher."); return model.getSubDtmc(subSys); } @@ -476,11 +476,11 @@ public: if((initStates & targetStates).getNumberOfSetBits() != 0) { subSys.set(*(initStates & targetStates).begin()); - LOG4CPLUS_INFO(logger, "Critical subsystem found."); - LOG4CPLUS_INFO(logger, "Paths needed: " << pathCount); - LOG4CPLUS_INFO(logger, "State count of critical subsystem: " << subSys.getNumberOfSetBits()); - LOG4CPLUS_INFO(logger, "Prob: " << 1); - LOG4CPLUS_INFO(logger, "Model checks: " << mcCount); + STORM_LOG_INFO("Critical subsystem found."); + STORM_LOG_INFO("Paths needed: " << pathCount); + STORM_LOG_INFO("State count of critical subsystem: " << subSys.getNumberOfSetBits()); + STORM_LOG_INFO("Prob: " << 1); + STORM_LOG_INFO("Model checks: " << mcCount); return model.getSubDtmc(subSys); } @@ -555,11 +555,11 @@ public: } } - LOG4CPLUS_INFO(logger, "Critical subsystem found."); - LOG4CPLUS_INFO(logger, "Paths needed: " << pathCount); - LOG4CPLUS_INFO(logger, "State count of critical subsystem: " << subSys.getNumberOfSetBits()); - LOG4CPLUS_INFO(logger, "Prob: " << subSysProb); - LOG4CPLUS_INFO(logger, "Model checks: " << mcCount); + STORM_LOG_INFO("Critical subsystem found."); + STORM_LOG_INFO("Paths needed: " << pathCount); + STORM_LOG_INFO("State count of critical subsystem: " << subSys.getNumberOfSetBits()); + STORM_LOG_INFO("Prob: " << subSysProb); + STORM_LOG_INFO("Model checks: " << mcCount); return model.getSubDtmc(subSys); } diff --git a/src/counterexamples/SMTMinimalCommandSetGenerator.h b/src/counterexamples/SMTMinimalCommandSetGenerator.h index 3f03440d3..f7a2704b5 100644 --- a/src/counterexamples/SMTMinimalCommandSetGenerator.h +++ b/src/counterexamples/SMTMinimalCommandSetGenerator.h @@ -99,8 +99,8 @@ namespace storm { relevancyInformation.relevantStates = storm::utility::graph::performProbGreater0E(labeledMdp.getTransitionMatrix(), labeledMdp.getNondeterministicChoiceIndices(), backwardTransitions, phiStates, psiStates); relevancyInformation.relevantStates &= ~psiStates; - LOG4CPLUS_DEBUG(logger, "Found " << relevancyInformation.relevantStates.getNumberOfSetBits() << " relevant states."); - LOG4CPLUS_DEBUG(logger, relevancyInformation.relevantStates); + STORM_LOG_DEBUG("Found " << relevancyInformation.relevantStates.getNumberOfSetBits() << " relevant states."); + STORM_LOG_DEBUG(relevancyInformation.relevantStates); // Retrieve some references for convenient access. storm::storage::SparseMatrix<T> const& transitionMatrix = labeledMdp.getTransitionMatrix(); @@ -141,7 +141,7 @@ namespace storm { std::cout << "Found " << relevancyInformation.relevantLabels.size() << " relevant and " << relevancyInformation.knownLabels.size() << " known labels." << std::endl; - LOG4CPLUS_DEBUG(logger, "Found " << relevancyInformation.relevantLabels.size() << " relevant and " << relevancyInformation.knownLabels.size() << " known labels."); + STORM_LOG_DEBUG("Found " << relevancyInformation.relevantLabels.size() << " relevant and " << relevancyInformation.knownLabels.size() << " known labels."); return relevancyInformation; } @@ -350,9 +350,9 @@ namespace storm { } } - LOG4CPLUS_DEBUG(logger, "Successfully gathered data for explicit cuts."); + STORM_LOG_DEBUG("Successfully gathered data for explicit cuts."); - LOG4CPLUS_DEBUG(logger, "Asserting initial combination is taken."); + STORM_LOG_DEBUG("Asserting initial combination is taken."); { std::vector<storm::expressions::Expression> formulae; @@ -378,7 +378,7 @@ namespace storm { } } - LOG4CPLUS_DEBUG(logger, "Asserting target combination is taken."); + STORM_LOG_DEBUG("Asserting target combination is taken."); { std::vector<storm::expressions::Expression> formulae; @@ -414,7 +414,7 @@ namespace storm { } } - LOG4CPLUS_DEBUG(logger, "Asserting taken labels are followed by another label if they are not a target label."); + STORM_LOG_DEBUG("Asserting taken labels are followed by another label if they are not a target label."); // Now assert that for each non-target label, we take a following label. for (auto const& labelSetFollowingSetsPair : followingLabels) { std::vector<storm::expressions::Expression> formulae; @@ -502,7 +502,7 @@ namespace storm { } } - LOG4CPLUS_DEBUG(logger, "Asserting synchronization cuts."); + STORM_LOG_DEBUG("Asserting synchronization cuts."); // Finally, assert that if we take one of the synchronizing labels, we also take one of the combinations // the label appears in. for (auto const& labelSynchronizingSetsPair : synchronizingLabels) { @@ -667,7 +667,7 @@ namespace storm { // If the solver reports unsat, then we know that the current selection is not enabled in the initial state. if (checkResult == storm::solver::SmtSolver::CheckResult::Unsat) { - LOG4CPLUS_DEBUG(logger, "Selection not enabled in initial state."); + STORM_LOG_DEBUG("Selection not enabled in initial state."); storm::expressions::Expression guardConjunction; if (currentCommandVector.size() == 1) { guardConjunction = currentCommandVector.begin()->get().getGuardExpression(); @@ -685,10 +685,10 @@ namespace storm { } } else { throw storm::exceptions::InvalidStateException() << "Choice label set is empty."; - LOG4CPLUS_DEBUG(logger, "Choice label set is empty."); + STORM_LOG_DEBUG("Choice label set is empty."); } - LOG4CPLUS_DEBUG(logger, "About to assert disjunction of negated guards."); + STORM_LOG_DEBUG("About to assert disjunction of negated guards."); storm::expressions::Expression guardExpression = localManager.boolean(false); bool firstAssignment = true; for (auto const& command : currentCommandVector) { @@ -699,7 +699,7 @@ namespace storm { } } localSolver->add(guardExpression); - LOG4CPLUS_DEBUG(logger, "Asserted disjunction of negated guards."); + STORM_LOG_DEBUG("Asserted disjunction of negated guards."); // Now check the possible preceding label sets for the essential ones. for (auto const& precedingLabelSet : labelSetAndPrecedingLabelSetsPair.second) { @@ -742,10 +742,10 @@ namespace storm { } } - LOG4CPLUS_DEBUG(logger, "About to assert a weakest precondition."); + STORM_LOG_DEBUG("About to assert a weakest precondition."); storm::expressions::Expression wp = guardConjunction.substitute(currentUpdateCombinationMap); formulae.push_back(wp); - LOG4CPLUS_DEBUG(logger, "Asserted weakest precondition."); + STORM_LOG_DEBUG("Asserted weakest precondition."); // Now try to move iterators to the next position if possible. If we could properly move it, we can directly // move on to the next combination of updates. If we have to reset it to the start, we @@ -768,7 +768,7 @@ namespace storm { // Now assert the disjunction of all weakest preconditions of all considered update combinations. assertDisjunction(*localSolver, formulae, localManager); - LOG4CPLUS_DEBUG(logger, "Asserted disjunction of all weakest preconditions."); + STORM_LOG_DEBUG("Asserted disjunction of all weakest preconditions."); if (localSolver->check() == storm::solver::SmtSolver::CheckResult::Sat) { backwardImplications[labelSetAndPrecedingLabelSetsPair.first].insert(precedingLabelSet); @@ -793,7 +793,7 @@ namespace storm { } } - LOG4CPLUS_DEBUG(logger, "Asserting taken labels are preceded by another label if they are not an initial label."); + STORM_LOG_DEBUG("Asserting taken labels are preceded by another label if they are not an initial label."); // Now assert that for each non-target label, we take a following label. for (auto const& labelSetImplicationsPair : backwardImplications) { std::vector<storm::expressions::Expression> formulae; @@ -1042,7 +1042,7 @@ namespace storm { static std::vector<storm::expressions::Expression> createAdder(VariableInformation const& variableInformation, std::vector<storm::expressions::Expression> const& in1, std::vector<storm::expressions::Expression> const& in2) { // Sanity check for sizes of input. if (in1.size() != in2.size() || in1.size() == 0) { - LOG4CPLUS_ERROR(logger, "Illegal input to adder (" << in1.size() << ", " << in2.size() << ")."); + STORM_LOG_ERROR("Illegal input to adder (" << in1.size() << ", " << in2.size() << ")."); throw storm::exceptions::InvalidArgumentException() << "Illegal input to adder."; } @@ -1097,7 +1097,7 @@ namespace storm { * @return A bit vector representing the number of literals that are set to true. */ static std::vector<storm::expressions::Expression> createCounterCircuit(VariableInformation const& variableInformation, std::vector<storm::expressions::Variable> const& literals) { - LOG4CPLUS_DEBUG(logger, "Creating counter circuit for " << literals.size() << " literals."); + STORM_LOG_DEBUG("Creating counter circuit for " << literals.size() << " literals."); // Create the auxiliary vector. std::vector<std::vector<storm::expressions::Expression>> aux; @@ -1136,7 +1136,7 @@ namespace storm { * @return The relaxation variable associated with the constraint. */ static storm::expressions::Variable assertLessOrEqualKRelaxed(storm::solver::SmtSolver& solver, VariableInformation const& variableInformation, uint64_t k) { - LOG4CPLUS_DEBUG(logger, "Asserting solution has size less or equal " << k << "."); + STORM_LOG_DEBUG("Asserting solution has size less or equal " << k << "."); std::vector<storm::expressions::Variable> const& input = variableInformation.adderVariables; @@ -1209,16 +1209,16 @@ namespace storm { } // Check whether the assumptions are satisfiable. - LOG4CPLUS_DEBUG(logger, "Invoking satisfiability checking."); + STORM_LOG_DEBUG("Invoking satisfiability checking."); z3::check_result result = solver.check(assumptions); - LOG4CPLUS_DEBUG(logger, "Done invoking satisfiability checking."); + STORM_LOG_DEBUG("Done invoking satisfiability checking."); if (result == z3::sat) { return true; } else { - LOG4CPLUS_DEBUG(logger, "Computing unsat core."); + STORM_LOG_DEBUG("Computing unsat core."); z3::expr_vector unsatCore = solver.unsat_core(); - LOG4CPLUS_DEBUG(logger, "Computed unsat core."); + STORM_LOG_DEBUG("Computed unsat core."); std::vector<z3::expr> blockingVariables; blockingVariables.reserve(unsatCore.size()); @@ -1334,7 +1334,7 @@ namespace storm { // As long as the constraints are unsatisfiable, we need to relax the last at-most-k constraint and // try with an increased bound. while (solver.checkWithAssumptions({assumption}) == storm::solver::SmtSolver::CheckResult::Unsat) { - LOG4CPLUS_DEBUG(logger, "Constraint system is unsatisfiable with at most " << currentBound << " taken commands; increasing bound."); + STORM_LOG_DEBUG("Constraint system is unsatisfiable with at most " << currentBound << " taken commands; increasing bound."); solver.add(variableInformation.auxiliaryVariables.back()); variableInformation.auxiliaryVariables.push_back(assertLessOrEqualKRelaxed(solver, variableInformation, ++currentBound)); assumption = !variableInformation.auxiliaryVariables.back(); @@ -1359,7 +1359,7 @@ namespace storm { static void analyzeZeroProbabilitySolution(storm::solver::SmtSolver& solver, storm::models::sparse::Mdp<T> const& subMdp, storm::models::sparse::Mdp<T> const& originalMdp, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, boost::container::flat_set<uint_fast64_t> const& commandSet, VariableInformation& variableInformation, RelevancyInformation const& relevancyInformation) { storm::storage::BitVector reachableStates(subMdp.getNumberOfStates()); - LOG4CPLUS_DEBUG(logger, "Analyzing solution with zero probability."); + STORM_LOG_DEBUG("Analyzing solution with zero probability."); // Initialize the stack for the DFS. bool targetStateIsReachable = false; @@ -1403,10 +1403,10 @@ namespace storm { } } - LOG4CPLUS_DEBUG(logger, "Successfully performed reachability analysis."); + STORM_LOG_DEBUG("Successfully performed reachability analysis."); if (targetStateIsReachable) { - LOG4CPLUS_ERROR(logger, "Target must be unreachable for this analysis."); + STORM_LOG_ERROR("Target must be unreachable for this analysis."); throw storm::exceptions::InvalidStateException() << "Target must be unreachable for this analysis."; } @@ -1417,7 +1417,7 @@ namespace storm { std::set_difference(relevancyInformation.relevantLabels.begin(), relevancyInformation.relevantLabels.end(), commandSet.begin(), commandSet.end(), std::inserter(locallyRelevantLabels, locallyRelevantLabels.begin())); std::vector<boost::container::flat_set<uint_fast64_t>> guaranteedLabelSets = storm::utility::counterexamples::getGuaranteedLabelSets(originalMdp, statesThatCanReachTargetStates, locallyRelevantLabels); - LOG4CPLUS_DEBUG(logger, "Found " << reachableLabels.size() << " reachable labels and " << reachableStates.getNumberOfSetBits() << " reachable states."); + STORM_LOG_DEBUG("Found " << reachableLabels.size() << " reachable labels and " << reachableStates.getNumberOfSetBits() << " reachable states."); // Search for states on the border of the reachable state space, i.e. states that are still reachable // and possess a (disabled) option to leave the reachable part of the state space. @@ -1466,7 +1466,7 @@ namespace storm { formulae.push_back(cube); } - LOG4CPLUS_DEBUG(logger, "Asserting reachability implications."); + STORM_LOG_DEBUG("Asserting reachability implications."); assertDisjunction(solver, formulae, *variableInformation.manager); } @@ -1484,7 +1484,7 @@ namespace storm { */ static void analyzeInsufficientProbabilitySolution(storm::solver::SmtSolver& solver, storm::models::sparse::Mdp<T> const& subMdp, storm::models::sparse::Mdp<T> const& originalMdp, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, boost::container::flat_set<uint_fast64_t> const& commandSet, VariableInformation& variableInformation, RelevancyInformation const& relevancyInformation) { - LOG4CPLUS_DEBUG(logger, "Analyzing solution with insufficient probability."); + STORM_LOG_DEBUG("Analyzing solution with insufficient probability."); storm::storage::BitVector reachableStates(subMdp.getNumberOfStates()); @@ -1529,7 +1529,7 @@ namespace storm { } } } - LOG4CPLUS_DEBUG(logger, "Successfully determined reachable state space."); + STORM_LOG_DEBUG("Successfully determined reachable state space."); storm::storage::BitVector unreachableRelevantStates = ~reachableStates & relevancyInformation.relevantStates; storm::storage::BitVector statesThatCanReachTargetStates = storm::utility::graph::performProbGreater0E(subMdp.getTransitionMatrix(), subMdp.getNondeterministicChoiceIndices(), subMdp.getBackwardTransitions(), phiStates, psiStates); @@ -1574,7 +1574,7 @@ namespace storm { formulae.push_back(cube); } - LOG4CPLUS_DEBUG(logger, "Asserting reachability implications."); + STORM_LOG_DEBUG("Asserting reachability implications."); assertDisjunction(solver, formulae, *variableInformation.manager); } #endif @@ -1627,7 +1627,7 @@ namespace storm { double maximalReachabilityProbability = 0; if (checkThresholdFeasible) { storm::modelchecker::helper::SparseMdpPrctlHelper<T> modelCheckerHelper; - LOG4CPLUS_DEBUG(logger, "Invoking model checker."); + STORM_LOG_DEBUG("Invoking model checker."); std::vector<T> result = std::move(modelCheckerHelper.computeUntilProbabilities(false, labeledMdp.getTransitionMatrix(), labeledMdp.getBackwardTransitions(), phiStates, psiStates, false, false, storm::utility::solver::MinMaxLinearEquationSolverFactory<T>()).values); for (auto state : labeledMdp.getInitialStates()) { maximalReachabilityProbability = std::max(maximalReachabilityProbability, result[state]); @@ -1645,7 +1645,7 @@ namespace storm { // (4) Create the variables for the relevant commands. VariableInformation variableInformation = createVariables(manager, labeledMdp, psiStates, relevancyInformation, includeReachabilityEncoding); - LOG4CPLUS_DEBUG(logger, "Created variables."); + STORM_LOG_DEBUG("Created variables."); // (5) Now assert an adder whose result variables can later be used to constrain the nummber of label // variables that were set to true. Initially, we are looking for a solution that has no label enabled @@ -1654,14 +1654,14 @@ namespace storm { variableInformation.auxiliaryVariables.push_back(assertLessOrEqualKRelaxed(*solver, variableInformation, 0)); // (6) Add constraints that cut off a lot of suboptimal solutions. - LOG4CPLUS_DEBUG(logger, "Asserting cuts."); + STORM_LOG_DEBUG("Asserting cuts."); assertExplicitCuts(labeledMdp, psiStates, variableInformation, relevancyInformation, *solver); - LOG4CPLUS_DEBUG(logger, "Asserted explicit cuts."); + STORM_LOG_DEBUG("Asserted explicit cuts."); assertSymbolicCuts(preparedProgram, labeledMdp, variableInformation, relevancyInformation, *solver); - LOG4CPLUS_DEBUG(logger, "Asserted symbolic cuts."); + STORM_LOG_DEBUG("Asserted symbolic cuts."); if (includeReachabilityEncoding) { assertReachabilityCuts(labeledMdp, psiStates, variableInformation, relevancyInformation, *solver); - LOG4CPLUS_DEBUG(logger, "Asserted reachability cuts."); + STORM_LOG_DEBUG("Asserted reachability cuts."); } // As we are done with the setup at this point, stop the clock for the setup time. @@ -1680,20 +1680,20 @@ namespace storm { maximalReachabilityProbability = 0; uint_fast64_t zeroProbabilityCount = 0; do { - LOG4CPLUS_DEBUG(logger, "Computing minimal command set."); + STORM_LOG_DEBUG("Computing minimal command set."); solverClock = std::chrono::high_resolution_clock::now(); commandSet = findSmallestCommandSet(*solver, variableInformation, currentBound); totalSolverTime += std::chrono::high_resolution_clock::now() - solverClock; - LOG4CPLUS_DEBUG(logger, "Computed minimal command set of size " << (commandSet.size() + relevancyInformation.knownLabels.size()) << "."); + STORM_LOG_DEBUG("Computed minimal command set of size " << (commandSet.size() + relevancyInformation.knownLabels.size()) << "."); // Restrict the given MDP to the current set of labels and compute the reachability probability. modelCheckingClock = std::chrono::high_resolution_clock::now(); commandSet.insert(relevancyInformation.knownLabels.begin(), relevancyInformation.knownLabels.end()); storm::models::sparse::Mdp<T> subMdp = labeledMdp.restrictChoiceLabels(commandSet); storm::modelchecker::helper::SparseMdpPrctlHelper<T> modelCheckerHelper; - LOG4CPLUS_DEBUG(logger, "Invoking model checker."); + STORM_LOG_DEBUG("Invoking model checker."); std::vector<T> result = std::move(modelCheckerHelper.computeUntilProbabilities(false, subMdp.getTransitionMatrix(), subMdp.getBackwardTransitions(), phiStates, psiStates, false, false, storm::utility::solver::MinMaxLinearEquationSolverFactory<T>()).values); - LOG4CPLUS_DEBUG(logger, "Computed model checking results."); + STORM_LOG_DEBUG("Computed model checking results."); totalModelCheckingTime += std::chrono::high_resolution_clock::now() - modelCheckingClock; // Now determine the maximal reachability probability by checking all initial states. diff --git a/src/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp b/src/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp index adec586dd..09cac3521 100644 --- a/src/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp +++ b/src/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp @@ -87,9 +87,9 @@ namespace storm { storm::storage::BitVector statesWithProbability0 = std::move(statesWithProbability01.first); storm::storage::BitVector statesWithProbability1 = std::move(statesWithProbability01.second); storm::storage::BitVector maybeStates = ~(statesWithProbability0 | statesWithProbability1); - LOG4CPLUS_INFO(logger, "Found " << statesWithProbability0.getNumberOfSetBits() << " 'no' states."); - LOG4CPLUS_INFO(logger, "Found " << statesWithProbability1.getNumberOfSetBits() << " 'yes' states."); - LOG4CPLUS_INFO(logger, "Found " << maybeStates.getNumberOfSetBits() << " 'maybe' states."); + STORM_LOG_INFO("Found " << statesWithProbability0.getNumberOfSetBits() << " 'no' states."); + STORM_LOG_INFO("Found " << statesWithProbability1.getNumberOfSetBits() << " 'yes' states."); + STORM_LOG_INFO("Found " << maybeStates.getNumberOfSetBits() << " 'maybe' states."); // Create resulting vector. std::vector<ValueType> result(transitionMatrix.getRowGroupCount()); @@ -287,16 +287,16 @@ namespace storm { } infinityStates.complement(); storm::storage::BitVector maybeStates = ~targetStates & ~infinityStates; - LOG4CPLUS_INFO(logger, "Found " << infinityStates.getNumberOfSetBits() << " 'infinity' states."); - LOG4CPLUS_INFO(logger, "Found " << targetStates.getNumberOfSetBits() << " 'target' states."); - LOG4CPLUS_INFO(logger, "Found " << maybeStates.getNumberOfSetBits() << " 'maybe' states."); + STORM_LOG_INFO("Found " << infinityStates.getNumberOfSetBits() << " 'infinity' states."); + STORM_LOG_INFO("Found " << targetStates.getNumberOfSetBits() << " 'target' states."); + STORM_LOG_INFO("Found " << maybeStates.getNumberOfSetBits() << " 'maybe' states."); // Create resulting vector. std::vector<ValueType> result(transitionMatrix.getRowGroupCount(), storm::utility::zero<ValueType>()); // Check whether we need to compute exact rewards for some states. if (qualitative) { - LOG4CPLUS_INFO(logger, "The rewards for the initial states were determined in a preprocessing step. No exact rewards were computed."); + STORM_LOG_INFO("The rewards for the initial states were determined in a preprocessing step. No exact rewards were computed."); // Set the values for all maybe-states to 1 to indicate that their reward values // are neither 0 nor infinity. storm::utility::vector::setVectorValues<ValueType>(result, maybeStates, storm::utility::one<ValueType>()); diff --git a/src/models/sparse/Dtmc.cpp b/src/models/sparse/Dtmc.cpp index 31c222207..cbfeed391 100644 --- a/src/models/sparse/Dtmc.cpp +++ b/src/models/sparse/Dtmc.cpp @@ -33,7 +33,7 @@ namespace storm { // // // Is there any state in the subsystem? // if(subSysStates.getNumberOfSetBits() == 0) { - // LOG4CPLUS_ERROR(logger, "No states in subsystem!"); + // STORM_LOG_ERROR("No states in subsystem!"); // return storm::models::Dtmc<ValueType>(storm::storage::SparseMatrix<ValueType>(), // storm::models::sparse::StateLabeling(this->getStateLabeling(), subSysStates), // boost::optional<std::vector<ValueType>>(), @@ -43,13 +43,13 @@ namespace storm { // // // Does the vector have the right size? // if(subSysStates.size() != this->getNumberOfStates()) { - // LOG4CPLUS_INFO(logger, "BitVector has wrong size. Resizing it..."); + // STORM_LOG_INFO("BitVector has wrong size. Resizing it..."); // subSysStates.resize(this->getNumberOfStates()); // } // // // Test if it is a proper subsystem of this Dtmc, i.e. if there is at least one state to be left out. // if(subSysStates.getNumberOfSetBits() == subSysStates.size()) { - // LOG4CPLUS_INFO(logger, "All states are kept. This is no proper subsystem."); + // STORM_LOG_INFO("All states are kept. This is no proper subsystem."); // return storm::models::Dtmc<ValueType>(*this); // } // diff --git a/src/parser/AtomicPropositionLabelingParser.cpp b/src/parser/AtomicPropositionLabelingParser.cpp index 8e51fb305..349bfb56b 100644 --- a/src/parser/AtomicPropositionLabelingParser.cpp +++ b/src/parser/AtomicPropositionLabelingParser.cpp @@ -29,7 +29,7 @@ namespace storm { // Open the given file. if (!MappedFile::fileExistsAndIsReadable(filename.c_str())) { - LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": The supplied Labeling input file does not exist or is not readable by this process."); + STORM_LOG_ERROR("Error while parsing " << filename << ": The supplied Labeling input file does not exist or is not readable by this process."); throw storm::exceptions::FileIoException() << "Error while parsing " << filename << ": The supplied Labeling input file does not exist or is not readable by this process."; } @@ -68,9 +68,9 @@ namespace storm { // If #DECLARATION or #END have not been found, the file format is wrong. if (!(foundDecl && foundEnd)) { - LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": File header is corrupted (#DECLARATION or #END missing - case sensitive)."); - if (!foundDecl) LOG4CPLUS_ERROR(logger, "\tDid not find #DECLARATION token."); - if (!foundEnd) LOG4CPLUS_ERROR(logger, "\tDid not find #END token."); + STORM_LOG_ERROR("Error while parsing " << filename << ": File header is corrupted (#DECLARATION or #END missing - case sensitive)."); + if (!foundDecl) STORM_LOG_ERROR("\tDid not find #DECLARATION token."); + if (!foundEnd) STORM_LOG_ERROR("\tDid not find #END token."); throw storm::exceptions::WrongFormatException() << "Error while parsing " << filename << ": File header is corrupted (#DECLARATION or #END missing - case sensitive)."; } @@ -99,7 +99,7 @@ namespace storm { if (cnt >= sizeof(proposition)) { // if token is longer than our buffer, the following strncpy code might get risky... - LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": Atomic proposition with length > " << (sizeof(proposition) - 1) << " was found."); + STORM_LOG_ERROR("Error while parsing " << filename << ": Atomic proposition with length > " << (sizeof(proposition) - 1) << " was found."); throw storm::exceptions::WrongFormatException() << "Error while parsing " << filename << ": Atomic proposition with length > " << (sizeof(proposition) - 1) << " was found."; } else if (cnt > 0) { @@ -138,7 +138,7 @@ namespace storm { // If the state has already been read or skipped once there might be a problem with the file (doubled lines, or blocks). if (state <= lastState && lastState != startIndexComparison) { - LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": State " << state << " was found but has already been read or skipped previously."); + STORM_LOG_ERROR("Error while parsing " << filename << ": State " << state << " was found but has already been read or skipped previously."); throw storm::exceptions::WrongFormatException() << "Error while parsing " << filename << ": State " << state << " was found but has already been read or skipped previously."; } @@ -159,7 +159,7 @@ namespace storm { // Has the label been declared in the header? if(!labeling.containsLabel(proposition)) { - LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": Atomic proposition" << proposition << " was found but not declared."); + STORM_LOG_ERROR("Error while parsing " << filename << ": Atomic proposition" << proposition << " was found but not declared."); throw storm::exceptions::WrongFormatException() << "Error while parsing " << filename << ": Atomic proposition" << proposition << " was found but not declared."; } labeling.addLabelToState(proposition, state); diff --git a/src/parser/AutoParser.cpp b/src/parser/AutoParser.cpp index 2ec30fb64..6f3c60c46 100644 --- a/src/parser/AutoParser.cpp +++ b/src/parser/AutoParser.cpp @@ -54,7 +54,7 @@ namespace storm { break; } default: - LOG4CPLUS_WARN(logger, "Unknown/Unhandled Model Type which cannot be parsed."); // Unknown + STORM_LOG_WARN("Unknown/Unhandled Model Type which cannot be parsed."); // Unknown } return model; diff --git a/src/parser/DeterministicSparseTransitionParser.cpp b/src/parser/DeterministicSparseTransitionParser.cpp index 94b82a4c7..f18b46441 100644 --- a/src/parser/DeterministicSparseTransitionParser.cpp +++ b/src/parser/DeterministicSparseTransitionParser.cpp @@ -46,7 +46,7 @@ namespace storm { setlocale(LC_NUMERIC, "C"); if (!MappedFile::fileExistsAndIsReadable(filename.c_str())) { - LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": File does not exist or is not readable."); + STORM_LOG_ERROR("Error while parsing " << filename << ": File does not exist or is not readable."); throw storm::exceptions::FileIoException() << "The supplied Transition input file \"" << filename << "\" does not exist or is not readable by this process."; } @@ -58,11 +58,11 @@ namespace storm { bool insertDiagonalEntriesIfMissing = !isRewardFile; DeterministicSparseTransitionParser<ValueType>::FirstPassResult firstPass = DeterministicSparseTransitionParser<ValueType>::firstPass(file.getData(), insertDiagonalEntriesIfMissing); - LOG4CPLUS_INFO(logger, "First pass on " << filename << " shows " << firstPass.numberOfNonzeroEntries << " NonZeros."); + STORM_LOG_INFO("First pass on " << filename << " shows " << firstPass.numberOfNonzeroEntries << " NonZeros."); // If first pass returned zero, the file format was wrong. if (firstPass.numberOfNonzeroEntries == 0) { - LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": empty or erroneous file format."); + STORM_LOG_ERROR("Error while parsing " << filename << ": empty or erroneous file format."); throw storm::exceptions::WrongFormatException(); } @@ -78,7 +78,7 @@ namespace storm { if (isRewardFile) { // The reward matrix should match the size of the transition matrix. if (firstPass.highestStateIndex + 1 > transitionMatrix.getRowCount() || firstPass.highestStateIndex + 1 > transitionMatrix.getColumnCount()) { - LOG4CPLUS_ERROR(logger, "Reward matrix has more rows or columns than transition matrix."); + STORM_LOG_ERROR("Reward matrix has more rows or columns than transition matrix."); throw storm::exceptions::WrongFormatException() << "Reward matrix has more rows or columns than transition matrix."; } else { // If we found the right number of states or less, we set it to the number of states represented by the transition matrix. @@ -122,9 +122,9 @@ namespace storm { hadDeadlocks = true; if (!dontFixDeadlocks) { resultMatrix.addNextValue(skippedRow, skippedRow, storm::utility::one<ValueType>()); - LOG4CPLUS_WARN(logger, "Warning while parsing " << filename << ": state " << skippedRow << " has no outgoing transitions. A self-loop was inserted."); + STORM_LOG_WARN("Warning while parsing " << filename << ": state " << skippedRow << " has no outgoing transitions. A self-loop was inserted."); } else { - LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": state " << skippedRow << " has no outgoing transitions."); + STORM_LOG_ERROR("Error while parsing " << filename << ": state " << skippedRow << " has no outgoing transitions."); // Before throwing the appropriate exception we will give notice of all deadlock states. } } @@ -143,9 +143,9 @@ namespace storm { if (!rowHadDiagonalEntry) { if (insertDiagonalEntriesIfMissing) { resultMatrix.addNextValue(lastRow, lastRow, storm::utility::zero<ValueType>()); - LOG4CPLUS_DEBUG(logger, "While parsing " << filename << ": state " << lastRow << " has no transition to itself. Inserted a 0-transition. (1)"); + STORM_LOG_DEBUG("While parsing " << filename << ": state " << lastRow << " has no transition to itself. Inserted a 0-transition. (1)"); } else { - LOG4CPLUS_WARN(logger, "Warning while parsing " << filename << ": state " << lastRow << " has no transition to itself."); + STORM_LOG_WARN("Warning while parsing " << filename << ": state " << lastRow << " has no transition to itself."); } // No increment for lastRow. rowHadDiagonalEntry = true; @@ -154,9 +154,9 @@ namespace storm { hadDeadlocks = true; if (!dontFixDeadlocks) { resultMatrix.addNextValue(skippedRow, skippedRow, storm::utility::one<ValueType>()); - LOG4CPLUS_WARN(logger, "Warning while parsing " << filename << ": state " << skippedRow << " has no outgoing transitions. A self-loop was inserted."); + STORM_LOG_WARN("Warning while parsing " << filename << ": state " << skippedRow << " has no outgoing transitions. A self-loop was inserted."); } else { - LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": state " << skippedRow << " has no outgoing transitions."); + STORM_LOG_ERROR("Error while parsing " << filename << ": state " << skippedRow << " has no outgoing transitions."); // Before throwing the appropriate exception we will give notice of all deadlock states. } } @@ -171,9 +171,9 @@ namespace storm { if (col > row && !rowHadDiagonalEntry) { if (insertDiagonalEntriesIfMissing) { resultMatrix.addNextValue(row, row, storm::utility::zero<ValueType>()); - LOG4CPLUS_DEBUG(logger, "While parsing " << filename << ": state " << row << " has no transition to itself. Inserted a 0-transition. (2)"); + STORM_LOG_DEBUG("While parsing " << filename << ": state " << row << " has no transition to itself. Inserted a 0-transition. (2)"); } else { - LOG4CPLUS_WARN(logger, "Warning while parsing " << filename << ": state " << row << " has no transition to itself."); + STORM_LOG_WARN("Warning while parsing " << filename << ": state " << row << " has no transition to itself."); } rowHadDiagonalEntry = true; } @@ -185,9 +185,9 @@ namespace storm { if (!rowHadDiagonalEntry) { if (insertDiagonalEntriesIfMissing) { resultMatrix.addNextValue(lastRow, lastRow, storm::utility::zero<ValueType>()); - LOG4CPLUS_DEBUG(logger, "While parsing " << filename << ": state " << lastRow << " has no transition to itself. Inserted a 0-transition. (3)"); + STORM_LOG_DEBUG("While parsing " << filename << ": state " << lastRow << " has no transition to itself. Inserted a 0-transition. (3)"); } else { - LOG4CPLUS_WARN(logger, "Warning while parsing " << filename << ": state " << lastRow << " has no transition to itself."); + STORM_LOG_WARN("Warning while parsing " << filename << ": state " << lastRow << " has no transition to itself."); } } @@ -200,7 +200,7 @@ namespace storm { // Since we cannot check if each transition for which there is a reward in the reward file also exists in the transition matrix during parsing, we have to do it afterwards. if (isRewardFile && !result.isSubmatrixOf(transitionMatrix)) { - LOG4CPLUS_ERROR(logger, "There are rewards for non existent transitions given in the reward file."); + STORM_LOG_ERROR("There are rewards for non existent transitions given in the reward file."); throw storm::exceptions::WrongFormatException() << "There are rewards for non existent transitions given in the reward file."; } @@ -272,7 +272,7 @@ namespace storm { // Have we already seen this transition? if (row == lastRow && col == lastCol) { - LOG4CPLUS_ERROR(logger, "The same transition (" << row << ", " << col << ") is given twice."); + STORM_LOG_ERROR("The same transition (" << row << ", " << col << ") is given twice."); throw storm::exceptions::InvalidArgumentException() << "The same transition (" << row << ", " << col << ") is given twice."; } diff --git a/src/parser/MappedFile.cpp b/src/parser/MappedFile.cpp index 7abf526cf..86f2648eb 100644 --- a/src/parser/MappedFile.cpp +++ b/src/parser/MappedFile.cpp @@ -33,20 +33,20 @@ namespace storm { #else if (stat64(filename, &(this->st)) != 0) { #endif - LOG4CPLUS_ERROR(logger, "Error in stat(" << filename << "): Probably, this file does not exist."); + STORM_LOG_ERROR("Error in stat(" << filename << "): Probably, this file does not exist."); throw exceptions::FileIoException() << "MappedFile Error in stat(): Probably, this file does not exist."; } this->file = open(filename, O_RDONLY); if (this->file < 0) { - LOG4CPLUS_ERROR(logger, "Error in open(" << filename << "): Probably, we may not read this file."); + STORM_LOG_ERROR("Error in open(" << filename << "): Probably, we may not read this file."); throw exceptions::FileIoException() << "MappedFile Error in open(): Probably, we may not read this file."; } this->data = static_cast<char*>(mmap(NULL, this->st.st_size, PROT_READ, MAP_PRIVATE, this->file, 0)); if (this->data == MAP_FAILED) { close(this->file); - LOG4CPLUS_ERROR(logger, "Error in mmap(" << filename << "): " << std::strerror(errno)); + STORM_LOG_ERROR("Error in mmap(" << filename << "): " << std::strerror(errno)); throw exceptions::FileIoException() << "MappedFile Error in mmap(): " << std::strerror(errno); } this->dataEnd = this->data + this->st.st_size; @@ -56,20 +56,20 @@ namespace storm { // _stat64(), CreateFile(), CreateFileMapping(), MapViewOfFile() if (_stat64(filename, &(this->st)) != 0) { - LOG4CPLUS_ERROR(logger, "Error in _stat(" << filename << "): Probably, this file does not exist."); + STORM_LOG_ERROR("Error in _stat(" << filename << "): Probably, this file does not exist."); throw exceptions::FileIoException("MappedFile Error in stat(): Probably, this file does not exist."); } this->file = CreateFileA(filename, GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (this->file == INVALID_HANDLE_VALUE) { - LOG4CPLUS_ERROR(logger, "Error in CreateFileA(" << filename << "): Probably, we may not read this file."); + STORM_LOG_ERROR("Error in CreateFileA(" << filename << "): Probably, we may not read this file."); throw exceptions::FileIoException("MappedFile Error in CreateFileA(): Probably, we may not read this file."); } this->mapping = CreateFileMappingA(this->file, NULL, PAGE_READONLY, (DWORD)(st.st_size >> 32), (DWORD)st.st_size, NULL); if (this->mapping == NULL) { CloseHandle(this->file); - LOG4CPLUS_ERROR(logger, "Error in CreateFileMappingA(" << filename << ")."); + STORM_LOG_ERROR("Error in CreateFileMappingA(" << filename << ")."); throw exceptions::FileIoException("MappedFile Error in CreateFileMappingA()."); } @@ -77,7 +77,7 @@ namespace storm { if (this->data == NULL) { CloseHandle(this->mapping); CloseHandle(this->file); - LOG4CPLUS_ERROR(logger, "Error in MapViewOfFile(" << filename << ")."); + STORM_LOG_ERROR("Error in MapViewOfFile(" << filename << ")."); throw exceptions::FileIoException("MappedFile Error in MapViewOfFile()."); } this->dataEnd = this->data + this->st.st_size; diff --git a/src/parser/MarkovAutomatonParser.cpp b/src/parser/MarkovAutomatonParser.cpp index 6a68abda8..b4ee7be34 100644 --- a/src/parser/MarkovAutomatonParser.cpp +++ b/src/parser/MarkovAutomatonParser.cpp @@ -37,7 +37,7 @@ namespace storm { // Since Markov Automata do not support transition rewards no path should be given here. if (transitionRewardFilename != "") { - LOG4CPLUS_ERROR(logger, "Transition rewards are unsupported for Markov automata."); + STORM_LOG_ERROR("Transition rewards are unsupported for Markov automata."); throw storm::exceptions::WrongFormatException() << "Transition rewards are unsupported for Markov automata."; } diff --git a/src/parser/MarkovAutomatonSparseTransitionParser.cpp b/src/parser/MarkovAutomatonSparseTransitionParser.cpp index 6bc214cab..18d87d314 100644 --- a/src/parser/MarkovAutomatonSparseTransitionParser.cpp +++ b/src/parser/MarkovAutomatonSparseTransitionParser.cpp @@ -48,11 +48,11 @@ namespace storm { result.numberOfNonzeroEntries += source - lastsource - 1; result.numberOfChoices += source - lastsource - 1; } else { - LOG4CPLUS_ERROR(logger, "Found deadlock states (e.g. " << lastsource + 1 << ") during parsing. Please fix them or set the appropriate flag."); + STORM_LOG_ERROR("Found deadlock states (e.g. " << lastsource + 1 << ") during parsing. Please fix them or set the appropriate flag."); throw storm::exceptions::WrongFormatException() << "Found deadlock states (e.g. " << lastsource + 1 << ") during parsing. Please fix them or set the appropriate flag."; } } else if (source < lastsource) { - LOG4CPLUS_ERROR(logger, "Illegal state choice order. A choice of state " << source << " appears at an illegal position."); + STORM_LOG_ERROR("Illegal state choice order. A choice of state " << source << " appears at an illegal position."); throw storm::exceptions::WrongFormatException() << "Illegal state choice order. A choice of state " << source << " appears at an illegal position."; } @@ -80,11 +80,11 @@ namespace storm { if (isMarkovianChoice) { if (stateHasMarkovianChoice) { - LOG4CPLUS_ERROR(logger, "The state " << source << " has multiple Markovian choices."); + STORM_LOG_ERROR("The state " << source << " has multiple Markovian choices."); throw storm::exceptions::WrongFormatException() << "The state " << source << " has multiple Markovian choices."; } if (stateHasProbabilisticChoice) { - LOG4CPLUS_ERROR(logger, "The state " << source << " has a probabilistic choice preceding a Markovian choice. The Markovian choice must be the first choice listed."); + STORM_LOG_ERROR("The state " << source << " has a probabilistic choice preceding a Markovian choice. The Markovian choice must be the first choice listed."); throw storm::exceptions::WrongFormatException() << "The state " << source << " has a probabilistic choice preceding a Markovian choice. The Markovian choice must be the first choice listed."; } stateHasMarkovianChoice = true; @@ -106,7 +106,7 @@ namespace storm { // If the end of the file was reached, we need to abort and check whether we are in a legal state. if (buf[0] == '\0') { if (!hasSuccessorState) { - LOG4CPLUS_ERROR(logger, "Premature end-of-file. Expected at least one successor state for state " << source << "."); + STORM_LOG_ERROR("Premature end-of-file. Expected at least one successor state for state " << source << "."); throw storm::exceptions::WrongFormatException() << "Premature end-of-file. Expected at least one successor state for state " << source << "."; } else { // If there was at least one successor for the current choice, this is legal and we need to move on. @@ -122,18 +122,18 @@ namespace storm { result.highestStateIndex = target; } if (hasSuccessorState && target <= lastSuccessorState) { - LOG4CPLUS_ERROR(logger, "Illegal transition order for source state " << source << "."); + STORM_LOG_ERROR("Illegal transition order for source state " << source << "."); throw storm::exceptions::WrongFormatException() << "Illegal transition order for source state " << source << "."; } // And the corresponding probability/rate. double val = checked_strtod(buf, &buf); if (val < 0.0) { - LOG4CPLUS_ERROR(logger, "Illegal negative probability/rate value for transition from " << source << " to " << target << ": " << val << "."); + STORM_LOG_ERROR("Illegal negative probability/rate value for transition from " << source << " to " << target << ": " << val << "."); throw storm::exceptions::WrongFormatException() << "Illegal negative probability/rate value for transition from " << source << " to " << target << ": " << val << "."; } if (!isMarkovianChoice && val > 1.0) { - LOG4CPLUS_ERROR(logger, "Illegal probability value for transition from " << source << " to " << target << ": " << val << "."); + STORM_LOG_ERROR("Illegal probability value for transition from " << source << " to " << target << ": " << val << "."); throw storm::exceptions::WrongFormatException() << "Illegal probability value for transition from " << source << " to " << target << ": " << val << "."; } @@ -191,7 +191,7 @@ namespace storm { ++currentChoice; } } else { - LOG4CPLUS_ERROR(logger, "Found deadlock states (e.g. " << lastsource + 1 << ") during parsing. Please fix them or set the appropriate flag."); + STORM_LOG_ERROR("Found deadlock states (e.g. " << lastsource + 1 << ") during parsing. Please fix them or set the appropriate flag."); throw storm::exceptions::WrongFormatException() << "Found deadlock states (e.g. " << lastsource + 1 << ") during parsing. Please fix them or set the appropriate flag."; } } @@ -269,7 +269,7 @@ namespace storm { setlocale(LC_NUMERIC, "C"); if (!MappedFile::fileExistsAndIsReadable(filename.c_str())) { - LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": File does not exist or is not readable."); + STORM_LOG_ERROR("Error while parsing " << filename << ": File does not exist or is not readable."); throw storm::exceptions::FileIoException() << "Error while parsing " << filename << ": File does not exist or is not readable."; } diff --git a/src/parser/NondeterministicSparseTransitionParser.cpp b/src/parser/NondeterministicSparseTransitionParser.cpp index 421f3b8cc..89322808c 100644 --- a/src/parser/NondeterministicSparseTransitionParser.cpp +++ b/src/parser/NondeterministicSparseTransitionParser.cpp @@ -44,7 +44,7 @@ namespace storm { setlocale(LC_NUMERIC, "C"); if (!MappedFile::fileExistsAndIsReadable(filename.c_str())) { - LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": File does not exist or is not readable."); + STORM_LOG_ERROR("Error while parsing " << filename << ": File does not exist or is not readable."); throw storm::exceptions::FileIoException() << "Error while parsing " << filename << ": File does not exist or is not readable."; } @@ -57,7 +57,7 @@ namespace storm { // If first pass returned zero, the file format was wrong. if (firstPass.numberOfNonzeroEntries == 0) { - LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": erroneous file format."); + STORM_LOG_ERROR("Error while parsing " << filename << ": erroneous file format."); throw storm::exceptions::WrongFormatException() << "Error while parsing " << filename << ": erroneous file format."; } @@ -73,13 +73,13 @@ namespace storm { if (isRewardFile) { // The reward matrix should match the size of the transition matrix. if (firstPass.choices > modelInformation.getRowCount() || (uint_fast64_t) (firstPass.highestStateIndex + 1) > modelInformation.getColumnCount()) { - LOG4CPLUS_ERROR(logger, "Reward matrix size exceeds transition matrix size."); + STORM_LOG_ERROR("Reward matrix size exceeds transition matrix size."); throw storm::exceptions::OutOfRangeException() << "Reward matrix size exceeds transition matrix size."; } else if (firstPass.choices != modelInformation.getRowCount()) { - LOG4CPLUS_ERROR(logger, "Reward matrix row count does not match transition matrix row count."); + STORM_LOG_ERROR("Reward matrix row count does not match transition matrix row count."); throw storm::exceptions::OutOfRangeException() << "Reward matrix row count does not match transition matrix row count."; } else if (firstPass.numberOfNonzeroEntries > modelInformation.getEntryCount()) { - LOG4CPLUS_ERROR(logger, "The reward matrix has more entries than the transition matrix. There must be a reward for a non existent transition"); + STORM_LOG_ERROR("The reward matrix has more entries than the transition matrix. There must be a reward for a non existent transition"); throw storm::exceptions::OutOfRangeException() << "The reward matrix has more entries than the transition matrix."; } else { firstPass.highestStateIndex = modelInformation.getColumnCount() - 1; @@ -89,7 +89,7 @@ namespace storm { // Create the matrix builder. // The matrix to be build should have as many columns as we have nodes and as many rows as we have choices. // Those two values, as well as the number of nonzero elements, was been calculated in the first run. - LOG4CPLUS_INFO(logger, "Attempting to create matrix of size " << firstPass.choices << " x " << (firstPass.highestStateIndex + 1) << " with " << firstPass.numberOfNonzeroEntries << " entries."); + STORM_LOG_INFO("Attempting to create matrix of size " << firstPass.choices << " x " << (firstPass.highestStateIndex + 1) << " with " << firstPass.numberOfNonzeroEntries << " entries."); storm::storage::SparseMatrixBuilder<ValueType> matrixBuilder; if (!isRewardFile) { matrixBuilder = storm::storage::SparseMatrixBuilder<ValueType>(firstPass.choices, firstPass.highestStateIndex + 1, firstPass.numberOfNonzeroEntries, true, true, firstPass.highestStateIndex + 1); @@ -155,9 +155,9 @@ namespace storm { matrixBuilder.newRowGroup(curRow); matrixBuilder.addNextValue(curRow, node, 1); ++curRow; - LOG4CPLUS_WARN(logger, "Warning while parsing " << filename << ": node " << node << " has no outgoing transitions. A self-loop was inserted."); + STORM_LOG_WARN("Warning while parsing " << filename << ": node " << node << " has no outgoing transitions. A self-loop was inserted."); } else { - LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": node " << node << " has no outgoing transitions."); + STORM_LOG_ERROR("Error while parsing " << filename << ": node " << node << " has no outgoing transitions."); } } if (source != lastSource) { @@ -194,7 +194,7 @@ namespace storm { // Since we cannot check if each transition for which there is a reward in the reward file also exists in the transition matrix during parsing, we have to do it afterwards. if (isRewardFile && !resultMatrix.isSubmatrixOf(modelInformation)) { - LOG4CPLUS_ERROR(logger, "There are rewards for non existent transitions given in the reward file."); + STORM_LOG_ERROR("There are rewards for non existent transitions given in the reward file."); throw storm::exceptions::WrongFormatException() << "There are rewards for non existent transitions given in the reward file."; } @@ -230,7 +230,7 @@ namespace storm { choice = checked_strtol(buf, &buf); if (source < lastSource) { - LOG4CPLUS_ERROR(logger, "The current source state " << source << " is smaller than the last one " << lastSource << "."); + STORM_LOG_ERROR("The current source state " << source << " is smaller than the last one " << lastSource << "."); throw storm::exceptions::InvalidArgumentException() << "The current source state " << source << " is smaller than the last one " << lastSource << "."; } @@ -243,7 +243,7 @@ namespace storm { // Make sure that the highest state index of the reward file is not higher than the highest state index of the corresponding model. if (result.highestStateIndex > modelInformation.getColumnCount() - 1) { - LOG4CPLUS_ERROR(logger, "State index " << result.highestStateIndex << " found. This exceeds the highest state index of the model, which is " << modelInformation.getColumnCount() - 1 << " ."); + STORM_LOG_ERROR("State index " << result.highestStateIndex << " found. This exceeds the highest state index of the model, which is " << modelInformation.getColumnCount() - 1 << " ."); throw storm::exceptions::OutOfRangeException() << "State index " << result.highestStateIndex << " found. This exceeds the highest state index of the model, which is " << modelInformation.getColumnCount() - 1 << " ."; } @@ -292,18 +292,18 @@ namespace storm { // Also, have we already seen this transition? if (target == lastTarget && choice == lastChoice && source == lastSource) { - LOG4CPLUS_ERROR(logger, "The same transition (" << source << ", " << choice << ", " << target << ") is given twice."); + STORM_LOG_ERROR("The same transition (" << source << ", " << choice << ", " << target << ") is given twice."); throw storm::exceptions::InvalidArgumentException() << "The same transition (" << source << ", " << choice << ", " << target << ") is given twice."; } // Read value and check whether it's positive. val = checked_strtod(buf, &buf); if (!isRewardFile && (val < 0.0 || val > 1.0)) { - LOG4CPLUS_ERROR(logger, "Expected a positive probability but got \"" << std::string(buf, 0, 16) << "\"."); + STORM_LOG_ERROR("Expected a positive probability but got \"" << std::string(buf, 0, 16) << "\"."); NondeterministicSparseTransitionParser::FirstPassResult nullResult; return nullResult; } else if (val < 0.0) { - LOG4CPLUS_ERROR(logger, "Expected a positive reward value but got \"" << std::string(buf, 0, 16) << "\"."); + STORM_LOG_ERROR("Expected a positive reward value but got \"" << std::string(buf, 0, 16) << "\"."); NondeterministicSparseTransitionParser::FirstPassResult nullResult; return nullResult; } diff --git a/src/parser/SparseChoiceLabelingParser.cpp b/src/parser/SparseChoiceLabelingParser.cpp index 7bfeeb459..999a98841 100644 --- a/src/parser/SparseChoiceLabelingParser.cpp +++ b/src/parser/SparseChoiceLabelingParser.cpp @@ -14,7 +14,7 @@ namespace storm { std::vector<storm::models::sparse::LabelSet> SparseChoiceLabelingParser::parseChoiceLabeling(std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, std::string const& filename) { // Open file. if (!MappedFile::fileExistsAndIsReadable(filename.c_str())) { - LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": File does not exist or is not readable."); + STORM_LOG_ERROR("Error while parsing " << filename << ": File does not exist or is not readable."); throw storm::exceptions::FileIoException() << "Error while parsing " << filename << ": File does not exist or is not readable."; } diff --git a/src/parser/SparseStateRewardParser.cpp b/src/parser/SparseStateRewardParser.cpp index b60856eb8..35e1c3d59 100644 --- a/src/parser/SparseStateRewardParser.cpp +++ b/src/parser/SparseStateRewardParser.cpp @@ -22,7 +22,7 @@ namespace storm { std::vector<ValueType> SparseStateRewardParser<ValueType>::parseSparseStateReward(uint_fast64_t stateCount, std::string const& filename) { // Open file. if (!MappedFile::fileExistsAndIsReadable(filename.c_str())) { - LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": File does not exist or is not readable."); + STORM_LOG_ERROR("Error while parsing " << filename << ": File does not exist or is not readable."); throw storm::exceptions::FileIoException() << "Error while parsing " << filename << ": File does not exist or is not readable."; } @@ -47,12 +47,12 @@ namespace storm { // If the state has already been read or skipped once there might be a problem with the file (doubled lines, or blocks). // Note: The value -1 shows that lastState has not yet been set, i.e. this is the first run of the loop (state index (2^64)-1 is a really bad starting index). if (state <= lastState && lastState != startIndexComparison) { - LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": State " << state << " was found but has already been read or skipped previously."); + STORM_LOG_ERROR("Error while parsing " << filename << ": State " << state << " was found but has already been read or skipped previously."); throw storm::exceptions::WrongFormatException() << "Error while parsing " << filename << ": State " << state << " was found but has already been read or skipped previously."; } if (stateCount <= state) { - LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": Found reward for a state of an invalid index \"" << state << "\". The model has only " << stateCount << " states."); + STORM_LOG_ERROR("Error while parsing " << filename << ": Found reward for a state of an invalid index \"" << state << "\". The model has only " << stateCount << " states."); throw storm::exceptions::OutOfRangeException() << "Error while parsing " << filename << ": Found reward for a state of an invalid index \"" << state << "\""; } @@ -60,7 +60,7 @@ namespace storm { reward = checked_strtod(buf, &buf); if (reward < 0.0) { - LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": Expected positive reward value but got \"" << reward << "\"."); + STORM_LOG_ERROR("Error while parsing " << filename << ": Expected positive reward value but got \"" << reward << "\"."); throw storm::exceptions::WrongFormatException() << "Error while parsing " << filename << ": State reward file specifies illegal reward value."; } diff --git a/src/solver/GmmxxLinearEquationSolver.cpp b/src/solver/GmmxxLinearEquationSolver.cpp index 3b7bbf476..eb869481c 100644 --- a/src/solver/GmmxxLinearEquationSolver.cpp +++ b/src/solver/GmmxxLinearEquationSolver.cpp @@ -56,9 +56,9 @@ namespace storm { template<typename ValueType> void GmmxxLinearEquationSolver<ValueType>::solveEquationSystem(std::vector<ValueType>& x, std::vector<ValueType> const& b, std::vector<ValueType>* multiplyResult) const { - LOG4CPLUS_INFO(logger, "Using method '" << methodToString() << "' with preconditioner '" << preconditionerToString() << "' (max. " << maximalNumberOfIterations << " iterations)."); + STORM_LOG_INFO("Using method '" << methodToString() << "' with preconditioner '" << preconditionerToString() << "' (max. " << maximalNumberOfIterations << " iterations)."); if (method == SolutionMethod::Jacobi && preconditioner != Preconditioner::None) { - LOG4CPLUS_WARN(logger, "Jacobi method currently does not support preconditioners. The requested preconditioner will be ignored."); + STORM_LOG_WARN("Jacobi method currently does not support preconditioners. The requested preconditioner will be ignored."); } if (method == SolutionMethod::Bicgstab || method == SolutionMethod::Qmr || method == SolutionMethod::Gmres) { @@ -93,18 +93,18 @@ namespace storm { // Check if the solver converged and issue a warning otherwise. if (iter.converged()) { - LOG4CPLUS_INFO(logger, "Iterative solver converged after " << iter.get_iteration() << " iterations."); + STORM_LOG_INFO("Iterative solver converged after " << iter.get_iteration() << " iterations."); } else { - LOG4CPLUS_WARN(logger, "Iterative solver did not converge."); + STORM_LOG_WARN("Iterative solver did not converge."); } } else if (method == SolutionMethod::Jacobi) { uint_fast64_t iterations = solveLinearEquationSystemWithJacobi(*originalA, x, b, multiplyResult); // Check if the solver converged and issue a warning otherwise. if (iterations < maximalNumberOfIterations) { - LOG4CPLUS_INFO(logger, "Iterative solver converged after " << iterations << " iterations."); + STORM_LOG_INFO("Iterative solver converged after " << iterations << " iterations."); } else { - LOG4CPLUS_WARN(logger, "Iterative solver did not converge."); + STORM_LOG_WARN("Iterative solver did not converge."); } } } diff --git a/src/solver/GmmxxMinMaxLinearEquationSolver.cpp b/src/solver/GmmxxMinMaxLinearEquationSolver.cpp index 07052e6eb..eed6fb258 100644 --- a/src/solver/GmmxxMinMaxLinearEquationSolver.cpp +++ b/src/solver/GmmxxMinMaxLinearEquationSolver.cpp @@ -69,9 +69,9 @@ namespace storm { // Check if the solver converged and issue a warning otherwise. if (converged) { - LOG4CPLUS_INFO(logger, "Iterative solver converged after " << iterations << " iterations."); + STORM_LOG_INFO("Iterative solver converged after " << iterations << " iterations."); } else { - LOG4CPLUS_WARN(logger, "Iterative solver did not converge after " << iterations << " iterations."); + STORM_LOG_WARN("Iterative solver did not converge after " << iterations << " iterations."); } // If we performed an odd number of iterations, we need to swap the x and currentX, because the newest result @@ -149,9 +149,9 @@ namespace storm { // Check if the solver converged and issue a warning otherwise. if (converged) { - LOG4CPLUS_INFO(logger, "Iterative solver converged after " << iterations << " iterations."); + STORM_LOG_INFO("Iterative solver converged after " << iterations << " iterations."); } else { - LOG4CPLUS_WARN(logger, "Iterative solver did not converge after " << iterations << " iterations."); + STORM_LOG_WARN("Iterative solver did not converge after " << iterations << " iterations."); } // If requested, we store the scheduler for retrieval. diff --git a/src/solver/GurobiLpSolver.cpp b/src/solver/GurobiLpSolver.cpp index 202aa6e45..4108f2bb8 100644 --- a/src/solver/GurobiLpSolver.cpp +++ b/src/solver/GurobiLpSolver.cpp @@ -26,7 +26,7 @@ namespace storm { // Create the environment. int error = GRBloadenv(&env, ""); if (error || env == nullptr) { - LOG4CPLUS_ERROR(logger, "Could not initialize Gurobi (" << GRBgeterrormsg(env) << ", error code " << error << ")."); + STORM_LOG_ERROR("Could not initialize Gurobi (" << GRBgeterrormsg(env) << ", error code " << error << ")."); throw storm::exceptions::InvalidStateException() << "Could not initialize Gurobi environment (" << GRBgeterrormsg(env) << ", error code " << error << ")."; } @@ -36,7 +36,7 @@ namespace storm { // Create the model. error = GRBnewmodel(env, &model, name.c_str(), 0, nullptr, nullptr, nullptr, nullptr, nullptr); if (error) { - LOG4CPLUS_ERROR(logger, "Could not initialize Gurobi model (" << GRBgeterrormsg(env) << ", error code " << error << ")."); + STORM_LOG_ERROR("Could not initialize Gurobi model (" << GRBgeterrormsg(env) << ", error code " << error << ")."); throw storm::exceptions::InvalidStateException() << "Could not initialize Gurobi model (" << GRBgeterrormsg(env) << ", error code " << error << ")."; } } @@ -346,7 +346,7 @@ namespace storm { void GurobiLpSolver::writeModelToFile(std::string const& filename) const { int error = GRBwrite(model, filename.c_str()); if (error) { - LOG4CPLUS_ERROR(logger, "Unable to write Gurobi model (" << GRBgeterrormsg(env) << ", error code " << error << ") to file."); + STORM_LOG_ERROR("Unable to write Gurobi model (" << GRBgeterrormsg(env) << ", error code " << error << ") to file."); throw storm::exceptions::InvalidStateException() << "Unable to write Gurobi model (" << GRBgeterrormsg(env) << ", error code " << error << ") to file."; } } diff --git a/src/solver/NativeMinMaxLinearEquationSolver.cpp b/src/solver/NativeMinMaxLinearEquationSolver.cpp index 22ccf956c..ec369ee3e 100644 --- a/src/solver/NativeMinMaxLinearEquationSolver.cpp +++ b/src/solver/NativeMinMaxLinearEquationSolver.cpp @@ -65,9 +65,9 @@ namespace storm { // Check if the solver converged and issue a warning otherwise. if (converged) { - LOG4CPLUS_INFO(logger, "Iterative solver converged after " << iterations << " iterations."); + STORM_LOG_INFO("Iterative solver converged after " << iterations << " iterations."); } else { - LOG4CPLUS_WARN(logger, "Iterative solver did not converge after " << iterations << " iterations."); + STORM_LOG_WARN("Iterative solver did not converge after " << iterations << " iterations."); } // If we performed an odd number of iterations, we need to swap the x and currentX, because the newest result @@ -147,9 +147,9 @@ namespace storm { // Check if the solver converged and issue a warning otherwise. if (converged) { - LOG4CPLUS_INFO(logger, "Iterative solver converged after " << iterations << " iterations."); + STORM_LOG_INFO("Iterative solver converged after " << iterations << " iterations."); } else { - LOG4CPLUS_WARN(logger, "Iterative solver did not converge after " << iterations << " iterations."); + STORM_LOG_WARN("Iterative solver did not converge after " << iterations << " iterations."); } // If requested, we store the scheduler for retrieval. diff --git a/src/solver/TopologicalMinMaxLinearEquationSolver.cpp b/src/solver/TopologicalMinMaxLinearEquationSolver.cpp index f16c92a07..bb912371b 100644 --- a/src/solver/TopologicalMinMaxLinearEquationSolver.cpp +++ b/src/solver/TopologicalMinMaxLinearEquationSolver.cpp @@ -73,10 +73,10 @@ namespace storm { // For testing only if (sizeof(ValueType) == sizeof(double)) { //std::cout << "<<< Using CUDA-DOUBLE Kernels >>>" << std::endl; - LOG4CPLUS_INFO(logger, "<<< Using CUDA-DOUBLE Kernels >>>"); + STORM_LOG_INFO("<<< Using CUDA-DOUBLE Kernels >>>"); } else { //std::cout << "<<< Using CUDA-FLOAT Kernels >>>" << std::endl; - LOG4CPLUS_INFO(logger, "<<< Using CUDA-FLOAT Kernels >>>"); + STORM_LOG_INFO("<<< Using CUDA-FLOAT Kernels >>>"); } // Now, we need to determine the SCCs of the MDP and perform a topological sort. @@ -107,12 +107,12 @@ namespace storm { } else { result = __basicValueIteration_mvReduce_maximize<uint_fast64_t, ValueType>(this->maximalNumberOfIterations, this->precision, this->relative, A.rowIndications, A.columnsAndValues, x, b, nondeterministicChoiceIndices, globalIterations); } - LOG4CPLUS_INFO(logger, "Executed " << globalIterations << " of max. " << maximalNumberOfIterations << " Iterations on GPU."); + STORM_LOG_INFO("Executed " << globalIterations << " of max. " << maximalNumberOfIterations << " Iterations on GPU."); bool converged = false; if (!result) { converged = false; - LOG4CPLUS_ERROR(logger, "An error occurred in the CUDA Plugin. Can not continue."); + STORM_LOG_ERROR("An error occurred in the CUDA Plugin. Can not continue."); throw storm::exceptions::InvalidStateException() << "An error occurred in the CUDA Plugin. Can not continue."; } else { converged = true; @@ -120,12 +120,12 @@ namespace storm { // Check if the solver converged and issue a warning otherwise. if (converged) { - LOG4CPLUS_INFO(logger, "Iterative solver converged after " << globalIterations << " iterations."); + STORM_LOG_INFO("Iterative solver converged after " << globalIterations << " iterations."); } else { - LOG4CPLUS_WARN(logger, "Iterative solver did not converged after " << globalIterations << " iterations."); + STORM_LOG_WARN("Iterative solver did not converged after " << globalIterations << " iterations."); } #else - LOG4CPLUS_ERROR(logger, "The useGpu Flag of a SCC was set, but this version of StoRM does not support CUDA acceleration. Internal Error!"); + STORM_LOG_ERROR("The useGpu Flag of a SCC was set, but this version of StoRM does not support CUDA acceleration. Internal Error!"); throw storm::exceptions::InvalidStateException() << "The useGpu Flag of a SCC was set, but this version of StoRM does not support CUDA acceleration. Internal Error!"; #endif } else { @@ -139,7 +139,7 @@ namespace storm { // Calculate the optimal distribution of sccs std::vector<std::pair<bool, storm::storage::StateBlock>> optimalSccs = this->getOptimalGroupingFromTopologicalSccDecomposition(sccDecomposition, topologicalSort, this->A); - LOG4CPLUS_INFO(logger, "Optimized SCC Decomposition, originally " << topologicalSort.size() << " SCCs, optimized to " << optimalSccs.size() << " SCCs."); + STORM_LOG_INFO("Optimized SCC Decomposition, originally " << topologicalSort.size() << " SCCs, optimized to " << optimalSccs.size() << " SCCs."); std::vector<ValueType>* currentX = nullptr; std::vector<ValueType>* swap = nullptr; @@ -198,9 +198,9 @@ namespace storm { #ifdef STORM_HAVE_CUDA STORM_LOG_THROW(resetCudaDevice(), storm::exceptions::InvalidStateException, "Could not reset CUDA Device, can not use CUDA-based equation solver."); - //LOG4CPLUS_INFO(logger, "Device has " << getTotalCudaMemory() << " Bytes of Memory with " << getFreeCudaMemory() << "Bytes free (" << (static_cast<double>(getFreeCudaMemory()) / static_cast<double>(getTotalCudaMemory())) * 100 << "%)."); - //LOG4CPLUS_INFO(logger, "We will allocate " << (sizeof(uint_fast64_t)* sccSubmatrix.rowIndications.size() + sizeof(uint_fast64_t)* sccSubmatrix.columnsAndValues.size() * 2 + sizeof(double)* sccSubX.size() + sizeof(double)* sccSubX.size() + sizeof(double)* sccSubB.size() + sizeof(double)* sccSubB.size() + sizeof(uint_fast64_t)* sccSubNondeterministicChoiceIndices.size()) << " Bytes."); - //LOG4CPLUS_INFO(logger, "The CUDA Runtime Version is " << getRuntimeCudaVersion()); + //STORM_LOG_INFO("Device has " << getTotalCudaMemory() << " Bytes of Memory with " << getFreeCudaMemory() << "Bytes free (" << (static_cast<double>(getFreeCudaMemory()) / static_cast<double>(getTotalCudaMemory())) * 100 << "%)."); + //STORM_LOG_INFO("We will allocate " << (sizeof(uint_fast64_t)* sccSubmatrix.rowIndications.size() + sizeof(uint_fast64_t)* sccSubmatrix.columnsAndValues.size() * 2 + sizeof(double)* sccSubX.size() + sizeof(double)* sccSubX.size() + sizeof(double)* sccSubB.size() + sizeof(double)* sccSubB.size() + sizeof(uint_fast64_t)* sccSubNondeterministicChoiceIndices.size()) << " Bytes."); + //STORM_LOG_INFO("The CUDA Runtime Version is " << getRuntimeCudaVersion()); bool result = false; localIterations = 0; @@ -209,11 +209,11 @@ namespace storm { } else { result = __basicValueIteration_mvReduce_maximize<uint_fast64_t, ValueType>(this->maximalNumberOfIterations, this->precision, this->relative, sccSubmatrix.rowIndications, sccSubmatrix.columnsAndValues, *currentX, sccSubB, sccSubNondeterministicChoiceIndices, localIterations); } - LOG4CPLUS_INFO(logger, "Executed " << localIterations << " of max. " << maximalNumberOfIterations << " Iterations on GPU."); + STORM_LOG_INFO("Executed " << localIterations << " of max. " << maximalNumberOfIterations << " Iterations on GPU."); if (!result) { converged = false; - LOG4CPLUS_ERROR(logger, "An error occurred in the CUDA Plugin. Can not continue."); + STORM_LOG_ERROR("An error occurred in the CUDA Plugin. Can not continue."); throw storm::exceptions::InvalidStateException() << "An error occurred in the CUDA Plugin. Can not continue."; } else { converged = true; @@ -226,12 +226,12 @@ namespace storm { } globalIterations += localIterations; #else - LOG4CPLUS_ERROR(logger, "The useGpu Flag of a SCC was set, but this version of StoRM does not support CUDA acceleration. Internal Error!"); + STORM_LOG_ERROR("The useGpu Flag of a SCC was set, but this version of StoRM does not support CUDA acceleration. Internal Error!"); throw storm::exceptions::InvalidStateException() << "The useGpu Flag of a SCC was set, but this version of StoRM does not support CUDA acceleration. Internal Error!"; #endif } else { //std::cout << "WARNING: Using CPU based TopoSolver! (double)" << std::endl; - LOG4CPLUS_INFO(logger, "Performance Warning: Using CPU based TopoSolver! (double)"); + STORM_LOG_INFO("Performance Warning: Using CPU based TopoSolver! (double)"); localIterations = 0; converged = false; while (!converged && localIterations < this->maximalNumberOfIterations) { @@ -263,7 +263,7 @@ namespace storm { ++localIterations; ++globalIterations; } - LOG4CPLUS_INFO(logger, "Executed " << localIterations << " of max. " << this->maximalNumberOfIterations << " Iterations."); + STORM_LOG_INFO("Executed " << localIterations << " of max. " << this->maximalNumberOfIterations << " Iterations."); } @@ -289,9 +289,9 @@ namespace storm { // Check if the solver converged and issue a warning otherwise. if (converged) { - LOG4CPLUS_INFO(logger, "Iterative solver converged after " << currentMaxLocalIterations << " iterations."); + STORM_LOG_INFO("Iterative solver converged after " << currentMaxLocalIterations << " iterations."); } else { - LOG4CPLUS_WARN(logger, "Iterative solver did not converged after " << currentMaxLocalIterations << " iterations."); + STORM_LOG_WARN("Iterative solver did not converged after " << currentMaxLocalIterations << " iterations."); } } } diff --git a/src/utility/ErrorHandling.h b/src/utility/ErrorHandling.h index 5b9b50bdc..9bc228d6e 100644 --- a/src/utility/ErrorHandling.h +++ b/src/utility/ErrorHandling.h @@ -49,7 +49,7 @@ std::string demangle(char const* symbol) { if (!SymInitialize(hProcess, NULL, TRUE)) { // SymInitialize failed error = GetLastError(); - LOG4CPLUS_ERROR(logger, "SymInitialize returned error : " << error); + STORM_LOG_ERROR("SymInitialize returned error : " << error); return FALSE; } else { char demangled[1024]; @@ -58,7 +58,7 @@ std::string demangle(char const* symbol) { } else { // UnDecorateSymbolName failed DWORD error = GetLastError(); - LOG4CPLUS_ERROR(logger, "UnDecorateSymbolName returned error: " << error); + STORM_LOG_ERROR("UnDecorateSymbolName returned error: " << error); } } #endif @@ -87,7 +87,7 @@ void printUsage(); * @param sig The code of the signal that needs to be handled. */ void signalHandler(int sig) { - LOG4CPLUS_FATAL(logger, "The program received signal " << sig << ". The following backtrace shows the status upon reception of the signal."); + STORM_LOG_ERROR("The program received signal " << sig << ". The following backtrace shows the status upon reception of the signal."); printUsage(); #ifndef WINDOWS # define SIZE 128 @@ -106,13 +106,13 @@ void signalHandler(int sig) { // Starting this for-loop at j=2 means that we skip the handler itself. Currently this is not // done. for (int j = 1; j < nptrs; j++) { - LOG4CPLUS_FATAL(logger, nptrs-j << ": " << demangle(strings[j])); + STORM_LOG_ERROR(nptrs-j << ": " << demangle(strings[j])); } free(strings); #else - LOG4CPLUS_WARN(logger, "No Backtrace Support available on Platform Windows!"); + STORM_LOG_WARN("No Backtrace Support available on Platform Windows!"); #endif - LOG4CPLUS_FATAL(logger, "Exiting."); + STORM_LOG_ERROR("Exiting."); exit(2); } diff --git a/src/utility/cstring.cpp b/src/utility/cstring.cpp index 71bcbe69a..d80059e94 100644 --- a/src/utility/cstring.cpp +++ b/src/utility/cstring.cpp @@ -25,8 +25,8 @@ namespace cstring { uint_fast64_t checked_strtol(char const* str, char const** end) { uint_fast64_t res = strtol(str, const_cast<char**>(end), 10); if (str == *end) { - LOG4CPLUS_ERROR(logger, "Error while parsing integer. Next input token is not a number."); - LOG4CPLUS_ERROR(logger, "\tUpcoming input is: \"" << std::string(str, 0, 16) << "\""); + STORM_LOG_ERROR("Error while parsing integer. Next input token is not a number."); + STORM_LOG_ERROR("\tUpcoming input is: \"" << std::string(str, 0, 16) << "\""); throw storm::exceptions::WrongFormatException("Error while parsing integer. Next input token is not a number."); } return res; @@ -43,8 +43,8 @@ uint_fast64_t checked_strtol(char const* str, char const** end) { double checked_strtod(char const* str, char const** end) { double res = strtod(str, const_cast<char**>(end)); if (str == *end) { - LOG4CPLUS_ERROR(logger, "Error while parsing floating point. Next input token is not a number."); - LOG4CPLUS_ERROR(logger, "\tUpcoming input is: \"" << std::string(str, 0, 16) << "\""); + STORM_LOG_ERROR("Error while parsing floating point. Next input token is not a number."); + STORM_LOG_ERROR("\tUpcoming input is: \"" << std::string(str, 0, 16) << "\""); throw storm::exceptions::WrongFormatException("Error while parsing floating point. Next input token is not a number."); } return res; diff --git a/src/utility/graph.cpp b/src/utility/graph.cpp index 0aa8b2836..e4839b1aa 100644 --- a/src/utility/graph.cpp +++ b/src/utility/graph.cpp @@ -829,7 +829,7 @@ namespace storm { template <typename T> std::vector<uint_fast64_t> getTopologicalSort(storm::storage::SparseMatrix<T> const& matrix) { if (matrix.getRowCount() != matrix.getColumnCount()) { - LOG4CPLUS_ERROR(logger, "Provided matrix is required to be square."); + STORM_LOG_ERROR("Provided matrix is required to be square."); throw storm::exceptions::InvalidArgumentException() << "Provided matrix is required to be square."; } @@ -903,7 +903,7 @@ namespace storm { storm::storage::BitVector const& startingStates, storm::storage::BitVector const* filterStates) { - LOG4CPLUS_INFO(logger, "Performing Dijkstra search."); + STORM_LOG_INFO("Performing Dijkstra search."); const uint_fast64_t noPredecessorValue = storm::utility::zero<uint_fast64_t>(); std::vector<T> probabilities(model.getNumberOfStates(), storm::utility::zero<T>()); @@ -949,7 +949,7 @@ namespace storm { std::pair<std::vector<T>, std::vector<uint_fast64_t>> result; result.first = std::move(probabilities); result.second = std::move(predecessors); - LOG4CPLUS_INFO(logger, "Done performing Dijkstra search."); + STORM_LOG_INFO("Done performing Dijkstra search."); return result; } diff --git a/test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp b/test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp index b293e2a4f..b2a39f5dd 100644 --- a/test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp +++ b/test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp @@ -78,7 +78,7 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, SynchronousLeader) { EXPECT_NEAR(0.9993949793, quantitativeResult2[0], storm::settings::gmmxxEquationSolverSettings().getPrecision()); labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("elected"); - auto reachabilityRewardFormula = std::make_shared<storm::logic::ReachabilityRewardFormula>(labelFormula); + auto reachabilityRewardFormula = std::make_shared<storm::logic::EventuallyFormula>(labelFormula, storm::logic::FormulaContext::Reward); result = checker.check(*reachabilityRewardFormula); storm::modelchecker::ExplicitQuantitativeCheckResult<double> quantitativeResult3 = result->asExplicitQuantitativeCheckResult<double>(); diff --git a/test/performance/modelchecker/NativeDtmcPrctlModelCheckerTest.cpp b/test/performance/modelchecker/NativeDtmcPrctlModelCheckerTest.cpp index eda9620df..23949131a 100644 --- a/test/performance/modelchecker/NativeDtmcPrctlModelCheckerTest.cpp +++ b/test/performance/modelchecker/NativeDtmcPrctlModelCheckerTest.cpp @@ -79,7 +79,7 @@ TEST(NativeDtmcPrctlModelCheckerTest, SynchronousLeader) { EXPECT_NEAR(0.9993949793, quantitativeResult2[0], storm::settings::gmmxxEquationSolverSettings().getPrecision()); labelFormula = std::make_shared<storm::logic::AtomicLabelFormula>("elected"); - auto reachabilityRewardFormula = std::make_shared<storm::logic::ReachabilityRewardFormula>(labelFormula); + auto reachabilityRewardFormula = std::make_shared<storm::logic::EventuallyFormula>(labelFormula, storm::logic::FormulaContext::Reward); result = checker.check(*reachabilityRewardFormula); storm::modelchecker::ExplicitQuantitativeCheckResult<double> quantitativeResult3 = result->asExplicitQuantitativeCheckResult<double>(); From 5b6dcd0eed4fb795c810ab41f947ccb2fb57af92 Mon Sep 17 00:00:00 2001 From: Mavo <matthias.volk@rwth-aachen.de> Date: Wed, 24 Feb 2016 18:14:18 +0100 Subject: [PATCH 13/23] UsageIndex is number of used child now Former-commit-id: 629aeae3182982c94900a8b890f4a1b81ac8021c --- examples/dft/spare_symmetry.dft | 9 +++++++++ src/storage/dft/DFT.cpp | 29 +++++++++++++++++++++++++---- src/storage/dft/DFT.h | 12 +++++++++++- src/storage/dft/DFTElements.h | 4 ++-- src/storage/dft/DFTState.cpp | 15 +++++++++++++-- src/storage/dft/DFTState.h | 11 +++++++++-- 6 files changed, 69 insertions(+), 11 deletions(-) create mode 100644 examples/dft/spare_symmetry.dft diff --git a/examples/dft/spare_symmetry.dft b/examples/dft/spare_symmetry.dft new file mode 100644 index 000000000..04b5c253b --- /dev/null +++ b/examples/dft/spare_symmetry.dft @@ -0,0 +1,9 @@ +toplevel "A"; +"A" and "B" "C"; +"B" wsp "I" "J"; +"C" wsp "K" "L"; +"I" lambda=0.5 dorm=0.3; +"J" lambda=0.5 dorm=0.3; +"K" lambda=0.5 dorm=0.3; +"L" lambda=0.5 dorm=0.3; + diff --git a/src/storage/dft/DFT.cpp b/src/storage/dft/DFT.cpp index eef83928d..2924789fd 100644 --- a/src/storage/dft/DFT.cpp +++ b/src/storage/dft/DFT.cpp @@ -11,7 +11,7 @@ namespace storm { namespace storage { template<typename ValueType> - DFT<ValueType>::DFT(DFTElementVector const& elements, DFTElementPointer const& tle) : mElements(elements), mNrOfBEs(0), mNrOfSpares(0), mTopLevelIndex(tle->id()) { + DFT<ValueType>::DFT(DFTElementVector const& elements, DFTElementPointer const& tle) : mElements(elements), mNrOfBEs(0), mNrOfSpares(0), mTopLevelIndex(tle->id()), mMaxSpareChildCount(0) { assert(elementIndicesCorrect()); size_t nrRepresentatives = 0; @@ -25,6 +25,7 @@ namespace storm { else if (elem->isSpareGate()) { ++mNrOfSpares; bool firstChild = true; + mMaxSpareChildCount = std::max(mMaxSpareChildCount, std::static_pointer_cast<DFTSpare<ValueType>>(elem)->children().size()); for(auto const& spareReprs : std::static_pointer_cast<DFTSpare<ValueType>>(elem)->children()) { std::set<size_t> module = {spareReprs->id()}; spareReprs->extendSpareModule(module); @@ -63,7 +64,9 @@ namespace storm { } mTopModule = std::vector<size_t>(topModuleSet.begin(), topModuleSet.end()); - size_t usageInfoBits = mElements.size() > 1 ? storm::utility::math::uint64_log2(mElements.size()-1) + 1 : 1; + //Reserve space for failed spares + ++mMaxSpareChildCount; + size_t usageInfoBits = storm::utility::math::uint64_log2(mMaxSpareChildCount) + 1; mStateVectorSize = nrElements() * 2 + mNrOfSpares * usageInfoBits + nrRepresentatives; } @@ -73,7 +76,7 @@ namespace storm { // Collect all elements in the first subtree // TODO make recursive to use for nested subtrees - DFTStateGenerationInfo generationInfo(nrElements()); + DFTStateGenerationInfo generationInfo(nrElements(), mMaxSpareChildCount); // Perform DFS and insert all elements of subtree sequentially size_t stateIndex = 0; @@ -296,7 +299,25 @@ namespace storm { } return stream.str(); } - + + template<typename ValueType> + size_t DFT<ValueType>::getChild(size_t spareId, size_t nrUsedChild) const { + assert(mElements[spareId]->isSpareGate()); + return getGate(spareId)->children()[nrUsedChild]->id(); + } + + template<typename ValueType> + size_t DFT<ValueType>::getNrChild(size_t spareId, size_t childId) const { + assert(mElements[spareId]->isSpareGate()); + DFTElementVector children = getGate(spareId)->children(); + for (size_t nrChild = 0; nrChild < children.size(); ++nrChild) { + if (children[nrChild]->id() == childId) { + return nrChild; + } + } + assert(false); + } + template <typename ValueType> std::vector<size_t> DFT<ValueType>::getIndependentSubDftRoots(size_t index) const { auto elem = getElement(index); diff --git a/src/storage/dft/DFT.h b/src/storage/dft/DFT.h index 453db1443..48bb60f68 100644 --- a/src/storage/dft/DFT.h +++ b/src/storage/dft/DFT.h @@ -45,7 +45,8 @@ namespace storm { public: - DFTStateGenerationInfo(size_t nrElements) : mUsageInfoBits(nrElements > 1 ? storm::utility::math::uint64_log2(nrElements-1) + 1 : 1), mIdToStateIndex(nrElements) { + DFTStateGenerationInfo(size_t nrElements, size_t maxSpareChildCount) : mUsageInfoBits(storm::utility::math::uint64_log2(maxSpareChildCount) + 1), mIdToStateIndex(nrElements) { + assert(maxSpareChildCount < pow(2, mUsageInfoBits)); } size_t usageInfoBits() const { @@ -144,6 +145,7 @@ namespace storm { size_t mNrOfSpares; size_t mTopLevelIndex; size_t mStateVectorSize; + size_t mMaxSpareChildCount; std::map<size_t, std::vector<size_t>> mSpareModules; std::vector<size_t> mDependencies; std::vector<size_t> mTopModule; @@ -175,6 +177,10 @@ namespace storm { return mTopLevelIndex; } + size_t getMaxSpareChildCount() const { + return mMaxSpareChildCount; + } + std::vector<size_t> getSpareIndices() const { std::vector<size_t> indices; for(auto const& elem : mElements) { @@ -288,6 +294,10 @@ namespace storm { return storm::storage::DFTState<ValueType>::isFailsafe(state, stateGenerationInfo.getStateIndex(mTopLevelIndex)); } + size_t getChild(size_t spareId, size_t nrUsedChild) const; + + size_t getNrChild(size_t spareId, size_t childId) const; + std::string getElementsString() const; std::string getInfoString() const; diff --git a/src/storage/dft/DFTElements.h b/src/storage/dft/DFTElements.h index 3236a5551..48318d0ae 100644 --- a/src/storage/dft/DFTElements.h +++ b/src/storage/dft/DFTElements.h @@ -412,12 +412,12 @@ namespace storm { } /** - * Finish failed/failsafe spare gate by activating the children and setting the useIndex to the spare id. + * Finish failed/failsafe spare gate by activating the children and setting the useIndex to the maximum value. * This prevents multiple fail states with different usages or activations. * @param state The current state. */ void finalizeSpare(DFTState<ValueType>& state) const { - state.setUses(this->mId, this->mId); + state.finalizeUses(this->mId); for (auto child : this->children()) { if (!state.isActive(child->id())) { state.activate(child->id()); diff --git a/src/storage/dft/DFTState.cpp b/src/storage/dft/DFTState.cpp index be5c33060..8af84255c 100644 --- a/src/storage/dft/DFTState.cpp +++ b/src/storage/dft/DFTState.cpp @@ -201,7 +201,12 @@ namespace storm { template<typename ValueType> uint_fast64_t DFTState<ValueType>::uses(size_t id) const { - return extractUses(mStateGenerationInfo.getSpareUsageIndex(id)); + size_t nrUsedChild = extractUses(mStateGenerationInfo.getSpareUsageIndex(id)); + if (nrUsedChild == mDft.getMaxSpareChildCount()) { + return id; + } else { + return mDft.getChild(id, nrUsedChild); + } } template<typename ValueType> @@ -217,9 +222,15 @@ namespace storm { template<typename ValueType> void DFTState<ValueType>::setUses(size_t spareId, size_t child) { - mStatus.setFromInt(mStateGenerationInfo.getSpareUsageIndex(spareId), mStateGenerationInfo.usageInfoBits(), child); + mStatus.setFromInt(mStateGenerationInfo.getSpareUsageIndex(spareId), mStateGenerationInfo.usageInfoBits(), mDft.getNrChild(spareId, child)); mUsedRepresentants.push_back(child); } + + template<typename ValueType> + void DFTState<ValueType>::finalizeUses(size_t spareId) { + assert(hasFailed(spareId)); + mStatus.setFromInt(mStateGenerationInfo.getSpareUsageIndex(spareId), mStateGenerationInfo.usageInfoBits(), mDft.getMaxSpareChildCount()); + } template<typename ValueType> bool DFTState<ValueType>::claimNew(size_t spareId, size_t currentlyUses, std::vector<std::shared_ptr<DFTElement<ValueType>>> const& children) { diff --git a/src/storage/dft/DFTState.h b/src/storage/dft/DFTState.h index eccf7f01d..ea874cf1b 100644 --- a/src/storage/dft/DFTState.h +++ b/src/storage/dft/DFTState.h @@ -93,9 +93,10 @@ namespace storm { } /** - * This method gets the usage information for a spare + * This method returns the id of the used child for a spare. If no element is used, it returns the given id. * @param id Id of the spare - * @return The child that currently is used. + * @return The id of the currently used child or if non is used (because of spare failure) the id of + * the spare. */ uint_fast64_t uses(size_t id) const; @@ -120,6 +121,12 @@ namespace storm { */ void setUses(size_t spareId, size_t child); + /** + * Sets the use for the spare to a default value to gain consistent states after failures. + * @param spareId Id of the spare + */ + void finalizeUses(size_t spareId); + bool claimNew(size_t spareId, size_t currentlyUses, std::vector<std::shared_ptr<DFTElement<ValueType>>> const& children); bool hasOutgoingEdges() const { From d32d90de5b7f5a75062ecd1146077b99d4c0489c Mon Sep 17 00:00:00 2001 From: Mavo <matthias.volk@rwth-aachen.de> Date: Wed, 24 Feb 2016 18:18:19 +0100 Subject: [PATCH 14/23] Fixed some compile warnings Former-commit-id: 91055b14cff62f8a06b7cbfad79f504a83f44563 --- src/storage/dft/DFT.h | 4 ++-- src/storage/dft/elements/DFTRestriction.h | 2 +- src/storm-dyftee.cpp | 1 - 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/storage/dft/DFT.h b/src/storage/dft/DFT.h index 48bb60f68..7d10b2ee1 100644 --- a/src/storage/dft/DFT.h +++ b/src/storage/dft/DFT.h @@ -81,8 +81,8 @@ namespace storm { return mSpareActivationIndex.at(id); } - size_t addSymmetry(size_t lenght, std::vector<size_t>& startingIndices) { - mSymmetries.push_back(std::make_pair(lenght, startingIndices)); + void addSymmetry(size_t length, std::vector<size_t>& startingIndices) { + mSymmetries.push_back(std::make_pair(length, startingIndices)); } size_t getSymmetrySize() const { diff --git a/src/storage/dft/elements/DFTRestriction.h b/src/storage/dft/elements/DFTRestriction.h index 46b6e23cc..d0482e4a7 100644 --- a/src/storage/dft/elements/DFTRestriction.h +++ b/src/storage/dft/elements/DFTRestriction.h @@ -183,7 +183,7 @@ namespace storm { } - bool checkDontCareAnymore(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) { + bool checkDontCareAnymore(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const override { } diff --git a/src/storm-dyftee.cpp b/src/storm-dyftee.cpp index ba50d90f3..07bff5732 100644 --- a/src/storm-dyftee.cpp +++ b/src/storm-dyftee.cpp @@ -32,7 +32,6 @@ void analyzeDFT(std::string filename, std::string property, bool symred = false) std::map<size_t, std::vector<std::vector<size_t>>> emptySymmetry; storm::storage::DFTIndependentSymmetries symmetries(emptySymmetry); if(symred) { - std::cout << dft.getElementsString() << std::endl; auto colouring = dft.colourDFT(); symmetries = dft.findSymmetries(colouring); std::cout << "Symmetries: " << symmetries << std::endl; From e0980de0ba6f39fcbdeca662ccfb1b6ac64c79f7 Mon Sep 17 00:00:00 2001 From: sjunges <sebastian.junges@rwth-aachen.de> Date: Wed, 24 Feb 2016 19:14:33 +0100 Subject: [PATCH 15/23] first version of storm without log4cplus as a dependency Former-commit-id: 5aa64fabd71b7f6a02b46de3336d1f1b55de74d6 --- CMakeLists.txt | 30 +++-- src/adapters/GmmxxAdapter.h | 5 +- src/cli/cli.cpp | 12 +- .../AtomicPropositionLabelingParser.cpp | 4 - .../DeterministicSparseTransitionParser.cpp | 6 +- src/parser/MappedFile.cpp | 6 +- src/parser/MarkovAutomatonParser.cpp | 4 - src/parser/NondeterministicModelParser.cpp | 1 + ...NondeterministicSparseTransitionParser.cpp | 6 +- src/parser/SparseStateRewardParser.cpp | 6 +- .../TopologicalMinMaxLinearEquationSolver.cpp | 6 +- src/storage/ModelFormulasPair.h | 2 +- src/storage/SparseMatrix.cpp | 4 - src/utility/cstring.cpp | 6 +- src/utility/graph.cpp | 6 +- src/utility/initialize.cpp | 12 +- src/utility/initialize.h | 7 +- src/utility/macros.h | 127 +++++++++++++++++- storm-config.h.in | 1 + 19 files changed, 170 insertions(+), 81 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b297bca7c..c17fb7774 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,6 +28,7 @@ option(USE_LIBCXX "Sets whether the standard library is libc++." OFF) option(USE_CARL "Sets whether carl should be included." ON) option(FORCE_COLOR "Force color output" OFF) option(STORM_COMPILE_WITH_CCACHE "Compile using CCache" ON) +option(STORM_LOGGING_FRAMEWORK "Use a framework for logging" OFF) set(GUROBI_ROOT "" CACHE STRING "A hint to the root directory of Gurobi (optional).") set(Z3_ROOT "" CACHE STRING "A hint to the root directory of Z3 (optional).") set(CUDA_ROOT "" CACHE STRING "The root directory of CUDA.") @@ -573,20 +574,21 @@ endif() ## Log4CPlus ## ############################################################# -set(BUILD_SHARED_LIBS OFF CACHE BOOL "If TRUE, log4cplus is built as a shared library, otherwise as a static library") -set(LOG4CPLUS_BUILD_LOGGINGSERVER OFF) -set(LOG4CPLUS_BUILD_TESTING OFF) -set(LOG4CPLUS_USE_UNICODE OFF) -set(LOG4CPLUS_DEFINE_INSTALL_TARGET OFF) -add_subdirectory("${PROJECT_SOURCE_DIR}/resources/3rdparty/log4cplus-1.1.3-rc1") -include_directories("${PROJECT_SOURCE_DIR}/resources/3rdparty/log4cplus-1.1.3-rc1/include") -include_directories("${PROJECT_BINARY_DIR}/resources/3rdparty/log4cplus-1.1.3-rc1/include") # This adds the defines.hxx file - -list(APPEND STORM_LINK_LIBRARIES log4cplusS) -if (UNIX AND NOT APPLE) - list(APPEND STORM_LINK_LIBRARIES rt) -endif(UNIX AND NOT APPLE) - +if(STORM_LOGGING_FRAMEWORK) + set(BUILD_SHARED_LIBS OFF CACHE BOOL "If TRUE, log4cplus is built as a shared library, otherwise as a static library") + set(LOG4CPLUS_BUILD_LOGGINGSERVER OFF) + set(LOG4CPLUS_BUILD_TESTING OFF) + set(LOG4CPLUS_USE_UNICODE OFF) + set(LOG4CPLUS_DEFINE_INSTALL_TARGET OFF) + add_subdirectory("${PROJECT_SOURCE_DIR}/resources/3rdparty/log4cplus-1.1.3-rc1") + include_directories("${PROJECT_SOURCE_DIR}/resources/3rdparty/log4cplus-1.1.3-rc1/include") + include_directories("${PROJECT_BINARY_DIR}/resources/3rdparty/log4cplus-1.1.3-rc1/include") # This adds the defines.hxx file + + list(APPEND STORM_LINK_LIBRARIES log4cplusS) + if (UNIX AND NOT APPLE) + list(APPEND STORM_LINK_LIBRARIES rt) + endif(UNIX AND NOT APPLE) +endif() ############################################################# ## ## Intel Threading Building Blocks (optional) diff --git a/src/adapters/GmmxxAdapter.h b/src/adapters/GmmxxAdapter.h index df81b46f7..ad4c82a0e 100644 --- a/src/adapters/GmmxxAdapter.h +++ b/src/adapters/GmmxxAdapter.h @@ -16,10 +16,7 @@ #include "src/storage/SparseMatrix.h" #include "src/utility/ConversionHelper.h" -#include "log4cplus/logger.h" -#include "log4cplus/loggingmacros.h" - -extern log4cplus::Logger logger; +#include "src/utility/macros.h" namespace storm { diff --git a/src/cli/cli.cpp b/src/cli/cli.cpp index 758ac9a2a..0b384b539 100644 --- a/src/cli/cli.cpp +++ b/src/cli/cli.cpp @@ -186,18 +186,14 @@ namespace storm { } if (storm::settings::generalSettings().isVerboseSet()) { - logger.getAppender("mainConsoleAppender")->setThreshold(log4cplus::INFO_LOG_LEVEL); - LOG4CPLUS_INFO(logger, "Enabled verbose mode, log output gets printed to console."); + STORM_GLOBAL_LOGLEVEL_INFO(); } if (storm::settings::debugSettings().isDebugSet()) { - logger.setLogLevel(log4cplus::DEBUG_LOG_LEVEL); - logger.getAppender("mainConsoleAppender")->setThreshold(log4cplus::DEBUG_LOG_LEVEL); - LOG4CPLUS_INFO(logger, "Enabled very verbose mode, log output gets printed to console."); + STORM_GLOBAL_LOGLEVEL_DEBUG(); + } if (storm::settings::debugSettings().isTraceSet()) { - logger.setLogLevel(log4cplus::TRACE_LOG_LEVEL); - logger.getAppender("mainConsoleAppender")->setThreshold(log4cplus::TRACE_LOG_LEVEL); - LOG4CPLUS_INFO(logger, "Enabled trace mode, log output gets printed to console."); + STORM_GLOBAL_LOGLEVEL_TRACE(); } if (storm::settings::debugSettings().isLogfileSet()) { storm::utility::initializeFileLogging(); diff --git a/src/parser/AtomicPropositionLabelingParser.cpp b/src/parser/AtomicPropositionLabelingParser.cpp index 349bfb56b..090a568b7 100644 --- a/src/parser/AtomicPropositionLabelingParser.cpp +++ b/src/parser/AtomicPropositionLabelingParser.cpp @@ -16,10 +16,6 @@ #include "src/exceptions/WrongFormatException.h" #include "src/exceptions/FileIoException.h" -#include "log4cplus/logger.h" -#include "log4cplus/loggingmacros.h" -extern log4cplus::Logger logger; - namespace storm { namespace parser { diff --git a/src/parser/DeterministicSparseTransitionParser.cpp b/src/parser/DeterministicSparseTransitionParser.cpp index f18b46441..da200fe2e 100644 --- a/src/parser/DeterministicSparseTransitionParser.cpp +++ b/src/parser/DeterministicSparseTransitionParser.cpp @@ -17,11 +17,7 @@ #include "src/settings/modules/GeneralSettings.h" #include "src/adapters/CarlAdapter.h" - -#include "log4cplus/logger.h" -#include "log4cplus/loggingmacros.h" -extern log4cplus::Logger logger; - +#include "src/utility/macros.h" namespace storm { namespace parser { diff --git a/src/parser/MappedFile.cpp b/src/parser/MappedFile.cpp index 86f2648eb..b4e8f30f0 100644 --- a/src/parser/MappedFile.cpp +++ b/src/parser/MappedFile.cpp @@ -14,11 +14,7 @@ #include <boost/integer/integer_mask.hpp> #include "src/exceptions/FileIoException.h" - -#include "log4cplus/logger.h" -#include "log4cplus/loggingmacros.h" -extern log4cplus::Logger logger; - +#include "src/utility/macros.h" namespace storm { namespace parser { diff --git a/src/parser/MarkovAutomatonParser.cpp b/src/parser/MarkovAutomatonParser.cpp index b4ee7be34..37eeacbcd 100644 --- a/src/parser/MarkovAutomatonParser.cpp +++ b/src/parser/MarkovAutomatonParser.cpp @@ -8,10 +8,6 @@ #include "src/adapters/CarlAdapter.h" -#include "log4cplus/logger.h" -#include "log4cplus/loggingmacros.h" -extern log4cplus::Logger logger; - namespace storm { namespace parser { diff --git a/src/parser/NondeterministicModelParser.cpp b/src/parser/NondeterministicModelParser.cpp index 220451c33..b2d539c3a 100644 --- a/src/parser/NondeterministicModelParser.cpp +++ b/src/parser/NondeterministicModelParser.cpp @@ -11,6 +11,7 @@ #include "src/parser/SparseChoiceLabelingParser.h" #include "src/adapters/CarlAdapter.h" +#include "src/utility/macros.h" namespace storm { namespace parser { diff --git a/src/parser/NondeterministicSparseTransitionParser.cpp b/src/parser/NondeterministicSparseTransitionParser.cpp index 89322808c..e89fe76e2 100644 --- a/src/parser/NondeterministicSparseTransitionParser.cpp +++ b/src/parser/NondeterministicSparseTransitionParser.cpp @@ -14,11 +14,7 @@ #include "src/utility/cstring.h" #include "src/adapters/CarlAdapter.h" - -#include "log4cplus/logger.h" -#include "log4cplus/loggingmacros.h" -extern log4cplus::Logger logger; - +#include "src/utility/macros.h" namespace storm { namespace parser { diff --git a/src/parser/SparseStateRewardParser.cpp b/src/parser/SparseStateRewardParser.cpp index 35e1c3d59..2207813ab 100644 --- a/src/parser/SparseStateRewardParser.cpp +++ b/src/parser/SparseStateRewardParser.cpp @@ -8,11 +8,7 @@ #include "src/parser/MappedFile.h" #include "src/adapters/CarlAdapter.h" - -#include "log4cplus/logger.h" -#include "log4cplus/loggingmacros.h" -extern log4cplus::Logger logger; - +#include "src/utility/macros.h" namespace storm { namespace parser { diff --git a/src/solver/TopologicalMinMaxLinearEquationSolver.cpp b/src/solver/TopologicalMinMaxLinearEquationSolver.cpp index bb912371b..793842849 100644 --- a/src/solver/TopologicalMinMaxLinearEquationSolver.cpp +++ b/src/solver/TopologicalMinMaxLinearEquationSolver.cpp @@ -13,11 +13,7 @@ #include "src/settings/modules/NativeEquationSolverSettings.h" #include "src/settings/modules/TopologicalValueIterationEquationSolverSettings.h" - -#include "log4cplus/logger.h" -#include "log4cplus/loggingmacros.h" -extern log4cplus::Logger logger; - +#include "src/utility/macros.h" #include "storm-config.h" #ifdef STORM_HAVE_CUDA # include "cudaForStorm.h" diff --git a/src/storage/ModelFormulasPair.h b/src/storage/ModelFormulasPair.h index 490116c46..fab8cb3d1 100644 --- a/src/storage/ModelFormulasPair.h +++ b/src/storage/ModelFormulasPair.h @@ -1,6 +1,6 @@ #pragma once #include "../models/ModelBase.h" - +#include <vector> namespace storm { namespace logic { diff --git a/src/storage/SparseMatrix.cpp b/src/storage/SparseMatrix.cpp index 253609210..3dbabf854 100644 --- a/src/storage/SparseMatrix.cpp +++ b/src/storage/SparseMatrix.cpp @@ -22,10 +22,6 @@ #include "src/utility/macros.h" -#include "log4cplus/logger.h" -#include "log4cplus/loggingmacros.h" -extern log4cplus::Logger logger; - namespace storm { namespace storage { diff --git a/src/utility/cstring.cpp b/src/utility/cstring.cpp index d80059e94..f27ca73a4 100644 --- a/src/utility/cstring.cpp +++ b/src/utility/cstring.cpp @@ -3,11 +3,7 @@ #include <cstring> #include "src/exceptions/WrongFormatException.h" - -#include "log4cplus/logger.h" -#include "log4cplus/loggingmacros.h" -extern log4cplus::Logger logger; - +#include "src/utility/macros.h" namespace storm { namespace utility { diff --git a/src/utility/graph.cpp b/src/utility/graph.cpp index e4839b1aa..de920ad21 100644 --- a/src/utility/graph.cpp +++ b/src/utility/graph.cpp @@ -16,11 +16,7 @@ #include "src/storage/dd/Bdd.h" #include "src/storage/dd/Add.h" #include "src/storage/dd/DdManager.h" - -#include "log4cplus/logger.h" -#include "log4cplus/loggingmacros.h" - -extern log4cplus::Logger logger; +#include "src/utility/macros.h" namespace storm { namespace utility { diff --git a/src/utility/initialize.cpp b/src/utility/initialize.cpp index d5cbb58db..72e3fd964 100644 --- a/src/utility/initialize.cpp +++ b/src/utility/initialize.cpp @@ -4,19 +4,26 @@ #include "src/settings/SettingsManager.h" #include "src/settings/modules/DebugSettings.h" - +#ifdef STORM_LOGGING_FRAMEWORK log4cplus::Logger logger; log4cplus::Logger printer; +#else +int storm_runtime_loglevel = STORM_LOGLEVEL_WARN; +#endif + namespace storm { namespace utility { void initializeLogger() { +#ifdef STORM_LOGGING_FRAMEWORK auto loglevel = storm::settings::debugSettings().isTraceSet() ? log4cplus::TRACE_LOG_LEVEL : storm::settings::debugSettings().isDebugSet() ? log4cplus::DEBUG_LOG_LEVEL : log4cplus::WARN_LOG_LEVEL; initializeLogger(loglevel); +#endif } +#ifdef STORM_LOGGING_FRAMEWORK void initializeLogger(log4cplus::LogLevel const& loglevel) { logger = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("main")); log4cplus::SharedAppenderPtr consoleLogAppender(new log4cplus::ConsoleAppender()); @@ -26,6 +33,7 @@ namespace storm { logger.setLogLevel(loglevel); consoleLogAppender->setThreshold(loglevel); } +#endif void setUp() { initializeLogger(); @@ -37,10 +45,12 @@ namespace storm { } void initializeFileLogging() { +#ifdef STORM_LOGGING_FRAMEWORK log4cplus::SharedAppenderPtr fileLogAppender(new log4cplus::FileAppender(storm::settings::debugSettings().getLogfilename())); fileLogAppender->setName("mainFileAppender"); fileLogAppender->setLayout(std::auto_ptr<log4cplus::Layout>(new log4cplus::PatternLayout("%-5p - %D{%H:%M:%S} (%r ms) - %F:%L: %m%n"))); logger.addAppender(fileLogAppender); +#endif } } diff --git a/src/utility/initialize.h b/src/utility/initialize.h index 06fa8c2fa..dac87fa74 100644 --- a/src/utility/initialize.h +++ b/src/utility/initialize.h @@ -4,10 +4,6 @@ -#include "log4cplus/logger.h" -#include "log4cplus/loggingmacros.h" -#include "log4cplus/consoleappender.h" -#include "log4cplus/fileappender.h" #include "macros.h" #include "src/settings/SettingsManager.h" @@ -19,8 +15,9 @@ namespace storm { * Initializes the logging framework and sets up logging to console. */ void initializeLogger(); +#ifdef STORM_LOGGING_FRAMEWORK void initializeLogger(log4cplus::LogLevel const&); - +#endif /*! * Performs some necessary initializations. */ diff --git a/src/utility/macros.h b/src/utility/macros.h index 037d1882b..79293f3ea 100644 --- a/src/utility/macros.h +++ b/src/utility/macros.h @@ -2,12 +2,113 @@ #define STORM_UTILITY_MACROS_H_ #include <cassert> +#include "storm-config.h" +#ifndef STORM_LOGGING_FRAMEWORK +#include <iostream> +#include <sstream> + +extern int storm_runtime_loglevel; + +#define STORM_LOGLEVEL_ERROR 0 +#define STORM_LOGLEVEL_WARN 1 +#define STORM_LOGLEVEL_INFO 2 +#define STORM_LOGLEVEL_DEBUG 3 +#define STORM_LOGLEVEL_TRACE 4 + +#define STORM_LOG_DEBUG(message) \ +do { \ + if(storm_runtime_loglevel <= STORM_LOGLEVEL_DEBUG) { \ + std::cout << "LOG DBG: " << message << std::endl; \ + } \ +} while (false) + +#define STORM_LOG_TRACE(message) \ +do { \ + std::cout << "LOG TRC: " << message << std::endl; \ +} while(false) + + +// Define STORM_LOG_ASSERT which is only checked when NDEBUG is not set. +#ifndef NDEBUG +#define STORM_LOG_ASSERT(cond, message) \ +do { \ +if (!(cond)) { \ +std::cout << "LOG ERR: " << message << std::endl; \ +assert(cond); \ +} \ +} while (false) \ + +#else +#define STORM_LOG_ASSERT(cond, message) +#endif +// Define STORM_LOG_THROW to always throw the exception with the given message if the condition fails to hold. +#define STORM_LOG_THROW(cond, exception, message) \ +do { \ + if (!(cond)) { \ + std::cout << "LOG ERR: " << message << std::endl; \ + throw exception() << message; \ + } \ +} while (false) \ + + +// Define STORM_LOG_WARN, STORM_LOG_ERROR and STORM_LOG_INFO to log the given message with the corresponding log levels. +#define STORM_LOG_WARN(message) \ +do { \ + std::cout << "LOG WRN: " << message << std::endl; \ +} while (false) \ + +#define STORM_LOG_WARN_COND(cond, message) \ +do { \ + if (!(cond)) { \ + std::cout << "LOG WRN: " << message << std::endl; \ + } \ +} while (false) \ + +#define STORM_LOG_INFO(message) \ +do { \ + std::cout << "LOG INF: " << message << std::endl; \ +} while (false) \ + +#define STORM_LOG_INFO_COND(cond, message) \ +do { \ + if (!(cond)) { \ + std::cout << "LOG INF: " << message << std::endl; \ + } \ +} while (false) \ + +#define STORM_LOG_ERROR(message) \ +do { \ + std::stringstream __ss; \ + __ss << message; \ + std::cout << "LOG ERR: " << __ss.str() << std::endl; \ +} while (false) \ + +#define STORM_LOG_ERROR_COND(cond, message) \ +do { \ + if (!(cond)) { \ + STORM_LOG_ERROR(message) \ + } \ +} while (false) \ + +#define STORM_GLOBAL_LOGLEVEL_INFO() \ +do { \ +} while (false) + +#define STORM_GLOBAL_LOGLEVEL_DEBUG() \ +do { \ +} while(false) + +#define STORM_GLOBAL_LOGLEVEL_TRACE() \ +do { \ +} while(false) + + +#else // Include the parts necessary for Log4cplus. #include "log4cplus/logger.h" #include "log4cplus/loggingmacros.h" extern log4cplus::Logger logger; - /*! * Define the macros STORM_LOG_DEBUG and STORM_LOG_TRACE. */ @@ -81,6 +182,30 @@ do { \ } \ } while (false) \ + +#define STORM_GLOBAL_LOGLEVEL_INFO() \ +do { \ +logger.getAppender("mainConsoleAppender")->setThreshold(log4cplus::INFO_LOG_LEVEL); \ +LOG4CPLUS_INFO(logger, "Enabled verbose mode, log output gets printed to console."); \ +} while (false) + +#define STORM_GLOBAL_LOGLEVEL_DEBUG() \ +do { \ +logger.setLogLevel(log4cplus::DEBUG_LOG_LEVEL); \ +logger.getAppender("mainConsoleAppender")->setThreshold(log4cplus::DEBUG_LOG_LEVEL); \ +LOG4CPLUS_INFO(logger, "Enabled very verbose mode, log output gets printed to console."); \ +} while(false) + +#define STORM_GLOBAL_LOGLEVEL_TRACE() \ +do { \ +logger.setLogLevel(log4cplus::TRACE_LOG_LEVEL); \ +logger.getAppender("mainConsoleAppender")->setThreshold(log4cplus::TRACE_LOG_LEVEL); \ +LOG4CPLUS_INFO(logger, "Enabled trace mode, log output gets printed to console."); \ +} while(false) + + + +#endif /*! * Define the macros that print information and optionally also log it. */ diff --git a/storm-config.h.in b/storm-config.h.in index ec45f1445..e7fbd50e6 100644 --- a/storm-config.h.in +++ b/storm-config.h.in @@ -44,5 +44,6 @@ // Whether smtrat is available and to be used. #cmakedefine STORM_HAVE_SMTRAT +#cmakedefine STORM_LOGGING_FRAMEWORK #endif // STORM_GENERATED_STORMCONFIG_H_ From e0379b9c50668e1dc565f2b2b989dfd2e8d20965 Mon Sep 17 00:00:00 2001 From: sjunges <sebastian.junges@rwth-aachen.de> Date: Wed, 24 Feb 2016 22:25:15 +0100 Subject: [PATCH 16/23] Log CUDD build process Former-commit-id: daf41bb2654b99a08699160937c6218cb18bce8e --- resources/3rdparty/CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/resources/3rdparty/CMakeLists.txt b/resources/3rdparty/CMakeLists.txt index fadcbd3f6..d62f72f95 100644 --- a/resources/3rdparty/CMakeLists.txt +++ b/resources/3rdparty/CMakeLists.txt @@ -32,6 +32,8 @@ ExternalProject_Add( ) add_dependencies(resources glpk) +set(GLPK_LIBRARIES ${CMAKE_BINARY_DIR}/resources/3rdparty/glpk-4.57/lib/libglpk${DYNAMIC_EXT} PARENT_SCOPE) +set(GLPK_INCLUDE_DIR ${CMAKE_BINARY_DIR}/resources/3rdparty/glpk-4.57/include PARENT_SCOPE) ExternalProject_Add( cudd3 @@ -42,6 +44,9 @@ ExternalProject_Add( BUILD_COMMAND make "CFLAGS=-O2 -w" INSTALL_COMMAND make install BUILD_IN_SOURCE 0 + LOG_CONFIGURE ON + LOG_BUILD ON + LOG_INSTALL ON ) add_dependencies(resources cudd3) From abac11ab5070d94f21ae97d2da894d321185b614 Mon Sep 17 00:00:00 2001 From: sjunges <sebastian.junges@rwth-aachen.de> Date: Wed, 24 Feb 2016 22:52:36 +0100 Subject: [PATCH 17/23] sylvan build stuff in 3rd party folder now Former-commit-id: 3ea163dfeda863332440ff3ba19ae3d6747ed60e --- CMakeLists.txt | 21 +++------------------ resources/3rdparty/CMakeLists.txt | 16 ++++++++++++++++ 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c17fb7774..38c216d00 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -260,8 +260,6 @@ endif(STORM_HAVE_Z3) set(STORM_HAVE_GLPK 1) message (STATUS "StoRM - Linking with glpk") -set(GLPK_LIBRARIES ${CMAKE_BINARY_DIR}/resources/3rdparty/glpk-4.57/lib/libglpk${DYNAMIC_EXT}) -set(GLPK_INCLUDE_DIR ${CMAKE_BINARY_DIR}/resources/3rdparty/glpk-4.57/include) include_directories(${GLPK_INCLUDE_DIR}) list(APPEND STORM_LINK_LIBRARIES ${GLPK_LIBRARIES}) @@ -538,28 +536,15 @@ endif() ## ############################################################# -set(STORM_SYLVAN_ROOT "${PROJECT_SOURCE_DIR}/resources/3rdparty/sylvan") -ExternalProject_Add( - sylvan - DOWNLOAD_COMMAND "" - PREFIX "sylvan" - SOURCE_DIR "${STORM_SYLVAN_ROOT}" - CMAKE_ARGS -DSYLVAN_BUILD_TEST=Off -DSYLVAN_BUILD_EXAMPLES=Off -DCMAKE_BUILD_TYPE=Release - BINARY_DIR "${PROJECT_BINARY_DIR}/sylvan" - INSTALL_COMMAND "" - INSTALL_DIR "${PROJECT_BINARY_DIR}/sylvan" -) -ExternalProject_Get_Property(sylvan binary_dir) -set(Sylvan_INCLUDE_DIR "${STORM_SYLVAN_ROOT}/src") message(STATUS "Linking with shipped version of sylvan (in directory ${STORM_SYLVAN_ROOT}).") include_directories("${Sylvan_INCLUDE_DIR}") -list(APPEND STORM_LINK_LIBRARIES "${binary_dir}/src/libsylvan.a") +list(APPEND STORM_LINK_LIBRARIES ${Sylvan_LIBRARY}) if(${OPERATING_SYSTEM} MATCHES "Linux") find_package(Hwloc QUIET) if(NOT Hwloc_FOUND) - message(SEND_ERROR "HWLOC is required but was not found.") + message(SEND_ERROR "HWLOC is required but was not found.") else() - list(APPEND STORM_LINK_LIBRARIES ${Hwloc_LIBRARIES}) + list(APPEND STORM_LINK_LIBRARIES ${Hwloc_LIBRARIES}) endif() endif() diff --git a/resources/3rdparty/CMakeLists.txt b/resources/3rdparty/CMakeLists.txt index d62f72f95..d935a003f 100644 --- a/resources/3rdparty/CMakeLists.txt +++ b/resources/3rdparty/CMakeLists.txt @@ -56,6 +56,22 @@ set(CUDD3_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/cudd-3.0.0/include PARENT_SCOP set(CUDD3_SHARED_LIBRARIES ${CMAKE_CURRENT_BINARY_DIR}/cudd-3.0.0/lib/libcudd${DYNAMIC_EXT} PARENT_SCOPE) set(CUDD3_STATIC_LIBRARIES ${CMAKE_CURRENT_BINARY_DIR}/cudd-3.0.0/liblibcudd${STATIC_EXT} PARENT_SCOPE) +set(STORM_SYLVAN_ROOT "${PROJECT_SOURCE_DIR}/resources/3rdparty/sylvan") +ExternalProject_Add( + sylvan + DOWNLOAD_COMMAND "" + PREFIX "sylvan" + SOURCE_DIR "${STORM_SYLVAN_ROOT}" + CMAKE_ARGS -DSYLVAN_BUILD_TEST=Off -DSYLVAN_BUILD_EXAMPLES=Off -DCMAKE_BUILD_TYPE=Release + BINARY_DIR "${PROJECT_BINARY_DIR}/sylvan" + INSTALL_COMMAND "" + INSTALL_DIR "${PROJECT_BINARY_DIR}/sylvan" +) +ExternalProject_Get_Property(sylvan binary_dir) +set(Sylvan_INCLUDE_DIR "${STORM_SYLVAN_ROOT}/src" PARENT_SCOPE) +set(Sylvan_LIBRARY "${binary_dir}/src/libsylvan.a" PARENT_SCOPE) + + ExternalProject_Add( googletest #For downloads (may be useful later!) From cf986311ad928c23f5691e9d03abad2aff6dee9a Mon Sep 17 00:00:00 2001 From: sjunges <sebastian.junges@rwth-aachen.de> Date: Wed, 24 Feb 2016 22:53:13 +0100 Subject: [PATCH 18/23] loglevel can be set now and all logging macros support streaming Former-commit-id: c8c32b43e64da8e266c471f5d50ae8a3e6495397 --- src/utility/macros.h | 130 ++++++++++++++++++++++++------------------- 1 file changed, 74 insertions(+), 56 deletions(-) diff --git a/src/utility/macros.h b/src/utility/macros.h index 79293f3ea..769825139 100644 --- a/src/utility/macros.h +++ b/src/utility/macros.h @@ -18,92 +18,110 @@ extern int storm_runtime_loglevel; #define STORM_LOG_DEBUG(message) \ do { \ - if(storm_runtime_loglevel <= STORM_LOGLEVEL_DEBUG) { \ - std::cout << "LOG DBG: " << message << std::endl; \ + if(storm_runtime_loglevel >= STORM_LOGLEVEL_DEBUG) { \ + std::stringstream __ss; \ + __ss << message; \ + std::cout << "LOG DBG: " << __ss.str() << std::endl; \ } \ } while (false) -#define STORM_LOG_TRACE(message) \ -do { \ - std::cout << "LOG TRC: " << message << std::endl; \ +#define STORM_LOG_TRACE(message) \ +do { \ + if(storm_runtime_loglevel >= STORM_LOGLEVEL_TRACE) { \ + std::stringstream __ss; \ + __ss << message; \ + std::cout << "LOG TRC: " << message << std::endl; \ + } \ } while(false) // Define STORM_LOG_ASSERT which is only checked when NDEBUG is not set. #ifndef NDEBUG -#define STORM_LOG_ASSERT(cond, message) \ -do { \ -if (!(cond)) { \ -std::cout << "LOG ERR: " << message << std::endl; \ -assert(cond); \ -} \ -} while (false) \ +#define STORM_LOG_ASSERT(cond, message) \ +do { \ +if (!(cond)) { \ +std::cout << "ASSERT FAILED: " << message << std::endl; \ +assert(cond); \ +} \ +} while (false) #else #define STORM_LOG_ASSERT(cond, message) #endif // Define STORM_LOG_THROW to always throw the exception with the given message if the condition fails to hold. -#define STORM_LOG_THROW(cond, exception, message) \ -do { \ - if (!(cond)) { \ +#define STORM_LOG_THROW(cond, exception, message) \ +do { \ + if (!(cond)) { \ std::cout << "LOG ERR: " << message << std::endl; \ - throw exception() << message; \ - } \ -} while (false) \ + throw exception() << message; \ + } \ +} while (false) // Define STORM_LOG_WARN, STORM_LOG_ERROR and STORM_LOG_INFO to log the given message with the corresponding log levels. -#define STORM_LOG_WARN(message) \ -do { \ - std::cout << "LOG WRN: " << message << std::endl; \ -} while (false) \ - -#define STORM_LOG_WARN_COND(cond, message) \ -do { \ - if (!(cond)) { \ - std::cout << "LOG WRN: " << message << std::endl; \ - } \ -} while (false) \ - -#define STORM_LOG_INFO(message) \ -do { \ - std::cout << "LOG INF: " << message << std::endl; \ -} while (false) \ - -#define STORM_LOG_INFO_COND(cond, message) \ -do { \ - if (!(cond)) { \ - std::cout << "LOG INF: " << message << std::endl; \ - } \ -} while (false) \ - -#define STORM_LOG_ERROR(message) \ -do { \ - std::stringstream __ss; \ - __ss << message; \ - std::cout << "LOG ERR: " << __ss.str() << std::endl; \ -} while (false) \ +#define STORM_LOG_WARN(message) \ +do { \ + if(storm_runtime_loglevel >= STORM_LOGLEVEL_WARN) { \ + std::stringstream __ss; \ + __ss << message; \ + std::cout << "LOG WRN: " << message << std::endl; \ + } \ +} while (false) + +#define STORM_LOG_WARN_COND(cond, message) \ +do { \ + if (!(cond)) { \ + STORM_LOG_WARN(message); \ + } \ +} while (false) + +#define STORM_LOG_INFO(message) \ +do { \ + if(storm_runtime_loglevel >= STORM_LOGLEVEL_INFO) { \ + std::stringstream __ss; \ + __ss << message; \ + std::cout << "LOG INF: " << message << std::endl; \ + } \ +} while (false) + +#define STORM_LOG_INFO_COND(cond, message) \ +do { \ + if (!(cond)) { \ + STORM_LOG_INFO(message); \ + } \ +} while (false) + +#define STORM_LOG_ERROR(message) \ +do { \ + if(storm_runtime_loglevel >= STORM_LOGLEVEL_ERROR) { \ + std::stringstream __ss; \ + __ss << message; \ + std::cout << "LOG ERR: " << message << std::endl; \ + } \ +} while (false) \ #define STORM_LOG_ERROR_COND(cond, message) \ do { \ if (!(cond)) { \ - STORM_LOG_ERROR(message) \ + STORM_LOG_ERROR(message); \ } \ } while (false) \ -#define STORM_GLOBAL_LOGLEVEL_INFO() \ -do { \ +#define STORM_GLOBAL_LOGLEVEL_INFO() \ +do { \ +storm_runtime_loglevel = STORM_LOGLEVEL_INFO; \ } while (false) -#define STORM_GLOBAL_LOGLEVEL_DEBUG() \ -do { \ +#define STORM_GLOBAL_LOGLEVEL_DEBUG() \ +do { \ +storm_runtime_loglevel = STORM_LOGLEVEL_DEBUG; \ } while(false) -#define STORM_GLOBAL_LOGLEVEL_TRACE() \ -do { \ +#define STORM_GLOBAL_LOGLEVEL_TRACE() \ +do { \ +storm_runtime_loglevel = STORM_LOGLEVEL_TRACE; \ } while(false) - #else // Include the parts necessary for Log4cplus. #include "log4cplus/logger.h" From fcd98793eecf279eba99d2cff6b45d4ef493d0dc Mon Sep 17 00:00:00 2001 From: sjunges <sebastian.junges@rwth-aachen.de> Date: Thu, 25 Feb 2016 11:44:02 +0100 Subject: [PATCH 19/23] fixed supp for log4cplus Former-commit-id: 7e0b2c449fa78bf216a8e581165baf034484b4a3 --- src/utility/initialize.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/utility/initialize.cpp b/src/utility/initialize.cpp index 72e3fd964..e7909d8ef 100644 --- a/src/utility/initialize.cpp +++ b/src/utility/initialize.cpp @@ -4,7 +4,11 @@ #include "src/settings/SettingsManager.h" #include "src/settings/modules/DebugSettings.h" + #ifdef STORM_LOGGING_FRAMEWORK +#include "log4cplus/consoleappender.h" +#include "log4cplus/fileappender.h" + log4cplus::Logger logger; log4cplus::Logger printer; #else From 6818c6dc0d8da01869368d630dbdd0a92079b61e Mon Sep 17 00:00:00 2001 From: sjunges <sebastian.junges@rwth-aachen.de> Date: Thu, 25 Feb 2016 13:44:58 +0100 Subject: [PATCH 20/23] Fixed tests when no log4plus is available. Former-commit-id: f1ae81376c79043b32e8a05f2a9b5c1a1bed4227 --- test/functional/storm-functional-tests.cpp | 17 +++++++++++------ test/performance/storm-performance-tests.cpp | 14 ++++++++++---- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/test/functional/storm-functional-tests.cpp b/test/functional/storm-functional-tests.cpp index 5051bb659..e206561e0 100644 --- a/test/functional/storm-functional-tests.cpp +++ b/test/functional/storm-functional-tests.cpp @@ -2,21 +2,25 @@ #include <list> #include <string> +#include "storm-config.h" + #include "gtest/gtest.h" +#ifdef STORM_LOGGING_FRAMEWORK #include "log4cplus/logger.h" #include "log4cplus/loggingmacros.h" #include "log4cplus/consoleappender.h" #include "log4cplus/fileappender.h" -#include "storm-config.h" -#include "src/settings/SettingsManager.h" - log4cplus::Logger logger; +#endif + +#include "src/settings/SettingsManager.h" /*! * Initializes the logging framework. */ void setUpLogging() { +#ifdef STORM_LOGGING_FRAMEWORK logger = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("main")); logger.setLogLevel(log4cplus::ERROR_LOG_LEVEL); log4cplus::SharedAppenderPtr fileLogAppender(new log4cplus::FileAppender("storm-functional-tests.log")); @@ -24,7 +28,7 @@ void setUpLogging() { fileLogAppender->setThreshold(log4cplus::FATAL_LOG_LEVEL); fileLogAppender->setLayout(std::auto_ptr<log4cplus::Layout>(new log4cplus::PatternLayout("%-5p - %D{%H:%M} (%r ms) - %F:%L : %m%n"))); logger.addAppender(fileLogAppender); - +#endif // Uncomment these lines to enable console logging output // log4cplus::SharedAppenderPtr consoleLogAppender(new log4cplus::ConsoleAppender()); // consoleLogAppender->setName("mainConsoleAppender"); @@ -39,9 +43,10 @@ int main(int argc, char* argv[]) { testing::InitGoogleTest(&argc, argv); int result = RUN_ALL_TESTS(); - +#ifdef STORM_LOGGING_FRAMEWORK logger.closeNestedAppenders(); - +#endif + std::list<std::string> untestedModules; #ifndef STORM_HAVE_GUROBI untestedModules.push_back("Gurobi"); diff --git a/test/performance/storm-performance-tests.cpp b/test/performance/storm-performance-tests.cpp index 0c29f19c8..3291d6823 100644 --- a/test/performance/storm-performance-tests.cpp +++ b/test/performance/storm-performance-tests.cpp @@ -1,19 +1,24 @@ #include <iostream> #include "gtest/gtest.h" +#include "storm-config.h" + + +#include "src/settings/SettingsManager.h" +#ifdef STORM_LOGGING_FRAMEWORK #include "log4cplus/logger.h" #include "log4cplus/loggingmacros.h" #include "log4cplus/consoleappender.h" #include "log4cplus/fileappender.h" -#include "src/settings/SettingsManager.h" - log4cplus::Logger logger; +#endif /*! * Initializes the logging framework. */ void setUpLogging() { +#ifdef STORM_LOGGING_FRAMEWORK logger = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("main")); logger.setLogLevel(log4cplus::WARN_LOG_LEVEL); log4cplus::SharedAppenderPtr fileLogAppender(new log4cplus::FileAppender("storm-performance-tests.log")); @@ -21,7 +26,7 @@ void setUpLogging() { fileLogAppender->setThreshold(log4cplus::WARN_LOG_LEVEL); fileLogAppender->setLayout(std::auto_ptr<log4cplus::Layout>(new log4cplus::PatternLayout("%-5p - %D{%H:%M} (%r ms) - %F:%L : %m%n"))); logger.addAppender(fileLogAppender); - +#endif // Uncomment these lines to enable console logging output // log4cplus::SharedAppenderPtr consoleLogAppender(new log4cplus::ConsoleAppender()); // consoleLogAppender->setName("mainConsoleAppender"); @@ -36,7 +41,8 @@ int main(int argc, char* argv[]) { testing::InitGoogleTest(&argc, argv); int result = RUN_ALL_TESTS(); - +#ifdef STORM_LOGGING_FRAMEWORK logger.closeNestedAppenders(); +#endif return result; } From 8c2cb4887f73e41bc30d9ef2ae7de9543ba4dba2 Mon Sep 17 00:00:00 2001 From: sjunges <sebastian.junges@rwth-aachen.de> Date: Thu, 25 Feb 2016 13:49:36 +0100 Subject: [PATCH 21/23] Cmake option to disable debug and trace outputs Former-commit-id: 9758862579554eb3f83af62c09cfef5e4dbcd06c --- CMakeLists.txt | 1 + src/utility/macros.h | 32 ++++++++++++++++++++++++++++++-- storm-config.h.in | 2 ++ 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 38c216d00..e19b6266d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,6 +29,7 @@ option(USE_CARL "Sets whether carl should be included." ON) option(FORCE_COLOR "Force color output" OFF) option(STORM_COMPILE_WITH_CCACHE "Compile using CCache" ON) option(STORM_LOGGING_FRAMEWORK "Use a framework for logging" OFF) +option(STORM_LOG_DISABLE_DEBUG "Disable log and trace message support" OFF) set(GUROBI_ROOT "" CACHE STRING "A hint to the root directory of Gurobi (optional).") set(Z3_ROOT "" CACHE STRING "A hint to the root directory of Z3 (optional).") set(CUDA_ROOT "" CACHE STRING "The root directory of CUDA.") diff --git a/src/utility/macros.h b/src/utility/macros.h index 769825139..db1394380 100644 --- a/src/utility/macros.h +++ b/src/utility/macros.h @@ -16,6 +16,12 @@ extern int storm_runtime_loglevel; #define STORM_LOGLEVEL_DEBUG 3 #define STORM_LOGLEVEL_TRACE 4 +#ifdef STORM_LOG_DISABLE_DEBUG +#define STORM_LOG_DISABLE_TRACE +#endif + + +#ifndef STORM_LOG_DISABLE_DEBUG #define STORM_LOG_DEBUG(message) \ do { \ if(storm_runtime_loglevel >= STORM_LOGLEVEL_DEBUG) { \ @@ -24,15 +30,26 @@ do { \ std::cout << "LOG DBG: " << __ss.str() << std::endl; \ } \ } while (false) +#else +#define STORM_LOG_DEBUG(message) \ +do { \ +} while (false) +#endif +#ifndef STORM_LOG_DISABLE_TRACE #define STORM_LOG_TRACE(message) \ do { \ if(storm_runtime_loglevel >= STORM_LOGLEVEL_TRACE) { \ std::stringstream __ss; \ __ss << message; \ - std::cout << "LOG TRC: " << message << std::endl; \ + std::cout << "LOG TRC: " << __ss.str() << std::endl; \ } \ } while(false) +#else +#define STORM_LOG_TRACE(message) \ +do { \ +} while (false) +#endif // Define STORM_LOG_ASSERT which is only checked when NDEBUG is not set. @@ -112,15 +129,26 @@ do { \ storm_runtime_loglevel = STORM_LOGLEVEL_INFO; \ } while (false) +#ifndef STORM_LOG_DISABLE_DEBUG #define STORM_GLOBAL_LOGLEVEL_DEBUG() \ do { \ storm_runtime_loglevel = STORM_LOGLEVEL_DEBUG; \ } while(false) - +#else +#define STORM_GLOBAL_LOGLEVEL_DEBUG() \ +std::cout << "***** warning ***** loglevel debug is not compiled\n" +#endif + +#ifndef STORM_LOG_DISABLE_TRACE #define STORM_GLOBAL_LOGLEVEL_TRACE() \ do { \ storm_runtime_loglevel = STORM_LOGLEVEL_TRACE; \ } while(false) +#else +#define STORM_GLOBAL_LOGLEVEL_TRACE() \ +std::cout << "***** warning ***** loglevel trace is not compiled\n" +#endif + #else // Include the parts necessary for Log4cplus. diff --git a/storm-config.h.in b/storm-config.h.in index e7fbd50e6..7000bd141 100644 --- a/storm-config.h.in +++ b/storm-config.h.in @@ -46,4 +46,6 @@ #cmakedefine STORM_LOGGING_FRAMEWORK +#cmakedefine STORM_LOG_DISABLE_DEBUG + #endif // STORM_GENERATED_STORMCONFIG_H_ From 9c30394b33ce72e4a7b467743910061ae8c49d09 Mon Sep 17 00:00:00 2001 From: Mavo <matthias.volk@rwth-aachen.de> Date: Thu, 25 Feb 2016 14:59:27 +0100 Subject: [PATCH 22/23] Finalize sparse for failed, failsafe, dontcare Former-commit-id: 722285c8d5e4c4d350ae56150bb287f1c8c5d298 --- src/storage/dft/DFTElements.cpp | 13 +++++++--- src/storage/dft/DFTElements.h | 42 ++++++++++++++++----------------- src/storage/dft/DFTState.cpp | 8 ++++--- 3 files changed, 35 insertions(+), 28 deletions(-) diff --git a/src/storage/dft/DFTElements.cpp b/src/storage/dft/DFTElements.cpp index 7bb8c2cf5..3f1d30017 100644 --- a/src/storage/dft/DFTElements.cpp +++ b/src/storage/dft/DFTElements.cpp @@ -17,17 +17,24 @@ namespace storm { return false; } } + + bool hasParentSpare = false; + // Check that no parent can fail anymore for(DFTGatePointer const& parent : mParents) { if(state.isOperational(parent->id())) { return false; } + if (parent->isSpareGate()) { + hasParentSpare = true; + } } - - - state.setDontCare(mId); + if (hasParentSpare && !state.isActive(mId)) { + // Activate child for consistency in failed spares + state.activate(mId); + } return true; } diff --git a/src/storage/dft/DFTElements.h b/src/storage/dft/DFTElements.h index 48318d0ae..0b970355f 100644 --- a/src/storage/dft/DFTElements.h +++ b/src/storage/dft/DFTElements.h @@ -387,10 +387,6 @@ namespace storm { queues.checkRestrictionLater(restr); } state.setFailed(this->mId); - // TODO can this be moved towards DFTSpare? - if (this->isSpareGate()) { - this->finalizeSpare(state); - } this->childrenDontCare(state, queues); } @@ -401,30 +397,13 @@ namespace storm { } } state.setFailsafe(this->mId); - if (this->isSpareGate()) { - this->finalizeSpare(state); - } this->childrenDontCare(state, queues); } - + void childrenDontCare(DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const { queues.propagateDontCare(mChildren); } - /** - * Finish failed/failsafe spare gate by activating the children and setting the useIndex to the maximum value. - * This prevents multiple fail states with different usages or activations. - * @param state The current state. - */ - void finalizeSpare(DFTState<ValueType>& state) const { - state.finalizeUses(this->mId); - for (auto child : this->children()) { - if (!state.isActive(child->id())) { - state.activate(child->id()); - } - } - } - bool hasFailsafeChild(DFTState<ValueType>& state) const { for(auto const& child : mChildren) { if(state.isFailsafe(child->id())) @@ -959,6 +938,24 @@ namespace storm { return true; } + void fail(DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const { + DFTGate<ValueType>::fail(state, queues); + state.finalizeUses(this->mId); + } + + void failsafe(DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const { + DFTGate<ValueType>::failsafe(state, queues); + state.finalizeUses(this->mId); + } + + bool checkDontCareAnymore(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const override { + if (DFTGate<ValueType>::checkDontCareAnymore(state, queues)) { + state.finalizeUses(this->mId); + return true; + } + return false; + } + void checkFails(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const override { if(state.isOperational(this->mId)) { size_t uses = state.uses(this->mId); @@ -979,6 +976,7 @@ namespace storm { } } } + }; template<typename ValueType> diff --git a/src/storage/dft/DFTState.cpp b/src/storage/dft/DFTState.cpp index 8af84255c..7d3b25c8a 100644 --- a/src/storage/dft/DFTState.cpp +++ b/src/storage/dft/DFTState.cpp @@ -179,7 +179,6 @@ namespace storm { size_t activationIndex = mStateGenerationInfo.getSpareActivationIndex(repr); assert(!mStatus[activationIndex]); mStatus.set(activationIndex); - propagateActivation(repr); } template<typename ValueType> @@ -190,11 +189,14 @@ namespace storm { template<typename ValueType> void DFTState<ValueType>::propagateActivation(size_t representativeId) { + if (representativeId != mDft.getTopLevelIndex()) { + activate(representativeId); + } for(size_t elem : mDft.module(representativeId)) { if(mDft.getElement(elem)->isColdBasicElement() && isOperational(elem)) { mIsCurrentlyFailableBE.push_back(elem); } else if (mDft.getElement(elem)->isSpareGate() && !isActive(uses(elem))) { - activate(uses(elem)); + propagateActivation(uses(elem)); } } } @@ -245,7 +247,7 @@ namespace storm { if(!hasFailed(childId) && !isUsed(childId)) { setUses(spareId, childId); if(isActive(currentlyUses)) { - activate(childId); + propagateActivation(childId); } return true; } From fde7b71933e809cb1cc7e4d0513db9e4d050065b Mon Sep 17 00:00:00 2001 From: sjunges <sebastian.junges@rwth-aachen.de> Date: Thu, 25 Feb 2016 15:20:06 +0100 Subject: [PATCH 23/23] Nice printing when no logging framework is enabled Former-commit-id: 783fe7eea12722d4abc1b0187353ddef50ed84e7 --- src/utility/macros.h | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/utility/macros.h b/src/utility/macros.h index db1394380..4f70b1691 100644 --- a/src/utility/macros.h +++ b/src/utility/macros.h @@ -21,13 +21,19 @@ extern int storm_runtime_loglevel; #endif +#define __SHORT_FORM_OF_FILE__ \ +(strrchr(__FILE__,'/') \ +? strrchr(__FILE__,'/')+1 \ +: __FILE__ \ +) + #ifndef STORM_LOG_DISABLE_DEBUG #define STORM_LOG_DEBUG(message) \ do { \ if(storm_runtime_loglevel >= STORM_LOGLEVEL_DEBUG) { \ std::stringstream __ss; \ __ss << message; \ - std::cout << "LOG DBG: " << __ss.str() << std::endl; \ + std::cout << "DEBUG (" << __SHORT_FORM_OF_FILE__ << ":" << __LINE__ << "): " << __ss.str() << std::endl; \ } \ } while (false) #else @@ -42,7 +48,7 @@ do { \ if(storm_runtime_loglevel >= STORM_LOGLEVEL_TRACE) { \ std::stringstream __ss; \ __ss << message; \ - std::cout << "LOG TRC: " << __ss.str() << std::endl; \ + std::cout << "TRACE (" << __SHORT_FORM_OF_FILE__ << ":" << __LINE__ << "): " << __ss.str() << std::endl; \ } \ } while(false) #else @@ -57,7 +63,7 @@ do { \ #define STORM_LOG_ASSERT(cond, message) \ do { \ if (!(cond)) { \ -std::cout << "ASSERT FAILED: " << message << std::endl; \ +std::cout << "ASSERT FAILED (" << __SHORT_FORM_OF_FILE__ << ":" << __LINE__ << "): " << message << std::endl; \ assert(cond); \ } \ } while (false) @@ -69,7 +75,7 @@ assert(cond); \ #define STORM_LOG_THROW(cond, exception, message) \ do { \ if (!(cond)) { \ - std::cout << "LOG ERR: " << message << std::endl; \ + std::cout << "ERROR (" << __SHORT_FORM_OF_FILE__ << ":" << __LINE__ << "): " << message << std::endl; \ throw exception() << message; \ } \ } while (false) @@ -81,7 +87,7 @@ do { \ if(storm_runtime_loglevel >= STORM_LOGLEVEL_WARN) { \ std::stringstream __ss; \ __ss << message; \ - std::cout << "LOG WRN: " << message << std::endl; \ + std::cout << "WARN (" << __SHORT_FORM_OF_FILE__ << ":" << __LINE__ << "): " << __ss.str() << std::endl; \ } \ } while (false) @@ -97,7 +103,7 @@ do { \ if(storm_runtime_loglevel >= STORM_LOGLEVEL_INFO) { \ std::stringstream __ss; \ __ss << message; \ - std::cout << "LOG INF: " << message << std::endl; \ + std::cout << "INFO (" << __SHORT_FORM_OF_FILE__ << ":" << __LINE__ << "): " << __ss.str() << std::endl; \ } \ } while (false) @@ -113,7 +119,7 @@ do { \ if(storm_runtime_loglevel >= STORM_LOGLEVEL_ERROR) { \ std::stringstream __ss; \ __ss << message; \ - std::cout << "LOG ERR: " << message << std::endl; \ + std::cout << "ERROR (" << __SHORT_FORM_OF_FILE__ << ":" << __LINE__ << "): " << __ss.str() << std::endl; \ } \ } while (false) \