diff --git a/src/counterexamples/MILPMinimalLabelSetGenerator.h b/src/counterexamples/MILPMinimalLabelSetGenerator.h index ad581e616..a4c8707c7 100644 --- a/src/counterexamples/MILPMinimalLabelSetGenerator.h +++ b/src/counterexamples/MILPMinimalLabelSetGenerator.h @@ -985,38 +985,38 @@ namespace storm { * @param formulaPtr A pointer to a safety formula. The outermost operator must be a probabilistic bound operator with a strict upper bound. The nested * formula can be either an unbounded until formula or an eventually formula. */ - static void computeCounterexample(storm::prism::Program const& program, storm::models::Mdp<T> const& labeledMdp, storm::property::prctl::AbstractPrctlFormula<double> const* formulaPtr) { + static void computeCounterexample(storm::prism::Program const& program, storm::models::Mdp<T> const& labeledMdp, std::shared_ptr<storm::properties::prctl::AbstractPrctlFormula<double>> const & formulaPtr) { std::cout << std::endl << "Generating minimal label counterexample for formula " << formulaPtr->toString() << std::endl; // First, we need to check whether the current formula is an Until-Formula. - storm::property::prctl::ProbabilisticBoundOperator<double> const* probBoundFormula = dynamic_cast<storm::property::prctl::ProbabilisticBoundOperator<double> const*>(formulaPtr); + auto probBoundFormula = std::dynamic_pointer_cast<storm::properties::prctl::ProbabilisticBoundOperator<double>>(formulaPtr); if (probBoundFormula == nullptr) { LOG4CPLUS_ERROR(logger, "Illegal formula " << probBoundFormula->toString() << " for counterexample generation."); throw storm::exceptions::InvalidPropertyException() << "Illegal formula " << probBoundFormula->toString() << " for counterexample generation."; } - if (probBoundFormula->getComparisonOperator() != storm::property::ComparisonType::LESS && probBoundFormula->getComparisonOperator() != storm::property::ComparisonType::LESS_EQUAL) { + if (probBoundFormula->getComparisonOperator() != storm::properties::ComparisonType::LESS && probBoundFormula->getComparisonOperator() != storm::properties::ComparisonType::LESS_EQUAL) { LOG4CPLUS_ERROR(logger, "Illegal comparison operator in formula " << probBoundFormula->toString() << ". Only upper bounds are supported for counterexample generation."); throw storm::exceptions::InvalidPropertyException() << "Illegal comparison operator in formula " << probBoundFormula->toString() << ". Only upper bounds are supported for counterexample generation."; } - bool strictBound = !(probBoundFormula->getComparisonOperator() == storm::property::ComparisonType::LESS); + bool strictBound = !(probBoundFormula->getComparisonOperator() == storm::properties::ComparisonType::LESS); // Now derive the probability threshold we need to exceed as well as the phi and psi states. Simultaneously, check whether the formula is of a valid shape. double bound = probBoundFormula->getBound(); - storm::property::prctl::AbstractPathFormula<double> const& pathFormula = probBoundFormula->getPathFormula(); + std::shared_ptr<storm::properties::prctl::AbstractPathFormula<double>> pathFormula = probBoundFormula->getChild(); storm::storage::BitVector phiStates; storm::storage::BitVector psiStates; storm::modelchecker::prctl::SparseMdpPrctlModelChecker<T> modelchecker(labeledMdp); try { - storm::property::prctl::Until<double> const& untilFormula = dynamic_cast<storm::property::prctl::Until<double> const&>(pathFormula); + auto untilFormula = std::dynamic_pointer_cast<storm::properties::prctl::Until<double>>(pathFormula); - phiStates = untilFormula.getLeft().check(modelchecker); - psiStates = untilFormula.getRight().check(modelchecker); + phiStates = untilFormula->getLeft()->check(modelchecker); + psiStates = untilFormula->getRight()->check(modelchecker); } catch (std::bad_cast const&) { // If the nested formula was not an until formula, it remains to check whether it's an eventually formula. try { - storm::property::prctl::Eventually<double> const& eventuallyFormula = dynamic_cast<storm::property::prctl::Eventually<double> const&>(pathFormula); + auto eventuallyFormula = std::dynamic_pointer_cast<storm::properties::prctl::Eventually<double>>(pathFormula); phiStates = storm::storage::BitVector(labeledMdp.getNumberOfStates(), true); - psiStates = eventuallyFormula.getChild().check(modelchecker); + psiStates = eventuallyFormula->getChild()->check(modelchecker); } catch (std::bad_cast const&) { // If the nested formula is neither an until nor a finally formula, we throw an exception. throw storm::exceptions::InvalidPropertyException() << "Formula nested inside probability bound operator must be an until or eventually formula for counterexample generation."; diff --git a/src/counterexamples/PathBasedSubsystemGenerator.h b/src/counterexamples/PathBasedSubsystemGenerator.h index 48a175494..d4204a18c 100644 --- a/src/counterexamples/PathBasedSubsystemGenerator.h +++ b/src/counterexamples/PathBasedSubsystemGenerator.h @@ -272,138 +272,6 @@ public: LOG4CPLUS_DEBUG(logger, "Discovery done."); } - /*! - * - *//* - template <typename T> - static void doBackwardsSearch(storm::storage::SparseMatrix<T> const& transMat, storm::storage::BitVector& initStates, storm::storage::BitVector& subSysStates, storm::storage::BitVector& terminalStates, storm::storage::BitVector& allowedStates, std::vector<T>& probabilities, std::vector<uint_fast64_t>& shortestPath, T& probability) { - std::multiset<std::pair<uint_fast64_t, T>, CompareStates<T> > activeSet; - - // resize and init distances - const std::pair<uint_fast64_t, T> initDistances(0, (T) -1); - std::vector<std::pair<uint_fast64_t, T>> distances(transMat.getColumnCount(), initDistances); - - //since the transition matrix only gives a means to iterate over successors and not over predecessors and there is no Transpose for the matrix - //GraphTransitions is used - storm::models::GraphTransitions<T> backTrans(transMat, false); - - //First store all allowed predecessors of target states that are not in the subsystem - for(storm::storage::BitVector::constIndexIterator target = terminalStates.begin(); target != terminalStates.end(); ++target) { - - // if there is a terminal state that is an initial state then prob == 1 and return - if(initStates.get(*target)){ - distances[*target].getColumn() = *target; - distances[*target].getValue() = (T) 1; - return; - } - - //iterate over predecessors - for(auto iter = backTrans.beginStateSuccessorsIterator(*target); iter != backTrans.endStateSuccessorsIterator(*target); iter++) { - //only use if allowed and not in subsys and not terminal - if(allowedStates.get(*iter) && !subSysStates.get(*iter) && !terminalStates.get(*iter)) { - //new state? - if(distances[*iter].getValue() == (T) -1) { - // save as discovered and push into active set - distances[*iter].getColumn() = *target; //successor - distances[*iter].getValue() = transMat.getValue(*iter, *target); //prob of shortest path - - activeSet.insert(std::pair<uint_fast64_t, T>(*iter, probabilities[*iter])); //prob of reaching some terminal state from pred. - } - else { - // state was already discovered - // is this the better transition? - if(distances[*iter].getValue() > transMat.getValue(*iter, *target)) { - distances[*iter].getColumn() = *target; - distances[*iter].getValue() = transMat.getValue(*iter, *target); - } - } - } - } - } - - //Now store all allowed predecessors of subsystem states that are not subsystem states themselves - for(storm::storage::BitVector::constIndexIterator sysState = subSysStates.begin(); sysState != subSysStates.end(); ++sysState) { - //iterate over predecessors - for(auto iter = backTrans.beginStateSuccessorsIterator(*sysState); iter != backTrans.endStateSuccessorsIterator(*sysState); iter++) { - //only use if allowed and not in subsys and not terminal - if(allowedStates.get(*iter) && !subSysStates.get(*iter) && !terminalStates.get(*iter)) { - //new state? - if(distances[*iter].getValue() == (T) -1) { - // save as discovered and push into active set - distances[*iter].getColumn() = *sysState; //successor - distances[*iter].getValue() = transMat.getValue(*iter, *sysState); //prob of shortest path - - activeSet.insert(std::pair<uint_fast64_t, T>(*iter, probabilities[*iter])); //prob of reaching some terminal state from pred. - } - else { - // state was already discovered - // is this the better transition? - if(distances[*iter].getValue() > transMat.getValue(*iter, *sysState)) { - distances[*iter].getColumn() = *sysState; - distances[*iter].getValue() = transMat.getValue(*iter, *sysState); - } - } - } - } - } - - LOG4CPLUS_DEBUG(logger, "Initialized."); - - // Do the backwards search - std::pair<uint_fast64_t, T> state; - uint_fast64_t activeState; - while(!activeSet.empty()) { - // copy here since using a reference leads to segfault - state = *(--activeSet.end()); - activeState = state.getColumn(); - activeSet.erase(--activeSet.end()); - - //stop on the first subsys/init state - if(initStates.get(activeState) || subSysStates.get(activeState)) break; - - // If this is a subSys or terminal state, do not consider its incoming transitions, since all relevant ones have already been considered - if(!terminalStates.get(activeState) && !subSysStates.get(activeState)) { - //iterate over predecessors - for(auto iter = backTrans.beginStateSuccessorsIterator(activeState); iter != backTrans.endStateSuccessorsIterator(activeState); iter++) { - //only if transition is not "virtual" and no selfloop - if(*iter != activeState && transMat.getValue(*iter, activeState) != (T) 0) { - //new state? - if(distances[*iter].getValue() == (T) -1) { - // save as discovered and push into active set - distances[*iter].getColumn() = activeState; - distances[*iter].getValue() = transMat.getValue(*iter, activeState) * distances[activeState].getValue(); - - activeSet.insert(std::pair<uint_fast64_t, T>(*iter, probabilities[*iter])); - } - else { - // state was already discovered - // is this the better transition? - if(distances[*iter].getValue() < transMat.getValue(*iter, activeState) * distances[activeState].getValue()) { - distances[*iter].getColumn() = activeState; - distances[*iter].getValue() = transMat.getValue(*iter, activeState) * distances[activeState].getValue(); - } - } - } - } - } - } - - //get path probability - probability = distances[activeState].getValue(); - if(probability == (T) -1) probability = 1; - - // iterate over the successors until reaching the end of the finite path - shortestPath.push_back(activeState); - activeState = distances[activeState].getColumn(); - while(!terminalStates.get(activeState) && !subSysStates.get(activeState)) { - shortestPath.push_back(activeState); - activeState = distances[activeState].getColumn(); - } - shortestPath.push_back(activeState); - } - - */ - /*! * */ @@ -507,7 +375,7 @@ public: /*! * */ - static storm::models::Dtmc<T> computeCriticalSubsystem(storm::models::Dtmc<T> & model, storm::property::prctl::AbstractStateFormula<T> const& stateFormula) { + static storm::models::Dtmc<T> computeCriticalSubsystem(storm::models::Dtmc<T> & model, std::shared_ptr<storm::properties::prctl::AbstractStateFormula<T>> const & stateFormula) { //------------------------------------------------------------- // 1. Strip and handle formulas @@ -525,27 +393,22 @@ public: // init bit vector to contain the subsystem storm::storage::BitVector subSys(model.getNumberOfStates()); - storm::property::prctl::AbstractPathFormula<T> const* pathFormulaPtr; - T bound = 0; - // Strip bound operator - storm::property::prctl::ProbabilisticBoundOperator<T> const* boundOperator = dynamic_cast<storm::property::prctl::ProbabilisticBoundOperator<T> const*>(&stateFormula); + std::shared_ptr<storm::properties::prctl::ProbabilisticBoundOperator<T>> boundOperator = std::dynamic_pointer_cast<storm::properties::prctl::ProbabilisticBoundOperator<T>>(stateFormula); if(boundOperator == nullptr){ LOG4CPLUS_ERROR(logger, "No path bound operator at formula root."); return model.getSubDtmc(subSys); } - bound = boundOperator->getBound(); - - storm::property::prctl::AbstractPathFormula<T> const& abstractPathFormula = boundOperator->getPathFormula(); - pathFormulaPtr = &abstractPathFormula; + T bound = boundOperator->getBound(); + std::shared_ptr<storm::properties::prctl::AbstractPathFormula<T>> pathFormula = boundOperator->getChild(); // get "init" labeled states storm::storage::BitVector initStates = model.getLabeledStates("init"); //get real prob for formula logger.getAppender("mainFileAppender")->setThreshold(log4cplus::WARN_LOG_LEVEL); - std::vector<T> trueProbs = pathFormulaPtr->check(modelCheck, false); + std::vector<T> trueProbs = pathFormula->check(modelCheck, false); logger.getAppender("mainFileAppender")->setThreshold(log4cplus::INFO_LOG_LEVEL); T trueProb = 0; @@ -559,22 +422,22 @@ public: storm::storage::BitVector allowedStates; storm::storage::BitVector targetStates; - storm::property::prctl::Eventually<T> const* eventually = dynamic_cast<storm::property::prctl::Eventually<T> const*>(pathFormulaPtr); - storm::property::prctl::Globally<T> const* globally = dynamic_cast<storm::property::prctl::Globally<T> const*>(pathFormulaPtr); - storm::property::prctl::Until<T> const* until = dynamic_cast<storm::property::prctl::Until<T> const*>(pathFormulaPtr); - if(eventually != nullptr) { - targetStates = eventually->getChild().check(modelCheck); + std::shared_ptr<storm::properties::prctl::Eventually<T>> eventually = std::dynamic_pointer_cast<storm::properties::prctl::Eventually<T>>(pathFormula); + std::shared_ptr<storm::properties::prctl::Globally<T>> globally = std::dynamic_pointer_cast<storm::properties::prctl::Globally<T>>(pathFormula); + std::shared_ptr<storm::properties::prctl::Until<T>> until = std::dynamic_pointer_cast<storm::properties::prctl::Until<T>>(pathFormula); + if(eventually.get() != nullptr) { + targetStates = eventually->getChild()->check(modelCheck); allowedStates = storm::storage::BitVector(targetStates.size(), true); } - else if(globally != nullptr){ + else if(globally.get() != nullptr){ //eventually reaching a state without property visiting only states with property - allowedStates = globally->getChild().check(modelCheck); + allowedStates = globally->getChild()->check(modelCheck); targetStates = storm::storage::BitVector(allowedStates); targetStates.complement(); } - else if(until != nullptr) { - allowedStates = until->getLeft().check(modelCheck); - targetStates = until->getRight().check(modelCheck); + else if(until.get() != nullptr) { + allowedStates = until->getLeft()->check(modelCheck); + targetStates = until->getRight()->check(modelCheck); } else { LOG4CPLUS_ERROR(logger, "Strange path formula. Can't decipher."); diff --git a/src/counterexamples/SMTMinimalCommandSetGenerator.h b/src/counterexamples/SMTMinimalCommandSetGenerator.h index 94f550141..06cdfd3a7 100644 --- a/src/counterexamples/SMTMinimalCommandSetGenerator.h +++ b/src/counterexamples/SMTMinimalCommandSetGenerator.h @@ -1785,42 +1785,41 @@ namespace storm { #ifdef STORM_HAVE_Z3 std::cout << std::endl << "Generating minimal label counterexample for formula " << formulaPtr->toString() << std::endl; // First, we need to check whether the current formula is an Until-Formula. - storm::property::prctl::ProbabilisticBoundOperator<double> const* probBoundFormula = dynamic_cast<storm::property::prctl::ProbabilisticBoundOperator<double> const*>(formulaPtr); - if (probBoundFormula == nullptr) { + std::shared_ptr<storm::properties::prctl::ProbabilisticBoundOperator<double>> probBoundFormula = std::dynamic_pointer_cast<storm::properties::prctl::ProbabilisticBoundOperator<double>>(formulaPtr); + if (probBoundFormula.get() == nullptr) { LOG4CPLUS_ERROR(logger, "Illegal formula " << probBoundFormula->toString() << " for counterexample generation."); throw storm::exceptions::InvalidPropertyException() << "Illegal formula " << probBoundFormula->toString() << " for counterexample generation."; } // Check whether we were given an upper bound, because counterexample generation is limited to this case. - if (probBoundFormula->getComparisonOperator() != storm::property::ComparisonType::LESS && probBoundFormula->getComparisonOperator() != storm::property::ComparisonType::LESS_EQUAL) { + if (probBoundFormula->getComparisonOperator() != storm::properties::ComparisonType::LESS && probBoundFormula->getComparisonOperator() != storm::properties::ComparisonType::LESS_EQUAL) { LOG4CPLUS_ERROR(logger, "Illegal comparison operator in formula " << probBoundFormula->toString() << ". Only upper bounds are supported for counterexample generation."); throw storm::exceptions::InvalidPropertyException() << "Illegal comparison operator in formula " << probBoundFormula->toString() << ". Only upper bounds are supported for counterexample generation."; } - bool strictBound = probBoundFormula->getComparisonOperator() == storm::property::ComparisonType::LESS; + bool strictBound = probBoundFormula->getComparisonOperator() == storm::properties::ComparisonType::LESS; // Now derive the probability threshold we need to exceed as well as the phi and psi states. Simultaneously, check whether the formula is of a valid shape. double bound = probBoundFormula->getBound(); - storm::property::prctl::AbstractPathFormula<double> const& pathFormula = probBoundFormula->getPathFormula(); + std::shared_ptr<storm::properties::prctl::AbstractPathFormula<double>> pathFormula = probBoundFormula->getPathFormula(); storm::storage::BitVector phiStates; storm::storage::BitVector psiStates; storm::modelchecker::prctl::SparseMdpPrctlModelChecker<T> modelchecker(labeledMdp); - try { - storm::property::prctl::Until<double> const& untilFormula = dynamic_cast<storm::property::prctl::Until<double> const&>(pathFormula); - - phiStates = untilFormula.getLeft().check(modelchecker); - psiStates = untilFormula.getRight().check(modelchecker); - } catch (std::bad_cast const&) { + + std::shared_ptr<storm::properties::prctl::Until<double>> untilFormula = std::dynamic_pointer_cast<storm::properties::prctl::Until<double>>(pathFormula); + if(untilFormula.get() != nullptr) { + phiStates = untilFormula->getLeft()->check(modelchecker); + psiStates = untilFormula->getRight()->check(modelchecker); + + } if (std::dynamic_pointer_cast<storm::properties::prctl::Eventually<double>>(pathFormula).get() != nullptr) { // If the nested formula was not an until formula, it remains to check whether it's an eventually formula. - try { - storm::property::prctl::Eventually<double> const& eventuallyFormula = dynamic_cast<storm::property::prctl::Eventually<double> const&>(pathFormula); - - phiStates = storm::storage::BitVector(labeledMdp.getNumberOfStates(), true); - psiStates = eventuallyFormula.getChild().check(modelchecker); - } catch (std::bad_cast const&) { - // If the nested formula is neither an until nor a finally formula, we throw an exception. - LOG4CPLUS_ERROR(logger, "Formula nested inside probability bound operator must be an until or eventually formula for counterexample generation."); - throw storm::exceptions::InvalidPropertyException() << "Formula nested inside probability bound operator must be an until or eventually formula for counterexample generation."; - } + std::shared_ptr<storm::properties::prctl::Eventually<double>> eventuallyFormula = std::dynamic_pointer_cast<storm::properties::prctl::Eventually<double>>(pathFormula); + + phiStates = storm::storage::BitVector(labeledMdp.getNumberOfStates(), true); + psiStates = eventuallyFormula->getChild()->check(modelchecker); + + } else { + // If the nested formula is neither an until nor a finally formula, we throw an exception. + throw storm::exceptions::InvalidPropertyException() << "Formula nested inside probability bound operator must be an until or eventually formula for counterexample generation."; } // Delegate the actual computation work to the function of equal name. diff --git a/src/formula/AbstractFormulaChecker.h b/src/formula/AbstractFormulaChecker.h deleted file mode 100644 index 92858bfac..000000000 --- a/src/formula/AbstractFormulaChecker.h +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef STORM_FORMULA_ABSTRACTFORMULACHECKER_H_ -#define STORM_FORMULA_ABSTRACTFORMULACHECKER_H_ - -namespace storm { -namespace property { - -template <class T> class AbstractFormulaChecker; - -} //namespace property -} //namespace storm - - -#include "src/formula/abstract/AbstractFormula.h" - -namespace storm { -namespace property { - -/*! - * @brief Base class for all formula checkers. - * - * A formula checker is used to check if a given formula is valid in some - * logic. Hence, this pure virtual base class should be subclassed for - * every logic we support. - * - * Every subclass must implement validate(). It gets a pointer to an - * AbstractFormula object and should return if the subtree represented by - * this formula is valid in the logic. - * - * Usually, this will be implemented like this: - * @code - * if ( - * dynamic_cast<const And<T>*>(formula) || - * dynamic_cast<const Not<T>*>(formula) || - * dynamic_cast<const Or<T>*>(formula) - * ) { - * return formula->validate(*this); - * } else return false; - * @endcode - * - * Every formula class implements a validate() method itself which calls - * validate() on the given checker for every child in the formula tree. - * - * If the formula structure is not an actual tree, but an directed acyclic - * graph, the shared subtrees will be checked twice. If we have directed - * cycles, we will have infinite recursions. - */ -template <class T> -class AbstractFormulaChecker { - public: - /*! - * Virtual destructor - * To ensure that the right destructor is called - */ - virtual ~AbstractFormulaChecker() { - //intentionally left empty - } - - /*! - * @brief Checks if the given formula is valid in some logic. - * - * Every subclass must implement this method and check, if the - * formula object is valid in the logic of the subclass. - * - * @param formula A pointer to some formula object. - * @return true iff the formula is valid. - */ - virtual bool validate(const storm::property::abstract::AbstractFormula<T>* formula) const = 0; -}; - -} // namespace property -} // namespace storm - -#endif diff --git a/src/formula/Csl.h b/src/formula/Csl.h deleted file mode 100644 index a6a6c4e67..000000000 --- a/src/formula/Csl.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Csl.h - * - * Created on: 19.04.2013 - * Author: Thomas Heinemann - */ - -#ifndef STORM_FORMULA_CSL_H_ -#define STORM_FORMULA_CSL_H_ - -#include "src/modelchecker/csl/ForwardDeclarations.h" - -#include "Csl/And.h" -#include "Csl/Ap.h" -#include "Csl/Next.h" -#include "Csl/Not.h" -#include "Csl/Or.h" -#include "Csl/ProbabilisticNoBoundOperator.h" -#include "Csl/ProbabilisticBoundOperator.h" -#include "Csl/SteadyStateNoBoundOperator.h" -#include "Csl/SteadyStateBoundOperator.h" - -#include "Csl/Until.h" -#include "Csl/Eventually.h" -#include "Csl/Globally.h" -#include "Csl/TimeBoundedEventually.h" -#include "Csl/TimeBoundedUntil.h" - -#include "modelchecker/csl/AbstractModelChecker.h" - -#endif /* STORM_FORMULA_CSL_H_ */ diff --git a/src/formula/Csl/AbstractCslFormula.h b/src/formula/Csl/AbstractCslFormula.h deleted file mode 100644 index 1c8503180..000000000 --- a/src/formula/Csl/AbstractCslFormula.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * AbstractCslFormula.h - * - * Created on: 19.04.2013 - * Author: Thomas Heinemann - */ - -#ifndef ABSTRACTCSLFORMULA_H_ -#define ABSTRACTCSLFORMULA_H_ - -#include "src/formula/abstract/AbstractFormula.h" - -namespace storm { -namespace property { -namespace csl { - -/*! - * Abstract base class for all CSL root formulas. - */ -template <class T> -class AbstractCslFormula : public virtual storm::property::abstract::AbstractFormula<T>{ -public: - virtual ~AbstractCslFormula() { - // Intentionally left empty - } -}; - -} /* namespace csl */ -} /* namespace property */ -} /* namespace storm */ -#endif /* ABSTRACTCSLFORMULA_H_ */ diff --git a/src/formula/Csl/AbstractNoBoundOperator.h b/src/formula/Csl/AbstractNoBoundOperator.h deleted file mode 100644 index 9960e8de2..000000000 --- a/src/formula/Csl/AbstractNoBoundOperator.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * AbstractNoBoundOperator.h - * - * Created on: 16.04.2013 - * Author: thomas - */ - -#ifndef STORM_FORMULA_CSL_ABSTRACTNOBOUNDOPERATOR_H_ -#define STORM_FORMULA_CSL_ABSTRACTNOBOUNDOPERATOR_H_ - -#include "AbstractCslFormula.h" -#include "src/formula/abstract/IOptimizingOperator.h" - -namespace storm { -namespace property { -namespace csl { - -template <class T> -class AbstractNoBoundOperator; - -/*! - * @brief Interface class for model checkers that support PathNoBoundOperator. - * - * All model checkers that support the formula class NoBoundOperator must inherit - * this pure virtual class. - */ -template <class T> -class INoBoundOperatorModelChecker { -public: - /*! - * @brief Evaluates NoBoundOperator formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual std::vector<T> checkNoBoundOperator(const AbstractNoBoundOperator<T>& obj) const = 0; - - -}; - -/*! - * Interface class for all CSL No Bound operators. - */ -template <class T> -class AbstractNoBoundOperator: public AbstractCslFormula<T>, - public virtual storm::property::abstract::IOptimizingOperator { -public: - AbstractNoBoundOperator() { - // Intentionally left empty - - } - virtual ~AbstractNoBoundOperator() { - // Intentionally left empty - } - - /*! - * Clones the called object. - * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones - * - * @note This function is not implemented in this class. - * @returns a new AND-object that is identical the called object. - */ - virtual AbstractNoBoundOperator<T>* clone() const = 0; - - /*! - * Calls the model checker to check this formula. - * Needed to infer the correct type of formula class. - * - * @note This function should only be called in a generic check function of a model checker class. For other uses, - * the methods of the model checker should be used. - * - * @note This function is not implemented in this class. - * - * @returns A vector indicating the probability that the formula holds for each state. - */ - virtual std::vector<T> check(const storm::modelchecker::csl::AbstractModelChecker<T>& modelChecker, bool qualitative=false) const = 0; -}; - -} /* namespace csl */ -} /* namespace property */ -} /* namespace storm */ -#endif /* STORM_FORMULA_CSL_ABSTRACTNOBOUNDOPERATOR_H_ */ diff --git a/src/formula/Csl/And.h b/src/formula/Csl/And.h deleted file mode 100644 index efed92f17..000000000 --- a/src/formula/Csl/And.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - * And.h - * - * Created on: 19.10.2012 - * Author: Thomas Heinemann - */ - -#ifndef STORM_FORMULA_CSL_AND_H_ -#define STORM_FORMULA_CSL_AND_H_ - -#include "AbstractStateFormula.h" -#include "src/formula/abstract/And.h" -#include "src/formula/AbstractFormulaChecker.h" -#include "src/modelchecker/csl/ForwardDeclarations.h" -#include <string> - -namespace storm { -namespace property { -namespace csl { - -template <class T> class And; - -/*! - * @brief Interface class for model checkers that support And. - * - * All model checkers that support the formula class And must inherit - * this pure virtual class. - */ -template <class T> -class IAndModelChecker { - public: - /*! - * @brief Evaluates And formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual storm::storage::BitVector checkAnd(const And<T>& obj) const = 0; -}; - -/*! - * @brief - * Class for an abstract formula tree with AND node as root. - * - * Has two Abstract state formulas as sub formulas/trees. - * - * As AND is commutative, the order is \e theoretically not important, but will influence the order in which - * the model checker works. - * - * The subtrees are seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @see AbstractStateFormula - * @see AbstractCslFormula - */ -template <class T> -class And : public storm::property::abstract::And<T, AbstractStateFormula<T>>, public AbstractStateFormula<T> { - -public: - /*! - * Empty constructor. - * Will create an AND-node without subnotes. Will not represent a complete formula! - */ - And() { - //intentionally left empty - } - - /*! - * Constructor. - * Creates an AND note with the parameters as subtrees. - * - * @param left The left sub formula - * @param right The right sub formula - */ - And(AbstractStateFormula<T>* left, AbstractStateFormula<T>* right) - : storm::property::abstract::And<T, AbstractStateFormula<T>>(left, right) { - //intentionally left empty - } - - /*! - * Destructor. - * - * The subtrees are deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - */ - virtual ~And() { - //intentionally left empty - } - - /*! - * Clones the called object. - * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones - * - * @returns a new AND-object that is identical the called object. - */ - virtual AbstractStateFormula<T>* clone() const override { - And<T>* result = new And(); - if (this->leftIsSet()) { - result->setLeft(this->getLeft().clone()); - } - if (this->rightIsSet()) { - result->setRight(this->getRight().clone()); - } - return result; - } - - /*! - * Calls the model checker to check this formula. - * Needed to infer the correct type of formula class. - * - * @note This function should only be called in a generic check function of a model checker class. For other uses, - * the methods of the model checker should be used. - * - * @returns A bit vector indicating all states that satisfy the formula represented by the called object. - */ - virtual storm::storage::BitVector check(const storm::modelchecker::csl::AbstractModelChecker<T>& modelChecker) const override { - return modelChecker.template as<IAndModelChecker>()->checkAnd(*this); - } - -}; - -} //namespace csl - -} //namespace property - -} //namespace storm - -#endif /* STORM_FORMULA_CSL_AND_H_ */ diff --git a/src/formula/Csl/Ap.h b/src/formula/Csl/Ap.h deleted file mode 100644 index cebd9aa49..000000000 --- a/src/formula/Csl/Ap.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Ap.h - * - * Created on: 19.10.2012 - * Author: Thomas Heinemann - */ - -#ifndef STORM_FORMULA_CSL_AP_H_ -#define STORM_FORMULA_CSL_AP_H_ - -#include "AbstractStateFormula.h" -#include "src/formula/abstract/Ap.h" -#include "src/formula/AbstractFormulaChecker.h" -#include "src/modelchecker/csl/ForwardDeclarations.h" - -namespace storm { -namespace property { -namespace csl { - -template <class T> class Ap; - -/*! - * @brief Interface class for model checkers that support Ap. - * - * All model checkers that support the formula class Ap must inherit - * this pure virtual class. - */ -template <class T> -class IApModelChecker { - public: - /*! - * @brief Evaluates Ap formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual storm::storage::BitVector checkAp(const Ap<T>& obj) const = 0; -}; - -/*! - * @brief - * Class for an abstract formula tree with atomic proposition as root. - * - * This class represents the leaves in the formula tree. - * - * @see AbstractCslFormula - * @see AbstractStateFormula - */ -template <class T> -class Ap : public storm::property::abstract::Ap<T>, - public AbstractStateFormula<T> { - -public: - /*! - * Constructor - * - * Creates a new atomic proposition leaf, with the label Ap - * - * @param ap The string representing the atomic proposition - */ - Ap(std::string ap) - : storm::property::abstract::Ap<T>(ap) { - // Intentionally left empty - } - - /*! - * Destructor. - * At this time, empty... - */ - virtual ~Ap() { - // Intentionally left empty - } - - /*! - * Clones the called object. - * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones - * - * @returns a new AND-object that is identical the called object. - */ - virtual AbstractStateFormula<T>* clone() const override { - return new Ap(this->getAp()); - } - - /*! - * Calls the model checker to check this formula. - * Needed to infer the correct type of formula class. - * - * @note This function should only be called in a generic check function of a model checker class. For other uses, - * the methods of the model checker should be used. - * - * @returns A bit vector indicating all states that satisfy the formula represented by the called object. - */ - virtual storm::storage::BitVector check(const storm::modelchecker::csl::AbstractModelChecker<T>& modelChecker) const override { - return modelChecker.template as<IApModelChecker>()->checkAp(*this); - } - -}; - -} //namespace abstract - -} //namespace property - -} //namespace storm - -#endif /* STORM_FORMULA_CSL_AP_H_ */ diff --git a/src/formula/Csl/Eventually.h b/src/formula/Csl/Eventually.h deleted file mode 100644 index 5553d16c7..000000000 --- a/src/formula/Csl/Eventually.h +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Next.h - * - * Created on: 26.12.2012 - * Author: Christian Dehnert - */ - -#ifndef STORM_FORMULA_CSL_EVENTUALLY_H_ -#define STORM_FORMULA_CSL_EVENTUALLY_H_ - -#include "src/formula/abstract/Eventually.h" -#include "src/formula/Csl/AbstractPathFormula.h" -#include "src/formula/Csl/AbstractStateFormula.h" -#include "src/modelchecker/csl/ForwardDeclarations.h" - -namespace storm { -namespace property { -namespace csl { - -template <class T> class Eventually; - -/*! - * @brief Interface class for model checkers that support Eventually. - * - * All model checkers that support the formula class Eventually must inherit - * this pure virtual class. - */ -template <class T> -class IEventuallyModelChecker { - public: - /*! - * @brief Evaluates Eventually formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual std::vector<T> checkEventually(const Eventually<T>& obj, bool qualitative) const = 0; -}; - -/*! - * @brief - * Class for an abstract (path) formula tree with an Eventually node as root. - * - * Has one Abstract state formula as sub formula/tree. - * - * @par Semantics - * The formula holds iff eventually \e child holds. - * - * The subtree is seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to nullptr before deletion) - * - * @see AbstractPathFormula - * @see AbstractCslFormula - */ -template <class T> -class Eventually : public storm::property::abstract::Eventually<T, AbstractStateFormula<T>>, - public AbstractPathFormula<T> { - -public: - /*! - * Empty constructor - */ - Eventually() { - // Intentionally left empty - } - - /*! - * Constructor - * - * @param child The child node - */ - Eventually(AbstractStateFormula<T>* child) - : storm::property::abstract::Eventually<T, AbstractStateFormula<T>>(child) { - - } - - /*! - * Constructor. - * - * Also deletes the subtree. - * (this behaviour can be prevented by setting the subtrees to nullptr before deletion) - */ - virtual ~Eventually() { - //intentionally left empty - } - - /*! - * Clones the called object. - * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones - * - * @returns a new Eventually-object that is identical the called object. - */ - virtual AbstractPathFormula<T>* clone() const override { - Eventually<T>* result = new Eventually<T>(); - if (this->childIsSet()) { - result->setChild(this->getChild().clone()); - } - return result; - } - - /*! - * Calls the model checker to check this formula. - * Needed to infer the correct type of formula class. - * - * @note This function should only be called in a generic check function of a model checker class. For other uses, - * the methods of the model checker should be used. - * - * @returns A vector indicating the probability that the formula holds for each state. - */ - virtual std::vector<T> check(const storm::modelchecker::csl::AbstractModelChecker<T>& modelChecker, bool qualitative) const override { - return modelChecker.template as<IEventuallyModelChecker>()->checkEventually(*this, qualitative); - } -}; - -} //namespace csl -} //namespace property -} //namespace storm - -#endif /* STORM_FORMULA_CSL_EVENTUALLY_H_ */ diff --git a/src/formula/Csl/Globally.h b/src/formula/Csl/Globally.h deleted file mode 100644 index 954b59fd4..000000000 --- a/src/formula/Csl/Globally.h +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Next.h - * - * Created on: 26.12.2012 - * Author: Christian Dehnert - */ - -#ifndef STORM_FORMULA_CSL_GLOBALLY_H_ -#define STORM_FORMULA_CSL_GLOBALLY_H_ - -#include "src/formula/abstract/Globally.h" -#include "AbstractPathFormula.h" -#include "AbstractStateFormula.h" -#include "src/formula/AbstractFormulaChecker.h" -#include "src/modelchecker/csl/ForwardDeclarations.h" - -namespace storm { -namespace property { -namespace csl { - -template <class T> class Globally; - -/*! - * @brief Interface class for model checkers that support Globally. - * - * All model checkers that support the formula class Globally must inherit - * this pure virtual class. - */ -template <class T> -class IGloballyModelChecker { - public: - /*! - * @brief Evaluates Globally formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual std::vector<T> checkGlobally(const Globally<T>& obj, bool qualitative) const = 0; -}; - -/*! - * @brief - * Class for an abstract (path) formula tree with a Globally node as root. - * - * Has one Abstract state formula as sub formula/tree. - * - * @par Semantics - * The formula holds iff globally \e child holds. - * - * The subtree is seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to nullptr before deletion) - * - * @see AbstractPathFormula - * @see AbstractCslFormula - */ -template <class T> -class Globally : public storm::property::abstract::Globally<T, AbstractStateFormula<T>>, - public AbstractPathFormula<T> { - -public: - /*! - * Empty constructor - */ - Globally() { - //intentionally left empty - } - - /*! - * Constructor - * - * @param child The child node - */ - Globally(AbstractStateFormula<T>* child) - : storm::property::abstract::Globally<T, AbstractStateFormula<T>>(child) { - //intentionally left empty - } - - /*! - * Constructor. - * - * Also deletes the subtree. - * (this behaviour can be prevented by setting the subtrees to nullptr before deletion) - */ - virtual ~Globally() { - //intentionally left empty - } - - - /*! - * Clones the called object. - * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones - * - * @returns a new Globally-object that is identical the called object. - */ - virtual AbstractPathFormula<T>* clone() const override { - Globally<T>* result = new Globally<T>(); - if (this->childIsSet()) { - result->setChild(this->getChild().clone()); - } - return result; - } - - /*! - * Calls the model checker to check this formula. - * Needed to infer the correct type of formula class. - * - * @note This function should only be called in a generic check function of a model checker class. For other uses, - * the methods of the model checker should be used. - * - * @returns A vector indicating the probability that the formula holds for each state. - */ - virtual std::vector<T> check(const storm::modelchecker::csl::AbstractModelChecker<T>& modelChecker, bool qualitative) const override { - return modelChecker.template as<IGloballyModelChecker>()->checkGlobally(*this, qualitative); - } -}; - -} //namespace csl -} //namespace property -} //namespace storm - -#endif /* STORM_FORMULA_CSL_GLOBALLY_H_ */ diff --git a/src/formula/Csl/Next.h b/src/formula/Csl/Next.h deleted file mode 100644 index 338d119e5..000000000 --- a/src/formula/Csl/Next.h +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Next.h - * - * Created on: 19.10.2012 - * Author: Thomas Heinemann - */ - -#ifndef STORM_FORMULA_CSL_NEXT_H_ -#define STORM_FORMULA_CSL_NEXT_H_ - -#include "AbstractPathFormula.h" -#include "AbstractStateFormula.h" -#include "src/formula/abstract/Next.h" -#include "src/formula/AbstractFormulaChecker.h" - -namespace storm { -namespace property { -namespace csl { - -template <class T> class Next; - -/*! - * @brief Interface class for model checkers that support Next. - * - * All model checkers that support the formula class Next must inherit - * this pure virtual class. - */ -template <class T> -class INextModelChecker { - public: - /*! - * @brief Evaluates Next formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual std::vector<T> checkNext(const Next<T>& obj, bool qualitative) const = 0; -}; - -/*! - * @brief - * Class for an abstract (path) formula tree with a Next node as root. - * - * Has two Abstract state formulas as sub formulas/trees. - * - * @par Semantics - * The formula holds iff in the next step, \e child holds - * - * The subtree is seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @see AbstractPathFormula - * @see AbstractCslFormula - */ -template <class T> -class Next : public storm::property::abstract::Next<T, AbstractStateFormula<T>>, - public AbstractPathFormula<T> { - -public: - /*! - * Empty constructor - */ - Next() { - //intentionally left empty - } - - /*! - * Constructor - * - * @param child The child node - */ - Next(AbstractStateFormula<T>* child) - : storm::property::abstract::Next<T, AbstractStateFormula<T>>(child) { - //intentionally left empty - } - - /*! - * Constructor. - * - * Also deletes the subtree. - * (this behaviour can be prevented by setting the subtrees to NULL before deletion) - */ - virtual ~Next() { - //intentionally left empty - } - - /*! - * Clones the called object. - * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones - * - * @returns a new BoundedUntil-object that is identical the called object. - */ - virtual AbstractPathFormula<T>* clone() const override { - Next<T>* result = new Next<T>(); - if (this->childIsSet()) { - result->setChild(this->getChild().clone()); - } - return result; - } - - /*! - * Calls the model checker to check this formula. - * Needed to infer the correct type of formula class. - * - * @note This function should only be called in a generic check function of a model checker class. For other uses, - * the methods of the model checker should be used. - * - * @returns A vector indicating the probability that the formula holds for each state. - */ - virtual std::vector<T> check(const storm::modelchecker::csl::AbstractModelChecker<T>& modelChecker, bool qualitative) const override { - return modelChecker.template as<INextModelChecker>()->checkNext(*this, qualitative); - } -}; - -} //namespace csl -} //namespace property -} //namespace storm - -#endif /* STORM_FORMULA_CSL_NEXT_H_ */ diff --git a/src/formula/Csl/Not.h b/src/formula/Csl/Not.h deleted file mode 100644 index dd0c2a705..000000000 --- a/src/formula/Csl/Not.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Not.h - * - * Created on: 19.10.2012 - * Author: Thomas Heinemann - */ - -#ifndef STORM_FORMULA_CSL_NOT_H_ -#define STORM_FORMULA_CSL_NOT_H_ - -#include "AbstractStateFormula.h" -#include "src/formula/abstract/Not.h" -#include "src/formula/AbstractFormulaChecker.h" -#include "src/modelchecker/csl/ForwardDeclarations.h" - -namespace storm { -namespace property { -namespace csl { - -template <class T> class Not; - -/*! - * @brief Interface class for model checkers that support Not. - * - * All model checkers that support the formula class Not must inherit - * this pure virtual class. - */ -template <class T> -class INotModelChecker { - public: - /*! - * @brief Evaluates Not formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual storm::storage::BitVector checkNot(const Not<T>& obj) const = 0; -}; - -/*! - * @brief - * Class for an abstract formula tree with NOT node as root. - * - * Has one Abstract state formula as sub formula/tree. - * - * The subtree is seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @see AbstractStateFormula - * @see AbstractCslFormula - */ -template <class T> -class Not : public storm::property::abstract::Not<T, AbstractStateFormula<T>>, - public AbstractStateFormula<T> { - -public: - /*! - * Empty constructor - */ - Not() { - //intentionally left empty - } - - /*! - * Constructor - * @param child The child node - */ - Not(AbstractStateFormula<T>* child) : - storm::property::abstract::Not<T, AbstractStateFormula<T>>(child){ - //intentionally left empty - } - - /*! - * Destructor - * - * Also deletes the subtree - * (this behavior can be prevented by setting them to NULL before deletion) - */ - virtual ~Not() { - //intentionally left empty - } - - /*! - * Clones the called object. - * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones - * - * @returns a new AND-object that is identical the called object. - */ - virtual AbstractStateFormula<T>* clone() const override { - Not<T>* result = new Not<T>(); - if (this->childIsSet()) { - result->setChild(this->getChild().clone()); - } - return result; - } - - /*! - * Calls the model checker to check this formula. - * Needed to infer the correct type of formula class. - * - * @note This function should only be called in a generic check function of a model checker class. For other uses, - * the methods of the model checker should be used. - * - * @returns A bit vector indicating all states that satisfy the formula represented by the called object. - */ - virtual storm::storage::BitVector check(const storm::modelchecker::csl::AbstractModelChecker<T>& modelChecker) const override { - return modelChecker.template as<INotModelChecker>()->checkNot(*this); - } -}; - -} //namespace csl -} //namespace property -} //namespace storm - -#endif /* STORM_FORMULA_CSL_NOT_H_ */ diff --git a/src/formula/Csl/Or.h b/src/formula/Csl/Or.h deleted file mode 100644 index 29add98cc..000000000 --- a/src/formula/Csl/Or.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Or.h - * - * Created on: 19.10.2012 - * Author: Thomas Heinemann - */ - -#ifndef STORM_FORMULA_CSL_OR_H_ -#define STORM_FORMULA_CSL_OR_H_ - -#include "AbstractStateFormula.h" -#include "src/formula/abstract/Or.h" -#include "src/formula/AbstractFormulaChecker.h" - -namespace storm { -namespace property { -namespace csl { - -template <class T> class Or; - -/*! - * @brief Interface class for model checkers that support Or. - * - * All model checkers that support the formula class Or must inherit - * this pure virtual class. - */ -template <class T> -class IOrModelChecker { - public: - /*! - * @brief Evaluates Or formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual storm::storage::BitVector checkOr(const Or<T>& obj) const = 0; -}; - -/*! - * @brief - * Class for an abstract formula tree with OR node as root. - * - * Has two Abstract state formulas as sub formulas/trees. - * - * As OR is commutative, the order is \e theoretically not important, but will influence the order in which - * the model checker works. - * - * The subtrees are seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @see AbstractStateFormula - * @see AbstractCslFormula - */ -template <class T> -class Or : public storm::property::abstract::Or<T, AbstractStateFormula<T>>, - public AbstractStateFormula<T> { - -public: - /*! - * Empty constructor. - * Will create an OR-node without subnotes. The result does not represent a complete formula! - */ - Or() { - //intentionally left empty - } - - /*! - * Constructor. - * Creates an OR note with the parameters as subtrees. - * - * @param left The left sub formula - * @param right The right sub formula - */ - Or(AbstractStateFormula<T>* left, AbstractStateFormula<T>* right) : - storm::property::abstract::Or<T, AbstractStateFormula<T>>(left, right) { - //intentionally left empty - } - - /*! - * Destructor. - * - * The subtrees are deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - */ - virtual ~Or() { - //intentionally left empty - } - - /*! - * Clones the called object. - * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones - * - * @returns a new AND-object that is identical the called object. - */ - virtual AbstractStateFormula<T>* clone() const override { - Or<T>* result = new Or(); - if (this->leftIsSet()) { - result->setLeft(this->getLeft().clone()); - } - if (this->rightIsSet()) { - result->setRight(this->getRight().clone()); - } - return result; - } - - /*! - * Calls the model checker to check this formula. - * Needed to infer the correct type of formula class. - * - * @note This function should only be called in a generic check function of a model checker class. For other uses, - * the methods of the model checker should be used. - * - * @returns A bit vector indicating all states that satisfy the formula represented by the called object. - */ - virtual storm::storage::BitVector check(const storm::modelchecker::csl::AbstractModelChecker<T>& modelChecker) const override { - return modelChecker.template as<IOrModelChecker>()->checkOr(*this); - } -}; - -} //namespace csl -} //namespace property -} //namespace storm - -#endif /* STORM_FORMULA_CSL_OR_H_ */ diff --git a/src/formula/Csl/ProbabilisticBoundOperator.h b/src/formula/Csl/ProbabilisticBoundOperator.h deleted file mode 100644 index 28937fab4..000000000 --- a/src/formula/Csl/ProbabilisticBoundOperator.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * ProbabilisticBoundOperator.h - * - * Created on: 19.10.2012 - * Author: Thomas Heinemann - */ - -#ifndef STORM_FORMULA_CSL_PROBABILISTICBOUNDOPERATOR_H_ -#define STORM_FORMULA_CSL_PROBABILISTICBOUNDOPERATOR_H_ - -#include "AbstractStateFormula.h" -#include "AbstractPathFormula.h" -#include "src/formula/abstract/ProbabilisticBoundOperator.h" -#include "utility/constants.h" - -namespace storm { -namespace property { -namespace csl { - -template <class T> class ProbabilisticBoundOperator; - -/*! - * @brief Interface class for model checkers that support ProbabilisticBoundOperator. - * - * All model checkers that support the formula class PathBoundOperator must inherit - * this pure virtual class. - */ -template <class T> -class IProbabilisticBoundOperatorModelChecker { - public: - virtual storm::storage::BitVector checkProbabilisticBoundOperator(const ProbabilisticBoundOperator<T>& obj) const = 0; -}; - -/*! - * @brief - * Class for an abstract formula tree with a P (probablistic) operator node over a probability interval - * as root. - * - * Has one Abstract path formula as sub formula/tree. - * - * @par Semantics - * The formula holds iff the probability that the path formula holds is inside the bounds - * specified in this operator - * - * The subtree is seen as part of the object and deleted with it - * (this behavior can be prevented by setting them to NULL before deletion) - * - * - * @see AbstractStateFormula - * @see AbstractPathFormula - * @see ProbabilisticOperator - * @see ProbabilisticNoBoundsOperator - * @see AbstractCslFormula - */ -template<class T> -class ProbabilisticBoundOperator : public storm::property::abstract::ProbabilisticBoundOperator<T, AbstractPathFormula<T>>, - public AbstractStateFormula<T> { - -public: - /*! - * Empty constructor - */ - ProbabilisticBoundOperator() : storm::property::abstract::ProbabilisticBoundOperator<T, AbstractPathFormula<T>> - (LESS_EQUAL, storm::utility::constantZero<T>(), nullptr) { - // Intentionally left empty - } - - - /*! - * Constructor - * - * @param comparisonRelation The relation to compare the actual value and the bound - * @param bound The bound for the probability - * @param pathFormula The child node - */ - ProbabilisticBoundOperator( - storm::property::ComparisonType comparisonRelation, T bound, AbstractPathFormula<T>* pathFormula) - : storm::property::abstract::ProbabilisticBoundOperator<T, AbstractPathFormula<T>>(comparisonRelation, bound, pathFormula) { - // Intentionally left empty - } - - ProbabilisticBoundOperator( - storm::property::ComparisonType comparisonRelation, T bound, AbstractPathFormula<T>* pathFormula, bool minimumOperator) - : storm::property::abstract::ProbabilisticBoundOperator<T, AbstractPathFormula<T>>(comparisonRelation, bound, pathFormula, minimumOperator){ - // Intentionally left empty - } - - /*! - * Clones the called object. - * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones - * - * @returns a new AND-object that is identical the called object. - */ - virtual AbstractStateFormula<T>* clone() const override { - ProbabilisticBoundOperator<T>* result = new ProbabilisticBoundOperator<T>(); - result->setComparisonOperator(this->getComparisonOperator()); - result->setBound(this->getBound()); - result->setPathFormula(this->getPathFormula().clone()); - return result; - } - - /*! - * Calls the model checker to check this formula. - * Needed to infer the correct type of formula class. - * - * @note This function should only be called in a generic check function of a model checker class. For other uses, - * the methods of the model checker should be used. - * - * @returns A bit vector indicating all states that satisfy the formula represented by the called object. - */ - virtual storm::storage::BitVector check(const storm::modelchecker::csl::AbstractModelChecker<T>& modelChecker) const override { - return modelChecker.template as<IProbabilisticBoundOperatorModelChecker>()->checkProbabilisticBoundOperator(*this); - } -}; - -} //namespace csl -} //namespace property -} //namespace storm - -#endif /* STORM_FORMULA_CSL_PROBABILISTICBOUNDOPERATOR_H_ */ diff --git a/src/formula/Csl/ProbabilisticNoBoundOperator.h b/src/formula/Csl/ProbabilisticNoBoundOperator.h deleted file mode 100644 index 63c9a501e..000000000 --- a/src/formula/Csl/ProbabilisticNoBoundOperator.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * ProbabilisticNoBoundOperator.h - * - * Created on: 12.12.2012 - * Author: thomas - */ - -#ifndef STORM_FORMULA_CSL_PROBABILISTICNOBOUNDOPERATOR_H_ -#define STORM_FORMULA_CSL_PROBABILISTICNOBOUNDOPERATOR_H_ - -#include "AbstractPathFormula.h" -#include "AbstractNoBoundOperator.h" -#include "src/formula/abstract/ProbabilisticNoBoundOperator.h" - -namespace storm { -namespace property { -namespace csl { - -/*! - * @brief - * Class for an abstract formula tree with a P (probablistic) operator without declaration of probabilities - * as root. - * - * Checking a formula with this operator as root returns the probabilities that the path formula holds - * (for each state) - * - * Has one Abstract path formula as sub formula/tree. - * - * @note - * This class is a hybrid of a state and path formula, and may only appear as the outermost operator. - * Hence, it is seen as neither a state nor a path formula, but is directly derived from AbstractFormula. - * - * @note - * This class does not contain a check() method like the other formula classes. - * The check method should only be called by the model checker to infer the correct check function for sub - * formulas. As this operator can only appear at the root, the method is not useful here. - * Use the checkProbabilisticNoBoundOperator method from the DtmccslModelChecker class instead. - * - * The subtree is seen as part of the object and deleted with it - * (this behavior can be prevented by setting them to NULL before deletion) - * - * - * @see AbstractStateFormula - * @see AbstractPathFormula - * @see ProbabilisticOperator - * @see ProbabilisticIntervalOperator - * @see AbstractCslFormula - */ -template <class T> -class ProbabilisticNoBoundOperator: public storm::property::abstract::ProbabilisticNoBoundOperator<T, AbstractPathFormula<T>>, - public AbstractNoBoundOperator<T> { -public: - /*! - * Empty constructor - */ - ProbabilisticNoBoundOperator() { - // Intentionally left empty - } - - /*! - * Constructor - * - * @param pathFormula The child node. - */ - ProbabilisticNoBoundOperator(AbstractPathFormula<T>* pathFormula) - : storm::property::abstract::ProbabilisticNoBoundOperator<T, AbstractPathFormula<T>>(pathFormula) { - // Intentionally left empty - } - - /*! - * Constructor - * - * @param pathFormula The child node. - */ - ProbabilisticNoBoundOperator(AbstractPathFormula<T>* pathFormula, bool minimumOperator) - : storm::property::abstract::ProbabilisticNoBoundOperator<T, AbstractPathFormula<T>>(pathFormula, minimumOperator) { - // Intentionally left empty - } - - /*! - * Destructor - */ - virtual ~ProbabilisticNoBoundOperator() { - // Intentionally left empty - } - - virtual AbstractNoBoundOperator<T>* clone() const override { - ProbabilisticNoBoundOperator<T>* result = new ProbabilisticNoBoundOperator<T>(); - if (this->pathFormulaIsSet()) { - result->setPathFormula(this->getPathFormula().clone()); - } - return result; - } - - /*! - * Calls the model checker to check this formula. - * Needed to infer the correct type of formula class. - * - * @note This function should only be called in a generic check function of a model checker class. For other uses, - * the methods of the model checker should be used. - * - * @note This function is not implemented in this class. - * - * @returns A vector indicating the probability that the formula holds for each state. - */ - virtual std::vector<T> check(const storm::modelchecker::csl::AbstractModelChecker<T>& modelChecker, bool qualitative=false) const override { - return this->getPathFormula().check(modelChecker, qualitative); - } -}; - -} //namespace csl -} //namespace property -} //namespace storm - -#endif /* STORM_FORMULA_CSL_PROBABILISTICNOBOUNDOPERATOR_H_ */ diff --git a/src/formula/Csl/SteadyStateBoundOperator.h b/src/formula/Csl/SteadyStateBoundOperator.h deleted file mode 100644 index ddd9be3b2..000000000 --- a/src/formula/Csl/SteadyStateBoundOperator.h +++ /dev/null @@ -1,118 +0,0 @@ -/* - * SteadyState.h - * - * Created on: 19.10.2012 - * Author: Thomas Heinemann - */ - -#ifndef STORM_FORMULA_CSL_STEADYSTATEOPERATOR_H_ -#define STORM_FORMULA_CSL_STEADYSTATEOPERATOR_H_ - -#include "AbstractStateFormula.h" -#include "src/formula/abstract/SteadyStateBoundOperator.h" -#include "src/formula/AbstractFormulaChecker.h" - -namespace storm { - -namespace property { - -namespace csl { - -template <class T> class SteadyStateBoundOperator; - -/*! - * @brief Interface class for model checkers that support SteadyStateOperator. - * - * All model checkers that support the formula class SteadyStateOperator must inherit - * this pure virtual class. - */ -template <class T> -class ISteadyStateBoundOperatorModelChecker { - public: - /*! - * @brief Evaluates SteadyStateOperator formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual storm::storage::BitVector checkSteadyStateBoundOperator(const SteadyStateBoundOperator<T>& obj) const = 0; -}; - -/*! - * @brief - * Class for an Abstract (path) formula tree with a SteadyStateOperator node as root. - * - * Has two Abstract state formulas as sub formulas/trees. - * - * @par Semantics - * The formula holds iff \e child holds SteadyStateOperator step, \e child holds - * - * The subtree is seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @see AbstractPathFormula - * @see AbstractCslFormula - */ -template <class T> -class SteadyStateBoundOperator : public storm::property::abstract::SteadyStateBoundOperator<T, AbstractStateFormula<T>>, - public AbstractStateFormula<T> { - -public: - /*! - * Empty constructor - */ - SteadyStateBoundOperator() : storm::property::abstract::SteadyStateBoundOperator<T, AbstractStateFormula<T>> - (LESS_EQUAL, storm::utility::constantZero<T>(), nullptr) { - // Intentionally left empty - } - - /*! - * Constructor - * - * @param stateFormula The child node - */ - SteadyStateBoundOperator( - storm::property::ComparisonType comparisonRelation, T bound, AbstractStateFormula<T>* stateFormula) : - storm::property::abstract::SteadyStateBoundOperator<T, AbstractStateFormula<T>>(comparisonRelation, bound, stateFormula) { - } - - /*! - * Destructor - */ - virtual ~SteadyStateBoundOperator() { - // Intentionally left empty - } - - /*! - * Clones the called object. - * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones - * - * @returns a new BoundedUntil-object that is identical the called object. - */ - virtual AbstractStateFormula<T>* clone() const override { - SteadyStateBoundOperator<T>* result = new SteadyStateBoundOperator<T>(); - result->setStateFormula(this->getStateFormula().clone()); - return result; - } - - /*! - * Calls the model checker to check this formula. - * Needed to infer the correct type of formula class. - * - * @note This function should only be called in a generic check function of a model checker class. For other uses, - * the methods of the model checker should be used. - * - * @returns A vector indicating the probability that the formula holds for each state. - */ - virtual storm::storage::BitVector check(const storm::modelchecker::csl::AbstractModelChecker<T>& modelChecker) const override { - return modelChecker.template as<ISteadyStateBoundOperatorModelChecker>()->checkSteadyStateBoundOperator(*this); - } - -}; - -} //namespace csl -} //namespace property -} //namespace storm - -#endif /* STORM_FORMULA_CSL_STEADYSTATEOPERATOR_H_ */ diff --git a/src/formula/Csl/SteadyStateNoBoundOperator.h b/src/formula/Csl/SteadyStateNoBoundOperator.h deleted file mode 100644 index b92526d47..000000000 --- a/src/formula/Csl/SteadyStateNoBoundOperator.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * SteadyStateNoBoundOperator.h - * - * Created on: 09.04.2013 - * Author: thomas - */ - -#ifndef STORM_FORMULA_CSL_STEADYSTATENOBOUNDOPERATOR_H_ -#define STORM_FORMULA_CSL_STEADYSTATENOBOUNDOPERATOR_H_ - -#include "AbstractStateFormula.h" -#include "AbstractNoBoundOperator.h" -#include "src/formula/abstract/SteadyStateNoBoundOperator.h" - -namespace storm { -namespace property { -namespace csl { - -template <class T> class SteadyStateNoBoundOperator; - -/*! - * @brief Interface class for model checkers that support SteadyStateOperator. - * - * All model checkers that support the formula class SteadyStateOperator must inherit - * this pure virtual class. - */ -template <class T> -class ISteadyStateNoBoundOperatorModelChecker { - public: - /*! - * @brief Evaluates SteadyStateOperator formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual std::vector<T> checkSteadyStateNoBoundOperator(const SteadyStateNoBoundOperator<T>& obj) const = 0; -}; - -template <class T> -class SteadyStateNoBoundOperator: public storm::property::abstract::SteadyStateNoBoundOperator<T, AbstractStateFormula<T>>, - public AbstractNoBoundOperator<T> { -public: - /*! - * Empty constructor - */ - SteadyStateNoBoundOperator() : storm::property::abstract::SteadyStateNoBoundOperator<T, AbstractStateFormula<T>>() { - // Intentionally left empty - - } - - /*! - * Constructor - * - * @param stateFormula The state formula that forms the subtree - */ - SteadyStateNoBoundOperator(AbstractStateFormula<T>* stateFormula) - : storm::property::abstract::SteadyStateNoBoundOperator<T, AbstractStateFormula<T>>(stateFormula) { - // Intentionally left empty - } - - /*! - * Destructor - */ - ~SteadyStateNoBoundOperator() { - // Intentionally left empty - } - - /*! - * Clones the called object. - * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones - * - * @returns a new BoundedUntil-object that is identical the called object. - */ - virtual AbstractNoBoundOperator <T>* clone() const override { - SteadyStateNoBoundOperator<T>* result = new SteadyStateNoBoundOperator<T>(); - result->setStateFormula(this->getStateFormula().clone()); - return result; - } - - /*! - * Calls the model checker to check this formula. - * Needed to infer the correct type of formula class. - * - * @note This function should only be called in a generic check function of a model checker class. For other uses, - * the methods of the model checker should be used. - * - * @returns A vector indicating the probability that the formula holds for each state. - */ - virtual std::vector<T> check(const storm::modelchecker::csl::AbstractModelChecker<T>& modelChecker, bool qualitative=false) const override { - return modelChecker.template as<ISteadyStateNoBoundOperatorModelChecker>()->checkSteadyStateNoBoundOperator(*this); - } - -}; - -} /* namespace csl */ -} /* namespace property */ -} /* namespace storm */ - -#endif /* STORM_FORMULA_CSL_STEADYSTATENOBOUNDOPERATOR_H_ */ diff --git a/src/formula/Csl/TimeBoundedEventually.h b/src/formula/Csl/TimeBoundedEventually.h deleted file mode 100644 index 3b443938a..000000000 --- a/src/formula/Csl/TimeBoundedEventually.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * TimeBoundedEventually.h - * - * Created on: 10.04.2013 - * Author: thomas - */ - -#ifndef STORM_FORMULA_CSL_TIMEBOUNDEDEVENTUALLY_H_ -#define STORM_FORMULA_CSL_TIMEBOUNDEDEVENTUALLY_H_ - -#include "src/formula/abstract/TimeBoundedEventually.h" -#include "AbstractPathFormula.h" -#include "AbstractStateFormula.h" - -namespace storm { -namespace property { -namespace csl { - -template<class T> class TimeBoundedEventually; - -/*! - * @brief Interface class for model checkers that support TimeBoundedEventually. - * - * All model checkers that support the formula class BoundedEventually must inherit - * this pure virtual class. - */ -template <class T> -class ITimeBoundedEventuallyModelChecker { - public: - /*! - * @brief Evaluates TimeBoundedUntil formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual std::vector<T> checkTimeBoundedEventually(const TimeBoundedEventually<T>& obj, bool qualitative) const = 0; -}; - - -template<class T> -class TimeBoundedEventually: public storm::property::abstract::TimeBoundedEventually<T, AbstractStateFormula<T>>, - public AbstractPathFormula<T> { -public: - /** - * Simple constructor: Only sets the bounds - * - * @param lowerBound - * @param upperBound - */ - TimeBoundedEventually(T lowerBound, T upperBound) - : storm::property::abstract::TimeBoundedEventually<T, AbstractStateFormula<T>>(lowerBound, upperBound) { - // Intentionally left empty - } - - TimeBoundedEventually(T lowerBound, T upperBound, AbstractStateFormula<T>* child) - : storm::property::abstract::TimeBoundedEventually<T, AbstractStateFormula<T>>(lowerBound, upperBound, child) { - // Intentionally left empty - } - - virtual ~TimeBoundedEventually() { - // Intentionally left empty - } - - /*! - * Clones the called object. - * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones - * - * @returns a new BoundedUntil-object that is identical the called object. - */ - virtual AbstractPathFormula<T>* clone() const override { - TimeBoundedEventually<T>* result = new TimeBoundedEventually<T>(this->getLowerBound(), this->getUpperBound()); - if (this->childIsSet()) { - result->setChild(this->getChild().clone()); - } - return result; - } - - /*! - * Calls the model checker to check this formula. - * Needed to infer the correct type of formula class. - * - * @note This function should only be called in a generic check function of a model checker class. For other uses, - * the methods of the model checker should be used. - * - * @returns A vector indicating the probability that the formula holds for each state. - */ - virtual std::vector<T> check(const storm::modelchecker::csl::AbstractModelChecker<T>& modelChecker, bool qualitative) const override { - return modelChecker.template as<ITimeBoundedEventuallyModelChecker>()->checkTimeBoundedEventually(*this, qualitative); - } -}; - -} /* namespace csl */ -} /* namespace property */ -} /* namespace storm */ - -#endif /* STORM_FORMULA_CSL_TIMEBOUNDEDEVENTUALLY_H_ */ diff --git a/src/formula/Csl/TimeBoundedUntil.h b/src/formula/Csl/TimeBoundedUntil.h deleted file mode 100644 index 7b2044daa..000000000 --- a/src/formula/Csl/TimeBoundedUntil.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * TimeBoundedUntil.h - * - * Created on: 10.04.2013 - * Author: thomas - */ - -#ifndef STORM_FORMULA_CSL_TIMEBOUNDEDUNTIL_H_ -#define STORM_FORMULA_CSL_TIMEBOUNDEDUNTIL_H_ - -#include "AbstractPathFormula.h" -#include "AbstractStateFormula.h" -#include "src/formula/abstract/TimeBoundedUntil.h" - -namespace storm { -namespace property { -namespace csl { - -template <class T> class TimeBoundedUntil; - -/*! - * @brief Interface class for model checkers that support TimeBoundedUntil. - * - * All model checkers that support the formula class BoundedEventually must inherit - * this pure virtual class. - */ -template <class T> -class ITimeBoundedUntilModelChecker { - public: - /*! - * @brief Evaluates TimeBoundedUntil formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual std::vector<T> checkTimeBoundedUntil(const TimeBoundedUntil<T>& obj, bool qualitative) const = 0; -}; - -template <class T> -class TimeBoundedUntil: public storm::property::abstract::TimeBoundedUntil<T, AbstractStateFormula<T>>, - public AbstractPathFormula<T> { -public: - /** - * Constructor providing bounds only; - * Sub formulas are set to null. - * - * @param lowerBound - * @param upperBound - */ - TimeBoundedUntil(T lowerBound, T upperBound) : - storm::property::abstract::TimeBoundedUntil<T, AbstractStateFormula<T>>(lowerBound, upperBound) { - // Intentionally left empty - } - - /** - * Full constructor - * @param lowerBound - * @param upperBound - * @param left - * @param right - */ - TimeBoundedUntil(T lowerBound, T upperBound, AbstractStateFormula<T>* left, AbstractStateFormula<T>* right) : - storm::property::abstract::TimeBoundedUntil<T, AbstractStateFormula<T>>(lowerBound, upperBound, left, right) { - - } - - /*! - * Destructor - */ - virtual ~TimeBoundedUntil() { - // Intentionally left empty - } - - /*! - * Clones the called object. - * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones - * - * @returns a new BoundedUntil-object that is identical the called object. - */ - virtual AbstractPathFormula<T>* clone() const override { - TimeBoundedUntil<T>* result = new TimeBoundedUntil<T>(this->getLowerBound(), this->getUpperBound()); - if (this->leftIsSet()) { - result->setLeft(this->getLeft().clone()); - } - if (this->rightIsSet()) { - result->setRight(this->getRight().clone()); - } - return result; - } - - - /*! - * Calls the model checker to check this formula. - * Needed to infer the correct type of formula class. - * - * @note This function should only be called in a generic check function of a model checker class. For other uses, - * the methods of the model checker should be used. - * - * @returns A vector indicating the probability that the formula holds for each state. - */ - virtual std::vector<T> check(const storm::modelchecker::csl::AbstractModelChecker<T>& modelChecker, bool qualitative) const override { - return modelChecker.template as<ITimeBoundedUntilModelChecker>()->checkTimeBoundedUntil(*this, qualitative); - } -}; - -} /* namespace csl */ -} /* namespace property */ -} /* namespace storm */ - -#endif /* STORM_FORMULA_CSL_TIMEBOUNDEDUNTIL_H_ */ diff --git a/src/formula/Csl/Until.h b/src/formula/Csl/Until.h deleted file mode 100644 index 6f6d68086..000000000 --- a/src/formula/Csl/Until.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Until.h - * - * Created on: 19.10.2012 - * Author: Thomas Heinemann - */ - -#ifndef STORM_FORMULA_CSL_UNTIL_H_ -#define STORM_FORMULA_CSL_UNTIL_H_ - -#include "AbstractPathFormula.h" -#include "AbstractStateFormula.h" -#include "src/formula/abstract/Until.h" -#include "src/formula/AbstractFormulaChecker.h" - -namespace storm { -namespace property { -namespace csl { - -template <class T> class Until; - -/*! - * @brief Interface class for model checkers that support Until. - * - * All model checkers that support the formula class Until must inherit - * this pure virtual class. - */ -template <class T> -class IUntilModelChecker { - public: - /*! - * @brief Evaluates Until formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual std::vector<T> checkUntil(const Until<T>& obj, bool qualitative) const = 0; -}; - -/*! - * @brief - * Class for an abstract (path) formula tree with an Until node as root. - * - * Has two Abstract state formulas as sub formulas/trees. - * - * @par Semantics - * The formula holds iff eventually, formula \e right (the right subtree) holds, and before, - * \e left holds always. - * - * The subtrees are seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @see AbstractPathFormula - * @see AbstractCslFormula - */ -template <class T> -class Until : public storm::property::abstract::Until<T, AbstractStateFormula<T>>, - public AbstractPathFormula<T> { - -public: - /*! - * Empty constructor - */ - Until() { - // Intentionally left empty - } - - /*! - * Constructor - * - * @param left The left formula subtree - * @param right The left formula subtree - */ - Until(AbstractStateFormula<T>* left, AbstractStateFormula<T>* right) - : storm::property::abstract::Until<T, AbstractStateFormula<T>>(left, right) { - // Intentionally left empty - } - - /*! - * Destructor. - * - * Also deletes the subtrees. - * (this behaviour can be prevented by setting the subtrees to NULL before deletion) - */ - virtual ~Until() { - // Intentionally left empty - } - - /*! - * Clones the called object. - * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones - * - * @returns a new BoundedUntil-object that is identical the called object. - */ - virtual AbstractPathFormula<T>* clone() const override { - Until<T>* result = new Until(); - if (this->leftIsSet()) { - result->setLeft(this->getLeft().clone()); - } - if (this->rightIsSet()) { - result->setRight(this->getRight().clone()); - } - return result; - } - - /*! - * Calls the model checker to check this formula. - * Needed to infer the correct type of formula class. - * - * @note This function should only be called in a generic check function of a model checker class. For other uses, - * the methods of the model checker should be used. - * - * @returns A vector indicating the probability that the formula holds for each state. - */ - virtual std::vector<T> check(const storm::modelchecker::csl::AbstractModelChecker<T>& modelChecker, bool qualitative) const override { - return modelChecker.template as<IUntilModelChecker>()->checkUntil(*this, qualitative); - } -}; - -} //namespace csl -} //namespace property -} //namespace storm - -#endif /* STORM_FORMULA_CSL_UNTIL_H_ */ diff --git a/src/formula/Ltl/And.h b/src/formula/Ltl/And.h deleted file mode 100644 index f7c901de3..000000000 --- a/src/formula/Ltl/And.h +++ /dev/null @@ -1,150 +0,0 @@ -/* - * And.h - * - * Created on: 19.10.2012 - * Author: Thomas Heinemann - */ - -#ifndef STORM_FORMULA_LTL_AND_H_ -#define STORM_FORMULA_LTL_AND_H_ - -#include "AbstractLtlFormula.h" -#include "src/formula/abstract/And.h" -#include "src/formula/AbstractFormulaChecker.h" -#include "src/modelchecker/ltl/ForwardDeclarations.h" -#include <string> - -namespace storm { -namespace property { -namespace ltl { - -template <class T> class And; - -/*! - * @brief Interface class for model checkers that support And. - * - * All model checkers that support the formula class And must inherit - * this pure virtual class. - */ -template <class T> -class IAndModelChecker { - public: - /*! - * @brief Evaluates And formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual std::vector<T> checkAnd(const And<T>& obj) const = 0; -}; - -/*! - * @brief Interface class for visitors that support And. - * - * All visitors that support the formula class And must inherit - * this pure virtual class. - */ -template <class T> -class IAndVisitor { - public: - /*! - * @brief Evaluates And formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual void visitAnd(const And<T>& obj) = 0; -}; - -/*! - * @brief - * Class for an abstract formula tree with AND node as root. - * - * Has two Abstract LTL formulas as sub formulas/trees. - * - * As AND is commutative, the order is \e theoretically not important, but will influence the order in which - * the model checker works. - * - * The subtrees are seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @see AbstractLtlFormula - */ -template <class T> -class And : public storm::property::abstract::And<T, AbstractLtlFormula<T>>, public AbstractLtlFormula<T> { - -public: - /*! - * Empty constructor. - * Will create an AND-node without subnotes. Will not represent a complete formula! - */ - And() { - //intentionally left empty - } - - /*! - * Constructor. - * Creates an AND node with the parameters as subtrees. - * - * @param left The left sub formula - * @param right The right sub formula - */ - And(AbstractLtlFormula<T>* left, AbstractLtlFormula<T>* right) - : storm::property::abstract::And<T, AbstractLtlFormula<T>>(left, right) { - //intentionally left empty - } - - /*! - * Destructor. - * - * The subtrees are deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - */ - virtual ~And() { - //intentionally left empty - } - - /*! - * Clones the called object. - * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones - * - * @returns a new AND-object that is identical the called object. - */ - virtual AbstractLtlFormula<T>* clone() const override { - And<T>* result = new And(); - if (this->leftIsSet()) { - result->setLeft(this->getLeft().clone()); - } - if (this->rightIsSet()) { - result->setRight(this->getRight().clone()); - } - return result; - } - - /*! - * Calls the model checker to check this formula. - * Needed to infer the correct type of formula class. - * - * @note This function should only be called in a generic check function of a model checker class. For other uses, - * the methods of the model checker should be used. - * - * @returns A bit vector indicating all states that satisfy the formula represented by the called object. - */ - virtual std::vector<T> check(const storm::modelchecker::ltl::AbstractModelChecker<T>& modelChecker) const override { - return modelChecker.template as<IAndModelChecker>()->checkAnd(*this); - } - - virtual void visit(visitor::AbstractLtlFormulaVisitor<T>& visitor) const override { - visitor.template as<IAndVisitor>()->visitAnd(*this); - } - -}; - -} //namespace ltl - -} //namespace property - -} //namespace storm - -#endif /* STORM_FORMULA_LTL_AND_H_ */ diff --git a/src/formula/Ltl/Ap.h b/src/formula/Ltl/Ap.h deleted file mode 100644 index d5a0069f8..000000000 --- a/src/formula/Ltl/Ap.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Ap.h - * - * Created on: 22.04.2013 - * Author: thomas - */ - -#ifndef STORM_FORMULA_LTL_AP_H_ -#define STORM_FORMULA_LTL_AP_H_ - -#include "AbstractLtlFormula.h" -#include "src/formula/abstract/Ap.h" - -namespace storm { -namespace property { -namespace ltl { - -template <class T> class Ap; - -/*! - * @brief Interface class for model checkers that support And. - * - * All model checkers that support the formula class And must inherit - * this pure virtual class. - */ -template <class T> -class IApModelChecker { - public: - /*! - * @brief Evaluates And formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual std::vector<T> checkAp(const Ap<T>& obj) const = 0; -}; - - -/*! - * @brief Interface class for visitors that support Ap. - * - * All visitors that support the formula class Ap must inherit - * this pure virtual class. - */ -template <class T> -class IApVisitor { - public: - /*! - * @brief Evaluates And formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual void visitAp(const Ap<T>& obj) = 0; -}; - -/*! - * @brief - * Class for an abstract formula tree with atomic proposition as root. - * - * This class represents the leaves in the formula tree. - * - * @see AbstractLtlFormula - */ -template <class T> -class Ap: public storm::property::abstract::Ap<T>, - public storm::property::ltl::AbstractLtlFormula<T> { -public: - /*! - * Empty constructor - */ - Ap() { - // Intentionally left empty - } - - /*! - * Constructor - * - * Creates a new atomic proposition leaf, with the label Ap - * - * @param ap The string representing the atomic proposition - */ - Ap(std::string ap) : - storm::property::abstract::Ap<T>(ap) { - // Intentionally left empty - } - - /*! - * Destructor - */ - virtual ~Ap() { - // Intentionally left empty - } - - /*! - * Calls the model checker to check this formula. - * Needed to infer the correct type of formula class. - * - * @note This function should only be called in a generic check function of a model checker class. For other uses, - * the methods of the model checker should be used. - * - * @note This function is not implemented in this class. - * - * @returns A vector indicating the probability that the formula holds for each state. - */ - virtual std::vector<T> check(const storm::modelchecker::ltl::AbstractModelChecker<T>& modelChecker) const override { - return modelChecker.template as<IApModelChecker>()->checkAp(*this); - } - - /*! - * Clones the called object. - * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones - * - * @returns a new AND-object that is identical the called object. - */ - virtual AbstractLtlFormula<T>* clone() const override { - return new Ap(this->getAp()); - } - - virtual void visit(visitor::AbstractLtlFormulaVisitor<T>& visitor) const override { - visitor.template as<IApVisitor>()->visitAp(*this); - } -}; - -} /* namespace ltl */ -} /* namespace property */ -} /* namespace storm */ -#endif /* STORM_FORMULA_LTL_AP_H_ */ diff --git a/src/formula/Ltl/BoundedEventually.h b/src/formula/Ltl/BoundedEventually.h deleted file mode 100644 index 2cbbc4c4a..000000000 --- a/src/formula/Ltl/BoundedEventually.h +++ /dev/null @@ -1,146 +0,0 @@ -/* - * BoundedUntil.h - * - * Created on: 27.11.2012 - * Author: Christian Dehnert - */ - -#ifndef STORM_FORMULA_LTL_BOUNDEDEVENTUALLY_H_ -#define STORM_FORMULA_LTL_BOUNDEDEVENTUALLY_H_ - -#include "src/formula/abstract/BoundedEventually.h" -#include "AbstractLtlFormula.h" -#include "src/formula/AbstractFormulaChecker.h" -#include <cstdint> -#include <string> -#include "src/modelchecker/ltl/ForwardDeclarations.h" - -namespace storm { -namespace property { -namespace ltl { - -template <class T> class BoundedEventually; - -/*! - * @brief Interface class for model checkers that support BoundedEventually. - * - * All model checkers that support the formula class BoundedEventually must inherit - * this pure virtual class. - */ -template <class T> -class IBoundedEventuallyModelChecker { - public: - /*! - * @brief Evaluates BoundedEventually formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual std::vector<T> checkBoundedEventually(const BoundedEventually<T>& obj) const = 0; -}; - -/*! - * @brief Interface class for visitors that support BoundedEventually. - * - * All visitors that support the formula class BoundedEventually must inherit - * this pure virtual class. - */ -template <class T> -class IBoundedEventuallyVisitor { - public: - /*! - * @brief Evaluates BoundedEventually formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual void visitBoundedEventually(const BoundedEventually<T>& obj) = 0; -}; - -/*! - * @brief - * Class for an abstract (path) formula tree with a BoundedEventually node as root. - * - * Has one Abstract LTL formulas as sub formula/tree. - * - * @par Semantics - * The formula holds iff in at most \e bound steps, formula \e child holds. - * - * The subtrees are seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @see AbstractLtlFormula - */ -template <class T> -class BoundedEventually : public storm::property::abstract::BoundedEventually<T, AbstractLtlFormula<T>>, - public AbstractLtlFormula<T> { - -public: - /*! - * Empty constructor - */ - BoundedEventually() { - //intentionally left empty - } - - /*! - * Constructor - * - * @param child The child formula subtree - * @param bound The maximal number of steps - */ - BoundedEventually(AbstractLtlFormula<T>* child, uint_fast64_t bound) : - storm::property::abstract::BoundedEventually<T, AbstractLtlFormula<T>>(child, bound){ - //intentionally left empty - } - - /*! - * Destructor. - * - * Also deletes the subtrees. - * (this behaviour can be prevented by setting the subtrees to NULL before deletion) - */ - virtual ~BoundedEventually() { - //intentionally left empty - } - - /*! - * Clones the called object. - * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones - * - * @returns a new BoundedUntil-object that is identical the called object. - */ - virtual AbstractLtlFormula<T>* clone() const override { - BoundedEventually<T>* result = new BoundedEventually<T>(); - result->setBound(this->getBound()); - if (this->childIsSet()) { - result->setChild(this->getChild().clone()); - } - return result; - } - - - /*! - * Calls the model checker to check this formula. - * Needed to infer the correct type of formula class. - * - * @note This function should only be called in a generic check function of a model checker class. For other uses, - * the methods of the model checker should be used. - * - * @returns A vector indicating the probability that the formula holds for each state. - */ - virtual std::vector<T> check(const storm::modelchecker::ltl::AbstractModelChecker<T>& modelChecker) const override { - return modelChecker.template as<IBoundedEventuallyModelChecker>()->checkBoundedEventually(*this); - } - - virtual void visit(visitor::AbstractLtlFormulaVisitor<T>& visitor) const override { - visitor.template as<IBoundedEventuallyVisitor>()->visitBoundedEventually(*this); - } -}; - -} //namespace ltl -} //namespace property -} //namespace storm - -#endif /* STORM_FORMULA_LTL_BOUNDEDUNTIL_H_ */ diff --git a/src/formula/Ltl/BoundedUntil.h b/src/formula/Ltl/BoundedUntil.h deleted file mode 100644 index 8d6f2fcf3..000000000 --- a/src/formula/Ltl/BoundedUntil.h +++ /dev/null @@ -1,163 +0,0 @@ -/* - * BoundedUntil.h - * - * Created on: 19.10.2012 - * Author: Thomas Heinemann - */ - -#ifndef STORM_FORMULA_LTL_BOUNDEDUNTIL_H_ -#define STORM_FORMULA_LTL_BOUNDEDUNTIL_H_ - -#include "src/formula/abstract/BoundedUntil.h" -#include "AbstractLtlFormula.h" -#include <cstdint> -#include <string> -#include "src/modelchecker/ltl/ForwardDeclarations.h" - -namespace storm { -namespace property { -namespace ltl { - -template <class T> class BoundedUntil; - -/*! - * @brief Interface class for model checkers that support BoundedUntil. - * - * All model checkers that support the formula class BoundedUntil must inherit - * this pure virtual class. - */ -template <class T> -class IBoundedUntilModelChecker { - public: - /*! - * @brief Evaluates BoundedUntil formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual std::vector<T> checkBoundedUntil(const BoundedUntil<T>& obj) const = 0; -}; - -/*! - * @brief Interface class for visitors that support BoundedUntil. - * - * All visitors that support the formula class BoundedUnitl must inherit - * this pure virtual class. - */ -template <class T> -class IBoundedUntilVisitor { - public: - /*! - * @brief Visits BoundedUntil formula. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual void visitBoundedUntil(const BoundedUntil<T>& obj) = 0; -}; - -/*! - * @brief - * Class for an abstract (path) formula tree with a BoundedUntil node as root. - * - * Has two Abstract LTL formulas as sub formulas/trees. - * - * @par Semantics - * The formula holds iff in at most \e bound steps, formula \e right (the right subtree) holds, and before, - * \e left holds. - * - * The subtrees are seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @see AbstractLtlFormula - */ -template <class T> -class BoundedUntil : public storm::property::abstract::BoundedUntil<T, AbstractLtlFormula<T>>, - public AbstractLtlFormula<T> { - -public: - /*! - * Empty constructor - */ - BoundedUntil() { - //Intentionally left empty - } - - /*! - * Constructor - * - * @param left The left formula subtree - * @param right The left formula subtree - * @param bound The maximal number of steps - */ - BoundedUntil(AbstractLtlFormula<T>* left, AbstractLtlFormula<T>* right, - uint_fast64_t bound) : - storm::property::abstract::BoundedUntil<T, AbstractLtlFormula<T>>(left,right,bound) { - //intentionally left empty - } - - /*! - * Destructor. - * - * Also deletes the subtrees. - * (this behaviour can be prevented by setting the subtrees to NULL before deletion) - */ - virtual ~BoundedUntil() { - //intentionally left empty - } - - /*! - * @brief Return string representation of this formula. - * - * In LTL, brackets are needed around the until, as Until may appear nested (in other logics, Until always is the - * root of a path formula); hence this function is overwritten in this class. - * - * @return A string representation of the formula. - */ - virtual std::string toString() const { - return "(" + storm::property::abstract::BoundedUntil<T, AbstractLtlFormula<T>>::toString() + ")"; - } - - /*! - * Clones the called object. - * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones - * - * @returns a new BoundedUntil-object that is identical the called object. - */ - virtual AbstractLtlFormula<T>* clone() const override { - BoundedUntil<T>* result = new BoundedUntil<T>(); - result->setBound(this->getBound()); - if (this->leftIsSet()) { - result->setLeft(this->getLeft().clone()); - } - if (this->rightIsSet()) { - result->setRight(this->getRight().clone()); - } - return result; - } - - - /*! - * Calls the model checker to check this formula. - * Needed to infer the correct type of formula class. - * - * @note This function should only be called in a generic check function of a model checker class. For other uses, - * the methods of the model checker should be used. - * - * @returns A vector indicating the probability that the formula holds for each state. - */ - virtual std::vector<T> check(const storm::modelchecker::ltl::AbstractModelChecker<T>& modelChecker) const { - return modelChecker.template as<IBoundedUntilModelChecker>()->checkBoundedUntil(*this); - } - - virtual void visit(visitor::AbstractLtlFormulaVisitor<T>& visitor) const override { - visitor.template as<IBoundedUntilVisitor>()->visitBoundedUntil(*this); - } -}; - -} //namespace ltl -} //namespace property -} //namespace storm - -#endif /* STORM_FORMULA_LTL_BOUNDEDUNTIL_H_ */ diff --git a/src/formula/Ltl/Eventually.h b/src/formula/Ltl/Eventually.h deleted file mode 100644 index 2ca73607c..000000000 --- a/src/formula/Ltl/Eventually.h +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Next.h - * - * Created on: 26.12.2012 - * Author: Christian Dehnert - */ - -#ifndef STORM_FORMULA_LTL_EVENTUALLY_H_ -#define STORM_FORMULA_LTL_EVENTUALLY_H_ - -#include "src/formula/abstract/Eventually.h" -#include "AbstractLtlFormula.h" -#include "src/modelchecker/ltl/ForwardDeclarations.h" - -namespace storm { -namespace property { -namespace ltl { - -template <class T> class Eventually; - -/*! - * @brief Interface class for model checkers that support Eventually. - * - * All model checkers that support the formula class Eventually must inherit - * this pure virtual class. - */ -template <class T> -class IEventuallyModelChecker { - public: - /*! - * @brief Evaluates Eventually formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual std::vector<T> checkEventually(const Eventually<T>& obj) const = 0; -}; - -/*! - * @brief Interface class for visitors that support Eventually. - * - * All visitors that support the formula class Eventually must inherit - * this pure virtual class. - */ -template <class T> -class IEventuallyVisitor { - public: - /*! - * @brief Visits Eventually formula. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual void visitEventually(const Eventually<T>& obj) = 0; -}; - -/*! - * @brief - * Class for an abstract (path) formula tree with an Eventually node as root. - * - * Has one Abstract LTL formula as sub formula/tree. - * - * @par Semantics - * The formula holds iff eventually \e child holds. - * - * The subtree is seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to nullptr before deletion) - * - * @see AbstractLtlFormula - */ -template <class T> -class Eventually : public storm::property::abstract::Eventually<T, AbstractLtlFormula<T>>, - public AbstractLtlFormula<T> { - -public: - /*! - * Empty constructor - */ - Eventually() { - // Intentionally left empty - } - - /*! - * Constructor - * - * @param child The child node - */ - Eventually(AbstractLtlFormula<T>* child) - : storm::property::abstract::Eventually<T, AbstractLtlFormula<T>>(child) { - - } - - /*! - * Constructor. - * - * Also deletes the subtree. - * (this behaviour can be prevented by setting the subtrees to nullptr before deletion) - */ - virtual ~Eventually() { - //intentionally left empty - } - - /*! - * Clones the called object. - * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones - * - * @returns a new Eventually-object that is identical the called object. - */ - virtual AbstractLtlFormula<T>* clone() const override { - Eventually<T>* result = new Eventually<T>(); - if (this->childIsSet()) { - result->setChild(this->getChild().clone()); - } - return result; - } - - /*! - * Calls the model checker to check this formula. - * Needed to infer the correct type of formula class. - * - * @note This function should only be called in a generic check function of a model checker class. For other uses, - * the methods of the model checker should be used. - * - * @returns A vector indicating the probability that the formula holds for each state. - */ - virtual std::vector<T> check(const storm::modelchecker::ltl::AbstractModelChecker<T>& modelChecker) const { - return modelChecker.template as<IEventuallyModelChecker>()->checkEventually(*this); - } - - virtual void visit(visitor::AbstractLtlFormulaVisitor<T>& visitor) const override { - visitor.template as<IEventuallyVisitor>()->visitEventually(*this); - } -}; - -} //namespace ltl -} //namespace property -} //namespace storm - -#endif /* STORM_FORMULA_LTL_EVENTUALLY_H_ */ diff --git a/src/formula/Ltl/Globally.h b/src/formula/Ltl/Globally.h deleted file mode 100644 index 21bacaf14..000000000 --- a/src/formula/Ltl/Globally.h +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Next.h - * - * Created on: 26.12.2012 - * Author: Christian Dehnert - */ - -#ifndef STORM_FORMULA_LTL_GLOBALLY_H_ -#define STORM_FORMULA_LTL_GLOBALLY_H_ - -#include "src/formula/abstract/Globally.h" -#include "AbstractLtlFormula.h" -#include "src/formula/AbstractFormulaChecker.h" -#include "src/modelchecker/ltl/ForwardDeclarations.h" - -namespace storm { -namespace property { -namespace ltl { - -template <class T> class Globally; - -/*! - * @brief Interface class for model checkers that support Globally. - * - * All model checkers that support the formula class Globally must inherit - * this pure virtual class. - */ -template <class T> -class IGloballyModelChecker { - public: - /*! - * @brief Evaluates Globally formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual std::vector<T> checkGlobally(const Globally<T>& obj) const = 0; -}; - -/*! - * @brief Interface class for visitors that support Globally. - * - * All visitors that support the formula class Globally must inherit - * this pure virtual class. - */ -template <class T> -class IGloballyVisitor { - public: - /*! - * @brief Visits Globally formula. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual void visitGlobally(const Globally<T>& obj) = 0; -}; - -/*! - * @brief - * Class for an abstract (path) formula tree with a Globally node as root. - * - * Has one Abstract LTL formula as sub formula/tree. - * - * @par Semantics - * The formula holds iff globally \e child holds. - * - * The subtree is seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to nullptr before deletion) - * - * @see AbstractLtlFormula - */ -template <class T> -class Globally : public storm::property::abstract::Globally<T, AbstractLtlFormula<T>>, - public AbstractLtlFormula<T> { - -public: - /*! - * Empty constructor - */ - Globally() { - //intentionally left empty - } - - /*! - * Constructor - * - * @param child The child node - */ - Globally(AbstractLtlFormula<T>* child) - : storm::property::abstract::Globally<T, AbstractLtlFormula<T>>(child) { - //intentionally left empty - } - - /*! - * Constructor. - * - * Also deletes the subtree. - * (this behaviour can be prevented by setting the subtrees to nullptr before deletion) - */ - virtual ~Globally() { - //intentionally left empty - } - - - /*! - * Clones the called object. - * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones - * - * @returns a new Globally-object that is identical the called object. - */ - virtual AbstractLtlFormula<T>* clone() const override { - Globally<T>* result = new Globally<T>(); - if (this->childIsSet()) { - result->setChild(this->getChild().clone()); - } - return result; - } - - /*! - * Calls the model checker to check this formula. - * Needed to infer the correct type of formula class. - * - * @note This function should only be called in a generic check function of a model checker class. For other uses, - * the methods of the model checker should be used. - * - * @returns A vector indicating the probability that the formula holds for each state. - */ - virtual std::vector<T> check(const storm::modelchecker::ltl::AbstractModelChecker<T>& modelChecker) const { - return modelChecker.template as<IGloballyModelChecker>()->checkGlobally(*this); - } - - virtual void visit(visitor::AbstractLtlFormulaVisitor<T>& visitor) const override { - visitor.template as<IGloballyVisitor>()->visitGlobally(*this); - } -}; - -} //namespace ltl -} //namespace property -} //namespace storm - -#endif /* STORM_FORMULA_LTL_GLOBALLY_H_ */ diff --git a/src/formula/Ltl/Next.h b/src/formula/Ltl/Next.h deleted file mode 100644 index 44d98e12f..000000000 --- a/src/formula/Ltl/Next.h +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Next.h - * - * Created on: 19.10.2012 - * Author: Thomas Heinemann - */ - -#ifndef STORM_FORMULA_LTL_NEXT_H_ -#define STORM_FORMULA_LTL_NEXT_H_ - -#include "AbstractLtlFormula.h" -#include "src/formula/abstract/Next.h" -#include "src/formula/AbstractFormulaChecker.h" - -namespace storm { -namespace property { -namespace ltl { - -template <class T> class Next; - -/*! - * @brief Interface class for model checkers that support Next. - * - * All model checkers that support the formula class Next must inherit - * this pure virtual class. - */ -template <class T> -class INextModelChecker { - public: - /*! - * @brief Evaluates Next formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual std::vector<T> checkNext(const Next<T>& obj) const = 0; -}; - -/*! - * @brief Interface class for visitors that support Next. - * - * All visitors that support the formula class Next must inherit - * this pure virtual class. - */ -template <class T> -class INextVisitor { - public: - /*! - * @brief Visits Next formula. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual void visitNext(const Next<T>& obj) = 0; -}; - -/*! - * @brief - * Class for an abstract (path) formula tree with a Next node as root. - * - * Has two Abstract LTL formulas as sub formulas/trees. - * - * @par Semantics - * The formula holds iff in the next step, \e child holds - * - * The subtree is seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @see AbstractLtlFormula - */ -template <class T> -class Next : public storm::property::abstract::Next<T, AbstractLtlFormula<T>>, - public AbstractLtlFormula<T> { - -public: - /*! - * Empty constructor - */ - Next() { - //intentionally left empty - } - - /*! - * Constructor - * - * @param child The child node - */ - Next(AbstractLtlFormula<T>* child) - : storm::property::abstract::Next<T, AbstractLtlFormula<T>>(child) { - //intentionally left empty - } - - /*! - * Constructor. - * - * Also deletes the subtree. - * (this behaviour can be prevented by setting the subtrees to NULL before deletion) - */ - virtual ~Next() { - //intentionally left empty - } - - /*! - * Clones the called object. - * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones - * - * @returns a new BoundedUntil-object that is identical the called object. - */ - virtual AbstractLtlFormula<T>* clone() const override { - Next<T>* result = new Next<T>(); - if (this->childIsSet()) { - result->setChild(this->getChild().clone()); - } - return result; - } - - /*! - * Calls the model checker to check this formula. - * Needed to infer the correct type of formula class. - * - * @note This function should only be called in a generic check function of a model checker class. For other uses, - * the methods of the model checker should be used. - * - * @returns A vector indicating the probability that the formula holds for each state. - */ - virtual std::vector<T> check(const storm::modelchecker::ltl::AbstractModelChecker<T>& modelChecker) const { - return modelChecker.template as<INextModelChecker>()->checkNext(*this); - } - - virtual void visit(visitor::AbstractLtlFormulaVisitor<T>& visitor) const override { - visitor.template as<INextVisitor>()->visitNext(*this); - } -}; - -} //namespace ltl -} //namespace property -} //namespace storm - -#endif /* STORM_FORMULA_LTL_NEXT_H_ */ diff --git a/src/formula/Ltl/Not.h b/src/formula/Ltl/Not.h deleted file mode 100644 index bcf510999..000000000 --- a/src/formula/Ltl/Not.h +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Not.h - * - * Created on: 19.10.2012 - * Author: Thomas Heinemann - */ - -#ifndef STORM_FORMULA_LTL_NOT_H_ -#define STORM_FORMULA_LTL_NOT_H_ - -#include "AbstractLtlFormula.h" -#include "src/formula/abstract/Not.h" -#include "src/formula/AbstractFormulaChecker.h" - -namespace storm { -namespace property { -namespace ltl { - -template <class T> class Not; - -/*! - * @brief Interface class for model checkers that support Not. - * - * All model checkers that support the formula class Not must inherit - * this pure virtual class. - */ -template <class T> -class INotModelChecker { - public: - /*! - * @brief Evaluates Not formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual std::vector<T> checkNot(const Not<T>& obj) const = 0; -}; - -/*! - * @brief Interface class for visitors that support Not. - * - * All visitors that support the formula class Not must inherit - * this pure virtual class. - */ -template <class T> -class INotVisitor { - public: - /*! - * @brief Visits Not formula. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual void visitNot(const Not<T>& obj) = 0; -}; - -/*! - * @brief - * Class for an abstract formula tree with NOT node as root. - * - * Has one Abstract LTL formula as sub formula/tree. - * - * The subtree is seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @see AbstractLtlFormula - */ -template <class T> -class Not : public storm::property::abstract::Not<T, AbstractLtlFormula<T>>, - public AbstractLtlFormula<T> { - -public: - /*! - * Empty constructor - */ - Not() { - //intentionally left empty - } - - /*! - * Constructor - * @param child The child node - */ - Not(AbstractLtlFormula<T>* child) : - storm::property::abstract::Not<T, AbstractLtlFormula<T>>(child){ - //intentionally left empty - } - - /*! - * Destructor - * - * Also deletes the subtree - * (this behavior can be prevented by setting them to NULL before deletion) - */ - virtual ~Not() { - //intentionally left empty - } - - /*! - * Clones the called object. - * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones - * - * @returns a new AND-object that is identical the called object. - */ - virtual AbstractLtlFormula<T>* clone() const override { - Not<T>* result = new Not<T>(); - if (this->childIsSet()) { - result->setChild(this->getChild().clone()); - } - return result; - } - - /*! - * Calls the model checker to check this formula. - * Needed to infer the correct type of formula class. - * - * @note This function should only be called in a generic check function of a model checker class. For other uses, - * the methods of the model checker should be used. - * - * @returns A bit vector indicating all states that satisfy the formula represented by the called object. - */ - virtual std::vector<T> check(const storm::modelchecker::ltl::AbstractModelChecker<T>& modelChecker) const override { - return modelChecker.template as<INotModelChecker>()->checkNot(*this); - } - - virtual void visit(visitor::AbstractLtlFormulaVisitor<T>& visitor) const override { - visitor.template as<INotVisitor>()->visitNot(*this); - } -}; - -} //namespace ltl -} //namespace property -} //namespace storm - -#endif /* STORM_FORMULA_LTL_NOT_H_ */ diff --git a/src/formula/Ltl/Or.h b/src/formula/Ltl/Or.h deleted file mode 100644 index 511420d5d..000000000 --- a/src/formula/Ltl/Or.h +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Or.h - * - * Created on: 22.04.2013 - * Author: thomas - */ - -#ifndef STORM_FORMULA_LTL_OR_H_ -#define STORM_FORMULA_LTL_OR_H_ - -#include "AbstractLtlFormula.h" -#include "src/formula/abstract/Or.h" - -namespace storm { -namespace property { -namespace ltl { - -template <class T> class Or; - -/*! - * @brief Interface class for model checkers that support And. - * - * All model checkers that support the formula class And must inherit - * this pure virtual class. - */ -template <class T> -class IOrModelChecker { - public: - /*! - * @brief Evaluates And formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual std::vector<T> checkOr(const Or<T>& obj) const = 0; -}; - -/*! - * @brief Interface class for visitors that support Or. - * - * All visitors that support the formula class Or must inherit - * this pure virtual class. - */ -template <class T> -class IOrVisitor { - public: - /*! - * @brief Visits Or formula. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual void visitOr(const Or<T>& obj) = 0; -}; - -/*! - * @brief - * Class for an abstract formula tree with OR node as root. - * - * Has two LTL formulas as sub formulas/trees. - * - * As OR is commutative, the order is \e theoretically not important, but will influence the order in which - * the model checker works. - * - * The subtrees are seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @see AbstractLtlFormula - */ -template <class T> -class Or: public storm::property::abstract::Or<T, AbstractLtlFormula<T>>, - public storm::property::ltl::AbstractLtlFormula<T> { -public: - /*! - * Empty constructor - */ - Or() { - // Intentionally left empty - - } - - /*! - * Constructor - * Creates an OR node with the parameters as subtrees. - * - * @param left The left subformula - * @param right The right subformula - */ - Or(AbstractLtlFormula<T>* left, AbstractLtlFormula<T>* right) - : storm::property::abstract::Or<T,AbstractLtlFormula<T>>(left, right) { - // Intentionally left empty - } - - /*! - * Destructor - */ - virtual ~Or() { - // Intentionally left empty - } - - /*! - * Clones the called object. - * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones - * - * @returns a new AND-object that is identical the called object. - */ - virtual AbstractLtlFormula<T>* clone() const override { - Or<T>* result = new Or(); - if (this->leftIsSet()) { - result->setLeft(this->getLeft().clone()); - } - if (this->rightIsSet()) { - result->setRight(this->getRight().clone()); - } - return result; - } - - /*! - * Calls the model checker to check this formula. - * Needed to infer the correct type of formula class. - * - * @note This function should only be called in a generic check function of a model checker class. For other uses, - * the methods of the model checker should be used. - * - * @returns A bit vector indicating all states that satisfy the formula represented by the called object. - */ - virtual std::vector<T> check(const storm::modelchecker::ltl::AbstractModelChecker<T>& modelChecker) const override { - return modelChecker.template as<IOrModelChecker>()->checkOr(*this); - } - - virtual void visit(visitor::AbstractLtlFormulaVisitor<T>& visitor) const override { - visitor.template as<IOrVisitor>()->visitOr(*this); - } - -}; - -} /* namespace ltl */ -} /* namespace property */ -} /* namespace storm */ -#endif /* OR_H_ */ diff --git a/src/formula/Ltl/Until.h b/src/formula/Ltl/Until.h deleted file mode 100644 index 359e64a0a..000000000 --- a/src/formula/Ltl/Until.h +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Until.h - * - * Created on: 19.10.2012 - * Author: Thomas Heinemann - */ - -#ifndef STORM_FORMULA_LTL_UNTIL_H_ -#define STORM_FORMULA_LTL_UNTIL_H_ - -#include "AbstractLtlFormula.h" -#include "src/formula/abstract/Until.h" -#include "src/formula/AbstractFormulaChecker.h" - -namespace storm { -namespace property { -namespace ltl { - -template <class T> class Until; - -/*! - * @brief Interface class for model checkers that support Until. - * - * All model checkers that support the formula class Until must inherit - * this pure virtual class. - */ -template <class T> -class IUntilModelChecker { - public: - /*! - * @brief Evaluates Until formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual std::vector<T> checkUntil(const Until<T>& obj) const = 0; -}; - -/*! - * @brief Interface class for visitors that support Until. - * - * All visitors that support the formula class Until must inherit - * this pure virtual class. - */ -template <class T> -class IUntilVisitor { - public: - /*! - * @brief Visits Until formula. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual void visitUntil(const Until<T>& obj) = 0; -}; - -/*! - * @brief - * Class for an abstract (path) formula tree with an Until node as root. - * - * Has two Abstract LTL formulas as sub formulas/trees. - * - * @par Semantics - * The formula holds iff eventually, formula \e right (the right subtree) holds, and before, - * \e left holds always. - * - * The subtrees are seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @see AbstractLtlFormula - */ -template <class T> -class Until : public storm::property::abstract::Until<T, AbstractLtlFormula<T>>, - public AbstractLtlFormula<T> { - -public: - /*! - * Empty constructor - */ - Until() { - // Intentionally left empty - } - - /*! - * Constructor - * - * @param left The left formula subtree - * @param right The left formula subtree - */ - Until(AbstractLtlFormula<T>* left, AbstractLtlFormula<T>* right) - : storm::property::abstract::Until<T, AbstractLtlFormula<T>>(left, right) { - // Intentionally left empty - } - - /*! - * Destructor. - * - * Also deletes the subtrees. - * (this behaviour can be prevented by setting the subtrees to NULL before deletion) - */ - virtual ~Until() { - // Intentionally left empty - } - - /*! - * @brief Return string representation of this formula. - * - * In LTL, brackets are needed around the until, as Until may appear nested (in other logics, Until always is the - * root of a path formula); hence this function is overwritten in this class. - * - * @return A string representation of the formula. - */ - virtual std::string toString() const { - return "(" + storm::property::abstract::Until<T, AbstractLtlFormula<T>>::toString() + ")"; - } - - /*! - * Clones the called object. - * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones - * - * @returns a new BoundedUntil-object that is identical the called object. - */ - virtual AbstractLtlFormula<T>* clone() const override { - Until<T>* result = new Until(); - if (this->leftIsSet()) { - result->setLeft(this->getLeft().clone()); - } - if (this->rightIsSet()) { - result->setRight(this->getRight().clone()); - } - return result; - } - - /*! - * Calls the model checker to check this formula. - * Needed to infer the correct type of formula class. - * - * @note This function should only be called in a generic check function of a model checker class. For other uses, - * the methods of the model checker should be used. - * - * @returns A vector indicating the probability that the formula holds for each state. - */ - virtual std::vector<T> check(const storm::modelchecker::ltl::AbstractModelChecker<T>& modelChecker) const { - return modelChecker.template as<IUntilModelChecker>()->checkUntil(*this); - } - - virtual void visit(visitor::AbstractLtlFormulaVisitor<T>& visitor) const override { - visitor.template as<IUntilVisitor>()->visitUntil(*this); - } -}; - -} //namespace ltl -} //namespace property -} //namespace storm - -#endif /* STORM_FORMULA_LTL_UNTIL_H_ */ diff --git a/src/formula/Ltl/visitor/AbstractLtlFormulaVisitor.cpp b/src/formula/Ltl/visitor/AbstractLtlFormulaVisitor.cpp deleted file mode 100644 index 99653fca2..000000000 --- a/src/formula/Ltl/visitor/AbstractLtlFormulaVisitor.cpp +++ /dev/null @@ -1,16 +0,0 @@ -/* - * AbstractLtlFormulaVisitor.cpp - * - * Created on: 29.05.2013 - * Author: thomas - */ - -#include "AbstractLtlFormulaVisitor.h" - -namespace storm { -namespace property { -namespace visitor { - -} /* namespace visitor */ -} /* namespace property */ -} /* namespace storm */ diff --git a/src/formula/Ltl/visitor/AbstractLtlFormulaVisitor.h b/src/formula/Ltl/visitor/AbstractLtlFormulaVisitor.h deleted file mode 100644 index db0ff8956..000000000 --- a/src/formula/Ltl/visitor/AbstractLtlFormulaVisitor.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * AbstractLtlFormulaVisitor.h - * - * Created on: 29.05.2013 - * Author: thomas - */ - -#ifndef STORM_PROPERTY_LTL_VISITOR_ABSTRACTLTLFORMULAVISITOR_H_ -#define STORM_PROPERTY_LTL_VISITOR_ABSTRACTLTLFORMULAVISITOR_H_ - -// Forward declaration of visitor -namespace storm { -namespace property { -namespace ltl { -namespace visitor { - -template <class T> -class AbstractLtlFormulaVisitor; - -} /* namespace visitor */ -} -} -} - -#include "../AbstractLtlFormula.h" -#include "log4cplus/logger.h" -#include "log4cplus/loggingmacros.h" - -#include <typeinfo> - -extern log4cplus::Logger logger; - -namespace storm { -namespace property { -namespace ltl { -namespace visitor { - -template <class T> -class AbstractLtlFormulaVisitor { -public: - virtual ~AbstractLtlFormulaVisitor() { - // TODO Auto-generated destructor stub - } - - - /*! - * Returns a pointer to the model checker object that is of the requested type as given by the template parameters. - * @returns A pointer to the model checker object that is of the requested type as given by the template parameters. - * If the model checker is not of the requested type, type casting will fail and result in an exception. - */ - template <template <class Type> class Target> - Target<T>* as() { - try { - Target<T>* target = dynamic_cast<Target<T>*>(this); - return target; - } catch (std::bad_cast& bc) { - LOG4CPLUS_ERROR(logger, "Bad cast: tried to cast " << typeid(*this).name() << " to " << typeid(Target<T>).name() << "."); - throw bc; - } - return nullptr; - } - - void visit(storm::property::ltl::AbstractLtlFormula<T> const& formula) { - formula.visit(*this); - } -}; - -} /* namespace visitor */ -} /* namespace ltl*/ -} /* namespace property */ -} /* namespace storm */ -#endif /* STORM_PROPERTY_LTL_VISITOR_ABSTRACTLTLFORMULAVISITOR_H_ */ diff --git a/src/formula/Prctl.h b/src/formula/Prctl.h deleted file mode 100644 index 87466f55f..000000000 --- a/src/formula/Prctl.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Prctl.h - * - * Created on: 06.12.2012 - * Author: Christian Dehnert - */ - -#ifndef STORM_FORMULA_PRCTL_H_ -#define STORM_FORMULA_PRCTL_H_ - -#include "modelchecker/prctl/ForwardDeclarations.h" - -#include "Prctl/And.h" -#include "Prctl/Ap.h" -#include "Prctl/BoundedUntil.h" -#include "Prctl/BoundedNaryUntil.h" -#include "Prctl/Next.h" -#include "Prctl/Not.h" -#include "Prctl/Or.h" -#include "Prctl/ProbabilisticNoBoundOperator.h" -#include "Prctl/ProbabilisticBoundOperator.h" - -#include "Prctl/Until.h" -#include "Prctl/Eventually.h" -#include "Prctl/Globally.h" -#include "Prctl/BoundedEventually.h" - -#include "Prctl/InstantaneousReward.h" -#include "Prctl/CumulativeReward.h" -#include "Prctl/ReachabilityReward.h" -#include "Prctl/RewardBoundOperator.h" -#include "Prctl/RewardNoBoundOperator.h" -#include "Prctl/SteadyStateReward.h" - -#include "Prctl/AbstractPrctlFormula.h" -#include "Prctl/AbstractStateFormula.h" -#include "Prctl/AbstractNoBoundOperator.h" -#include "Prctl/AbstractPathFormula.h" - -#include "modelchecker/prctl/AbstractModelChecker.h" - -#endif /* STORM_FORMULA_PRCTL_H_ */ diff --git a/src/formula/Prctl/AbstractNoBoundOperator.h b/src/formula/Prctl/AbstractNoBoundOperator.h deleted file mode 100644 index c73c4ed6f..000000000 --- a/src/formula/Prctl/AbstractNoBoundOperator.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * AbstractNoBoundOperator.h - * - * Created on: 16.04.2013 - * Author: thomas - */ - -#ifndef STORM_FORMULA_PRCTL_ABSTRACTNOBOUNDOPERATOR_H_ -#define STORM_FORMULA_PRCTL_ABSTRACTNOBOUNDOPERATOR_H_ - -#include "AbstractPrctlFormula.h" -#include "src/formula/abstract/IOptimizingOperator.h" - -namespace storm { -namespace property { -namespace prctl { - -template <class T> -class AbstractNoBoundOperator; - -/*! - * @brief Interface class for model checkers that support PathNoBoundOperator. - * - * All model checkers that support the formula class NoBoundOperator must inherit - * this pure virtual class. - */ -template <class T> -class INoBoundOperatorModelChecker { -public: - /*! - * @brief Evaluates NoBoundOperator formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual std::vector<T> checkNoBoundOperator(const AbstractNoBoundOperator<T>& obj) const = 0; - - -}; - -/*! - * Interface class for all PRCTL No bound operators - */ -template <class T> -class AbstractNoBoundOperator: public AbstractPrctlFormula<T>, - public virtual storm::property::abstract::IOptimizingOperator { -public: - AbstractNoBoundOperator() { - // Intentionally left empty. - - } - virtual ~AbstractNoBoundOperator() { - // Intentionally left empty - } - - /*! - * Clones the called object. - * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones - * - * @note This function is not implemented in this class. - * @returns a new AND-object that is identical the called object. - */ - virtual AbstractNoBoundOperator<T>* clone() const = 0; - - /*! - * Calls the model checker to check this formula. - * Needed to infer the correct type of formula class. - * - * @note This function should only be called in a generic check function of a model checker class. For other uses, - * the methods of the model checker should be used. - * - * @note This function is not implemented in this class. - * - * @returns A vector indicating the probability that the formula holds for each state. - */ - virtual std::vector<T> check(const storm::modelchecker::prctl::AbstractModelChecker<T>& modelChecker, bool qualitative=false) const = 0; -}; - -} /* namespace prctl */ -} /* namespace property */ -} /* namespace storm */ -#endif /* STORM_FORMULA_PRCTL_ABSTRACTNOBOUNDOPERATOR_H_ */ diff --git a/src/formula/Prctl/AbstractPrctlFormula.h b/src/formula/Prctl/AbstractPrctlFormula.h deleted file mode 100644 index 8855763a9..000000000 --- a/src/formula/Prctl/AbstractPrctlFormula.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * AbstractPrctlFormula.h - * - * Created on: 16.04.2013 - * Author: thomas - */ - -#ifndef STORM_FORMULA_PRCTL_ABSTRACTPRCTLFORMULA_H_ -#define STORM_FORMULA_PRCTL_ABSTRACTPRCTLFORMULA_H_ - -#include "src/formula/abstract/AbstractFormula.h" - -namespace storm { -namespace property { -namespace prctl { - -/*! - * Interface class for all PRCTL root formulas. - */ -template<class T> -class AbstractPrctlFormula : public virtual storm::property::abstract::AbstractFormula<T> { -public: - virtual ~AbstractPrctlFormula() { - // Intentionally left empty - } -}; - -} /* namespace prctl */ -} /* namespace property */ -} /* namespace storm */ -#endif /* ABSTRACTPRCTLFORMULA_H_ */ diff --git a/src/formula/Prctl/And.h b/src/formula/Prctl/And.h deleted file mode 100644 index eca17d73d..000000000 --- a/src/formula/Prctl/And.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - * And.h - * - * Created on: 19.10.2012 - * Author: Thomas Heinemann - */ - -#ifndef STORM_FORMULA_PRCTL_AND_H_ -#define STORM_FORMULA_PRCTL_AND_H_ - -#include "AbstractStateFormula.h" -#include "src/formula/abstract/And.h" -#include "src/formula/AbstractFormulaChecker.h" -#include "src/modelchecker/prctl/ForwardDeclarations.h" -#include <string> - -namespace storm { -namespace property { -namespace prctl { - -template <class T> class And; - -/*! - * @brief Interface class for model checkers that support And. - * - * All model checkers that support the formula class And must inherit - * this pure virtual class. - */ -template <class T> -class IAndModelChecker { - public: - /*! - * @brief Evaluates And formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual storm::storage::BitVector checkAnd(const And<T>& obj) const = 0; -}; - -/*! - * @brief - * Class for an abstract formula tree with AND node as root. - * - * Has two Abstract state formulas as sub formulas/trees. - * - * As AND is commutative, the order is \e theoretically not important, but will influence the order in which - * the model checker works. - * - * The subtrees are seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @see AbstractStateFormula - * @see AbstractPrctlFormula - */ -template <class T> -class And : public storm::property::abstract::And<T, AbstractStateFormula<T>>, public AbstractStateFormula<T> { - -public: - /*! - * Empty constructor. - * Will create an AND-node without subnotes. Will not represent a complete formula! - */ - And() { - //intentionally left empty - } - - /*! - * Constructor. - * Creates an AND note with the parameters as subtrees. - * - * @param left The left sub formula - * @param right The right sub formula - */ - And(AbstractStateFormula<T>* left, AbstractStateFormula<T>* right) - : storm::property::abstract::And<T, AbstractStateFormula<T>>(left, right) { - //intentionally left empty - } - - /*! - * Destructor. - * - * The subtrees are deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - */ - virtual ~And() { - //intentionally left empty - } - - /*! - * Clones the called object. - * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones - * - * @returns a new AND-object that is identical the called object. - */ - virtual AbstractStateFormula<T>* clone() const override { - And<T>* result = new And(); - if (this->leftIsSet()) { - result->setLeft(this->getLeft().clone()); - } - if (this->rightIsSet()) { - result->setRight(this->getRight().clone()); - } - return result; - } - - /*! - * Calls the model checker to check this formula. - * Needed to infer the correct type of formula class. - * - * @note This function should only be called in a generic check function of a model checker class. For other uses, - * the methods of the model checker should be used. - * - * @returns A bit vector indicating all states that satisfy the formula represented by the called object. - */ - virtual storm::storage::BitVector check(const storm::modelchecker::prctl::AbstractModelChecker<T>& modelChecker) const override { - return modelChecker.template as<IAndModelChecker>()->checkAnd(*this); - } - -}; - -} //namespace prctl - -} //namespace property - -} //namespace storm - -#endif /* STORM_FORMULA_PRCTL_AND_H_ */ diff --git a/src/formula/Prctl/Ap.h b/src/formula/Prctl/Ap.h deleted file mode 100644 index d2df03951..000000000 --- a/src/formula/Prctl/Ap.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Ap.h - * - * Created on: 19.10.2012 - * Author: Thomas Heinemann - */ - -#ifndef STORM_FORMULA_PRCTL_AP_H_ -#define STORM_FORMULA_PRCTL_AP_H_ - -#include "AbstractStateFormula.h" -#include "src/formula/abstract/Ap.h" -#include "src/formula/AbstractFormulaChecker.h" -#include "src/modelchecker/prctl/ForwardDeclarations.h" - -namespace storm { -namespace property { -namespace prctl { - -template <class T> class Ap; - -/*! - * @brief Interface class for model checkers that support Ap. - * - * All model checkers that support the formula class Ap must inherit - * this pure virtual class. - */ -template <class T> -class IApModelChecker { - public: - /*! - * @brief Evaluates Ap formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual storm::storage::BitVector checkAp(const Ap<T>& obj) const = 0; -}; - -/*! - * @brief - * Class for an abstract formula tree with atomic proposition as root. - * - * This class represents the leaves in the formula tree. - * - * @see AbstractPrctlFormula - * @see AbstractStateFormula - */ -template <class T> -class Ap : public storm::property::abstract::Ap<T>, - public AbstractStateFormula<T> { - -public: - /*! - * Constructor - * - * Creates a new atomic proposition leaf, with the label Ap - * - * @param ap The string representing the atomic proposition - */ - Ap(std::string ap) - : storm::property::abstract::Ap<T>(ap) { - // Intentionally left empty - } - - /*! - * Destructor. - * At this time, empty... - */ - virtual ~Ap() { - // Intentionally left empty - } - - /*! - * Clones the called object. - * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones - * - * @returns a new AND-object that is identical the called object. - */ - virtual AbstractStateFormula<T>* clone() const override { - return new Ap(this->getAp()); - } - - /*! - * Calls the model checker to check this formula. - * Needed to infer the correct type of formula class. - * - * @note This function should only be called in a generic check function of a model checker class. For other uses, - * the methods of the model checker should be used. - * - * @returns A bit vector indicating all states that satisfy the formula represented by the called object. - */ - virtual storm::storage::BitVector check(const storm::modelchecker::prctl::AbstractModelChecker<T>& modelChecker) const override { - return modelChecker.template as<IApModelChecker>()->checkAp(*this); - } - -}; - -} //namespace abstract - -} //namespace property - -} //namespace storm - -#endif /* STORM_FORMULA_PRCTL_AP_H_ */ diff --git a/src/formula/Prctl/BoundedEventually.h b/src/formula/Prctl/BoundedEventually.h deleted file mode 100644 index 870d88e1d..000000000 --- a/src/formula/Prctl/BoundedEventually.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - * BoundedUntil.h - * - * Created on: 27.11.2012 - * Author: Christian Dehnert - */ - -#ifndef STORM_FORMULA_PRCTL_BOUNDEDEVENTUALLY_H_ -#define STORM_FORMULA_PRCTL_BOUNDEDEVENTUALLY_H_ - -#include "src/formula/abstract/BoundedEventually.h" -#include "src/formula/Prctl/AbstractPathFormula.h" -#include "src/formula/Prctl/AbstractStateFormula.h" -#include "src/formula/AbstractFormulaChecker.h" -#include <cstdint> -#include <string> -#include "src/modelchecker/prctl/ForwardDeclarations.h" - -namespace storm { -namespace property { -namespace prctl{ - -template <class T> class BoundedEventually; - -/*! - * @brief Interface class for model checkers that support BoundedEventually. - * - * All model checkers that support the formula class BoundedEventually must inherit - * this pure virtual class. - */ -template <class T> -class IBoundedEventuallyModelChecker { - public: - /*! - * @brief Evaluates BoundedEventually formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual std::vector<T> checkBoundedEventually(const BoundedEventually<T>& obj, bool qualitative) const = 0; -}; - -/*! - * @brief - * Class for an abstract (path) formula tree with a BoundedEventually node as root. - * - * Has one Abstract state formulas as sub formula/tree. - * - * @par Semantics - * The formula holds iff in at most \e bound steps, formula \e child holds. - * - * The subtrees are seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @see AbstractPathFormula - * @see AbstractPrctlFormula - */ -template <class T> -class BoundedEventually : public storm::property::abstract::BoundedEventually<T, AbstractStateFormula<T>>, - public AbstractPathFormula<T> { - -public: - /*! - * Empty constructor - */ - BoundedEventually() { - //intentionally left empty - } - - /*! - * Constructor - * - * @param child The child formula subtree - * @param bound The maximal number of steps - */ - BoundedEventually(AbstractStateFormula<T>* child, uint_fast64_t bound) : - storm::property::abstract::BoundedEventually<T, AbstractStateFormula<T>>(child, bound){ - //intentionally left empty - } - - /*! - * Destructor. - * - * Also deletes the subtrees. - * (this behaviour can be prevented by setting the subtrees to NULL before deletion) - */ - virtual ~BoundedEventually() { - //intentionally left empty - } - - /*! - * Clones the called object. - * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones - * - * @returns a new BoundedUntil-object that is identical the called object. - */ - virtual AbstractPathFormula<T>* clone() const override { - BoundedEventually<T>* result = new BoundedEventually<T>(); - result->setBound(this->getBound()); - if (this->childIsSet()) { - result->setChild(this->getChild().clone()); - } - return result; - } - - - /*! - * Calls the model checker to check this formula. - * Needed to infer the correct type of formula class. - * - * @note This function should only be called in a generic check function of a model checker class. For other uses, - * the methods of the model checker should be used. - * - * @returns A vector indicating the probability that the formula holds for each state. - */ - virtual std::vector<T> check(const storm::modelchecker::prctl::AbstractModelChecker<T>& modelChecker, bool qualitative) const override { - return modelChecker.template as<IBoundedEventuallyModelChecker>()->checkBoundedEventually(*this, qualitative); - } -}; - -} //namespace prctl -} //namespace property -} //namespace storm - -#endif /* STORM_FORMULA_PRCTL_BOUNDEDUNTIL_H_ */ diff --git a/src/formula/Prctl/BoundedNaryUntil.h b/src/formula/Prctl/BoundedNaryUntil.h deleted file mode 100644 index e01169496..000000000 --- a/src/formula/Prctl/BoundedNaryUntil.h +++ /dev/null @@ -1,141 +0,0 @@ -/* - * BoundedNaryUntil.h - * - * Created on: 19.10.2012 - * Author: Thomas Heinemann - */ - -#ifndef STORM_FORMULA_PRCTL_BOUNDEDNARYUNTIL_H_ -#define STORM_FORMULA_PRCTL_BOUNDEDNARYUNTIL_H_ - -#include "src/formula/abstract/BoundedNaryUntil.h" -#include "src/formula/Prctl/AbstractPathFormula.h" -#include "src/formula/Prctl/AbstractStateFormula.h" -#include <cstdint> -#include <string> -#include <vector> -#include <tuple> -#include <sstream> -#include "src/modelchecker/prctl/ForwardDeclarations.h" - -namespace storm { -namespace property { -namespace prctl { - - -template <class T> class BoundedNaryUntil; - -/*! - * @brief Interface class for model checkers that support BoundedNaryUntil. - * - * All model checkers that support the formula class BoundedNaryUntil must inherit - * this pure virtual class. - */ -template <class T> -class IBoundedNaryUntilModelChecker { - public: - /*! - * @brief Evaluates BoundedNaryUntil formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual std::vector<T> checkBoundedNaryUntil(const BoundedNaryUntil<T>& obj, bool qualitative) const = 0; -}; - -/*! - * @brief - * Class for an abstract (path) formula tree with a BoundedNaryUntil node as root. - * - * Has at least two Abstract state formulas as sub formulas and an interval - * associated with all but the first sub formula. We'll call the first one - * \e left and all other one \e right. - * - * @par Semantics - * The formula holds iff \e left holds until eventually any of the \e right - * formulas holds after a number of steps contained in the interval - * associated with this formula. - * - * The subtrees are seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @see AbstractPathFormula - * @see AbstractPrctlFormula - */ -template <class T> -class BoundedNaryUntil : public storm::property::abstract::BoundedNaryUntil<T, AbstractStateFormula<T>>, - public AbstractPathFormula<T> { - -public: - /*! - * Empty constructor - */ - BoundedNaryUntil() { - - } - - /*! - * Constructor - * - * @param left The left formula subtree - * @param right The left formula subtree - */ - BoundedNaryUntil(AbstractStateFormula<T>* left, std::vector<std::tuple<AbstractStateFormula<T>*,T,T>>* right) : - storm::property::abstract::BoundedNaryUntil<T, AbstractStateFormula<T>>(left, right){ - - } - - /*! - * Destructor. - * - * Also deletes the subtrees. - * (this behaviour can be prevented by setting the subtrees to NULL before deletion) - */ - virtual ~BoundedNaryUntil() { - //intentionally left empty - } - - - /*! - * Clones the called object. - * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones - * - * @returns a new BoundedNaryUntil-object that is identical the called object. - */ - virtual AbstractPathFormula<T>* clone() const override { - BoundedNaryUntil<T>* result = new BoundedNaryUntil<T>(); - if (this->leftIsSet()) { - result->setLeft(this->getLeft().clone()); - } - if (this->rightIsSet()) { - std::vector<std::tuple<AbstractStateFormula<T>*,T,T>>* newright = new std::vector<std::tuple<AbstractStateFormula<T>*,T,T>>(); - for (auto it = this->right->begin(); it != this->right->end(); ++it) { - newright->push_back(std::tuple<AbstractStateFormula<T>*,T,T>(std::get<0>(*it)->clone(), std::get<1>(*it), std::get<2>(*it))); - } - result->setRight(newright); - } - return result; - } - - - /*! - * Calls the model checker to check this formula. - * Needed to infer the correct type of formula class. - * - * @note This function should only be called in a generic check function of a model checker class. For other uses, - * the methods of the model checker should be used. - * - * @returns A vector indicating the probability that the formula holds for each state. - */ - virtual std::vector<T> check(const storm::modelchecker::prctl::AbstractModelChecker<T>& modelChecker, bool qualitative) const override { - return modelChecker.template as<IBoundedNaryUntilModelChecker>()->checkBoundedNaryUntil(*this, qualitative); - } - -}; - -} //namespace prctl -} //namespace property -} //namespace storm - -#endif /* STORM_FORMULA_PRCTL_BOUNDEDNARYUNTIL_H_ */ diff --git a/src/formula/Prctl/BoundedUntil.h b/src/formula/Prctl/BoundedUntil.h deleted file mode 100644 index f17c9b743..000000000 --- a/src/formula/Prctl/BoundedUntil.h +++ /dev/null @@ -1,131 +0,0 @@ -/* - * BoundedUntil.h - * - * Created on: 19.10.2012 - * Author: Thomas Heinemann - */ - -#ifndef STORM_FORMULA_PRCTL_BOUNDEDUNTIL_H_ -#define STORM_FORMULA_PRCTL_BOUNDEDUNTIL_H_ - -#include "src/formula/abstract/BoundedUntil.h" -#include "src/formula/Prctl/AbstractPathFormula.h" -#include "src/formula/Prctl/AbstractStateFormula.h" -#include <cstdint> -#include <string> -#include "src/modelchecker/prctl/ForwardDeclarations.h" - -namespace storm { -namespace property { -namespace prctl { - -template <class T> class BoundedUntil; - -/*! - * @brief Interface class for model checkers that support BoundedUntil. - * - * All model checkers that support the formula class BoundedUntil must inherit - * this pure virtual class. - */ -template <class T> -class IBoundedUntilModelChecker { - public: - /*! - * @brief Evaluates BoundedUntil formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual std::vector<T> checkBoundedUntil(const BoundedUntil<T>& obj, bool qualitative) const = 0; -}; - -/*! - * @brief - * Class for an abstract (path) formula tree with a BoundedUntil node as root. - * - * Has two Abstract state formulas as sub formulas/trees. - * - * @par Semantics - * The formula holds iff in at most \e bound steps, formula \e right (the right subtree) holds, and before, - * \e left holds. - * - * The subtrees are seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @see AbstractPathFormula - * @see AbstractPrctlFormula - */ -template <class T> -class BoundedUntil : public storm::property::abstract::BoundedUntil<T, AbstractStateFormula<T>>, - public AbstractPathFormula<T> { - -public: - /*! - * Empty constructor - */ - BoundedUntil() { - //Intentionally left empty - } - - /*! - * Constructor - * - * @param left The left formula subtree - * @param right The left formula subtree - * @param bound The maximal number of steps - */ - BoundedUntil(AbstractStateFormula<T>* left, AbstractStateFormula<T>* right, - uint_fast64_t bound) : - storm::property::abstract::BoundedUntil<T, AbstractStateFormula<T>>(left,right,bound) { - //intentionally left empty - } - - /*! - * Destructor. - * - * Also deletes the subtrees. - * (this behaviour can be prevented by setting the subtrees to NULL before deletion) - */ - virtual ~BoundedUntil() { - //intentionally left empty - } - - /*! - * Clones the called object. - * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones - * - * @returns a new BoundedUntil-object that is identical the called object. - */ - virtual AbstractPathFormula<T>* clone() const override { - BoundedUntil<T>* result = new BoundedUntil<T>(); - result->setBound(this->getBound()); - if (this->leftIsSet()) { - result->setLeft(this->getLeft().clone()); - } - if (this->rightIsSet()) { - result->setRight(this->getRight().clone()); - } - return result; - } - - - /*! - * Calls the model checker to check this formula. - * Needed to infer the correct type of formula class. - * - * @note This function should only be called in a generic check function of a model checker class. For other uses, - * the methods of the model checker should be used. - * - * @returns A vector indicating the probability that the formula holds for each state. - */ - virtual std::vector<T> check(const storm::modelchecker::prctl::AbstractModelChecker<T>& modelChecker, bool qualitative) const override { - return modelChecker.template as<IBoundedUntilModelChecker>()->checkBoundedUntil(*this, qualitative); - } -}; - -} //namespace prctl -} //namespace property -} //namespace storm - -#endif /* STORM_FORMULA_PRCTL_BOUNDEDUNTIL_H_ */ diff --git a/src/formula/Prctl/CumulativeReward.h b/src/formula/Prctl/CumulativeReward.h deleted file mode 100644 index e1db7cb21..000000000 --- a/src/formula/Prctl/CumulativeReward.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - * InstantaneousReward.h - * - * Created on: 26.12.2012 - * Author: Christian Dehnert - */ - -#ifndef STORM_FORMULA_PRCTL_CUMULATIVEREWARD_H_ -#define STORM_FORMULA_PRCTL_CUMULATIVEREWARD_H_ - -#include "AbstractPathFormula.h" -#include "AbstractStateFormula.h" -#include "src/formula/abstract/CumulativeReward.h" -#include "src/formula/AbstractFormulaChecker.h" -#include <string> - -namespace storm { -namespace property { -namespace prctl { - -template <class T> class CumulativeReward; - -/*! - * @brief Interface class for model checkers that support CumulativeReward. - * - * All model checkers that support the formula class CumulativeReward must inherit - * this pure virtual class. - */ -template <class T> -class ICumulativeRewardModelChecker { - public: - /*! - * @brief Evaluates CumulativeReward formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual std::vector<T> checkCumulativeReward(const CumulativeReward<T>& obj, bool qualitative) const = 0; -}; - -/*! - * @brief - * Class for an abstract (path) formula tree with a Cumulative Reward node as root. - * - * The subtrees are seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @see AbstractPathFormula - * @see AbstractPrctlFormula - */ -template <class T> -class CumulativeReward : public storm::property::abstract::CumulativeReward<T>, - public AbstractPathFormula<T> { - -public: - /*! - * Empty constructor - */ - CumulativeReward() { - // Intentionally left empty - } - - /*! - * Constructor - * - * @param bound The time bound of the reward formula - */ - CumulativeReward(T bound) : - storm::property::abstract::CumulativeReward<T>(bound) { - // Intentionally left empty - } - - /*! - * Empty destructor. - */ - virtual ~CumulativeReward() { - // Intentionally left empty. - } - - /*! - * Clones the called object. - * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones - * - * @returns a new CumulativeReward-object that is identical the called object. - */ - virtual AbstractPathFormula<T>* clone() const override { - return new CumulativeReward(this->getBound()); - } - - - /*! - * Calls the model checker to check this formula. - * Needed to infer the correct type of formula class. - * - * @note This function should only be called in a generic check function of a model checker class. For other uses, - * the methods of the model checker should be used. - * - * @returns A vector indicating the probability that the formula holds for each state. - */ - virtual std::vector<T> check(const storm::modelchecker::prctl::AbstractModelChecker<T>& modelChecker, bool qualitative) const override { - return modelChecker.template as<ICumulativeRewardModelChecker>()->checkCumulativeReward(*this, qualitative); - } -}; - -} //namespace prctl -} //namespace property -} //namespace storm - -#endif /* STORM_FORMULA_PRCTL_INSTANTANEOUSREWARD_H_ */ diff --git a/src/formula/Prctl/Eventually.h b/src/formula/Prctl/Eventually.h deleted file mode 100644 index 4a0624df6..000000000 --- a/src/formula/Prctl/Eventually.h +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Next.h - * - * Created on: 26.12.2012 - * Author: Christian Dehnert - */ - -#ifndef STORM_FORMULA_PRCTL_EVENTUALLY_H_ -#define STORM_FORMULA_PRCTL_EVENTUALLY_H_ - -#include "src/formula/abstract/Eventually.h" -#include "src/formula/Prctl/AbstractPathFormula.h" -#include "src/formula/Prctl/AbstractStateFormula.h" -#include "src/modelchecker/prctl/ForwardDeclarations.h" - -namespace storm { -namespace property { -namespace prctl { - -template <class T> class Eventually; - -/*! - * @brief Interface class for model checkers that support Eventually. - * - * All model checkers that support the formula class Eventually must inherit - * this pure virtual class. - */ -template <class T> -class IEventuallyModelChecker { - public: - /*! - * @brief Evaluates Eventually formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual std::vector<T> checkEventually(const Eventually<T>& obj, bool qualitative) const = 0; -}; - -/*! - * @brief - * Class for an abstract (path) formula tree with an Eventually node as root. - * - * Has one Abstract state formula as sub formula/tree. - * - * @par Semantics - * The formula holds iff eventually \e child holds. - * - * The subtree is seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to nullptr before deletion) - * - * @see AbstractPathFormula - * @see AbstractPrctlFormula - */ -template <class T> -class Eventually : public storm::property::abstract::Eventually<T, AbstractStateFormula<T>>, - public AbstractPathFormula<T> { - -public: - /*! - * Empty constructor - */ - Eventually() { - // Intentionally left empty - } - - /*! - * Constructor - * - * @param child The child node - */ - Eventually(AbstractStateFormula<T>* child) - : storm::property::abstract::Eventually<T, AbstractStateFormula<T>>(child) { - - } - - /*! - * Constructor. - * - * Also deletes the subtree. - * (this behaviour can be prevented by setting the subtrees to nullptr before deletion) - */ - virtual ~Eventually() { - //intentionally left empty - } - - /*! - * Clones the called object. - * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones - * - * @returns a new Eventually-object that is identical the called object. - */ - virtual AbstractPathFormula<T>* clone() const override { - Eventually<T>* result = new Eventually<T>(); - if (this->childIsSet()) { - result->setChild(this->getChild().clone()); - } - return result; - } - - /*! - * Calls the model checker to check this formula. - * Needed to infer the correct type of formula class. - * - * @note This function should only be called in a generic check function of a model checker class. For other uses, - * the methods of the model checker should be used. - * - * @returns A vector indicating the probability that the formula holds for each state. - */ - virtual std::vector<T> check(const storm::modelchecker::prctl::AbstractModelChecker<T>& modelChecker, bool qualitative) const override { - return modelChecker.template as<IEventuallyModelChecker>()->checkEventually(*this, qualitative); - } -}; - -} //namespace prctl -} //namespace property -} //namespace storm - -#endif /* STORM_FORMULA_PRCTL_EVENTUALLY_H_ */ diff --git a/src/formula/Prctl/Globally.h b/src/formula/Prctl/Globally.h deleted file mode 100644 index 272bbab26..000000000 --- a/src/formula/Prctl/Globally.h +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Next.h - * - * Created on: 26.12.2012 - * Author: Christian Dehnert - */ - -#ifndef STORM_FORMULA_PRCTL_GLOBALLY_H_ -#define STORM_FORMULA_PRCTL_GLOBALLY_H_ - -#include "src/formula/abstract/Globally.h" -#include "AbstractPathFormula.h" -#include "AbstractStateFormula.h" -#include "src/formula/AbstractFormulaChecker.h" -#include "src/modelchecker/prctl/ForwardDeclarations.h" - -namespace storm { -namespace property { -namespace prctl { - -template <class T> class Globally; - -/*! - * @brief Interface class for model checkers that support Globally. - * - * All model checkers that support the formula class Globally must inherit - * this pure virtual class. - */ -template <class T> -class IGloballyModelChecker { - public: - /*! - * @brief Evaluates Globally formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual std::vector<T> checkGlobally(const Globally<T>& obj, bool qualitative) const = 0; -}; - -/*! - * @brief - * Class for an abstract (path) formula tree with a Globally node as root. - * - * Has one Abstract state formula as sub formula/tree. - * - * @par Semantics - * The formula holds iff globally \e child holds. - * - * The subtree is seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to nullptr before deletion) - * - * @see AbstractPathFormula - * @see AbstractPrctlFormula - */ -template <class T> -class Globally : public storm::property::abstract::Globally<T, AbstractStateFormula<T>>, - public AbstractPathFormula<T> { - -public: - /*! - * Empty constructor - */ - Globally() { - //intentionally left empty - } - - /*! - * Constructor - * - * @param child The child node - */ - Globally(AbstractStateFormula<T>* child) - : storm::property::abstract::Globally<T, AbstractStateFormula<T>>(child) { - //intentionally left empty - } - - /*! - * Constructor. - * - * Also deletes the subtree. - * (this behaviour can be prevented by setting the subtrees to nullptr before deletion) - */ - virtual ~Globally() { - //intentionally left empty - } - - - /*! - * Clones the called object. - * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones - * - * @returns a new Globally-object that is identical the called object. - */ - virtual AbstractPathFormula<T>* clone() const override { - Globally<T>* result = new Globally<T>(); - if (this->childIsSet()) { - result->setChild(this->getChild().clone()); - } - return result; - } - - /*! - * Calls the model checker to check this formula. - * Needed to infer the correct type of formula class. - * - * @note This function should only be called in a generic check function of a model checker class. For other uses, - * the methods of the model checker should be used. - * - * @returns A vector indicating the probability that the formula holds for each state. - */ - virtual std::vector<T> check(const storm::modelchecker::prctl::AbstractModelChecker<T>& modelChecker, bool qualitative) const override { - return modelChecker.template as<IGloballyModelChecker>()->checkGlobally(*this, qualitative); - } -}; - -} //namespace prctl -} //namespace property -} //namespace storm - -#endif /* STORM_FORMULA_PRCTL_GLOBALLY_H_ */ diff --git a/src/formula/Prctl/InstantaneousReward.h b/src/formula/Prctl/InstantaneousReward.h deleted file mode 100644 index b28effffe..000000000 --- a/src/formula/Prctl/InstantaneousReward.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * InstantaneousReward.h - * - * Created on: 26.12.2012 - * Author: Christian Dehnert - */ - -#ifndef STORM_FORMULA_PRCTL_INSTANTANEOUSREWARD_H_ -#define STORM_FORMULA_PRCTL_INSTANTANEOUSREWARD_H_ - -#include "AbstractPathFormula.h" -#include "AbstractStateFormula.h" -#include "src/formula/abstract/InstantaneousReward.h" -#include "src/formula/AbstractFormulaChecker.h" -#include <cstdint> -#include <string> - -namespace storm { -namespace property { -namespace prctl { - -template <class T> class InstantaneousReward; - -/*! - * @brief Interface class for model checkers that support InstantaneousReward. - * - * All model checkers that support the formula class InstantaneousReward must inherit - * this pure virtual class. - */ -template <class T> -class IInstantaneousRewardModelChecker { - public: - /*! - * @brief Evaluates InstantaneousReward formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual std::vector<T> checkInstantaneousReward(const InstantaneousReward<T>& obj, bool qualitative) const = 0; -}; - -/*! - * @brief - * Class for an abstract (path) formula tree with a Instantaneous Reward node as root. - * - * The subtrees are seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @see AbstractPathFormula - * @see AbstractPrctlFormula - */ -template <class T> -class InstantaneousReward : public storm::property::abstract::InstantaneousReward<T>, - public AbstractPathFormula<T> { - -public: - /*! - * Empty constructor - */ - InstantaneousReward() { - //intentionally left empty - } - - /*! - * Constructor - * - * @param bound The time instance of the reward formula - */ - InstantaneousReward(uint_fast64_t bound) : - storm::property::abstract::InstantaneousReward<T>(bound) { - //intentionally left empty - } - - /*! - * Empty destructor. - */ - virtual ~InstantaneousReward() { - // Intentionally left empty. - } - - /*! - * Clones the called object. - * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones - * - * @returns a new InstantaneousReward-object that is identical the called object. - */ - virtual AbstractPathFormula<T>* clone() const override { - return new InstantaneousReward(this->getBound()); - } - - - /*! - * Calls the model checker to check this formula. - * Needed to infer the correct type of formula class. - * - * @note This function should only be called in a generic check function of a model checker class. For other uses, - * the methods of the model checker should be used. - * - * @returns A vector indicating the probability that the formula holds for each state. - */ - virtual std::vector<T> check(const storm::modelchecker::prctl::AbstractModelChecker<T>& modelChecker, bool qualitative) const override { - return modelChecker.template as<IInstantaneousRewardModelChecker>()->checkInstantaneousReward(*this, qualitative); - } -}; - -} //namespace prctl -} //namespace property -} //namespace storm - -#endif /* STORM_FORMULA_PRCTL_INSTANTANEOUSREWARD_H_ */ diff --git a/src/formula/Prctl/Next.h b/src/formula/Prctl/Next.h deleted file mode 100644 index 7197da30c..000000000 --- a/src/formula/Prctl/Next.h +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Next.h - * - * Created on: 19.10.2012 - * Author: Thomas Heinemann - */ - -#ifndef STORM_FORMULA_PRCTL_NEXT_H_ -#define STORM_FORMULA_PRCTL_NEXT_H_ - -#include "AbstractPathFormula.h" -#include "AbstractStateFormula.h" -#include "src/formula/abstract/Next.h" -#include "src/formula/AbstractFormulaChecker.h" - -namespace storm { -namespace property { -namespace prctl { - -template <class T> class Next; - -/*! - * @brief Interface class for model checkers that support Next. - * - * All model checkers that support the formula class Next must inherit - * this pure virtual class. - */ -template <class T> -class INextModelChecker { - public: - /*! - * @brief Evaluates Next formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual std::vector<T> checkNext(const Next<T>& obj, bool qualitative) const = 0; -}; - -/*! - * @brief - * Class for an abstract (path) formula tree with a Next node as root. - * - * Has two Abstract state formulas as sub formulas/trees. - * - * @par Semantics - * The formula holds iff in the next step, \e child holds - * - * The subtree is seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @see AbstractPathFormula - * @see AbstractPrctlFormula - */ -template <class T> -class Next : public storm::property::abstract::Next<T, AbstractStateFormula<T>>, - public AbstractPathFormula<T> { - -public: - /*! - * Empty constructor - */ - Next() { - //intentionally left empty - } - - /*! - * Constructor - * - * @param child The child node - */ - Next(AbstractStateFormula<T>* child) - : storm::property::abstract::Next<T, AbstractStateFormula<T>>(child) { - //intentionally left empty - } - - /*! - * Constructor. - * - * Also deletes the subtree. - * (this behaviour can be prevented by setting the subtrees to NULL before deletion) - */ - virtual ~Next() { - //intentionally left empty - } - - /*! - * Clones the called object. - * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones - * - * @returns a new BoundedUntil-object that is identical the called object. - */ - virtual AbstractPathFormula<T>* clone() const override { - Next<T>* result = new Next<T>(); - if (this->childIsSet()) { - result->setChild(this->getChild().clone()); - } - return result; - } - - /*! - * Calls the model checker to check this formula. - * Needed to infer the correct type of formula class. - * - * @note This function should only be called in a generic check function of a model checker class. For other uses, - * the methods of the model checker should be used. - * - * @returns A vector indicating the probability that the formula holds for each state. - */ - virtual std::vector<T> check(const storm::modelchecker::prctl::AbstractModelChecker<T>& modelChecker, bool qualitative) const override { - return modelChecker.template as<INextModelChecker>()->checkNext(*this, qualitative); - } -}; - -} //namespace prctl -} //namespace property -} //namespace storm - -#endif /* STORM_FORMULA_PRCTL_NEXT_H_ */ diff --git a/src/formula/Prctl/Not.h b/src/formula/Prctl/Not.h deleted file mode 100644 index 7f6a992ab..000000000 --- a/src/formula/Prctl/Not.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Not.h - * - * Created on: 19.10.2012 - * Author: Thomas Heinemann - */ - -#ifndef STORM_FORMULA_PRCTL_NOT_H_ -#define STORM_FORMULA_PRCTL_NOT_H_ - -#include "AbstractStateFormula.h" -#include "src/formula/abstract/Not.h" -#include "src/formula/AbstractFormulaChecker.h" -#include "src/modelchecker/prctl/ForwardDeclarations.h" - -namespace storm { -namespace property { -namespace prctl { - -template <class T> class Not; - -/*! - * @brief Interface class for model checkers that support Not. - * - * All model checkers that support the formula class Not must inherit - * this pure virtual class. - */ -template <class T> -class INotModelChecker { - public: - /*! - * @brief Evaluates Not formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual storm::storage::BitVector checkNot(const Not<T>& obj) const = 0; -}; - -/*! - * @brief - * Class for an abstract formula tree with NOT node as root. - * - * Has one Abstract state formula as sub formula/tree. - * - * The subtree is seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @see AbstractStateFormula - * @see AbstractPrctlFormula - */ -template <class T> -class Not : public storm::property::abstract::Not<T, AbstractStateFormula<T>>, - public AbstractStateFormula<T> { - -public: - /*! - * Empty constructor - */ - Not() { - //intentionally left empty - } - - /*! - * Constructor - * @param child The child node - */ - Not(AbstractStateFormula<T>* child) : - storm::property::abstract::Not<T, AbstractStateFormula<T>>(child){ - //intentionally left empty - } - - /*! - * Destructor - * - * Also deletes the subtree - * (this behavior can be prevented by setting them to NULL before deletion) - */ - virtual ~Not() { - //intentionally left empty - } - - /*! - * Clones the called object. - * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones - * - * @returns a new AND-object that is identical the called object. - */ - virtual AbstractStateFormula<T>* clone() const override { - Not<T>* result = new Not<T>(); - if (this->childIsSet()) { - result->setChild(this->getChild().clone()); - } - return result; - } - - /*! - * Calls the model checker to check this formula. - * Needed to infer the correct type of formula class. - * - * @note This function should only be called in a generic check function of a model checker class. For other uses, - * the methods of the model checker should be used. - * - * @returns A bit vector indicating all states that satisfy the formula represented by the called object. - */ - virtual storm::storage::BitVector check(const storm::modelchecker::prctl::AbstractModelChecker<T>& modelChecker) const override { - return modelChecker.template as<INotModelChecker>()->checkNot(*this); - } -}; - -} //namespace prctl -} //namespace property -} //namespace storm - -#endif /* STORM_FORMULA_PRCTL_NOT_H_ */ diff --git a/src/formula/Prctl/Or.h b/src/formula/Prctl/Or.h deleted file mode 100644 index a13c385e3..000000000 --- a/src/formula/Prctl/Or.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Or.h - * - * Created on: 19.10.2012 - * Author: Thomas Heinemann - */ - -#ifndef STORM_FORMULA_PRCTL_OR_H_ -#define STORM_FORMULA_PRCTL_OR_H_ - -#include "AbstractStateFormula.h" -#include "src/formula/abstract/Or.h" -#include "src/formula/AbstractFormulaChecker.h" - -namespace storm { -namespace property { -namespace prctl { - -template <class T> class Or; - -/*! - * @brief Interface class for model checkers that support Or. - * - * All model checkers that support the formula class Or must inherit - * this pure virtual class. - */ -template <class T> -class IOrModelChecker { - public: - /*! - * @brief Evaluates Or formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual storm::storage::BitVector checkOr(const Or<T>& obj) const = 0; -}; - -/*! - * @brief - * Class for an abstract formula tree with OR node as root. - * - * Has two Abstract state formulas as sub formulas/trees. - * - * As OR is commutative, the order is \e theoretically not important, but will influence the order in which - * the model checker works. - * - * The subtrees are seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @see AbstractStateFormula - * @see AbstractPrctlFormula - */ -template <class T> -class Or : public storm::property::abstract::Or<T, AbstractStateFormula<T>>, - public AbstractStateFormula<T> { - -public: - /*! - * Empty constructor. - * Will create an OR-node without subnotes. The result does not represent a complete formula! - */ - Or() { - //intentionally left empty - } - - /*! - * Constructor. - * Creates an OR note with the parameters as subtrees. - * - * @param left The left sub formula - * @param right The right sub formula - */ - Or(AbstractStateFormula<T>* left, AbstractStateFormula<T>* right) : - storm::property::abstract::Or<T, AbstractStateFormula<T>>(left, right) { - //intentionally left empty - } - - /*! - * Destructor. - * - * The subtrees are deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - */ - virtual ~Or() { - //intentionally left empty - } - - /*! - * Clones the called object. - * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones - * - * @returns a new AND-object that is identical the called object. - */ - virtual AbstractStateFormula<T>* clone() const override { - Or<T>* result = new Or(); - if (this->leftIsSet()) { - result->setLeft(this->getLeft().clone()); - } - if (this->rightIsSet()) { - result->setRight(this->getRight().clone()); - } - return result; - } - - /*! - * Calls the model checker to check this formula. - * Needed to infer the correct type of formula class. - * - * @note This function should only be called in a generic check function of a model checker class. For other uses, - * the methods of the model checker should be used. - * - * @returns A bit vector indicating all states that satisfy the formula represented by the called object. - */ - virtual storm::storage::BitVector check(const storm::modelchecker::prctl::AbstractModelChecker<T>& modelChecker) const override { - return modelChecker.template as<IOrModelChecker>()->checkOr(*this); - } -}; - -} //namespace prctl -} //namespace property -} //namespace storm - -#endif /* STORM_FORMULA_PRCTL_OR_H_ */ diff --git a/src/formula/Prctl/ProbabilisticBoundOperator.h b/src/formula/Prctl/ProbabilisticBoundOperator.h deleted file mode 100644 index a2ea229aa..000000000 --- a/src/formula/Prctl/ProbabilisticBoundOperator.h +++ /dev/null @@ -1,139 +0,0 @@ -/* - * ProbabilisticBoundOperator.h - * - * Created on: 19.10.2012 - * Author: Thomas Heinemann - */ - -#ifndef STORM_FORMULA_PRCTL_PROBABILISTICBOUNDOPERATOR_H_ -#define STORM_FORMULA_PRCTL_PROBABILISTICBOUNDOPERATOR_H_ - -#include "AbstractStateFormula.h" -#include "AbstractPathFormula.h" -#include "src/formula/abstract/ProbabilisticBoundOperator.h" -#include "utility/constants.h" - -namespace storm { -namespace property { -namespace prctl { - -template <class T> class ProbabilisticBoundOperator; - -/*! - * @brief Interface class for model checkers that support ProbabilisticBoundOperator. - * - * All model checkers that support the formula class PathBoundOperator must inherit - * this pure virtual class. - */ -template <class T> -class IProbabilisticBoundOperatorModelChecker { - public: - virtual storm::storage::BitVector checkProbabilisticBoundOperator(const ProbabilisticBoundOperator<T>& obj) const = 0; -}; - -/*! - * @brief - * Class for an abstract formula tree with a P (probablistic) operator node over a probability interval - * as root. - * - * Has one Abstract path formula as sub formula/tree. - * - * @par Semantics - * The formula holds iff the probability that the path formula holds is inside the bounds - * specified in this operator - * - * The subtree is seen as part of the object and deleted with it - * (this behavior can be prevented by setting them to NULL before deletion) - * - * - * @see AbstractStateFormula - * @see AbstractPathFormula - * @see ProbabilisticOperator - * @see ProbabilisticNoBoundsOperator - * @see AbstractPrctlFormula - */ -template<class T> -class ProbabilisticBoundOperator : public storm::property::abstract::ProbabilisticBoundOperator<T, AbstractPathFormula<T>>, - public AbstractStateFormula<T> { - -public: - /*! - * Empty constructor - */ - ProbabilisticBoundOperator() { - // Intentionally left empty - } - - - /*! - * Constructor - * - * @param comparisonRelation The relation to compare the actual value and the bound - * @param bound The bound for the probability - * @param pathFormula The child node - */ - ProbabilisticBoundOperator( - storm::property::ComparisonType comparisonRelation, - T bound, - AbstractPathFormula<T>* pathFormula) - : storm::property::abstract::ProbabilisticBoundOperator<T, AbstractPathFormula<T>>(comparisonRelation, bound, pathFormula) { - // Intentionally left empty - } - - /*! - * - * @param comparisonRelation - * @param bound - * @param pathFormula - * @param minimumOperator - */ - ProbabilisticBoundOperator( - storm::property::ComparisonType comparisonRelation, - T bound, - AbstractPathFormula<T>* pathFormula, - bool minimumOperator) - : storm::property::abstract::ProbabilisticBoundOperator<T, AbstractPathFormula<T>>(comparisonRelation, bound, pathFormula, minimumOperator){ - // Intentionally left empty - } - - /*! - * - */ - virtual ~ProbabilisticBoundOperator() { - // Intentionally left empty - } - - /*! - * Clones the called object. - * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones - * - * @returns a new AND-object that is identical the called object. - */ - virtual AbstractStateFormula<T>* clone() const override { - ProbabilisticBoundOperator<T>* result = new ProbabilisticBoundOperator<T>(); - result->setComparisonOperator(this->getComparisonOperator()); - result->setBound(this->getBound()); - result->setPathFormula(this->getPathFormula().clone()); - return result; - } - - /*! - * Calls the model checker to check this formula. - * Needed to infer the correct type of formula class. - * - * @note This function should only be called in a generic check function of a model checker class. For other uses, - * the methods of the model checker should be used. - * - * @returns A bit vector indicating all states that satisfy the formula represented by the called object. - */ - virtual storm::storage::BitVector check(const storm::modelchecker::prctl::AbstractModelChecker<T>& modelChecker) const override { - return modelChecker.template as<IProbabilisticBoundOperatorModelChecker>()->checkProbabilisticBoundOperator(*this); - } -}; - -} //namespace prctl -} //namespace property -} //namespace storm - -#endif /* STORM_FORMULA_PRCTL_PROBABILISTICBOUNDOPERATOR_H_ */ diff --git a/src/formula/Prctl/ProbabilisticNoBoundOperator.h b/src/formula/Prctl/ProbabilisticNoBoundOperator.h deleted file mode 100644 index 5591a9555..000000000 --- a/src/formula/Prctl/ProbabilisticNoBoundOperator.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * ProbabilisticNoBoundOperator.h - * - * Created on: 12.12.2012 - * Author: thomas - */ - -#ifndef STORM_FORMULA_PRCTL_PROBABILISTICNOBOUNDOPERATOR_H_ -#define STORM_FORMULA_PRCTL_PROBABILISTICNOBOUNDOPERATOR_H_ - -#include "AbstractPathFormula.h" -#include "AbstractNoBoundOperator.h" -#include "src/formula/abstract/ProbabilisticNoBoundOperator.h" - -namespace storm { -namespace property { -namespace prctl { - -/*! - * @brief - * Class for an abstract formula tree with a P (probablistic) operator without declaration of probabilities - * as root. - * - * Checking a formula with this operator as root returns the probabilities that the path formula holds - * (for each state) - * - * Has one Abstract path formula as sub formula/tree. - * - * @note - * This class is a hybrid of a state and path formula, and may only appear as the outermost operator. - * Hence, it is seen as neither a state nor a path formula, but is directly derived from AbstractFormula. - * - * @note - * This class does not contain a check() method like the other formula classes. - * The check method should only be called by the model checker to infer the correct check function for sub - * formulas. As this operator can only appear at the root, the method is not useful here. - * Use the checkProbabilisticNoBoundOperator method from the DtmcPrctlModelChecker class instead. - * - * The subtree is seen as part of the object and deleted with it - * (this behavior can be prevented by setting them to NULL before deletion) - * - * - * @see AbstractStateFormula - * @see AbstractPathFormula - * @see ProbabilisticOperator - * @see ProbabilisticIntervalOperator - * @see AbstractPrctlFormula - */ -template <class T> -class ProbabilisticNoBoundOperator: public storm::property::abstract::ProbabilisticNoBoundOperator<T, AbstractPathFormula<T>>, - public AbstractNoBoundOperator<T> { -public: - /*! - * Empty constructor - */ - ProbabilisticNoBoundOperator() { - // Intentionally left empty - } - - /*! - * Constructor - * - * @param pathFormula The child node. - */ - ProbabilisticNoBoundOperator(AbstractPathFormula<T>* pathFormula) - : storm::property::abstract::ProbabilisticNoBoundOperator<T, AbstractPathFormula<T>>(pathFormula) { - // Intentionally left empty - } - - /*! - * Constructor - * - * @param pathFormula The child node. - */ - ProbabilisticNoBoundOperator(AbstractPathFormula<T>* pathFormula, bool minimumOperator) - : storm::property::abstract::ProbabilisticNoBoundOperator<T, AbstractPathFormula<T>>(pathFormula, minimumOperator) { - // Intentionally left empty - } - - /*! - * Destructor - */ - virtual ~ProbabilisticNoBoundOperator() { - // Intentionally left empty - } - - virtual AbstractNoBoundOperator<T>* clone() const override { - ProbabilisticNoBoundOperator<T>* result = new ProbabilisticNoBoundOperator<T>(); - if (this->pathFormulaIsSet()) { - result->setPathFormula(this->getPathFormula().clone()); - } - return result; - } - - /*! - * Calls the model checker to check this formula. - * Needed to infer the correct type of formula class. - * - * @note This function should only be called in a generic check function of a model checker class. For other uses, - * the methods of the model checker should be used. - * - * @note This function is not implemented in this class. - * - * @returns A vector indicating the probability that the formula holds for each state. - */ - virtual std::vector<T> check(const storm::modelchecker::prctl::AbstractModelChecker<T>& modelChecker, bool qualitative=false) const override { - return this->getPathFormula().check(modelChecker, qualitative); - } -}; - -} //namespace prctl -} //namespace property -} //namespace storm - -#endif /* STORM_FORMULA_PRCTL_PROBABILISTICNOBOUNDOPERATOR_H_ */ diff --git a/src/formula/Prctl/ReachabilityReward.h b/src/formula/Prctl/ReachabilityReward.h deleted file mode 100644 index d0bcdfc69..000000000 --- a/src/formula/Prctl/ReachabilityReward.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Next.h - * - * Created on: 26.12.2012 - * Author: Christian Dehnert - */ - -#ifndef STORM_FORMULA_PRCTL_REACHABILITYREWARD_H_ -#define STORM_FORMULA_PRCTL_REACHABILITYREWARD_H_ - -#include "AbstractPathFormula.h" -#include "AbstractStateFormula.h" -#include "../abstract/Eventually.h" -#include "src/formula/AbstractFormulaChecker.h" - -namespace storm { -namespace property { -namespace prctl { - -template <class T> class ReachabilityReward; - -/*! - * @brief Interface class for model checkers that support ReachabilityReward. - * - * All model checkers that support the formula class ReachabilityReward must inherit - * this pure virtual class. - */ -template <class T> -class IReachabilityRewardModelChecker { - public: - /*! - * @brief Evaluates ReachabilityReward formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual std::vector<T> checkReachabilityReward(const ReachabilityReward<T>& obj, bool qualitative) const = 0; -}; - -/*! - * @brief - * Class for an abstract (path) formula tree with an Reachability Reward node as root. - * - * Has one Abstract state formula as sub formula/tree. - * - * The subtree is seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to nullptr before deletion) - * - * @see AbstractPathFormula - * @see AbstractPrctlFormula - */ -template <class T> -class ReachabilityReward : public storm::property::abstract::Eventually<T, AbstractStateFormula<T>>, - public AbstractPathFormula<T> { - -public: - /*! - * Empty constructor - */ - ReachabilityReward() { - // Intentionally left empty - } - - /*! - * Constructor - * - * @param child The child node - */ - ReachabilityReward(AbstractStateFormula<T>* child) : - storm::property::abstract::Eventually<T, AbstractStateFormula<T>>(child){ - // Intentionally left empty - } - - /*! - * Constructor. - * - * Also deletes the subtree. - * (this behaviour can be prevented by setting the subtrees to nullptr before deletion) - */ - virtual ~ReachabilityReward() { - // Intentionally left empty - } - - /*! - * Clones the called object. - * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones - * - * @returns a new ReachabilityReward-object that is identical the called object. - */ - virtual AbstractPathFormula<T>* clone() const override { - ReachabilityReward<T>* result = new ReachabilityReward<T>(); - if (this->childIsSet()) { - result->setChild(this->getChild().clone()); - } - return result; - } - - /*! - * Calls the model checker to check this formula. - * Needed to infer the correct type of formula class. - * - * @note This function should only be called in a generic check function of a model checker class. For other uses, - * the methods of the model checker should be used. - * - * @returns A vector indicating the probability that the formula holds for each state. - */ - virtual std::vector<T> check(const storm::modelchecker::prctl::AbstractModelChecker<T>& modelChecker, bool qualitative) const override { - return modelChecker.template as<IReachabilityRewardModelChecker>()->checkReachabilityReward(*this, qualitative); - } -}; - -} //namespace prctl -} //namespace property -} //namespace storm - -#endif /* STORM_FORMULA_PRCTL_REACHABILITYREWARD_H_ */ diff --git a/src/formula/Prctl/RewardBoundOperator.h b/src/formula/Prctl/RewardBoundOperator.h deleted file mode 100644 index 4c5cf19d3..000000000 --- a/src/formula/Prctl/RewardBoundOperator.h +++ /dev/null @@ -1,132 +0,0 @@ -/* - * RewardBoundOperator.h - * - * Created on: 19.10.2012 - * Author: Thomas Heinemann - */ - -#ifndef STORM_FORMULA_PRCTL_REWARDBOUNDOPERATOR_H_ -#define STORM_FORMULA_PRCTL_REWARDBOUNDOPERATOR_H_ - -#include "AbstractPathFormula.h" -#include "AbstractStateFormula.h" -#include "src/formula/abstract/RewardBoundOperator.h" -#include "utility/constants.h" - -namespace storm { -namespace property { -namespace prctl { - -template <class T> class RewardBoundOperator; - -/*! - * @brief Interface class for model checkers that support RewardBoundOperator. - * - * All model checkers that support the formula class PathBoundOperator must inherit - * this pure virtual class. - */ -template <class T> -class IRewardBoundOperatorModelChecker { - public: - virtual storm::storage::BitVector checkRewardBoundOperator(const RewardBoundOperator<T>& obj) const = 0; -}; - -/*! - * @brief - * Class for an abstract formula tree with a R (reward) operator node over a reward interval as root. - * - * Has a reward path formula as sub formula/tree. - * - * @par Semantics - * The formula holds iff the reward of the reward path formula is inside the bounds - * specified in this operator - * - * The subtree is seen as part of the object and deleted with it - * (this behavior can be prevented by setting them to NULL before deletion) - * - * - * @see AbstractStateFormula - * @see AbstractPathFormula - * @see ProbabilisticOperator - * @see ProbabilisticNoBoundsOperator - * @see AbstractPrctlFormula - */ -template<class T> -class RewardBoundOperator : public storm::property::abstract::RewardBoundOperator<T, AbstractPathFormula<T>>, - public AbstractStateFormula<T> { - -public: - /*! - * Empty constructor - */ - RewardBoundOperator() { - // Intentionally left empty - } - - /*! - * Constructor - * - * @param comparisonRelation The relation to compare the actual value and the bound - * @param bound The bound for the probability - * @param pathFormula The child node - */ - RewardBoundOperator( - storm::property::ComparisonType comparisonRelation, - T bound, - AbstractPathFormula<T>* pathFormula) : - storm::property::abstract::RewardBoundOperator<T, AbstractPathFormula<T>>(comparisonRelation, bound, pathFormula) { - // Intentionally left empty - } - - - /*! - * Constructor - * - * @param comparisonRelation - * @param bound - * @param pathFormula - * @param minimumOperator - */ - RewardBoundOperator( - storm::property::ComparisonType comparisonRelation, - T bound, - AbstractPathFormula<T>* pathFormula, - bool minimumOperator) - : storm::property::abstract::RewardBoundOperator<T, AbstractPathFormula<T>>(comparisonRelation, bound, pathFormula, minimumOperator) { - // Intentionally left empty - } - - /*! - * Clones the called object. - * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones - * - * @returns a new AND-object that is identical the called object. - */ - virtual AbstractStateFormula<T>* clone() const override { - RewardBoundOperator<T>* result = new RewardBoundOperator<T>(); - result->setComparisonOperator(this->getComparisonOperator()); - result->setBound(this->getBound()); - result->setPathFormula(this->getPathFormula().clone()); - return result; - } - - /*! - * Calls the model checker to check this formula. - * Needed to infer the correct type of formula class. - * - * @note This function should only be called in a generic check function of a model checker class. For other uses, - * the methods of the model checker should be used. - * - * @returns A bit vector indicating all states that satisfy the formula represented by the called object. - */ - virtual storm::storage::BitVector check(const storm::modelchecker::prctl::AbstractModelChecker<T>& modelChecker) const override { - return modelChecker.template as<IRewardBoundOperatorModelChecker>()->checkRewardBoundOperator(*this); - } -}; - -} //namespace prctl -} //namespace property -} //namespace storm - -#endif /* STORM_FORMULA_PRCTL_REWARDBOUNDOPERATOR_H_ */ diff --git a/src/formula/Prctl/RewardNoBoundOperator.h b/src/formula/Prctl/RewardNoBoundOperator.h deleted file mode 100644 index 97a8dfeaa..000000000 --- a/src/formula/Prctl/RewardNoBoundOperator.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * RewardNoBoundOperator.h - * - * Created on: 25.12.2012 - * Author: Christian Dehnert - */ - -#ifndef STORM_FORMULA_PRCTL_REWARDNOBOUNDOPERATOR_H_ -#define STORM_FORMULA_PRCTL_REWARDNOBOUNDOPERATOR_H_ - -#include "AbstractNoBoundOperator.h" -#include "AbstractPathFormula.h" -#include "src/formula/abstract/RewardNoBoundOperator.h" - -namespace storm { -namespace property { -namespace prctl { - -/*! - * @brief - * Class for an abstract formula tree with a R (reward) operator without declaration of reward values - * as root. - * - * Checking a formula with this operator as root returns the reward for the reward path formula for - * each state - * - * Has one Abstract path formula as sub formula/tree. - * - * @note - * This class is a hybrid of a state and path formula, and may only appear as the outermost operator. - * Hence, it is seen as neither a state nor a path formula, but is directly derived from AbstractFormula. - * - * @note - * This class does not contain a check() method like the other formula classes. - * The check method should only be called by the model checker to infer the correct check function for sub - * formulas. As this operator can only appear at the root, the method is not useful here. - * Use the checkRewardNoBoundOperator method from the DtmcPrctlModelChecker class instead. - * - * The subtree is seen as part of the object and deleted with it - * (this behavior can be prevented by setting them to NULL before deletion) - * - * - * @see AbstractStateFormula - * @see AbstractPathFormula - * @see ProbabilisticOperator - * @see ProbabilisticIntervalOperator - * @see AbstractPrctlFormula - */ -template <class T> -class RewardNoBoundOperator: public storm::property::abstract::RewardNoBoundOperator<T, AbstractPathFormula<T>>, - public storm::property::prctl::AbstractNoBoundOperator<T> { -public: - /*! - * Empty constructor - */ - RewardNoBoundOperator() { - // Intentionally left empty - } - - /*! - * Constructor - * - * @param pathFormula The child node. - */ - RewardNoBoundOperator(AbstractPathFormula<T>* pathFormula) - : storm::property::abstract::RewardNoBoundOperator<T, AbstractPathFormula<T>>(pathFormula) { - // Intentionally left empty - } - - /*! - * Constructor - * - * @param pathFormula The child node. - */ - RewardNoBoundOperator(AbstractPathFormula<T>* pathFormula, bool minimumOperator) - : storm::property::abstract::RewardNoBoundOperator<T, AbstractPathFormula<T>>(pathFormula, minimumOperator) { - // Intentionally left empty - } - - virtual AbstractNoBoundOperator<T>* clone() const override { - RewardNoBoundOperator<T>* result = new RewardNoBoundOperator<T>(); - if (this->pathFormulaIsSet()) { - result->setPathFormula(this->getPathFormula().clone()); - } - return result; - } - - /*! - * Calls the model checker to check this formula. - * Needed to infer the correct type of formula class. - * - * @note This function should only be called in a generic check function of a model checker class. For other uses, - * the methods of the model checker should be used. - * - * @note This function is not implemented in this class. - * - * @returns A vector indicating the probability that the formula holds for each state. - */ - virtual std::vector<T> check(const storm::modelchecker::prctl::AbstractModelChecker<T>& modelChecker, bool qualitative=false) const override { - return this->getPathFormula().check(modelChecker, qualitative); - } -}; - -} //namespace prctl -} //namespace property -} //namespace storm - -#endif /* STORM_FORMULA_PRCTL_REWARDNOBOUNDOPERATOR_H_ */ diff --git a/src/formula/Prctl/SteadyStateReward.h b/src/formula/Prctl/SteadyStateReward.h deleted file mode 100644 index f7c87e90d..000000000 --- a/src/formula/Prctl/SteadyStateReward.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * SteadyStateReward.h - * - * Created on: 08.04.2013 - * Author: Thomas Heinemann - */ - -#ifndef STORM_FORMULA_PRCTL_STEADYSTATEREWARD_H_ -#define STORM_FORMULA_PRCTL_STEADYSTATEREWARD_H_ - -#include "AbstractPathFormula.h" -#include "AbstractStateFormula.h" -#include "src/formula/abstract/SteadyStateReward.h" -#include "src/formula/AbstractFormulaChecker.h" -#include <string> - -namespace storm { -namespace property { -namespace prctl { - -template <class T> class SteadyStateReward; - -/*! - * @brief Interface class for model checkers that support SteadyStateReward. - * - * All model checkers that support the formula class SteadyStateReward must inherit - * this pure virtual class. - */ -template <class T> -class ISteadyStateRewardModelChecker { - public: - /*! - * @brief Evaluates CumulativeReward formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual std::vector<T> checkSteadyStateReward(const SteadyStateReward<T>& obj, bool qualitative) const = 0; -}; - -/*! - * @brief - * Class for an abstract (path) formula tree with a Steady State Reward node as root. - * - * @see AbstractPathFormula - * @see AbstractPrctlFormula - */ -template <class T> -class SteadyStateReward: public storm::property::abstract::SteadyStateReward<T>, - public AbstractPathFormula<T> { -public: - /*! - * Empty constructor - */ - SteadyStateReward() { - // Intentionally left empty - - } - virtual ~SteadyStateReward() { - // Intentionally left empty - } - - /*! - * Clones the called object. - * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones - * - * @returns a new SteadyState-object that is identical the called object. - */ - virtual AbstractPathFormula<T>* clone() const override { - return new SteadyStateReward<T>(); - } - - /*! - * Calls the model checker to check this formula. - * Needed to infer the correct type of formula class. - * - * @note This function should only be called in a generic check function of a model checker class. For other uses, - * the methods of the model checker should be used. - * - * @returns A vector indicating the probability that the formula holds for each state. - */ - virtual std::vector<T> check(const storm::modelchecker::prctl::AbstractModelChecker<T>& modelChecker, bool qualitative) const override { - return modelChecker.template as<ISteadyStateRewardModelChecker>()->checkSteadyStateReward(*this, qualitative); - } -}; - -} //namespace prctl -} //namespace property -} //namespace storm -#endif /* STORM_FORMULA_PRCTL_STEADYSTATEREWARD_H_ */ diff --git a/src/formula/Prctl/Until.h b/src/formula/Prctl/Until.h deleted file mode 100644 index 53fb92f6b..000000000 --- a/src/formula/Prctl/Until.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Until.h - * - * Created on: 19.10.2012 - * Author: Thomas Heinemann - */ - -#ifndef STORM_FORMULA_PRCTL_UNTIL_H_ -#define STORM_FORMULA_PRCTL_UNTIL_H_ - -#include "AbstractPathFormula.h" -#include "AbstractStateFormula.h" -#include "src/formula/abstract/Until.h" -#include "src/formula/AbstractFormulaChecker.h" - -namespace storm { -namespace property { -namespace prctl { - -template <class T> class Until; - -/*! - * @brief Interface class for model checkers that support Until. - * - * All model checkers that support the formula class Until must inherit - * this pure virtual class. - */ -template <class T> -class IUntilModelChecker { - public: - /*! - * @brief Evaluates Until formula within a model checker. - * - * @param obj Formula object with subformulas. - * @return Result of the formula for every node. - */ - virtual std::vector<T> checkUntil(const Until<T>& obj, bool qualitative) const = 0; -}; - -/*! - * @brief - * Class for an abstract (path) formula tree with an Until node as root. - * - * Has two Abstract state formulas as sub formulas/trees. - * - * @par Semantics - * The formula holds iff eventually, formula \e right (the right subtree) holds, and before, - * \e left holds always. - * - * The subtrees are seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @see AbstractPathFormula - * @see AbstractPrctlFormula - */ -template <class T> -class Until : public storm::property::abstract::Until<T, AbstractStateFormula<T>>, - public AbstractPathFormula<T> { - -public: - /*! - * Empty constructor - */ - Until() { - // Intentionally left empty - } - - /*! - * Constructor - * - * @param left The left formula subtree - * @param right The left formula subtree - */ - Until(AbstractStateFormula<T>* left, AbstractStateFormula<T>* right) - : storm::property::abstract::Until<T, AbstractStateFormula<T>>(left, right) { - // Intentionally left empty - } - - /*! - * Destructor. - * - * Also deletes the subtrees. - * (this behaviour can be prevented by setting the subtrees to NULL before deletion) - */ - virtual ~Until() { - // Intentionally left empty - } - - /*! - * Clones the called object. - * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones - * - * @returns a new BoundedUntil-object that is identical the called object. - */ - virtual AbstractPathFormula<T>* clone() const override { - Until<T>* result = new Until(); - if (this->leftIsSet()) { - result->setLeft(this->getLeft().clone()); - } - if (this->rightIsSet()) { - result->setRight(this->getRight().clone()); - } - return result; - } - - /*! - * Calls the model checker to check this formula. - * Needed to infer the correct type of formula class. - * - * @note This function should only be called in a generic check function of a model checker class. For other uses, - * the methods of the model checker should be used. - * - * @returns A vector indicating the probability that the formula holds for each state. - */ - virtual std::vector<T> check(const storm::modelchecker::prctl::AbstractModelChecker<T>& modelChecker, bool qualitative) const override { - return modelChecker.template as<IUntilModelChecker>()->checkUntil(*this, qualitative); - } -}; - -} //namespace prctl -} //namespace property -} //namespace storm - -#endif /* STORM_FORMULA_PRCTL_UNTIL_H_ */ diff --git a/src/formula/PrctlFormulaChecker.h b/src/formula/PrctlFormulaChecker.h deleted file mode 100644 index f4379b47d..000000000 --- a/src/formula/PrctlFormulaChecker.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef STORM_FORMULA_PRCTLFORMULACHECKER_H_ -#define STORM_FORMULA_PRCTLFORMULACHECKER_H_ - -#include "src/formula/AbstractFormulaChecker.h" -#include "src/formula/Prctl.h" - -#include <iostream> - -namespace storm { -namespace property { - -/*! - * @brief Checks formulas if they are within PRCTL. - * - * This class implements AbstractFormulaChecker to check if a given formula - * is part of PRCTL logic. - */ -template <class T> -class PrctlFormulaChecker : public AbstractFormulaChecker<T> { - public: - /*! - * Implementation of AbstractFormulaChecker::validate() using code - * looking exactly like the sample code given there. - */ - virtual bool validate(const storm::property::abstract::AbstractFormula<T>* formula) const { - // What to support: Principles of Model Checking Def. 10.76 + syntactic sugar - if ( - dynamic_cast<const storm::property::prctl::And<T>*>(formula) || - dynamic_cast<const storm::property::prctl::Ap<T>*>(formula) || - dynamic_cast<const storm::property::prctl::BoundedUntil<T>*>(formula) || - dynamic_cast<const storm::property::prctl::Eventually<T>*>(formula) || - dynamic_cast<const storm::property::prctl::Globally<T>*>(formula) || - dynamic_cast<const storm::property::prctl::Next<T>*>(formula) || - dynamic_cast<const storm::property::prctl::Not<T>*>(formula) || - dynamic_cast<const storm::property::prctl::Or<T>*>(formula) || - dynamic_cast<const storm::property::prctl::ProbabilisticNoBoundOperator<T>*>(formula) || - dynamic_cast<const storm::property::prctl::ProbabilisticBoundOperator<T>*>(formula) || - dynamic_cast<const storm::property::prctl::Until<T>*>(formula) - ) { - return formula->validate(*this); - } - return false; - } -}; - -} // namespace property -} // namespace storm - -#endif diff --git a/src/formula/abstract/AbstractFormula.h b/src/formula/abstract/AbstractFormula.h deleted file mode 100644 index ad8122b52..000000000 --- a/src/formula/abstract/AbstractFormula.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Abstractformula.h - * - * Created on: 19.10.2012 - * Author: Thomas Heinemann - */ - -#ifndef STORM_FORMULA_ABSTRACT_ABSTRACTFORMULA_H_ -#define STORM_FORMULA_ABSTRACT_ABSTRACTFORMULA_H_ - -#include <string> - -namespace storm { -namespace property { -namespace abstract { -template <class T> class AbstractFormula; -} //namespace abstract -} //namespace property -} //namespace storm - - -#include "src/formula/AbstractFormulaChecker.h" - -namespace storm { -namespace property { -namespace abstract { - -//abstract -/*! - * @brief Abstract base class for logic Abstract formulas in general. - * - * The namespace storm::property::abstract contains versions of the formula classes which are logic abstract, and contain - * the implementation which is not directly dependent on the logics. - * The classes for the subtrees are referenced by the template parameter FormulaType, which is typically instantiated in - * the derived classes of concrete logics. - * - * The instantiation of FormulaType should be a subclass of AbstractFormula, as the functions "toString" and "validate" - * of the subformulas are needed. - * - * @note - * Even though the namespace is called "abstract", its classes may be completely implemented; abstract here denotes - * the abstraction from a concrete logic. - * - * @attention This class is abstract. - * @note Formula classes do not have copy constructors. The parameters of the constructors are usually the subtrees, so - * the syntax conflicts with copy constructors for unary operators. To produce an identical object, the classes - * AbstractFormula and AbstractFormula offer the method clone(). - * - * This is the base class for every formula class in every logic. - */ -template <class T> -class AbstractFormula { - -public: - /*! - * Virtual destructor. - */ - virtual ~AbstractFormula() { - // Intentionally left empty. - } - - /*! - * @brief Return string representation of this formula. - * - * @note every subclass must implement this method. - * - * @returns a string representation of the formula - */ - virtual std::string toString() const = 0; - - /*! - * @brief Checks if all subtrees are valid in some logic. - * - * @note Every subclass must implement this method. - * - * This method is given a checker object that knows which formula - * classes are allowed within the logic the checker represents. Every - * subclass is supposed to call checker.validate() for all child - * formulas and return true if and only if all those calls returned - * true. - * - * @param checker Checker object. - * @return true iff all subtrees are valid. - */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const = 0; -}; - -} // namespace abstract -} // namespace property -} // namespace storm - -#endif /* STORM_FORMULA_ABSTRACT_ABSTRACTFORMULA_H_ */ diff --git a/src/formula/abstract/And.h b/src/formula/abstract/And.h deleted file mode 100644 index c2739a9e4..000000000 --- a/src/formula/abstract/And.h +++ /dev/null @@ -1,164 +0,0 @@ -/* - * And.h - * - * Created on: 19.10.2012 - * Author: Thomas Heinemann - */ - -#ifndef STORM_FORMULA_ABSTRACT_AND_H_ -#define STORM_FORMULA_ABSTRACT_AND_H_ - -#include "src/formula/abstract/AbstractFormula.h" -#include "src/formula/AbstractFormulaChecker.h" -#include <string> -#include <type_traits> - -namespace storm { -namespace property { -namespace abstract { - -/*! - * @brief - * Logic-abstract Class for an abstract formula tree with AND node as root. - * - * Has two formulas as sub formulas/trees; the type is the template parameter FormulaType - * - * As AND is commutative, the order is \e theoretically not important, but will influence the order in which - * the model checker works. - * - * The subtrees are seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @see AbstractFormula - * - * @tparam FormulaType The type of the subformula. - * The instantiation of FormulaType should be a subclass of AbstractFormula, as the functions - * "toString" and "validate" of the subformulas are needed. - */ -template <class T, class FormulaType> -class And : public virtual AbstractFormula<T> { - - // Throw a compiler error when FormulaType is not a subclass of AbstractFormula. - static_assert(std::is_base_of<AbstractFormula<T>, FormulaType>::value, - "Instantiaton of FormulaType for storm::property::abstract::And<T,FormulaType> has to be a subtype of storm::property::abstract::AbstractFormula<T>"); - -public: - /*! - * Empty constructor. - * Will create an AND-node without subnotes. Will not represent a complete formula! - */ - And() { - left = NULL; - right = NULL; - } - - /*! - * Constructor. - * Creates an AND note with the parameters as subtrees. - * - * @param left The left sub formula - * @param right The right sub formula - */ - And(FormulaType* left, FormulaType* right) { - this->left = left; - this->right = right; - } - - /*! - * Destructor. - * - * The subtrees are deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - */ - virtual ~And() { - if (left != NULL) { - delete left; - } - if (right != NULL) { - delete right; - } - } - - /*! - * Sets the left child node. - * - * @param newLeft the new left child. - */ - void setLeft(FormulaType* newLeft) { - left = newLeft; - } - - /*! - * Sets the right child node. - * - * @param newRight the new right child. - */ - void setRight(FormulaType* newRight) { - right = newRight; - } - - /*! - * @returns a pointer to the left child node - */ - const FormulaType& getLeft() const { - return *left; - } - - /*! - * @returns a pointer to the right child node - */ - const FormulaType& getRight() const { - return *right; - } - - /*! - * - * @return True if the left child is set, i.e. it does not point to nullptr; false otherwise - */ - bool leftIsSet() const { - return left != nullptr; - } - - /*! - * - * @return True if the right child is set, i.e. it does not point to nullptr; false otherwise - */ - bool rightIsSet() const { - return right != nullptr; - } - - /*! - * @returns a string representation of the formula - */ - virtual std::string toString() const override { - std::string result = "("; - result += left->toString(); - result += " & "; - result += right->toString(); - result += ")"; - return result; - } - - /*! - * @brief Checks if all subtrees conform to some logic. - * - * @param checker Formula checker object. - * @return true iff all subtrees conform to some logic. - */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { - return checker.validate(this->left) && checker.validate(this->right); - } - - -private: - FormulaType* left; - FormulaType* right; -}; - -} //namespace abstract - -} //namespace property - -} //namespace storm - -#endif /* STORM_FORMULA_ABSTRACT_AND_H_ */ diff --git a/src/formula/abstract/Ap.h b/src/formula/abstract/Ap.h deleted file mode 100644 index dd0acce82..000000000 --- a/src/formula/abstract/Ap.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Ap.h - * - * Created on: 19.10.2012 - * Author: Thomas Heinemann - */ - -#ifndef STORM_FORMULA_ABSTRACT_AP_H_ -#define STORM_FORMULA_ABSTRACT_AP_H_ - -#include "src/formula/abstract/AbstractFormula.h" -#include "src/formula/AbstractFormulaChecker.h" - -namespace storm { -namespace property { -namespace abstract { - -/*! - * @brief - * Logic-abstract Class for an abstract formula tree with atomic proposition as root. - * - * This class represents the leaves in the formula tree. - * - * @see AbstractFormula - */ -template <class T> -class Ap : public virtual AbstractFormula<T> { - -public: - /*! - * Constructor - * - * Creates a new atomic proposition leaf, with the label Ap - * - * @param ap The string representing the atomic proposition - */ - Ap(std::string ap) { - this->ap = ap; - } - - /*! - * Destructor. - * At this time, empty... - */ - virtual ~Ap() { } - - /*! - * @returns the name of the atomic proposition - */ - const std::string& getAp() const { - return ap; - } - - /*! - * @returns a string representation of the leaf. - * - */ - virtual std::string toString() const override { - return getAp(); - } - - /*! - * @brief Checks if all subtrees conform to some logic. - * - * As atomic propositions have no subformulas, we return true here. - * - * @param checker Formula checker object. - * @return true - */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { - return true; - } - -private: - std::string ap; -}; - -} //namespace abstract - -} //namespace property - -} //namespace storm - -#endif /* STORM_FORMULA_ABSTRACT_ABSTRCT_AP_H_ */ diff --git a/src/formula/abstract/BoundedEventually.h b/src/formula/abstract/BoundedEventually.h deleted file mode 100644 index 2970d09d3..000000000 --- a/src/formula/abstract/BoundedEventually.h +++ /dev/null @@ -1,151 +0,0 @@ -/* - * BoundedUntil.h - * - * Created on: 27.11.2012 - * Author: Christian Dehnert - */ - -#ifndef STORM_FORMULA_ABSTRACT_BOUNDEDEVENTUALLY_H_ -#define STORM_FORMULA_ABSTRACT_BOUNDEDEVENTUALLY_H_ - -#include "src/formula/abstract/AbstractFormula.h" -#include "src/formula/AbstractFormulaChecker.h" -#include <cstdint> -#include <string> - -namespace storm { - -namespace property { - -namespace abstract { - -/*! - * @brief - * Class for an abstract (path) formula tree with a BoundedEventually node as root. - * - * Has one formula as sub formula/tree. - * - * @par Semantics - * The formula holds iff in at most \e bound steps, formula \e child holds. - * - * The subtrees are seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @tparam FormulaType The type of the subformula. - * The instantiation of FormulaType should be a subclass of AbstractFormula, as the functions - * "toString" and "validate" of the subformulas are needed. - * - * @see AbstractFormula - */ -template <class T, class FormulaType> -class BoundedEventually : public virtual AbstractFormula<T> { - - // Throw a compiler error when FormulaType is not a subclass of AbstractFormula. - static_assert(std::is_base_of<AbstractFormula<T>, FormulaType>::value, - "Instantiaton of FormulaType for storm::property::abstract::BoundedEventually<T,FormulaType> has to be a subtype of storm::property::abstract::AbstractFormula<T>"); - -public: - /*! - * Empty constructor - */ - BoundedEventually() { - this->child = nullptr; - bound = 0; - } - - /*! - * Constructor - * - * @param child The child formula subtree - * @param bound The maximal number of steps - */ - BoundedEventually(FormulaType* child, uint_fast64_t bound) { - this->child = child; - this->bound = bound; - } - - /*! - * Destructor. - * - * Also deletes the subtrees. - * (this behaviour can be prevented by setting the subtrees to NULL before deletion) - */ - virtual ~BoundedEventually() { - if (child != nullptr) { - delete child; - } - } - - /*! - * @returns the child node - */ - const FormulaType& getChild() const { - return *child; - } - - /*! - * Sets the subtree - * @param child the new child node - */ - void setChild(FormulaType* child) { - this->child = child; - } - - /*! - * - * @return True if the child is set, i.e. it does not point to nullptr; false otherwise - */ - bool childIsSet() const { - return child != nullptr; - } - - /*! - * @returns the maximally allowed number of steps for the bounded until operator - */ - uint_fast64_t getBound() const { - return bound; - } - - /*! - * Sets the maximally allowed number of steps for the bounded until operator - * - * @param bound the new bound. - */ - void setBound(uint_fast64_t bound) { - this->bound = bound; - } - - /*! - * @returns a string representation of the formula - */ - virtual std::string toString() const override { - std::string result = "F<="; - result += std::to_string(bound); - result += " "; - result += child->toString(); - return result; - } - - /*! - * @brief Checks if the subtree conforms to some logic. - * - * @param checker Formula checker object. - * @return true iff the subtree conforms to some logic. - */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { - return checker.validate(this->child); - } - - -private: - FormulaType* child; - uint_fast64_t bound; -}; - -} //namespace abstract - -} //namespace property - -} //namespace storm - -#endif /* STORM_FORMULA_ABSTRACT_BOUNDEDEVENTUALLY_H_ */ diff --git a/src/formula/abstract/BoundedNaryUntil.h b/src/formula/abstract/BoundedNaryUntil.h deleted file mode 100644 index 749f2305f..000000000 --- a/src/formula/abstract/BoundedNaryUntil.h +++ /dev/null @@ -1,175 +0,0 @@ -/* - * BoundedNaryUntil.h - * - * Created on: 19.10.2012 - * Author: Thomas Heinemann - */ - -#ifndef STORM_FORMULA_ABSTRACT_BOUNDEDNARYUNTIL_H_ -#define STORM_FORMULA_ABSTRACT_BOUNDEDNARYUNTIL_H_ - -#include "src/formula/abstract/AbstractFormula.h" -#include <cstdint> -#include <string> -#include <vector> -#include <tuple> -#include <sstream> - -namespace storm { -namespace property { -namespace abstract { - -/*! - * @brief - * Class for an abstract (path) formula tree with a BoundedNaryUntil node as root. - * - * Has at least two formulas as sub formulas and an interval - * associated with all but the first sub formula. We'll call the first one - * \e left and all other one \e right. - * - * @par Semantics - * The formula holds iff \e left holds until eventually any of the \e right - * formulas holds after a number of steps contained in the interval - * associated with this formula. - * - * The subtrees are seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @tparam FormulaType The type of the subformula. - * The instantiation of FormulaType should be a subclass of AbstractFormula, as the functions - * "toString" and "conforms" of the subformulas are needed. - * - * @see AbstractFormula - */ -template <class T, class FormulaType> -class BoundedNaryUntil : public virtual AbstractFormula<T> { - - // Throw a compiler error when FormulaType is not a subclass of AbstractFormula. - static_assert(std::is_base_of<AbstractFormula<T>, FormulaType>::value, - "Instantiaton of FormulaType for storm::property::abstract::BoundedNaryUntil<T,FormulaType> has to be a subtype of storm::property::abstract::AbstractFormula<T>"); - -public: - /*! - * Empty constructor - */ - BoundedNaryUntil() { - this->left = nullptr; - this->right = new std::vector<std::tuple<FormulaType*,T,T>>(); - } - - /*! - * Constructor - * - * @param left The left formula subtree - * @param right The left formula subtree - */ - BoundedNaryUntil(FormulaType* left, std::vector<std::tuple<FormulaType*,T,T>>* right) { - this->left = left; - this->right = right; - } - - /*! - * Destructor. - * - * Also deletes the subtrees. - * (this behaviour can be prevented by setting the subtrees to NULL before deletion) - */ - virtual ~BoundedNaryUntil() { - if (left != nullptr) { - delete left; - } - if (right != nullptr) { - delete right; - } - } - - /*! - * Sets the left child node. - * - * @param newLeft the new left child. - */ - void setLeft(FormulaType* newLeft) { - left = newLeft; - } - - void setRight(std::vector<std::tuple<FormulaType*,T,T>>* newRight) { - right = newRight; - } - - /*! - * - * @return True if the left child is set, i.e. it does not point to nullptr; false otherwise - */ - bool leftIsSet() const { - return left != nullptr; - } - - /*! - * - * @return True if the right child is set, i.e. it does not point to nullptr; false otherwise - */ - bool rightIsSet() const { - return right != nullptr; - } - - /*! - * Sets the right child node. - * - * @param newRight the new right child. - */ - void addRight(FormulaType* newRight, T upperBound, T lowerBound) { - this->right->push_back(std::tuple<FormulaType*,T,T>(newRight, upperBound, lowerBound)); - } - - /*! - * @returns a pointer to the left child node - */ - const FormulaType& getLeft() const { - return *left; - } - - /*! - * @returns a pointer to the right child nodes. - */ - const std::vector<std::tuple<FormulaType*,T,T>>& getRight() const { - return *right; - } - - /*! - * @returns a string representation of the formula - */ - virtual std::string toString() const override { - std::stringstream result; - result << "( " << left->toString(); - for (auto it = this->right->begin(); it != this->right->end(); ++it) { - result << " U[" << std::get<1>(*it) << "," << std::get<2>(*it) << "] " << std::get<0>(*it)->toString(); - } - result << ")"; - return result.str(); - } - - /*! - * @brief Checks if all subtrees conform to some logic. - * - * @param checker Formula checker object. - * @return true iff all subtrees conform to some logic. - */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { - bool res = checker.validate(this->left); - for (auto it = this->right->begin(); it != this->right->end(); ++it) { - res &= checker.validate(std::get<0>(*it)); - } - return res; - } - - -private: - FormulaType* left; - std::vector<std::tuple<FormulaType*,T,T>>* right; -}; - -} //namespace abstract -} //namespace property -} //namespace storm - -#endif /* STORM_FORMULA_ABSTRACT_BOUNDEDNARYUNTIL_H_ */ diff --git a/src/formula/abstract/BoundedUntil.h b/src/formula/abstract/BoundedUntil.h deleted file mode 100644 index 487fb0535..000000000 --- a/src/formula/abstract/BoundedUntil.h +++ /dev/null @@ -1,182 +0,0 @@ -/* - * BoundedUntil.h - * - * Created on: 19.10.2012 - * Author: Thomas Heinemann - */ - -#ifndef STORM_FORMULA_ABSTRACT_BOUNDEDUNTIL_H_ -#define STORM_FORMULA_ABSTRACT_BOUNDEDUNTIL_H_ - -#include "src/formula/abstract/AbstractFormula.h" -#include <cstdint> -#include <string> - -namespace storm { -namespace property { -namespace abstract { - -/*! - * @brief - * Class for an abstract (path) formula tree with a BoundedUntil node as root. - * - * Has two formulas as sub formulas/trees. - * - * @par Semantics - * The formula holds iff in at most \e bound steps, formula \e right (the right subtree) holds, and before, - * \e left holds. - * - * The subtrees are seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @tparam FormulaType The type of the subformula. - * The instantiation of FormulaType should be a subclass of AbstractFormula, as the functions - * "toString" and "conforms" of the subformulas are needed. - * - * @see AbstractFormula - */ -template <class T, class FormulaType> -class BoundedUntil : public virtual AbstractFormula<T> { - - // Throw a compiler error when FormulaType is not a subclass of AbstractFormula. - static_assert(std::is_base_of<AbstractFormula<T>, FormulaType>::value, - "Instantiaton of FormulaType for storm::property::abstract::BoundedUntil<T,FormulaType> has to be a subtype of storm::property::abstract::AbstractFormula<T>"); - -public: - /*! - * Empty constructor - */ - BoundedUntil() { - this->left = NULL; - this->right = NULL; - bound = 0; - } - - /*! - * Constructor - * - * @param left The left formula subtree - * @param right The left formula subtree - * @param bound The maximal number of steps - */ - BoundedUntil(FormulaType* left, FormulaType* right, - uint_fast64_t bound) { - this->left = left; - this->right = right; - this->bound = bound; - } - - /*! - * Destructor. - * - * Also deletes the subtrees. - * (this behaviour can be prevented by setting the subtrees to NULL before deletion) - */ - virtual ~BoundedUntil() { - if (left != NULL) { - delete left; - } - if (right != NULL) { - delete right; - } - } - - /*! - * Sets the left child node. - * - * @param newLeft the new left child. - */ - void setLeft(FormulaType* newLeft) { - left = newLeft; - } - - /*! - * Sets the right child node. - * - * @param newRight the new right child. - */ - void setRight(FormulaType* newRight) { - right = newRight; - } - - /*! - * @returns a pointer to the left child node - */ - const FormulaType& getLeft() const { - return *left; - } - - /*! - * @returns a pointer to the right child node - */ - const FormulaType& getRight() const { - return *right; - } - - /*! - * - * @return True if the left child is set, i.e. it does not point to nullptr; false otherwise - */ - bool leftIsSet() const { - return left != nullptr; - } - - /*! - * - * @return True if the right child is set, i.e. it does not point to nullptr; false otherwise - */ - bool rightIsSet() const { - return right != nullptr; - } - - /*! - * @returns the maximally allowed number of steps for the bounded until operator - */ - uint_fast64_t getBound() const { - return bound; - } - - /*! - * Sets the maximally allowed number of steps for the bounded until operator - * - * @param bound the new bound. - */ - void setBound(uint_fast64_t bound) { - this->bound = bound; - } - - /*! - * @returns a string representation of the formula - */ - virtual std::string toString() const override { - std::string result = left->toString(); - result += " U<="; - result += std::to_string(bound); - result += " "; - result += right->toString(); - return result; - } - - /*! - * @brief Checks if all subtrees conform to some logic. - * - * @param checker Formula checker object. - * @return true iff all subtrees conform to some logic. - */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { - return checker.validate(this->left) && checker.validate(this->right); - } - -private: - FormulaType* left; - FormulaType* right; - uint_fast64_t bound; -}; - -} //namespace abstract - -} //namespace property - -} //namespace storm - -#endif /* STORM_FORMULA_ABSTRACT_BOUNDEDUNTIL_H_ */ diff --git a/src/formula/abstract/CumulativeReward.h b/src/formula/abstract/CumulativeReward.h deleted file mode 100644 index f347ebd77..000000000 --- a/src/formula/abstract/CumulativeReward.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * InstantaneousReward.h - * - * Created on: 26.12.2012 - * Author: Christian Dehnert - */ - -#ifndef STORM_FORMULA_ABSTRACT_CUMULATIVEREWARD_H_ -#define STORM_FORMULA_ABSTRACT_CUMULATIVEREWARD_H_ - -#include "AbstractFormula.h" -#include "src/formula/AbstractFormulaChecker.h" -#include <string> - -namespace storm { -namespace property { -namespace abstract { - -/*! - * @brief - * Class for an abstract (path) formula tree with a Cumulative Reward node as root. - * - * The subtrees are seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @see AbstractPathFormula - * @see AbstractFormula - */ -template <class T> -class CumulativeReward : public virtual AbstractFormula<T> { - -public: - /*! - * Empty constructor - */ - CumulativeReward() { - bound = 0; - } - - /*! - * Constructor - * - * @param bound The time bound of the reward formula - */ - CumulativeReward(T bound) { - this->bound = bound; - } - - /*! - * Empty destructor. - */ - virtual ~CumulativeReward() { - // Intentionally left empty. - } - - /*! - * @returns the time instance for the instantaneous reward operator - */ - T getBound() const { - return bound; - } - - /*! - * Sets the the time instance for the instantaneous reward operator - * - * @param bound the new bound. - */ - void setBound(T bound) { - this->bound = bound; - } - - /*! - * @returns a string representation of the formula - */ - virtual std::string toString() const override { - std::string result = "C <= "; - result += std::to_string(bound); - return result; - } - - /*! - * @brief Checks if all subtrees conform to some logic. - * - * As CumulativeReward objects have no subformulas, we return true here. - * - * @param checker Formula checker object. - * @return true - */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { - return true; - } - -private: - T bound; -}; - -} //namespace abstract -} //namespace property -} //namespace storm - -#endif /* STORM_FORMULA_ABSTRACT_INSTANTANEOUSREWARD_H_ */ diff --git a/src/formula/abstract/Eventually.h b/src/formula/abstract/Eventually.h deleted file mode 100644 index 3171c559a..000000000 --- a/src/formula/abstract/Eventually.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Next.h - * - * Created on: 26.12.2012 - * Author: Christian Dehnert - */ - -#ifndef STORM_FORMULA_ABSTRACT_EVENTUALLY_H_ -#define STORM_FORMULA_ABSTRACT_EVENTUALLY_H_ - -#include "src/formula/abstract/AbstractFormula.h" - -namespace storm { - -namespace property { - -namespace abstract { - -/*! - * @brief - * Class for an abstract (path) formula tree with an Eventually node as root. - * - * Has one formula as sub formula/tree. - * - * @par Semantics - * The formula holds iff eventually \e child holds. - * - * The subtree is seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to nullptr before deletion) - * - * @tparam FormulaType The type of the subformula. - * The instantiation of FormulaType should be a subclass of AbstractFormula, as the functions - * "toString" and "conforms" of the subformulas are needed. - * - * @see AbstractFormula - */ -template <class T, class FormulaType> -class Eventually : public virtual AbstractFormula<T> { - - // Throw a compiler error when FormulaType is not a subclass of AbstractFormula. - static_assert(std::is_base_of<AbstractFormula<T>, FormulaType>::value, - "Instantiaton of FormulaType for storm::property::abstract::Eventually<T,FormulaType> has to be a subtype of storm::property::abstract::AbstractFormula<T>"); - -public: - /*! - * Empty constructor - */ - Eventually() { - this->child = nullptr; - } - - /*! - * Constructor - * - * @param child The child node - */ - Eventually(FormulaType* child) { - this->child = child; - } - - /*! - * Constructor. - * - * Also deletes the subtree. - * (this behaviour can be prevented by setting the subtrees to nullptr before deletion) - */ - virtual ~Eventually() { - if (child != nullptr) { - delete child; - } - } - - /*! - * @returns the child node - */ - const FormulaType& getChild() const { - return *child; - } - - /*! - * Sets the subtree - * @param child the new child node - */ - void setChild(FormulaType* child) { - this->child = child; - } - - /*! - * - * @return True if the child node is set, i.e. it does not point to nullptr; false otherwise - */ - bool childIsSet() const { - return child != nullptr; - } - - /*! - * @returns a string representation of the formula - */ - virtual std::string toString() const override { - std::string result = "F "; - result += child->toString(); - return result; - } - - /*! - * @brief Checks if the subtree conforms to some logic. - * - * @param checker Formula checker object. - * @return true iff the subtree conforms to some logic. - */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { - return checker.validate(this->child); - } - -private: - FormulaType* child; -}; - -} //namespace abstract - -} //namespace property - -} //namespace storm - -#endif /* STORM_FORMULA_ABSTRACT_EVENTUALLY_H_ */ diff --git a/src/formula/abstract/Globally.h b/src/formula/abstract/Globally.h deleted file mode 100644 index 77444c232..000000000 --- a/src/formula/abstract/Globally.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Next.h - * - * Created on: 26.12.2012 - * Author: Christian Dehnert - */ - -#ifndef STORM_FORMULA_ABSTRACT_GLOBALLY_H_ -#define STORM_FORMULA_ABSTRACT_GLOBALLY_H_ - -#include "src/formula/abstract/AbstractFormula.h" -#include "src/formula/AbstractFormulaChecker.h" - -namespace storm { - -namespace property { - -namespace abstract { - -/*! - * @brief - * Class for an abstract formula tree with a Globally node as root. - * - * Has one formula as sub formula/tree. - * - * @par Semantics - * The formula holds iff globally \e child holds. - * - * The subtree is seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to nullptr before deletion) - * - * @tparam FormulaType The type of the subformula. - * The instantiation of FormulaType should be a subclass of AbstractFormula, as the functions - * "toString" and "conforms" of the subformulas are needed. - * - * @see AbstractFormula - */ -template <class T, class FormulaType> -class Globally : public virtual AbstractFormula<T> { - - // Throw a compiler error when FormulaType is not a subclass of AbstractFormula. - static_assert(std::is_base_of<AbstractFormula<T>, FormulaType>::value, - "Instantiaton of FormulaType for storm::property::abstract::Globally<T,FormulaType> has to be a subtype of storm::property::abstract::AbstractFormula<T>"); - -public: - /*! - * Empty constructor - */ - Globally() { - this->child = nullptr; - } - - /*! - * Constructor - * - * @param child The child node - */ - Globally(FormulaType* child) { - this->child = child; - } - - /*! - * Constructor. - * - * Also deletes the subtree. - * (this behaviour can be prevented by setting the subtrees to nullptr before deletion) - */ - virtual ~Globally() { - if (child != nullptr) { - delete child; - } - } - - /*! - * @returns the child node - */ - const FormulaType& getChild() const { - return *child; - } - - /*! - * Sets the subtree - * @param child the new child node - */ - void setChild(FormulaType* child) { - this->child = child; - } - - /*! - * - * @return True if the child node is set, i.e. it does not point to nullptr; false otherwise - */ - bool childIsSet() const { - return child != nullptr; - } - - /*! - * @returns a string representation of the formula - */ - virtual std::string toString() const override { - std::string result = "G "; - result += child->toString(); - return result; - } - - /*! - * @brief Checks if the subtree conforms to some logic. - * - * @param checker Formula checker object. - * @return true iff the subtree conforms to some logic. - */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { - return checker.validate(this->child); - } - -private: - FormulaType* child; -}; - -} //namespace abstract - -} //namespace property - -} //namespace storm - -#endif /* STORM_FORMULA_ABSTRACT_GLOBALLY_H_ */ diff --git a/src/formula/abstract/IOptimizingOperator.h b/src/formula/abstract/IOptimizingOperator.h deleted file mode 100644 index 53a5f8769..000000000 --- a/src/formula/abstract/IOptimizingOperator.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * IOptimizingOperator.h - * - * Created on: 17.04.2013 - * Author: thomas - */ - -#ifndef STORM_FORMULA_ABSTRACT_IOPTIMIZINGOPERATOR_H_ -#define STORM_FORMULA_ABSTRACT_IOPTIMIZINGOPERATOR_H_ - -namespace storm { -namespace property { -namespace abstract { - -/*! - * @brief Interface for optimizing operators - * - * Needed to link abstract classes in concrete logics with the logic-abstract implementation. - */ -class IOptimizingOperator { -public: - - /*! - * Retrieves whether the operator is to be interpreted as an optimizing (i.e. min/max) operator. - * @returns True if the operator is an optimizing operator. - */ - virtual bool isOptimalityOperator() const = 0; - - /*! - * Retrieves whether the operator is a minimizing operator given that it is an optimality - * operator. - * @returns True if the operator is an optimizing operator and it is a minimizing operator and - * false otherwise, i.e. if it is either not an optimizing operator or not a minimizing operator. - */ - virtual bool isMinimumOperator() const = 0; -}; - -} /* namespace abstract */ -} /* namespace property */ -} /* namespace storm */ -#endif /* IOPTIMIZINGOPERATOR_H_ */ diff --git a/src/formula/abstract/InstantaneousReward.h b/src/formula/abstract/InstantaneousReward.h deleted file mode 100644 index 8e2674efb..000000000 --- a/src/formula/abstract/InstantaneousReward.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * InstantaneousReward.h - * - * Created on: 26.12.2012 - * Author: Christian Dehnert - */ - -#ifndef STORM_FORMULA_ABSTRACT_INSTANTANEOUSREWARD_H_ -#define STORM_FORMULA_ABSTRACT_INSTANTANEOUSREWARD_H_ - -#include "AbstractFormula.h" -#include "src/formula/AbstractFormulaChecker.h" -#include <cstdint> -#include <string> - -namespace storm { -namespace property { -namespace abstract { - -/*! - * @brief - * Class for an abstract (path) formula tree with a Instantaneous Reward node as root. - * - * The subtrees are seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @see AbstractFormula - */ -template <class T> -class InstantaneousReward : public virtual AbstractFormula<T> { - -public: - /*! - * Empty constructor - */ - InstantaneousReward() { - bound = 0; - } - - /*! - * Constructor - * - * @param bound The time instance of the reward formula - */ - InstantaneousReward(uint_fast64_t bound) { - this->bound = bound; - } - - /*! - * Empty destructor. - */ - virtual ~InstantaneousReward() { - // Intentionally left empty. - } - - /*! - * @returns the time instance for the instantaneous reward operator - */ - uint_fast64_t getBound() const { - return bound; - } - - /*! - * Sets the the time instance for the instantaneous reward operator - * - * @param bound the new bound. - */ - void setBound(uint_fast64_t bound) { - this->bound = bound; - } - - /*! - * @returns a string representation of the formula - */ - virtual std::string toString() const override { - std::string result = "I="; - result += std::to_string(bound); - return result; - } - - /*! - * @brief Checks if all subtrees conform to some logic. - * - * As InstantaneousReward formulas have no subformulas, we return true here. - * - * @param checker Formula checker object. - * @return true - */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { - return true; - } - -private: - uint_fast64_t bound; -}; - -} //namespace abstract -} //namespace property -} //namespace storm - -#endif /* STORM_FORMULA_ABSTRACT_INSTANTANEOUSREWARD_H_ */ diff --git a/src/formula/abstract/Next.h b/src/formula/abstract/Next.h deleted file mode 100644 index d4fc9fe94..000000000 --- a/src/formula/abstract/Next.h +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Next.h - * - * Created on: 19.10.2012 - * Author: Thomas Heinemann - */ - -#ifndef STORM_FORMULA_ABSTRACT_NEXT_H_ -#define STORM_FORMULA_ABSTRACT_NEXT_H_ - -#include "src/formula/abstract/AbstractFormula.h" -#include "src/formula/AbstractFormulaChecker.h" - -namespace storm { - -namespace property { - -namespace abstract { - -/*! - * @brief - * Class for an abstract (path) formula tree with a Next node as root. - * - * Has two formulas as sub formulas/trees. - * - * @par Semantics - * The formula holds iff in the next step, \e child holds - * - * The subtree is seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @tparam FormulaType The type of the subformula. - * The instantiation of FormulaType should be a subclass of AbstractFormula, as the functions - * "toString" and "conforms" of the subformulas are needed. - * - * @see AbstractFormula - */ -template <class T, class FormulaType> -class Next : public virtual AbstractFormula<T> { - - // Throw a compiler error when FormulaType is not a subclass of AbstractFormula. - static_assert(std::is_base_of<AbstractFormula<T>, FormulaType>::value, - "Instantiaton of FormulaType for storm::property::abstract::Next<T,FormulaType> has to be a subtype of storm::property::abstract::AbstractFormula<T>"); - -public: - /*! - * Empty constructor - */ - Next() { - this->child = NULL; - } - - /*! - * Constructor - * - * @param child The child node - */ - Next(FormulaType* child) { - this->child = child; - } - - /*! - * Constructor. - * - * Also deletes the subtree. - * (this behaviour can be prevented by setting the subtrees to NULL before deletion) - */ - virtual ~Next() { - if (child != NULL) { - delete child; - } - } - - /*! - * @returns the child node - */ - const FormulaType& getChild() const { - return *child; - } - - /*! - * Sets the subtree - * @param child the new child node - */ - void setChild(FormulaType* child) { - this->child = child; - } - - /*! - * - * @return True if the child node is set, i.e. it does not point to nullptr; false otherwise - */ - bool childIsSet() const { - return child != nullptr; - } - - /*! - * @returns a string representation of the formula - */ - virtual std::string toString() const override { - std::string result = "("; - result += " X "; - result += child->toString(); - result += ")"; - return result; - } - - /*! - * @brief Checks if the subtree conforms to some logic. - * - * @param checker Formula checker object. - * @return true iff the subtree conforms to some logic. - */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { - return checker.validate(this->child); - } - -private: - FormulaType* child; -}; - -} //namespace abstract - -} //namespace property - -} //namespace storm - -#endif /* STORM_FORMULA_ABSTRACT_NEXT_H_ */ diff --git a/src/formula/abstract/Not.h b/src/formula/abstract/Not.h deleted file mode 100644 index bfa24059d..000000000 --- a/src/formula/abstract/Not.h +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Not.h - * - * Created on: 19.10.2012 - * Author: Thomas Heinemann - */ - -#ifndef STORM_FORMULA_ABSTRACT_NOT_H_ -#define STORM_FORMULA_ABSTRACT_NOT_H_ - -#include "src/formula/abstract/AbstractFormula.h" -#include "src/formula/AbstractFormulaChecker.h" - -namespace storm { - -namespace property { - -namespace abstract { - -/*! - * @brief - * Class for an abstract formula tree with NOT node as root. - * - * Has one formula as sub formula/tree. - * - * The subtree is seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @tparam FormulaType The type of the subformula. - * The instantiation of FormulaType should be a subclass of AbstractFormula, as the functions - * "toString" and "conforms" of the subformulas are needed. - * - * @see AbstractFormula - */ -template <class T, class FormulaType> -class Not : public virtual AbstractFormula<T> { - - // Throw a compiler error if FormulaType is not a subclass of AbstractFormula. - static_assert(std::is_base_of<AbstractFormula<T>, FormulaType>::value, - "Instantiaton of FormulaType for storm::property::abstract::Not<T,FormulaType> has to be a subtype of storm::property::abstract::AbstractFormula<T>"); - -public: - /*! - * Empty constructor - */ - Not() { - this->child = NULL; - } - - /*! - * Constructor - * @param child The child node - */ - Not(FormulaType* child) { - this->child = child; - } - - /*! - * Destructor - * - * Also deletes the subtree - * (this behavior can be prevented by setting them to NULL before deletion) - */ - virtual ~Not() { - if (child != NULL) { - delete child; - } - } - - /*! - * @returns The child node - */ - const FormulaType& getChild() const { - return *child; - } - - /*! - * Sets the subtree - * @param child the new child node - */ - void setChild(FormulaType* child) { - this->child = child; - } - - /*! - * - * @return True if the child node is set, i.e. it does not point to nullptr; false otherwise - */ - bool childIsSet() const { - return child != nullptr; - } - - /*! - * @returns a string representation of the formula - */ - virtual std::string toString() const override { - std::string result = "!"; - result += child->toString(); - return result; - } - - /*! - * @brief Checks if the subtree conforms to some logic. - * - * @param checker Formula checker object. - * @return true iff the subtree conforms to some logic. - */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { - return checker.validate(this->child); - } - -private: - FormulaType* child; -}; - -} //namespace abstract - -} //namespace property - -} //namespace storm - -#endif /* STORM_FORMULA_ABSTRACT_NOT_H_ */ diff --git a/src/formula/abstract/OptimizingOperator.h b/src/formula/abstract/OptimizingOperator.h deleted file mode 100644 index 46d868a23..000000000 --- a/src/formula/abstract/OptimizingOperator.h +++ /dev/null @@ -1,72 +0,0 @@ -#ifndef STORM_FORMULA_ABSTRACT_OPTIMIZINGOPERATOR_H_ -#define STORM_FORMULA_ABSTRACT_OPTIMIZINGOPERATOR_H_ - -#include "IOptimizingOperator.h" - -namespace storm { - -namespace property { - -namespace abstract { - -/*! - * - */ -class OptimizingOperator : public virtual IOptimizingOperator { -public: - /*! - * Empty constructor - */ - OptimizingOperator() : optimalityOperator(false), minimumOperator(false) { - } - - /*! - * Constructor - * - * @param minimumOperator A flag indicating whether this operator is a minimizing or a maximizing operator. - */ - OptimizingOperator(bool minimumOperator) : optimalityOperator(true), minimumOperator(minimumOperator) { - } - - /*! - * Destructor - */ - virtual ~OptimizingOperator() { - // Intentionally left empty - } - - /*! - * Retrieves whether the operator is to be interpreted as an optimizing (i.e. min/max) operator. - * @returns True if the operator is an optimizing operator. - */ - virtual bool isOptimalityOperator() const { - return optimalityOperator; - } - - /*! - * Retrieves whether the operator is a minimizing operator given that it is an optimality - * operator. - * @returns True if the operator is an optimizing operator and it is a minimizing operator and - * false otherwise, i.e. if it is either not an optimizing operator or not a minimizing operator. - */ - virtual bool isMinimumOperator() const { - return optimalityOperator && minimumOperator; - } - -private: - // A flag that indicates whether this operator is meant as an optimizing (i.e. min/max) operator - // over a nondeterministic model. - bool optimalityOperator; - - // In the case this operator is an optimizing operator, this flag indicates whether it is - // looking for the minimum or the maximum value. - bool minimumOperator; -}; - -} //namespace abstract - -} //namespace property - -} //namespace storm - -#endif /* STORM_FORMULA_ABSTRACT_OPTIMIZINGOPERATOR_H_ */ diff --git a/src/formula/abstract/Or.h b/src/formula/abstract/Or.h deleted file mode 100644 index 67ed1e72d..000000000 --- a/src/formula/abstract/Or.h +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Or.h - * - * Created on: 19.10.2012 - * Author: Thomas Heinemann - */ - -#ifndef STORM_FORMULA_ABSTRACT_OR_H_ -#define STORM_FORMULA_ABSTRACT_OR_H_ - -#include "src/formula/abstract/AbstractFormula.h" -#include "src/formula/AbstractFormulaChecker.h" - -namespace storm { -namespace property { -namespace abstract { - -/*! - * @brief - * Class for an abstract formula tree with OR node as root. - * - * Has two formulas as sub formulas/trees. - * - * As OR is commutative, the order is \e theoretically not important, but will influence the order in which - * the model checker works. - * - * The subtrees are seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @tparam FormulaType The type of the subformula. - * The instantiation of FormulaType should be a subclass of AbstractFormula, as the functions - * "toString" and "conforms" of the subformulas are needed. - * - * @see AbstractFormula - */ -template <class T, class FormulaType> -class Or : public virtual AbstractFormula<T> { - - // Throw a compiler error if FormulaType is not a subclass of AbstractFormula. - static_assert(std::is_base_of<AbstractFormula<T>, FormulaType>::value, - "Instantiaton of FormulaType for storm::property::abstract::Or<T,FormulaType> has to be a subtype of storm::property::abstract::AbstractFormula<T>"); - -public: - /*! - * Empty constructor. - * Will create an AND-node without subnotes. Will not represent a complete formula! - */ - Or() { - left = NULL; - right = NULL; - } - - /*! - * Constructor. - * Creates an AND note with the parameters as subtrees. - * - * @param left The left sub formula - * @param right The right sub formula - */ - Or(FormulaType* left, FormulaType* right) { - this->left = left; - this->right = right; - } - - /*! - * Destructor. - * - * The subtrees are deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - */ - virtual ~Or() { - if (left != NULL) { - delete left; - } - if (right != NULL) { - delete right; - } - } - - /*! - * Sets the left child node. - * - * @param newLeft the new left child. - */ - void setLeft(FormulaType* newLeft) { - left = newLeft; - } - - /*! - * Sets the right child node. - * - * @param newRight the new right child. - */ - void setRight(FormulaType* newRight) { - right = newRight; - } - - /*! - * @returns a pointer to the left child node - */ - const FormulaType& getLeft() const { - return *left; - } - - /*! - * @returns a pointer to the right child node - */ - const FormulaType& getRight() const { - return *right; - } - - /*! - * - * @return True if the left child is set, i.e. it does not point to nullptr; false otherwise - */ - bool leftIsSet() const { - return left != nullptr; - } - - /*! - * - * @return True if the right child is set, i.e. it does not point to nullptr; false otherwise - */ - bool rightIsSet() const { - return right != nullptr; - } - - /*! - * @returns a string representation of the formula - */ - virtual std::string toString() const override { - std::string result = "("; - result += left->toString(); - result += " | "; - result += right->toString(); - result += ")"; - return result; - } - - /*! - * @brief Checks if all subtrees conform to some logic. - * - * @param checker Formula checker object. - * @return true iff all subtrees conform to some logic. - */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { - return checker.validate(this->left) && checker.validate(this->right); - } - -private: - FormulaType* left; - FormulaType* right; -}; - -} //namespace abstract - -} //namespace property - -} //namespace storm - -#endif /* STORM_FORMULA_ABSTRACT_OR_H_ */ diff --git a/src/formula/abstract/PathBoundOperator.h b/src/formula/abstract/PathBoundOperator.h deleted file mode 100644 index f6c1cd956..000000000 --- a/src/formula/abstract/PathBoundOperator.h +++ /dev/null @@ -1,194 +0,0 @@ -/* - * PathBoundOperator.h - * - * Created on: 27.12.2012 - * Author: Christian Dehnert - */ - -#ifndef STORM_FORMULA_ABSTRACT_PATHBOUNDOPERATOR_H_ -#define STORM_FORMULA_ABSTRACT_PATHBOUNDOPERATOR_H_ - -#include "src/formula/abstract/AbstractFormula.h" -#include "src/formula/abstract/AbstractFormula.h" -#include "src/formula/AbstractFormulaChecker.h" -#include "src/formula/ComparisonType.h" - -#include "src/formula/abstract/OptimizingOperator.h" - -#include "src/utility/constants.h" - -namespace storm { - -namespace property { - -namespace abstract { - -/*! - * @brief - * Class for an abstract formula tree with a P (probablistic) operator node over a probability interval - * as root. - * - * Has one formula as sub formula/tree. - * - * @par Semantics - * The formula holds iff the probability that the path formula holds is inside the bounds - * specified in this operator - * - * The subtree is seen as part of the object and deleted with it - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @tparam FormulaType The type of the subformula. - * The instantiation of FormulaType should be a subclass of AbstractFormula, as the functions - * "toString" and "conforms" of the subformulas are needed. - * - * @see AbstractFormula - * @see PathNoBoundOperator - */ -template<class T, class FormulaType> -class PathBoundOperator : public virtual AbstractFormula<T>, public OptimizingOperator { - - // Throw a compiler error if FormulaType is not a subclass of AbstractFormula. - static_assert(std::is_base_of<AbstractFormula<T>, FormulaType>::value, - "Instantiaton of FormulaType for storm::property::abstract::PathBoundOperator<T,FormulaType> has to be a subtype of storm::property::abstract::AbstractFormula<T>"); - -public: - /*! - * Constructor for non-optimizing operator. - * - * @param comparisonOperator The relation for the bound. - * @param bound The bound for the probability - * @param pathFormula The child node - */ - PathBoundOperator(storm::property::ComparisonType comparisonOperator, T bound, FormulaType* pathFormula) - : comparisonOperator(comparisonOperator), bound(bound), pathFormula(pathFormula) { - // Intentionally left empty - } - - /*! - * Constructor for optimizing operator. - * - * @param comparisonOperator The relation for the bound. - * @param bound The bound for the probability - * @param pathFormula The child node - * @param minimumOperator Indicator, if operator should be minimum or maximum operator. - */ - PathBoundOperator(storm::property::ComparisonType comparisonOperator, T bound, FormulaType* pathFormula, bool minimumOperator) - : OptimizingOperator(minimumOperator), comparisonOperator(comparisonOperator), bound(bound), pathFormula(pathFormula) { - // Intentionally left empty - } - - /*! - * Destructor - * - * The subtree is deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - */ - virtual ~PathBoundOperator() { - if (pathFormula != nullptr) { - delete pathFormula; - } - } - - /*! - * @returns the child node (representation of a formula) - */ - const FormulaType& getPathFormula () const { - return *pathFormula; - } - - /*! - * Sets the child node - * - * @param pathFormula the path formula that becomes the new child node - */ - void setPathFormula(FormulaType* pathFormula) { - this->pathFormula = pathFormula; - } - - /*! - * - * @return True if the path formula is set, i.e. it does not point to nullptr; false otherwise - */ - bool pathFormulaIsSet() const { - return pathFormula != nullptr; - } - - /*! - * @returns the comparison relation - */ - const storm::property::ComparisonType getComparisonOperator() const { - return comparisonOperator; - } - - void setComparisonOperator(storm::property::ComparisonType comparisonOperator) { - this->comparisonOperator = comparisonOperator; - } - - /*! - * @returns the bound for the measure - */ - const T& getBound() const { - return bound; - } - - /*! - * Sets the interval in which the probability that the path formula holds may lie in. - * - * @param bound The bound for the measure - */ - void setBound(T bound) { - this->bound = bound; - } - - /*! - * @returns a string representation of the formula - */ - virtual std::string toString() const override { - std::string result = ""; - switch (comparisonOperator) { - case LESS: result += "<"; break; - case LESS_EQUAL: result += "<="; break; - case GREATER: result += ">"; break; - case GREATER_EQUAL: result += ">="; break; - } - result += " "; - result += std::to_string(bound); - result += " ["; - result += pathFormula->toString(); - result += "]"; - return result; - } - - bool meetsBound(T value) const { - switch (comparisonOperator) { - case LESS: return value < bound; break; - case LESS_EQUAL: return value <= bound; break; - case GREATER: return value > bound; break; - case GREATER_EQUAL: return value >= bound; break; - default: return false; - } - } - - /*! - * @brief Checks if the subtree conforms to some logic. - * - * @param checker Formula checker object. - * @return true iff the subtree conforms to some logic. - */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { - return checker.validate(this->pathFormula); - } - -private: - storm::property::ComparisonType comparisonOperator; - T bound; - FormulaType* pathFormula; -}; - -} //namespace abstract - -} //namespace property - -} //namespace storm - -#endif /* STORM_FORMULA_ABSTRACT_PATHBOUNDOPERATOR_H_ */ diff --git a/src/formula/abstract/PathNoBoundOperator.h b/src/formula/abstract/PathNoBoundOperator.h deleted file mode 100644 index 1b0af8d1e..000000000 --- a/src/formula/abstract/PathNoBoundOperator.h +++ /dev/null @@ -1,160 +0,0 @@ -/* - * PathNoBoundOperator.h - * - * Created on: 27.12.2012 - * Author: Christian Dehnert - */ - -#ifndef STORM_FORMULA_ABSTRACT_NOBOUNDOPERATOR_H_ -#define STORM_FORMULA_ABSTRACT_NOBOUNDOPERATOR_H_ - -#include "src/formula/abstract/AbstractFormula.h" -#include "src/formula/AbstractFormulaChecker.h" -#include "src/formula/abstract/OptimizingOperator.h" - - -namespace storm { - -namespace property { - -namespace abstract { -/*! - * @brief - * Class for an abstract formula tree with a P (probablistic) operator without declaration of probabilities - * as root. - * - * Checking a formula with this operator as root returns the probabilities that the path formula holds - * (for each state) - * - * Has one formula as sub formula/tree. - * - * @note - * This class is a hybrid of a state and path formula, and may only appear as the outermost operator. - * Hence, it is seen as neither a state nor a path formula, but is directly derived from AbstractFormula. - * - * @note - * This class does not contain a check() method like the other formula classes. - * The check method should only be called by the model checker to infer the correct check function for sub - * formulas. As this operator can only appear at the root, the method is not useful here. - * Use the checkProbabilisticNoBoundOperator method from the DtmcPrctlModelChecker class instead. - * - * The subtree is seen as part of the object and deleted with it - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @tparam FormulaType The type of the subformula. - * The instantiation of FormulaType should be a subclass of AbstractFormula, as the functions - * "toString" and "conforms" of the subformulas are needed. - * - * @see AbstractFormula - * @see PathBoundOperator - */ -template <class T, class FormulaType> -class PathNoBoundOperator: public virtual AbstractFormula<T>, public OptimizingOperator { - - // Throw a compiler error if FormulaType is not a subclass of AbstractFormula. - static_assert(std::is_base_of<AbstractFormula<T>, FormulaType>::value, - "Instantiaton of FormulaType for storm::property::abstract::PathNoBoundOperator<T,FormulaType> has to be a subtype of storm::property::abstract::AbstractFormula<T>"); - - -public: - /*! - * Empty constructor - */ - PathNoBoundOperator() : - OptimizingOperator(false) { - this->pathFormula = nullptr; - } - - /*! - * Constructor - * - * @param pathFormula The child node. - */ - PathNoBoundOperator(FormulaType* pathFormula) { - this->pathFormula = pathFormula; - } - - /*! - * Constructor - * - * @param pathFormula The child node. - * @param minimumOperator A flag indicating whether this operator is a minimizing or a - * maximizing operator. - */ - PathNoBoundOperator(FormulaType* pathFormula, bool minimumOperator) - : OptimizingOperator(minimumOperator) { - this->pathFormula = pathFormula; - } - - /*! - * Destructor - */ - virtual ~PathNoBoundOperator() { - if (pathFormula != NULL) { - delete pathFormula; - } - } - - /*! - * @returns the child node (representation of an abstract path formula) - */ - const FormulaType& getPathFormula () const { - return *pathFormula; - } - - /*! - * Sets the child node - * - * @param pathFormula the path formula that becomes the new child node - */ - void setPathFormula(FormulaType* pathFormula) { - this->pathFormula = pathFormula; - } - - /*! - * - * @return True if the path formula is set, i.e. it does not point to nullptr; false otherwise - */ - bool pathFormulaIsSet() const { - return pathFormula != nullptr; - } - - /*! - * @returns a string representation of the formula - */ - virtual std::string toString() const override { - std::string result; - if (this->isOptimalityOperator()) { - if (this->isMinimumOperator()) { - result += "min"; - } else { - result += "max"; - } - } - result += " = ? ["; - result += this->getPathFormula().toString(); - result += "]"; - return result; - } - - /*! - * @brief Checks if the subtree conforms to some logic. - * - * @param checker Formula checker object. - * @return true iff the subtree conforms to some logic. - */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { - return checker.validate(this->pathFormula); - } - -private: - FormulaType* pathFormula; -}; - -} //namespace abstract - -} //namespace property - -} //namespace storm - -#endif /* STORM_FORMULA_ABSTRACT_NOBOUNDOPERATOR_H_ */ diff --git a/src/formula/abstract/ProbabilisticBoundOperator.h b/src/formula/abstract/ProbabilisticBoundOperator.h deleted file mode 100644 index b326e1c05..000000000 --- a/src/formula/abstract/ProbabilisticBoundOperator.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - * ProbabilisticBoundOperator.h - * - * Created on: 19.10.2012 - * Author: Thomas Heinemann - */ - -#ifndef STORM_FORMULA_ABSTRACT_PROBABILISTICBOUNDOPERATOR_H_ -#define STORM_FORMULA_ABSTRACT_PROBABILISTICBOUNDOPERATOR_H_ - -#include "src/formula/abstract/AbstractFormula.h" -#include "src/formula/abstract/PathBoundOperator.h" -#include "src/formula/abstract/OptimizingOperator.h" -#include "utility/constants.h" - -namespace storm { -namespace property { -namespace abstract { - -/*! - * @brief - * Class for an abstract formula tree with a P (probablistic) operator node over a probability interval - * as root. - * - * Has one Abstract path formula as sub formula/tree. - * - * @par Semantics - * The formula holds iff the probability that the path formula holds is inside the bounds - * specified in this operator - * - * The subtree is seen as part of the object and deleted with it - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @tparam FormulaType The type of the subformula. - * The instantiation of FormulaType should be a subclass of AbstractFormula, as the functions - * "toString" and "conforms" of the subformulas are needed. - * - * @see AbstractFormula - * @see AbstractFormula - * @see ProbabilisticOperator - * @see ProbabilisticNoBoundsOperator - * @see AbstractFormula - */ -template<class T, class FormulaType> -class ProbabilisticBoundOperator : public PathBoundOperator<T, FormulaType> { - - // Throw a compiler error if FormulaType is not a subclass of AbstractFormula. - static_assert(std::is_base_of<AbstractFormula<T>, FormulaType>::value, - "Instantiaton of FormulaType for storm::property::abstract::ProbabilisticBoundOperator<T,FormulaType> has to be a subtype of storm::property::abstract::AbstractFormula<T>"); - -public: - /*! - * Empty constructor - */ - ProbabilisticBoundOperator() : PathBoundOperator<T, FormulaType> - (LESS_EQUAL, storm::utility::constantZero<T>(), nullptr) { - // Intentionally left empty - } - - - /*! - * Constructor - * - * @param comparisonRelation The relation to compare the actual value and the bound - * @param bound The bound for the probability - * @param pathFormula The child node - */ - ProbabilisticBoundOperator( - storm::property::ComparisonType comparisonRelation, - T bound, - FormulaType* pathFormula) - : PathBoundOperator<T, FormulaType>(comparisonRelation, bound, pathFormula) { - // Intentionally left empty - } - - /*! - * Constructor - * - * @param comparisonRelation - * @param bound - * @param pathFormula - * @param minimumOperator - */ - ProbabilisticBoundOperator( - storm::property::ComparisonType comparisonRelation, - T bound, - FormulaType* pathFormula, - bool minimumOperator) - : PathBoundOperator<T, FormulaType>(comparisonRelation, bound, pathFormula, minimumOperator){ - // Intentionally left empty - } - - /*! - * Destructor - */ - virtual ~ProbabilisticBoundOperator() { - // Intentionally left empty - } - - /*! - * @returns a string representation of the formula - */ - virtual std::string toString() const override { - std::string result = "P "; - result += PathBoundOperator<T, FormulaType>::toString(); - return result; - } -}; - -} //namespace abstract -} //namespace property -} //namespace storm - -#endif /* STORM_FORMULA_ABSTRACT_PROBABILISTICBOUNDOPERATOR_H_ */ diff --git a/src/formula/abstract/ProbabilisticNoBoundOperator.h b/src/formula/abstract/ProbabilisticNoBoundOperator.h deleted file mode 100644 index 7bf01422e..000000000 --- a/src/formula/abstract/ProbabilisticNoBoundOperator.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * ProbabilisticNoBoundOperator.h - * - * Created on: 12.12.2012 - * Author: Thomas Heinemann - */ - -#ifndef STORM_FORMULA_ABSTRACT_PROBABILISTICNOBOUNDOPERATOR_H_ -#define STORM_FORMULA_ABSTRACT_PROBABILISTICNOBOUNDOPERATOR_H_ - -#include "AbstractFormula.h" -#include "src/formula/abstract/AbstractFormula.h" -#include "PathNoBoundOperator.h" - -namespace storm { -namespace property { -namespace abstract { - -/*! - * @brief - * Class for an abstract formula tree with a P (probablistic) operator without declaration of probabilities - * as root. - * - * Checking a formula with this operator as root returns the probabilities that the path formula holds - * (for each state) - * - * Has one Abstract path formula as sub formula/tree. - * - * @note - * This class is a hybrid of a state and path formula, and may only appear as the outermost operator. - * Hence, it is seen as neither a state nor a path formula, but is directly derived from AbstractFormula. - * - * @note - * This class does not contain a check() method like the other formula classes. - * The check method should only be called by the model checker to infer the correct check function for sub - * formulas. As this operator can only appear at the root, the method is not useful here. - * Use the checkProbabilisticNoBoundOperator method from the DtmcPrctlModelChecker class instead. - * - * The subtree is seen as part of the object and deleted with it - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @tparam FormulaType The type of the subformula. - * The instantiation of FormulaType should be a subclass of AbstractFormula, as the functions - * "toString" and "conforms" of the subformulas are needed. - * - * @see AbstractFormula - * @see PathNoBoundOperator - * @see ProbabilisticBoundOperator - */ -template <class T, class FormulaType> -class ProbabilisticNoBoundOperator: public PathNoBoundOperator<T, FormulaType> { - - // Throw a compiler error if FormulaType is not a subclass of AbstractFormula. - static_assert(std::is_base_of<AbstractFormula<T>, FormulaType>::value, - "Instantiaton of FormulaType for storm::property::abstract::ProbabilisticNoBoundOperator<T,FormulaType> has to be a subtype of storm::property::abstract::AbstractFormula<T>"); - -public: - /*! - * Empty constructor - */ - ProbabilisticNoBoundOperator() : PathNoBoundOperator<T, FormulaType>(nullptr) { - // Intentionally left empty - } - - /*! - * Constructor - * - * @param pathFormula The child node. - */ - ProbabilisticNoBoundOperator(FormulaType* pathFormula) : PathNoBoundOperator<T, FormulaType>(pathFormula) { - // Intentionally left empty - } - - /*! - * Destructor - */ - virtual ~ProbabilisticNoBoundOperator() { - // Intentionally left empty - } - - /*! - * Constructor - * - * @param pathFormula The child node. - */ - ProbabilisticNoBoundOperator(FormulaType* pathFormula, bool minimumOperator) : PathNoBoundOperator<T, FormulaType>(pathFormula, minimumOperator) { - // Intentionally left empty - } - - /*! - * @returns a string representation of the formula - */ - virtual std::string toString() const override { - std::string result = "P"; - result += PathNoBoundOperator<T, FormulaType>::toString(); - return result; - } -}; - -} //namespace abstract -} //namespace property -} //namespace storm - -#endif /* STORM_FORMULA_ABSTRACT_PROBABILISTICNOBOUNDOPERATOR_H_ */ diff --git a/src/formula/abstract/RewardBoundOperator.h b/src/formula/abstract/RewardBoundOperator.h deleted file mode 100644 index 30d2f3221..000000000 --- a/src/formula/abstract/RewardBoundOperator.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * RewardBoundOperator.h - * - * Created on: 19.10.2012 - * Author: Thomas Heinemann - */ - -#ifndef STORM_FORMULA_ABSTRACT_REWARDBOUNDOPERATOR_H_ -#define STORM_FORMULA_ABSTRACT_REWARDBOUNDOPERATOR_H_ - -#include "PathBoundOperator.h" -#include "utility/constants.h" - -namespace storm { -namespace property { -namespace abstract { - -/*! - * @brief - * Class for an abstract formula tree with a R (reward) operator node over a reward interval as root. - * - * Has a reward path formula as sub formula/tree. - * - * @par Semantics - * The formula holds iff the reward of the reward path formula is inside the bounds - * specified in this operator - * - * The subtree is seen as part of the object and deleted with it - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @tparam FormulaType The type of the subformula. - * The instantiation of FormulaType should be a subclass of AbstractFormula, as the functions - * "toString" and "conforms" of the subformulas are needed. - * - * @see AbstractFormula - * @see PathBoundOperator - * @see RewardNoBoundOperator - */ -template<class T, class FormulaType> -class RewardBoundOperator : public PathBoundOperator<T, FormulaType> { - - // Throw a compiler error if FormulaType is not a subclass of AbstractFormula. - static_assert(std::is_base_of<AbstractFormula<T>, FormulaType>::value, - "Instantiaton of FormulaType for storm::property::abstract::RewardBoundOperator<T,FormulaType> has to be a subtype of storm::property::abstract::AbstractFormula<T>"); - -public: - /*! - * Empty constructor - */ - RewardBoundOperator() : PathBoundOperator<T, FormulaType>(LESS_EQUAL, storm::utility::constantZero<T>(), nullptr) { - // Intentionally left empty - } - - /*! - * Constructor - * - * @param comparisonRelation The relation to compare the actual value and the bound - * @param bound The bound for the probability - * @param pathFormula The child node - */ - RewardBoundOperator( - storm::property::ComparisonType comparisonRelation, - T bound, - FormulaType* pathFormula) : - PathBoundOperator<T, FormulaType>(comparisonRelation, bound, pathFormula) { - // Intentionally left empty - } - - /*! - * Constructor - * @param comparisonRelation - * @param bound - * @param pathFormula - * @param minimumOperator - */ - RewardBoundOperator( - storm::property::ComparisonType comparisonRelation, - T bound, - FormulaType* pathFormula, - bool minimumOperator) - : PathBoundOperator<T, FormulaType>(comparisonRelation, bound, pathFormula, minimumOperator) { - // Intentionally left empty - } - - /*! - * Destructor - */ - virtual ~RewardBoundOperator() { - // Intentionally left empty - } - - /*! - * @returns a string representation of the formula - */ - virtual std::string toString() const override { - std::string result = "R "; - result += PathBoundOperator<T, FormulaType>::toString(); - return result; - } -}; - -} //namespace abstract -} //namespace property -} //namespace storm - -#endif /* STORM_FORMULA_ABSTRACT_REWARDBOUNDOPERATOR_H_ */ diff --git a/src/formula/abstract/RewardNoBoundOperator.h b/src/formula/abstract/RewardNoBoundOperator.h deleted file mode 100644 index a147502d8..000000000 --- a/src/formula/abstract/RewardNoBoundOperator.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * RewardNoBoundOperator.h - * - * Created on: 25.12.2012 - * Author: Christian Dehnert - */ - -#ifndef STORM_FORMULA_ABSTRACT_REWARDNOBOUNDOPERATOR_H_ -#define STORM_FORMULA_ABSTRACT_REWARDNOBOUNDOPERATOR_H_ - -#include "AbstractFormula.h" -#include "PathNoBoundOperator.h" - -namespace storm { -namespace property { -namespace abstract { - -/*! - * @brief - * Class for an abstract formula tree with a R (reward) operator without declaration of reward values - * as root. - * - * Checking a formula with this operator as root returns the reward for the reward path formula for - * each state - * - * Has one formula as sub formula/tree. - * - * @note - * This class is a hybrid of a state and path formula, and may only appear as the outermost operator. - * Hence, it is seen as neither a state nor a path formula, but is directly derived from AbstractFormula. - * - * @note - * This class does not contain a check() method like the other formula classes. - * The check method should only be called by the model checker to infer the correct check function for sub - * formulas. As this operator can only appear at the root, the method is not useful here. - * Use the checkRewardNoBoundOperator method from the DtmcPrctlModelChecker class instead. - * - * The subtree is seen as part of the object and deleted with it - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @tparam FormulaType The type of the subformula. - * The instantiation of FormulaType should be a subclass of AbstractFormula, as the functions - * "toString" and "conforms" of the subformulas are needed. - * - * @see AbstractFormula - * @see PathNoBoundOperator - * @see RewardBoundOperator - */ -template <class T, class FormulaType> -class RewardNoBoundOperator: public PathNoBoundOperator<T, FormulaType> { - - // Throw a compiler error if FormulaType is not a subclass of AbstractFormula. - static_assert(std::is_base_of<AbstractFormula<T>, FormulaType>::value, - "Instantiaton of FormulaType for storm::property::abstract::RewardNoBoundOperator<T,FormulaType> has to be a subtype of storm::property::abstract::AbstractFormula<T>"); - -public: - /*! - * Empty constructor - */ - RewardNoBoundOperator() : PathNoBoundOperator<T, FormulaType>(nullptr) { - // Intentionally left empty - } - - /*! - * Constructor - * - * @param pathFormula The child node. - */ - RewardNoBoundOperator(FormulaType* pathFormula) : PathNoBoundOperator<T, FormulaType>(pathFormula) { - // Intentionally left empty - } - - /*! - * Constructor - * - * @param pathFormula The child node. - */ - RewardNoBoundOperator(FormulaType* pathFormula, bool minimumOperator) : PathNoBoundOperator<T, FormulaType>(pathFormula, minimumOperator) { - // Intentionally left empty - } - - /*! - * Destructor - */ - virtual ~RewardNoBoundOperator() { - // Intentionally left empty - } - - /*! - * @returns a string representation of the formula - */ - virtual std::string toString() const override { - std::string result = "R"; - result += PathNoBoundOperator<T, FormulaType>::toString(); - return result; - } -}; - -} //namespace abstract -} //namespace property -} //namespace storm - -#endif /* STORM_FORMULA_ABSTRACT_REWARDNOBOUNDOPERATOR_H_ */ diff --git a/src/formula/abstract/StateBoundOperator.h b/src/formula/abstract/StateBoundOperator.h deleted file mode 100644 index c274bd2b3..000000000 --- a/src/formula/abstract/StateBoundOperator.h +++ /dev/null @@ -1,174 +0,0 @@ -/* - * BoundOperator.h - * - * Created on: 27.12.2012 - * Author: Christian Dehnert - */ - -#ifndef STORM_FORMULA_ABSTRACT_STATEBOUNDOPERATOR_H_ -#define STORM_FORMULA_ABSTRACT_STATEBOUNDOPERATOR_H_ - -#include "src/formula/abstract/AbstractFormula.h" -#include "src/formula/abstract/AbstractFormula.h" -#include "src/formula/AbstractFormulaChecker.h" -#include "src/formula/ComparisonType.h" -#include "src/utility/constants.h" - -namespace storm { -namespace property { -namespace abstract { - -/*! - * @brief - * Class for an abstract formula tree with a P (probablistic) operator node over a probability interval - * as root. - * - * Has one formula as sub formula/tree. - * - * @par Semantics - * The formula holds iff the probability that the state formula holds is inside the bounds - * specified in this operator - * - * The subtree is seen as part of the object and deleted with it - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @tparam FormulaType The type of the subformula. - * The instantiation of FormulaType should be a subclass of AbstractFormula, as the functions - * "toString" and "conforms" of the subformulas are needed. - * - * @see AbstractFormula - * @see StateNoBoundOperator - */ -template<class T, class FormulaType> -class StateBoundOperator : public virtual AbstractFormula<T> { - - // Throw a compiler error if FormulaType is not a subclass of AbstractFormula. - static_assert(std::is_base_of<AbstractFormula<T>, FormulaType>::value, - "Instantiaton of FormulaType for storm::property::abstract::StateBoundOperator<T,FormulaType> has to be a subtype of storm::property::abstract::AbstractFormula<T>"); - -public: - - /*! - * Constructor - * - * @param comparisonOperator The relation for the bound. - * @param bound The bound for the probability - * @param stateFormula The child node - */ - StateBoundOperator(storm::property::ComparisonType comparisonOperator, T bound, FormulaType* stateFormula) - : comparisonOperator(comparisonOperator), bound(bound), stateFormula(stateFormula) { - // Intentionally left empty - } - - /*! - * Destructor - * - * The subtree is deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - */ - virtual ~StateBoundOperator() { - if (stateFormula != nullptr) { - delete stateFormula; - } - } - - /*! - * @returns the child node (representation of a formula) - */ - const FormulaType& getStateFormula () const { - return *stateFormula; - } - - /*! - * Sets the child node - * - * @param stateFormula the state formula that becomes the new child node - */ - void setStateFormula(FormulaType* stateFormula) { - this->stateFormula = stateFormula; - } - - /*! - * - * @return True if the state formula is set, i.e. it does not point to nullptr; false otherwise - */ - bool stateFormulaIsSet() const { - return stateFormula != nullptr; - } - - /*! - * @returns the comparison relation - */ - const ComparisonType getComparisonOperator() const { - return comparisonOperator; - } - - void setComparisonOperator(ComparisonType comparisonOperator) { - this->comparisonOperator = comparisonOperator; - } - - /*! - * @returns the bound for the measure - */ - const T& getBound() const { - return bound; - } - - /*! - * Sets the interval in which the probability that the path formula holds may lie in. - * - * @param bound The bound for the measure - */ - void setBound(T bound) { - this->bound = bound; - } - - /*! - * @returns a string representation of the formula - */ - virtual std::string toString() const override { - std::string result = " "; - switch (comparisonOperator) { - case LESS: result += "< "; break; - case LESS_EQUAL: result += "<= "; break; - case GREATER: result += "> "; break; - case GREATER_EQUAL: result += ">= "; break; - } - result += std::to_string(bound); - result += " ["; - result += stateFormula->toString(); - result += "]"; - return result; - } - - bool meetsBound(T value) const { - switch (comparisonOperator) { - case LESS: return value < bound; break; - case LESS_EQUAL: return value <= bound; break; - case GREATER: return value > bound; break; - case GREATER_EQUAL: return value >= bound; break; - default: return false; - } - } - - /*! - * @brief Checks if the subtree conforms to some logic. - * - * @param checker Formula checker object. - * @return true iff the subtree conforms to some logic. - */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { - return checker.validate(this->stateFormula); - } - -private: - ComparisonType comparisonOperator; - T bound; - FormulaType* stateFormula; -}; - -} //namespace abstract -} //namespace property -} //namespace storm - -#endif /* STORM_FORMULA_ABSTRACT_STATEBOUNDOPERATOR_H_ */ diff --git a/src/formula/abstract/StateNoBoundOperator.h b/src/formula/abstract/StateNoBoundOperator.h deleted file mode 100644 index 4780f2587..000000000 --- a/src/formula/abstract/StateNoBoundOperator.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - * StateNoBoundOperator.h - * - * Created on: 09.04.2013 - * Author: Thomas Heinemann - */ - -#ifndef STORM_FORMULA_ABSTRACT_STATENOBOUNDOPERATOR_H_ -#define STORM_FORMULA_ABSTRACT_STATENOBOUNDOPERATOR_H_ - -#include "AbstractFormula.h" -#include "src/formula/AbstractFormulaChecker.h" - - -namespace storm { -namespace property { -namespace abstract { - -/*! - * @brief - * Class for an abstract formula tree with an operator without declaration of bounds. - * as root. - * - * Checking a formula with this operator as root returns the probabilities that the path formula holds - * (for each state) - * - * Has one formula as sub formula/tree. - * - * @note - * This class is a hybrid of a state and path formula, and may only appear as the outermost operator. - * Hence, it is seen as neither a state nor a path formula, but is directly derived from AbstractFormula. - * - * @note - * This class does not contain a check() method like the other formula classes. - * The check method should only be called by the model checker to infer the correct check function for sub - * formulas. As this operator can only appear at the root, the method is not useful here. - * Use the checkProbabilisticNoBoundOperator method from the DtmcPrctlModelChecker class instead. - * - * The subtree is seen as part of the object and deleted with it - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @tparam FormulaType The type of the subformula. - * The instantiation of FormulaType should be a subclass of AbstractFormula, as the functions - * "toString" and "conforms" of the subformulas are needed. - * - * @see AbstractFormula - * @see StateBoundOperator - */ -template <class T, class FormulaType> -class StateNoBoundOperator: public virtual AbstractFormula<T>, public OptimizingOperator { - - // Throw a compiler error if FormulaType is not a subclass of AbstractFormula. - static_assert(std::is_base_of<AbstractFormula<T>, FormulaType>::value, - "Instantiaton of FormulaType for storm::property::abstract::StateNoBoundOperator<T,FormulaType> has to be a subtype of storm::property::abstract::AbstractFormula<T>"); - -public: - /*! - * Empty constructor - */ - StateNoBoundOperator() { - stateFormula = nullptr; - } - - /*! - * Constructor - */ - StateNoBoundOperator(FormulaType* stateFormula) { - this->stateFormula = stateFormula; - } - - /*! - * Destructor - * - * Deletes the subtree - */ - virtual ~StateNoBoundOperator() { - if (stateFormula != nullptr) { - delete stateFormula; - } - } - - const FormulaType& getStateFormula() const { - return *(this->stateFormula); - } - - void setStateFormula(FormulaType* stateFormula) { - this->stateFormula = stateFormula; - } - - /*! - * - * @return True if the state formula is set, i.e. it does not point to nullptr; false otherwise - */ - bool stateFormulaIsSet() const { - return stateFormula != nullptr; - } - - /*! - * @returns a string representation of the formula - */ - virtual std::string toString() const override { - std::string result; - result += " = ? ["; - result += this->getStateFormula().toString(); - result += "]"; - return result; - } - - /*! - * @brief Checks if the subtree conforms to some logic. - * - * @param checker Formula checker object. - * @return true iff the subtree conforms to some logic. - */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { - return checker.validate(this->stateFormula); - } - -private: - FormulaType* stateFormula; -}; - -} //namespace abstract -} //namespace property -} //namespace storm -#endif /* STORM_FORMULA_ABSTRACT_STATENOBOUNDOPERATOR_H_ */ diff --git a/src/formula/abstract/SteadyStateBoundOperator.h b/src/formula/abstract/SteadyStateBoundOperator.h deleted file mode 100644 index a25e7d280..000000000 --- a/src/formula/abstract/SteadyStateBoundOperator.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * SteadyState.h - * - * Created on: 19.10.2012 - * Author: Thomas Heinemann - */ - -#ifndef STORM_FORMULA_ABSTRACT_STEADYSTATEOPERATOR_H_ -#define STORM_FORMULA_ABSTRACT_STEADYSTATEOPERATOR_H_ - -#include "StateBoundOperator.h" -#include "src/formula/AbstractFormulaChecker.h" - -namespace storm { -namespace property { -namespace abstract { - -/*! - * @brief - * Class for an Abstract (path) formula tree with a SteadyStateOperator node as root. - * - * Has two formulas as sub formulas/trees. - * - * @par Semantics - * The formula holds iff \e child holds SteadyStateOperator step, \e child holds - * - * The subtree is seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @see AbstractFormula - */ -template <class T, class FormulaType> -class SteadyStateBoundOperator : public StateBoundOperator<T, FormulaType> { - - // Throw a compiler error if FormulaType is not a subclass of AbstractFormula. - static_assert(std::is_base_of<AbstractFormula<T>, FormulaType>::value, - "Instantiaton of FormulaType for storm::property::abstract::SteadyStateBoundOperator<T,FormulaType> has to be a subtype of storm::property::abstract::AbstractFormula<T>"); - -public: - /*! - * Empty constructor - */ - SteadyStateBoundOperator() : StateBoundOperator<T, FormulaType> - (LESS_EQUAL, storm::utility::constantZero<T>(), nullptr) { - // Intentionally left empty - } - - /*! - * Constructor - * - * @param stateFormula The child node - */ - SteadyStateBoundOperator( - storm::property::ComparisonType comparisonRelation, T bound, FormulaType* stateFormula) : - StateBoundOperator<T, FormulaType>(comparisonRelation, bound, stateFormula) { - } - - /*! - * Destructor - */ - virtual ~SteadyStateBoundOperator() { - // Intentionally left empty - } - - /*! - * @returns a string representation of the formula - */ - virtual std::string toString() const override { - return "S" + StateBoundOperator<T, FormulaType>::toString(); - } -}; - -} //namespace abstract -} //namespace property -} //namespace storm - -#endif /* STORM_FORMULA_ABSTRACT_STEADYSTATEOPERATOR_H_ */ diff --git a/src/formula/abstract/SteadyStateNoBoundOperator.h b/src/formula/abstract/SteadyStateNoBoundOperator.h deleted file mode 100644 index 6e544d207..000000000 --- a/src/formula/abstract/SteadyStateNoBoundOperator.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * SteadyStateNoBoundOperator.h - * - * Created on: 09.04.2013 - * Author: thomas - */ - -#ifndef STORM_FORMULA_ABSTRACT_STEADYSTATENOBOUNDOPERATOR_H_ -#define STORM_FORMULA_ABSTRACT_STEADYSTATENOBOUNDOPERATOR_H_ - -#include "StateNoBoundOperator.h" - -namespace storm { -namespace property { -namespace abstract { - -/*! - * @brief - * Class for an abstract formula tree with a steady state operator as root, without explicit declaration of bounds. - * - * Checking a formula with this operator as root returns the exact bound parameter for the corresponding subformula. - * (for each state) - * - * Has one formula as sub formula/tree. - * - * @tparam FormulaType The type of the subformula. - * The instantiation of FormulaType should be a subclass of AbstractFormula, as the functions - * "toString" and "conforms" of the subformulas are needed. - */ -template <class T, class FormulaType> -class SteadyStateNoBoundOperator: public StateNoBoundOperator<T, FormulaType> { - - // Throw a compiler error if FormulaType is not a subclass of AbstractFormula. - static_assert(std::is_base_of<AbstractFormula<T>, FormulaType>::value, - "Instantiaton of FormulaType for storm::property::abstract::SteadyStateNoBoundOperator<T,FormulaType> has to be a subtype of storm::property::abstract::AbstractFormula<T>"); - -public: - /*! - * Empty constructor - */ - SteadyStateNoBoundOperator() : StateNoBoundOperator<T, FormulaType>() { - // Intentionally left empty - - } - - /*! - * Constructor - * - * @param stateFormula The state formula that forms the subtree - */ - SteadyStateNoBoundOperator(FormulaType* stateFormula) - : StateNoBoundOperator<T, FormulaType>(stateFormula) { - // Intentionally left empty - } - - /*! - * Destructor - */ - virtual ~SteadyStateNoBoundOperator() { - // Intentionally left empty - } - - /*! - * @returns a string representation of the formula - */ - virtual std::string toString() const override { - return "S" + StateNoBoundOperator<T, FormulaType>::toString(); - } - -}; - -} /* namespace abstract */ -} /* namespace property */ -} /* namespace storm */ - -#endif /* STORM_FORMULA_ABSTRACT_STEADYSTATENOBOUNDOPERATOR_H_ */ diff --git a/src/formula/abstract/SteadyStateReward.h b/src/formula/abstract/SteadyStateReward.h deleted file mode 100644 index d5f344752..000000000 --- a/src/formula/abstract/SteadyStateReward.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * SteadyStateReward.h - * - * Created on: 08.04.2013 - * Author: Thomas Heinemann - */ - -#ifndef STORM_FORMULA_ABSTRACT_STEADYSTATEREWARD_H_ -#define STORM_FORMULA_ABSTRACT_STEADYSTATEREWARD_H_ - -#include "AbstractFormula.h" -#include "src/formula/AbstractFormulaChecker.h" -#include <string> - -namespace storm { -namespace property { -namespace abstract { - -/*! - * @brief - * Class for an abstract (path) formula tree with a Steady State Reward node as root. - * - * @see AbstractFormula - */ -template <class T> -class SteadyStateReward: public virtual AbstractFormula<T> { -public: - /*! - * Empty constructor - */ - SteadyStateReward() { - // Intentionally left empty - - } - virtual ~SteadyStateReward() { - // Intentionally left empty - } - - /*! - * @returns a string representation of the formula - */ - virtual std::string toString() const override { - return "S"; - } - - /*! - * @brief Checks if all subtrees conform to some logic. - * - * As SteadyStateReward objects have no subformulas, we return true here. - * - * @param checker Formula checker object. - * @return true - */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { - return true; - } -}; - -} //namespace abstract -} //namespace property -} //namespace storm -#endif /* STORM_FORMULA_ABSTRACT_STEADYSTATEREWARD_H_ */ diff --git a/src/formula/abstract/TimeBoundedEventually.h b/src/formula/abstract/TimeBoundedEventually.h deleted file mode 100644 index eaecaa868..000000000 --- a/src/formula/abstract/TimeBoundedEventually.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - * TimeBoundedEventually.h - * - * Created on: 10.04.2013 - * Author: thomas - */ - -#ifndef STORM_FORMULA_ABSTRACT_TIMEBOUNDEDEVENTUALLY_H_ -#define STORM_FORMULA_ABSTRACT_TIMEBOUNDEDEVENTUALLY_H_ - -#include "TimeBoundedOperator.h" - -namespace storm { -namespace property { -namespace abstract { - -/*! - * Class for a formula tree with a time bounded eventually operator as root. - * - * Has two subformulas. - * - * @tparam FormulaType The type of the subformula. - * The instantiation of FormulaType should be a subclass of AbstractFormula, as the functions - * "toString" and "conforms" of the subformulas are needed. - */ -template<class T, class FormulaType> -class TimeBoundedEventually: public storm::property::abstract::TimeBoundedOperator<T> { - - // Throw a compiler error if FormulaType is not a subclass of AbstractFormula. - static_assert(std::is_base_of<AbstractFormula<T>, FormulaType>::value, - "Instantiaton of FormulaType for storm::property::abstract::TimeBoundedEventually<T,FormulaType> has to be a subtype of storm::property::abstract::AbstractFormula<T>"); - -public: - /** - * Simple constructor: Only sets the bounds - * - * @param lowerBound - * @param upperBound - */ - TimeBoundedEventually(T lowerBound, T upperBound) : TimeBoundedOperator<T>(lowerBound, upperBound) { - child = nullptr; - } - - TimeBoundedEventually(T lowerBound, T upperBound, FormulaType* child) : - TimeBoundedOperator<T>(lowerBound, upperBound) { - this->child = child; - } - - virtual ~TimeBoundedEventually() { - if (child != nullptr) { - delete child; - } - } - - /*! - * @returns the child node - */ - const FormulaType& getChild() const { - return *child; - } - - /*! - * Sets the subtree - * @param child the new child node - */ - void setChild(FormulaType* child) { - this->child = child; - } - - /*! - * - * @return True if the child is set, i.e. it does not point to nullptr; false otherwise - */ - bool childIsSet() const { - return child != nullptr; - } - - /*! - * @returns a string representation of the formula - */ - virtual std::string toString() const override { - std::string result = "F"; - result += TimeBoundedOperator<T>::toString(); - result += " "; - result += child->toString(); - return result; - } - - /*! - * @brief Checks if the subtree conforms to some logic. - * - * @param checker Formula checker object. - * @return true iff the subtree conforms to some logic. - */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { - return checker.validate(this->child); - } - -private: - FormulaType* child; -}; - -} /* namespace abstract */ -} /* namespace property */ -} /* namespace storm */ - -#endif /* STORM_FORMULA_ABSTRACT_TIMEBOUNDEDEVENTUALLY_H_ */ diff --git a/src/formula/abstract/TimeBoundedOperator.h b/src/formula/abstract/TimeBoundedOperator.h deleted file mode 100644 index d26fea552..000000000 --- a/src/formula/abstract/TimeBoundedOperator.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * TimeBoundedOperator.h - * - * Created on: 10.04.2013 - * Author: thomas - */ - -#ifndef STORM_FORMULA_ABSTRACT_TIMEBOUNDEDOPERATOR_H_ -#define STORM_FORMULA_ABSTRACT_TIMEBOUNDEDOPERATOR_H_ - -#include <limits> - -#include "src/formula/abstract/AbstractFormula.h" -#include "exceptions/InvalidArgumentException.h" - -namespace storm { -namespace property { -namespace abstract { - -/*! - * @brief - * Class for an abstract formula tree with a operator node as root that uses a time interval - * (with upper and lower bound) - * - * This class does not provide support for sub formulas; this has to be done in concrete subclasses of this abstract class. - * - * - * @see AbstractFormula - * @see AbstractFormula - * @see AbstractFormula - */ -template<class T> -class TimeBoundedOperator: public virtual AbstractFormula<T> { -public: - /** - * Constructor - * - * @param lowerBound The lower bound - * @param upperBound The upper bound - * @throw InvalidArgumentException if the lower bound is larger than the upper bound. - */ - TimeBoundedOperator(T lowerBound, T upperBound) { - setInterval(lowerBound, upperBound); - } - - /** - * Destructor - */ - virtual ~TimeBoundedOperator() { - // Intentionally left empty - } - - /** - * Getter for lowerBound attribute - * - * @return lower bound of the operator. - */ - T getLowerBound() const { - return lowerBound; - } - - /** - * Getter for upperBound attribute - * @return upper bound of the operator. - */ - T getUpperBound() const { - return upperBound; - } - - /** - * Set the time interval for the time bounded operator - * - * @param lowerBound - * @param upperBound - * @throw InvalidArgumentException if the lower bound is larger than the upper bound. - */ - void setInterval(T lowerBound, T upperBound) { - if (lowerBound > upperBound) { - throw new storm::exceptions::InvalidArgumentException("Lower bound is larger than upper bound"); - } - this->lowerBound = lowerBound; - this->upperBound = upperBound; - } - - - /*! - * @returns a string representation of the Interval of the formula - * May be used in subclasses to simplify string output. - */ - virtual std::string toString() const override { - std::string result = ""; - if (upperBound == std::numeric_limits<double>::infinity()) { - result = ">=" + std::to_string(lowerBound); - } else { - result = "["; - result += std::to_string(lowerBound); - result += ","; - result += std::to_string(upperBound); - result += "]"; - } - return result; - } - -private: - T lowerBound, upperBound; -}; - -} //namespace abstract -} //namespace property -} //namespace storm - -#endif /* STORM_FORMULA_ABSTRACT_TIMEBOUNDEDOPERATOR_H_ */ diff --git a/src/formula/abstract/TimeBoundedUntil.h b/src/formula/abstract/TimeBoundedUntil.h deleted file mode 100644 index 936baeef4..000000000 --- a/src/formula/abstract/TimeBoundedUntil.h +++ /dev/null @@ -1,149 +0,0 @@ -/* - * TimeBoundedUntil.h - * - * Created on: 10.04.2013 - * Author: thomas - */ - -#ifndef STORM_FORMULA_ABSTRACT_TIMEBOUNDEDUNTIL_H_ -#define STORM_FORMULA_ABSTRACT_TIMEBOUNDEDUNTIL_H_ - -#include "TimeBoundedOperator.h" - -namespace storm { -namespace property { -namespace abstract { - - -/** - * @brief - * Class for an abstract formula tree with an time bounded until operator as root. - * - * @tparam FormulaType The type of the subformula. - * The instantiation of FormulaType should be a subclass of AbstractFormula, as the functions - * "toString" and "conforms" of the subformulas are needed. - */ -template <class T, class FormulaType> -class TimeBoundedUntil: public TimeBoundedOperator<T> { - - // Throw a compiler error if FormulaType is not a subclass of AbstractFormula. - static_assert(std::is_base_of<AbstractFormula<T>, FormulaType>::value, - "Instantiaton of FormulaType for storm::property::abstract::TimeBoundedUntil<T,FormulaType> has to be a subtype of storm::property::abstract::AbstractFormula<T>"); - -public: - /** - * Constructor providing bounds only; - * Sub formulas are set to null. - * - * @param lowerBound - * @param upperBound - */ - TimeBoundedUntil(T lowerBound, T upperBound) : - TimeBoundedOperator<T>(lowerBound, upperBound) { - this->left = nullptr; - this->right = nullptr; - } - - - /** - * Full constructor - * @param lowerBound - * @param upperBound - * @param left - * @param right - */ - TimeBoundedUntil(T lowerBound, T upperBound, FormulaType* left, FormulaType* right) : - TimeBoundedOperator<T>(lowerBound, upperBound) { - this->left = left; - this->right = right; - } - - virtual ~TimeBoundedUntil() { - if (left != nullptr) { - delete left; - } - if (right != nullptr) { - delete right; - } - } - - /*! - * Sets the left child node. - * - * @param newLeft the new left child. - */ - void setLeft(FormulaType* newLeft) { - left = newLeft; - } - - /*! - * Sets the right child node. - * - * @param newRight the new right child. - */ - void setRight(FormulaType* newRight) { - right = newRight; - } - - /*! - * @returns a pointer to the left child node - */ - const FormulaType& getLeft() const { - return *left; - } - - /*! - * @returns a pointer to the right child node - */ - const FormulaType& getRight() const { - return *right; - } - - /*! - * - * @return True if the left child is set, i.e. it does not point to nullptr; false otherwise - */ - bool leftIsSet() const { - return left != nullptr; - } - - /*! - * - * @return True if the right child is set, i.e. it does not point to nullptr; false otherwise - */ - bool rightIsSet() const { - return right != nullptr; - } - - /*! - * @returns a string representation of the formula - */ - virtual std::string toString() const override { - std::string result = left->toString(); - result += " U"; - result += TimeBoundedOperator<T>::toString(); - result += " "; - result += right->toString(); - return result; - } - - /*! - * @brief Checks if the subtree conforms to some logic. - * - * @param checker Formula checker object. - * @return true iff the subtree conforms to some logic. - */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { - return checker.validate(this->left) && checker.validate(this->right); - } - -private: - FormulaType* left; - FormulaType* right; -}; - -} /* namespace abstract */ -} /* namespace property */ -} /* namespace storm */ - -#endif /* STORM_FORMULA_ABSTRACT_TIMEBOUNDEDUNTIL_H_ */ diff --git a/src/formula/abstract/Until.h b/src/formula/abstract/Until.h deleted file mode 100644 index dd093de88..000000000 --- a/src/formula/abstract/Until.h +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Until.h - * - * Created on: 19.10.2012 - * Author: Thomas Heinemann - */ - -#ifndef STORM_FORMULA_ABSTRACT_UNTIL_H_ -#define STORM_FORMULA_ABSTRACT_UNTIL_H_ - -#include "src/formula/abstract/AbstractFormula.h" -#include "src/formula/abstract/AbstractFormula.h" -#include "src/formula/AbstractFormulaChecker.h" - -namespace storm { -namespace property { -namespace abstract { - -/*! - * @brief - * Class for an abstract (path) formula tree with an Until node as root. - * - * Has two formulas as sub formulas/trees. - * - * @par Semantics - * The formula holds iff eventually, formula \e right (the right subtree) holds, and before, - * \e left holds always. - * - * The subtrees are seen as part of the object and deleted with the object - * (this behavior can be prevented by setting them to NULL before deletion) - * - * @tparam FormulaType The type of the subformula. - * The instantiation of FormulaType should be a subclass of AbstractFormula, as the functions - * "toString" and "conforms" of the subformulas are needed. - * - * @see AbstractFormula - */ -template <class T, class FormulaType> -class Until : public virtual AbstractFormula<T> { - - // Throw a compiler error if FormulaType is not a subclass of AbstractFormula. - static_assert(std::is_base_of<AbstractFormula<T>, FormulaType>::value, - "Instantiaton of FormulaType for storm::property::abstract::Until<T,FormulaType> has to be a subtype of storm::property::abstract::AbstractFormula<T>"); - -public: - /*! - * Empty constructor - */ - Until() { - this->left = NULL; - this->right = NULL; - } - - /*! - * Constructor - * - * @param left The left formula subtree - * @param right The left formula subtree - */ - Until(FormulaType* left, FormulaType* right) { - this->left = left; - this->right = right; - } - - /*! - * Destructor. - * - * Also deletes the subtrees. - * (this behaviour can be prevented by setting the subtrees to NULL before deletion) - */ - virtual ~Until() { - if (left != NULL) { - delete left; - } - if (right != NULL) { - delete right; - } - } - - /*! - * Sets the left child node. - * - * @param newLeft the new left child. - */ - void setLeft(FormulaType* newLeft) { - left = newLeft; - } - - /*! - * Sets the right child node. - * - * @param newRight the new right child. - */ - void setRight(FormulaType* newRight) { - right = newRight; - } - - /*! - * @returns a pointer to the left child node - */ - const FormulaType& getLeft() const { - return *left; - } - - /*! - * @returns a pointer to the right child node - */ - const FormulaType& getRight() const { - return *right; - } - - /*! - * - * @return True if the left child is set, i.e. it does not point to nullptr; false otherwise - */ - bool leftIsSet() const { - return left != nullptr; - } - - /*! - * - * @return True if the right child is set, i.e. it does not point to nullptr; false otherwise - */ - bool rightIsSet() const { - return right != nullptr; - } - - /*! - * @returns a string representation of the formula - */ - virtual std::string toString() const override { - std::string result = left->toString(); - result += " U "; - result += right->toString(); - return result; - } - - /*! - * @brief Checks if all subtrees conform to some logic. - * - * @param checker Formula checker object. - * @return true iff all subtrees conform to some logic. - */ - virtual bool validate(const AbstractFormulaChecker<T>& checker) const override { - return checker.validate(this->left) && checker.validate(this->right); - } - -private: - FormulaType* left; - FormulaType* right; -}; - -} //namespace abstract - -} //namespace property - -} //namespace storm - -#endif /* STORM_FORMULA_ABSTRACT_UNTIL_H_ */ diff --git a/src/modelchecker/csl/AbstractModelChecker.h b/src/modelchecker/csl/AbstractModelChecker.h index d1d3bc1dc..e2c68e740 100644 --- a/src/modelchecker/csl/AbstractModelChecker.h +++ b/src/modelchecker/csl/AbstractModelChecker.h @@ -8,8 +8,9 @@ #ifndef STORM_MODELCHECKER_CSL_ABSTRACTMODELCHECKER_H_ #define STORM_MODELCHECKER_CSL_ABSTRACTMODELCHECKER_H_ +#include <stack> #include "src/exceptions/InvalidPropertyException.h" -#include "src/formula/Csl.h" +#include "src/properties/Csl.h" #include "src/storage/BitVector.h" #include "src/models/AbstractModel.h" @@ -36,31 +37,30 @@ template<class Type> class AbstractModelChecker : // A list of interfaces the model checker supports. Typically, for each of the interfaces, a check method needs to // be implemented that performs the corresponding check. - public virtual storm::property::csl::IApModelChecker<Type>, - public virtual storm::property::csl::IAndModelChecker<Type>, - public virtual storm::property::csl::IOrModelChecker<Type>, - public virtual storm::property::csl::INotModelChecker<Type>, - public virtual storm::property::csl::IUntilModelChecker<Type>, - public virtual storm::property::csl::IEventuallyModelChecker<Type>, - public virtual storm::property::csl::IGloballyModelChecker<Type>, - public virtual storm::property::csl::INextModelChecker<Type>, - public virtual storm::property::csl::ITimeBoundedUntilModelChecker<Type>, - public virtual storm::property::csl::ITimeBoundedEventuallyModelChecker<Type>, - public virtual storm::property::csl::INoBoundOperatorModelChecker<Type>, - public virtual storm::property::csl::IProbabilisticBoundOperatorModelChecker<Type> { + public virtual storm::properties::csl::IApModelChecker<Type>, + public virtual storm::properties::csl::IAndModelChecker<Type>, + public virtual storm::properties::csl::IOrModelChecker<Type>, + public virtual storm::properties::csl::INotModelChecker<Type>, + public virtual storm::properties::csl::IUntilModelChecker<Type>, + public virtual storm::properties::csl::IEventuallyModelChecker<Type>, + public virtual storm::properties::csl::IGloballyModelChecker<Type>, + public virtual storm::properties::csl::INextModelChecker<Type>, + public virtual storm::properties::csl::ITimeBoundedUntilModelChecker<Type>, + public virtual storm::properties::csl::ITimeBoundedEventuallyModelChecker<Type>, + public virtual storm::properties::csl::IProbabilisticBoundOperatorModelChecker<Type> { public: /*! * Constructs an AbstractModelChecker with the given model. */ - explicit AbstractModelChecker(storm::models::AbstractModel<Type> const& model) : model(model) { + explicit AbstractModelChecker(storm::models::AbstractModel<Type> const& model) : minimumOperatorStack(), model(model) { // Intentionally left empty. } /*! * Copy constructs an AbstractModelChecker from the given model checker. In particular, this means that the newly * constructed model checker will have the model of the given model checker as its associated model. */ - explicit AbstractModelChecker(AbstractModelChecker<Type> const& modelchecker) : model(modelchecker.model) { + explicit AbstractModelChecker(AbstractModelChecker<Type> const& modelchecker) : minimumOperatorStack(), model(modelchecker.model) { // Intentionally left empty. } @@ -106,78 +106,13 @@ public: } } - /*! - * Checks the given abstract prctl formula on the model and prints the result (depending on the actual type of the formula) - * for all initial states, i.e. states that carry the atomic proposition "init". - * - * @param formula The formula to be checked. - */ - void check(storm::property::csl::AbstractCslFormula<Type> const& formula) const { - if (dynamic_cast<storm::property::csl::AbstractStateFormula<Type> const*>(&formula) != nullptr) { - this->check(static_cast<storm::property::csl::AbstractStateFormula<Type> const&>(formula)); - } else if (dynamic_cast<storm::property::csl::AbstractNoBoundOperator<Type> const*>(&formula) != nullptr) { - this->check(static_cast<storm::property::csl::AbstractNoBoundOperator<Type> const&>(formula)); - } - } - - /*! - * Checks the given state formula on the model and prints the result (true/false) for all initial states, i.e. - * states that carry the atomic proposition "init". - * - * @param stateFormula The formula to be checked. - */ - void check(storm::property::csl::AbstractStateFormula<Type> const& stateFormula) const { - std::cout << std::endl; - LOG4CPLUS_INFO(logger, "Model checking formula\t" << stateFormula.toString()); - std::cout << "Model checking formula:\t" << stateFormula.toString() << std::endl; - storm::storage::BitVector result; - try { - result = stateFormula.check(*this); - LOG4CPLUS_INFO(logger, "Result for initial states:"); - std::cout << "Result for initial states:" << std::endl; - for (auto initialState : model.getInitialStates()) { - LOG4CPLUS_INFO(logger, "\t" << initialState << ": " << (result.get(initialState) ? "satisfied" : "not satisfied")); - std::cout << "\t" << initialState << ": " << result.get(initialState) << std::endl; - } - } catch (std::exception& e) { - std::cout << "Error during computation: " << e.what() << "Skipping property." << std::endl; - LOG4CPLUS_ERROR(logger, "Error during computation: " << e.what() << "Skipping property."); - } - std::cout << std::endl << "-------------------------------------------" << std::endl; - } - - /*! - * Checks the given formula (with no bound) on the model and prints the result (probability/rewards) for all - * initial states, i.e. states that carry the atomic proposition "init". - * - * @param noBoundFormula The formula to be checked. - */ - void check(storm::property::csl::AbstractNoBoundOperator<Type> const& noBoundFormula) const { - std::cout << std::endl; - LOG4CPLUS_INFO(logger, "Model checking formula\t" << noBoundFormula.toString()); - std::cout << "Model checking formula:\t" << noBoundFormula.toString() << std::endl; - std::vector<Type> result; - try { - result = this->checkNoBoundOperator(noBoundFormula); - LOG4CPLUS_INFO(logger, "Result for initial states:"); - std::cout << "Result for initial states:" << std::endl; - for (auto initialState : model.getInitialStates()) { - LOG4CPLUS_INFO(logger, "\t" << initialState << ": " << (*result)[initialState]); - std::cout << "\t" << initialState << ": " << (*result)[initialState] << std::endl; - } - } catch (std::exception& e) { - std::cout << "Error during computation: " << e.what() << " Skipping property." << std::endl; - } - std::cout << std::endl << "-------------------------------------------" << std::endl; - } - /*! * Checks the given formula consisting of a single atomic proposition. * * @param formula The formula to be checked. * @returns The set of states satisfying the formula represented by a bit vector. */ - storm::storage::BitVector checkAp(storm::property::csl::Ap<Type> const& formula) const { + storm::storage::BitVector checkAp(storm::properties::csl::Ap<Type> const& formula) const { if (formula.getAp() == "true") { return storm::storage::BitVector(model.getNumberOfStates(), true); } else if (formula.getAp() == "false") { @@ -198,9 +133,9 @@ public: * @param formula The formula to be checked. * @returns The set of states satisfying the formula represented by a bit vector. */ - storm::storage::BitVector checkAnd(storm::property::csl::And<Type> const& formula) const { - storm::storage::BitVector result = formula.getLeft().check(*this); - storm::storage::BitVector right = formula.getRight().check(*this); + storm::storage::BitVector checkAnd(storm::properties::csl::And<Type> const& formula) const { + storm::storage::BitVector result = formula.getLeft()->check(*this); + storm::storage::BitVector right = formula.getRight()->check(*this); result &= right; return result; } @@ -211,9 +146,9 @@ public: * @param formula The formula to check. * @returns The set of states satisfying the formula represented by a bit vector. */ - storm::storage::BitVector checkOr(storm::property::csl::Or<Type> const& formula) const { - storm::storage::BitVector result = formula.getLeft().check(*this); - storm::storage::BitVector right = formula.getRight().check(*this); + storm::storage::BitVector checkOr(storm::properties::csl::Or<Type> const& formula) const { + storm::storage::BitVector result = formula.getLeft()->check(*this); + storm::storage::BitVector right = formula.getRight()->check(*this); result |= right; return result; } @@ -224,8 +159,8 @@ public: * @param formula The formula to check. * @returns The set of states satisfying the formula represented by a bit vector. */ - storm::storage::BitVector checkNot(const storm::property::csl::Not<Type>& formula) const { - storm::storage::BitVector result = formula.getChild().check(*this); + storm::storage::BitVector checkNot(const storm::properties::csl::Not<Type>& formula) const { + storm::storage::BitVector result = formula.getChild()->check(*this); result.complement(); return result; } @@ -237,9 +172,9 @@ public: * @param formula The formula to check. * @returns The set of states satisfying the formula represented by a bit vector. */ - storm::storage::BitVector checkProbabilisticBoundOperator(storm::property::csl::ProbabilisticBoundOperator<Type> const& formula) const { + virtual storm::storage::BitVector checkProbabilisticBoundOperator(storm::properties::csl::ProbabilisticBoundOperator<Type> const& formula) const { // First, we need to compute the probability for satisfying the path formula for each state. - std::vector<Type> quantitativeResult = formula.getPathFormula().check(*this, false); + std::vector<Type> quantitativeResult = formula.getChild()->check(*this, false); // Create resulting bit vector that will hold the yes/no-answer for every state. storm::storage::BitVector result(quantitativeResult.size()); @@ -255,6 +190,42 @@ public: return result; } + /*! + * Checks the given formula and determines whether minimum or maximum probabilities or rewards are to be computed for the formula. + * + * @param formula The formula to check. + * @param minimumOperator True iff minimum probabilities/rewards are to be computed. + * @returns The probabilities to satisfy the formula or the rewards accumulated by it, represented by a vector. + */ + virtual std::vector<Type> checkMinMaxOperator(storm::properties::csl::AbstractPathFormula<Type> const & formula, bool minimumOperator) const { + minimumOperatorStack.push(minimumOperator); + std::vector<Type> result = formula.check(*this, false); + minimumOperatorStack.pop(); + return result; + } + + /*! + * Checks the given formula and determines whether minimum or maximum probabilities or rewards are to be computed for the formula. + * + * @param formula The formula to check. + * @param minimumOperator True iff minimum probabilities/rewards are to be computed. + * @returns The set of states satisfying the formula represented by a bit vector. + */ + virtual storm::storage::BitVector checkMinMaxOperator(storm::properties::csl::AbstractStateFormula<Type> const & formula, bool minimumOperator) const { + minimumOperatorStack.push(minimumOperator); + storm::storage::BitVector result = formula.check(*this); + minimumOperatorStack.pop(); + return result; + } + +protected: + + /*! + * A stack used for storing whether we are currently computing min or max probabilities or rewards, respectively. + * The topmost element is true if and only if we are currently computing minimum probabilities or rewards. + */ + mutable std::stack<bool> minimumOperatorStack; + private: /*! @@ -270,4 +241,4 @@ private: } // namespace modelchecker } // namespace storm -#endif /* STORM_MODELCHECKER_CSL_DTMCPRCTLMODELCHECKER_H_ */ +#endif /* STORM_MODELCHECKER_CSL_ABSTRACTMODELCHECKER_H_ */ diff --git a/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h b/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h index e634ad597..fc1138b21 100644 --- a/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h +++ b/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h @@ -1,7 +1,6 @@ #ifndef STORM_MODELCHECKER_CSL_SPARSEMARKOVAUTOMATONCSLMODELCHECKER_H_ #define STORM_MODELCHECKER_CSL_SPARSEMARKOVAUTOMATONCSLMODELCHECKER_H_ -#include <stack> #include <utility> #include "src/modelchecker/csl/AbstractModelChecker.h" @@ -22,7 +21,7 @@ namespace storm { template<typename ValueType> class SparseMarkovAutomatonCslModelChecker : public AbstractModelChecker<ValueType> { public: - explicit SparseMarkovAutomatonCslModelChecker(storm::models::MarkovAutomaton<ValueType> const& model, std::shared_ptr<storm::solver::NondeterministicLinearEquationSolver<ValueType>> nondeterministicLinearEquationSolver) : AbstractModelChecker<ValueType>(model), minimumOperatorStack(), nondeterministicLinearEquationSolver(nondeterministicLinearEquationSolver) { + explicit SparseMarkovAutomatonCslModelChecker(storm::models::MarkovAutomaton<ValueType> const& model, std::shared_ptr<storm::solver::NondeterministicLinearEquationSolver<ValueType>> nondeterministicLinearEquationSolver) : AbstractModelChecker<ValueType>(model), nondeterministicLinearEquationSolver(nondeterministicLinearEquationSolver) { // Intentionally left empty. } @@ -30,7 +29,14 @@ namespace storm { This Second constructor is NEEDED and a workaround for a common Bug in C++ with nested templates See: http://stackoverflow.com/questions/14401308/visual-c-cannot-deduce-given-template-arguments-for-function-used-as-defaul */ - explicit SparseMarkovAutomatonCslModelChecker(storm::models::MarkovAutomaton<ValueType> const& model) : AbstractModelChecker<ValueType>(model), minimumOperatorStack(), nondeterministicLinearEquationSolver(storm::utility::solver::getNondeterministicLinearEquationSolver<ValueType>()) { + explicit SparseMarkovAutomatonCslModelChecker(storm::models::MarkovAutomaton<ValueType> const& model) : AbstractModelChecker<ValueType>(model), nondeterministicLinearEquationSolver(storm::utility::solver::getNondeterministicLinearEquationSolver<ValueType>()) { + // Intentionally left empty. + } + + /*! + * Virtual destructor. Needs to be virtual, because this class has virtual methods. + */ + virtual ~SparseMarkovAutomatonCslModelChecker() { // Intentionally left empty. } @@ -42,50 +48,89 @@ namespace storm { return AbstractModelChecker<ValueType>::template getModel<storm::models::MarkovAutomaton<ValueType>>(); } - std::vector<ValueType> checkUntil(storm::property::csl::Until<ValueType> const& formula, bool qualitative) const { - storm::storage::BitVector leftStates = formula.getLeft().check(*this); - storm::storage::BitVector rightStates = formula.getRight().check(*this); - return computeUnboundedUntilProbabilities(minimumOperatorStack.top(), leftStates, rightStates, qualitative).first; + /*! + * Checks the given formula that is a P operator over a path formula featuring a value bound. + * + * @param formula The formula to check. + * @returns The set of states satisfying the formula represented by a bit vector. + */ + virtual storm::storage::BitVector checkProbabilisticBoundOperator(storm::properties::csl::ProbabilisticBoundOperator<ValueType> const& formula) const override{ + // For P< and P<= the MA satisfies the formula iff the probability maximizing scheduler is used. + // For P> and P>= " iff the probability minimizing " . + if(formula.getComparisonOperator() == storm::properties::LESS || formula.getComparisonOperator() == storm::properties::LESS_EQUAL) { + this->minimumOperatorStack.push(false); + } + else { + this->minimumOperatorStack.push(true); + } + + // First, we need to compute the probability for satisfying the path formula for each state. + std::vector<ValueType> quantitativeResult = formula.getChild()->check(*this, false); + + //Remove the minimizing operator entry from the stack. + this->minimumOperatorStack.pop(); + + // Create resulting bit vector that will hold the yes/no-answer for every state. + storm::storage::BitVector result(quantitativeResult.size()); + + // Now, we can compute which states meet the bound specified in this operator and set the + // corresponding bits to true in the resulting vector. + for (uint_fast64_t i = 0; i < quantitativeResult.size(); ++i) { + if (formula.meetsBound(quantitativeResult[i])) { + result.set(i, true); + } + } + + return result; + } + + std::vector<ValueType> checkUntil(storm::properties::csl::Until<ValueType> const& formula, bool qualitative) const { + // Test wheter it is specified if the minimum or the maximum probabilities are to be computed. + if(this->minimumOperatorStack.empty()) { + LOG4CPLUS_ERROR(logger, "Formula does not specify either min or max optimality, which is not meaningful over nondeterministic models."); + throw storm::exceptions::InvalidArgumentException() << "Formula does not specify either min or max optimality, which is not meaningful over nondeterministic models."; + } + storm::storage::BitVector leftStates = formula.getLeft()->check(*this); + storm::storage::BitVector rightStates = formula.getRight()->check(*this); + return computeUnboundedUntilProbabilities(this->minimumOperatorStack.top(), leftStates, rightStates, qualitative).first; } std::pair<std::vector<ValueType>, storm::storage::TotalScheduler> computeUnboundedUntilProbabilities(bool min, storm::storage::BitVector const& leftStates, storm::storage::BitVector const& rightStates, bool qualitative) const { return storm::modelchecker::prctl::SparseMdpPrctlModelChecker<ValueType>::computeUnboundedUntilProbabilities(min, this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), this->getModel().getInitialStates(), leftStates, rightStates, nondeterministicLinearEquationSolver, qualitative); } - std::vector<ValueType> checkTimeBoundedUntil(storm::property::csl::TimeBoundedUntil<ValueType> const& formula, bool qualitative) const { + std::vector<ValueType> checkTimeBoundedUntil(storm::properties::csl::TimeBoundedUntil<ValueType> const& formula, bool qualitative) const { throw storm::exceptions::NotImplementedException() << "Model checking Until formulas on Markov automata is not yet implemented."; } - std::vector<ValueType> checkTimeBoundedEventually(storm::property::csl::TimeBoundedEventually<ValueType> const& formula, bool qualitative) const { - storm::storage::BitVector goalStates = formula.getChild().check(*this); + std::vector<ValueType> checkTimeBoundedEventually(storm::properties::csl::TimeBoundedEventually<ValueType> const& formula, bool qualitative) const { + // Test wheter it is specified if the minimum or the maximum probabilities are to be computed. + if(this->minimumOperatorStack.empty()) { + LOG4CPLUS_ERROR(logger, "Formula does not specify either min or max optimality, which is not meaningful over nondeterministic models."); + throw storm::exceptions::InvalidArgumentException() << "Formula does not specify either min or max optimality, which is not meaningful over nondeterministic models."; + } + storm::storage::BitVector goalStates = formula.getChild()->check(*this); return this->checkTimeBoundedEventually(this->minimumOperatorStack.top(), goalStates, formula.getLowerBound(), formula.getUpperBound()); } - std::vector<ValueType> checkGlobally(storm::property::csl::Globally<ValueType> const& formula, bool qualitative) const { + std::vector<ValueType> checkGlobally(storm::properties::csl::Globally<ValueType> const& formula, bool qualitative) const { throw storm::exceptions::NotImplementedException() << "Model checking Globally formulas on Markov automata is not yet implemented."; } - std::vector<ValueType> checkEventually(storm::property::csl::Eventually<ValueType> const& formula, bool qualitative) const { - storm::storage::BitVector subFormulaStates = formula.getChild().check(*this); - return computeUnboundedUntilProbabilities(minimumOperatorStack.top(), storm::storage::BitVector(this->getModel().getNumberOfStates(), true), subFormulaStates, qualitative).first; + std::vector<ValueType> checkEventually(storm::properties::csl::Eventually<ValueType> const& formula, bool qualitative) const { + // Test wheter it is specified if the minimum or the maximum probabilities are to be computed. + if(this->minimumOperatorStack.empty()) { + LOG4CPLUS_ERROR(logger, "Formula does not specify either min or max optimality, which is not meaningful over nondeterministic models."); + throw storm::exceptions::InvalidArgumentException() << "Formula does not specify either min or max optimality, which is not meaningful over nondeterministic models."; + } + storm::storage::BitVector subFormulaStates = formula.getChild()->check(*this); + return computeUnboundedUntilProbabilities(this->minimumOperatorStack.top(), storm::storage::BitVector(this->getModel().getNumberOfStates(), true), subFormulaStates, qualitative).first; } - std::vector<ValueType> checkNext(storm::property::csl::Next<ValueType> const& formula, bool qualitative) const { + std::vector<ValueType> checkNext(storm::properties::csl::Next<ValueType> const& formula, bool qualitative) const { throw storm::exceptions::NotImplementedException() << "Model checking Next formulas on Markov automata is not yet implemented."; } - std::vector<ValueType> checkNoBoundOperator(storm::property::csl::AbstractNoBoundOperator<ValueType> const& formula) const { - // Check if the operator was an non-optimality operator and report an error in that case. - if (!formula.isOptimalityOperator()) { - LOG4CPLUS_ERROR(logger, "Formula does not specify neither min nor max optimality, which is not meaningful for nondeterministic models."); - throw storm::exceptions::InvalidArgumentException() << "Formula does not specify neither min nor max optimality, which is not meaningful for nondeterministic models."; - } - minimumOperatorStack.push(formula.isMinimumOperator()); - std::vector<ValueType> result = formula.check(*this, false); - minimumOperatorStack.pop(); - return result; - } - static void computeBoundedReachabilityProbabilities(bool min, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRates, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& goalStates, storm::storage::BitVector const& markovianNonGoalStates, storm::storage::BitVector const& probabilisticNonGoalStates, std::vector<ValueType>& markovianNonGoalValues, std::vector<ValueType>& probabilisticNonGoalValues, ValueType delta, uint_fast64_t numberOfSteps) { // Start by computing four sparse matrices: // * a matrix aMarkovian with all (discretized) transitions from Markovian non-goal states to all Markovian non-goal states. @@ -580,12 +625,6 @@ namespace storm { return result; } - /*! - * A stack used for storing whether we are currently computing min or max probabilities or rewards, respectively. - * The topmost element is true if and only if we are currently computing minimum probabilities or rewards. - */ - mutable std::stack<bool> minimumOperatorStack; - /*! * A solver that is used for solving systems of linear equations that are the result of nondeterministic choices. */ diff --git a/src/modelchecker/ltl/AbstractModelChecker.h b/src/modelchecker/ltl/AbstractModelChecker.h index 8cc06cdbd..ce18dfb48 100644 --- a/src/modelchecker/ltl/AbstractModelChecker.h +++ b/src/modelchecker/ltl/AbstractModelChecker.h @@ -9,7 +9,7 @@ #define STORM_MODELCHECKER_LTL_ABSTRACTMODELCHECKER_H_ #include "src/exceptions/InvalidPropertyException.h" -#include "src/formula/Ltl.h" +#include "src/properties/Ltl.h" #include "src/storage/BitVector.h" #include "src/models/AbstractModel.h" @@ -36,16 +36,16 @@ template<class Type> class AbstractModelChecker : // A list of interfaces the model checker supports. Typically, for each of the interfaces, a check method needs to // be implemented that performs the corresponding check. - public virtual storm::property::ltl::IApModelChecker<Type>, - public virtual storm::property::ltl::IAndModelChecker<Type>, - public virtual storm::property::ltl::IOrModelChecker<Type>, - public virtual storm::property::ltl::INotModelChecker<Type>, - public virtual storm::property::ltl::IUntilModelChecker<Type>, - public virtual storm::property::ltl::IEventuallyModelChecker<Type>, - public virtual storm::property::ltl::IGloballyModelChecker<Type>, - public virtual storm::property::ltl::INextModelChecker<Type>, - public virtual storm::property::ltl::IBoundedUntilModelChecker<Type>, - public virtual storm::property::ltl::IBoundedEventuallyModelChecker<Type> { + public virtual storm::properties::ltl::IApModelChecker<Type>, + public virtual storm::properties::ltl::IAndModelChecker<Type>, + public virtual storm::properties::ltl::IOrModelChecker<Type>, + public virtual storm::properties::ltl::INotModelChecker<Type>, + public virtual storm::properties::ltl::IUntilModelChecker<Type>, + public virtual storm::properties::ltl::IEventuallyModelChecker<Type>, + public virtual storm::properties::ltl::IGloballyModelChecker<Type>, + public virtual storm::properties::ltl::INextModelChecker<Type>, + public virtual storm::properties::ltl::IBoundedUntilModelChecker<Type>, + public virtual storm::properties::ltl::IBoundedEventuallyModelChecker<Type> { public: /*! @@ -104,39 +104,13 @@ public: } } - /*! - * Checks the given state formula on the model and prints the result (true/false) for all initial states, i.e. - * states that carry the atomic proposition "init". - * - * @param stateFormula The formula to be checked. - */ - void check(storm::property::ltl::AbstractLtlFormula<Type> const& ltlFormula) const { - std::cout << std::endl; - LOG4CPLUS_INFO(logger, "Model checking formula\t" << ltlFormula.toString()); - std::cout << "Model checking formula:\t" << ltlFormula.toString() << std::endl; - storm::storage::BitVector result; - try { - result = ltlFormula.check(*this); - LOG4CPLUS_INFO(logger, "Result for initial states:"); - std::cout << "Result for initial states:" << std::endl; - for (auto initialState : model.getInitialStates()) { - LOG4CPLUS_INFO(logger, "\t" << initialState << ": " << (result.get(initialState) ? "satisfied" : "not satisfied")); - std::cout << "\t" << initialState << ": " << result.get(initialState) << std::endl; - } - } catch (std::exception& e) { - std::cout << "Error during computation: " << e.what() << "Skipping property." << std::endl; - LOG4CPLUS_ERROR(logger, "Error during computation: " << e.what() << "Skipping property."); - } - std::cout << std::endl << "-------------------------------------------" << std::endl; - } - /*! * Checks the given formula consisting of a single atomic proposition. * * @param formula The formula to be checked. * @returns The set of states satisfying the formula represented by a bit vector. */ - virtual std::vector<Type> checkAp(storm::property::ltl::Ap<Type> const& formula) const = 0; + virtual std::vector<Type> checkAp(storm::properties::ltl::Ap<Type> const& formula) const = 0; /*! * Checks the given formula that is a logical "and" of two formulae. @@ -144,7 +118,7 @@ public: * @param formula The formula to be checked. * @returns The set of states satisfying the formula represented by a bit vector. */ - virtual std::vector<Type> checkAnd(storm::property::ltl::And<Type> const& formula) const = 0; + virtual std::vector<Type> checkAnd(storm::properties::ltl::And<Type> const& formula) const = 0; /*! * Checks the given formula that is a logical "or" of two formulae. @@ -152,7 +126,7 @@ public: * @param formula The formula to check. * @returns The set of states satisfying the formula represented by a bit vector. */ - virtual std::vector<Type> checkOr(storm::property::ltl::Or<Type> const& formula) const = 0; + virtual std::vector<Type> checkOr(storm::properties::ltl::Or<Type> const& formula) const = 0; /*! * Checks the given formula that is a logical "not" of a sub-formula. @@ -160,7 +134,7 @@ public: * @param formula The formula to check. * @returns The set of states satisfying the formula represented by a bit vector. */ - virtual std::vector<Type> checkNot(const storm::property::ltl::Not<Type>& formula) const = 0; + virtual std::vector<Type> checkNot(const storm::properties::ltl::Not<Type>& formula) const = 0; private: diff --git a/src/modelchecker/prctl/AbstractModelChecker.h b/src/modelchecker/prctl/AbstractModelChecker.h index 5862fe9c9..930c002db 100644 --- a/src/modelchecker/prctl/AbstractModelChecker.h +++ b/src/modelchecker/prctl/AbstractModelChecker.h @@ -17,8 +17,9 @@ namespace prctl { } } +#include <stack> #include "src/exceptions/InvalidPropertyException.h" -#include "src/formula/Prctl.h" +#include "src/properties/Prctl.h" #include "src/storage/BitVector.h" #include "src/models/AbstractModel.h" #include "src/settings/Settings.h" @@ -46,35 +47,34 @@ template<class Type> class AbstractModelChecker : // A list of interfaces the model checker supports. Typically, for each of the interfaces, a check method needs to // be implemented that performs the corresponding check. - public virtual storm::property::prctl::IApModelChecker<Type>, - public virtual storm::property::prctl::IAndModelChecker<Type>, - public virtual storm::property::prctl::IOrModelChecker<Type>, - public virtual storm::property::prctl::INotModelChecker<Type>, - public virtual storm::property::prctl::IUntilModelChecker<Type>, - public virtual storm::property::prctl::IEventuallyModelChecker<Type>, - public virtual storm::property::prctl::IGloballyModelChecker<Type>, - public virtual storm::property::prctl::INextModelChecker<Type>, - public virtual storm::property::prctl::IBoundedUntilModelChecker<Type>, - public virtual storm::property::prctl::IBoundedEventuallyModelChecker<Type>, - public virtual storm::property::prctl::INoBoundOperatorModelChecker<Type>, - public virtual storm::property::prctl::IProbabilisticBoundOperatorModelChecker<Type>, - public virtual storm::property::prctl::IRewardBoundOperatorModelChecker<Type>, - public virtual storm::property::prctl::IReachabilityRewardModelChecker<Type>, - public virtual storm::property::prctl::ICumulativeRewardModelChecker<Type>, - public virtual storm::property::prctl::IInstantaneousRewardModelChecker<Type> { + public virtual storm::properties::prctl::IApModelChecker<Type>, + public virtual storm::properties::prctl::IAndModelChecker<Type>, + public virtual storm::properties::prctl::IOrModelChecker<Type>, + public virtual storm::properties::prctl::INotModelChecker<Type>, + public virtual storm::properties::prctl::IUntilModelChecker<Type>, + public virtual storm::properties::prctl::IEventuallyModelChecker<Type>, + public virtual storm::properties::prctl::IGloballyModelChecker<Type>, + public virtual storm::properties::prctl::INextModelChecker<Type>, + public virtual storm::properties::prctl::IBoundedUntilModelChecker<Type>, + public virtual storm::properties::prctl::IBoundedEventuallyModelChecker<Type>, + public virtual storm::properties::prctl::IProbabilisticBoundOperatorModelChecker<Type>, + public virtual storm::properties::prctl::IRewardBoundOperatorModelChecker<Type>, + public virtual storm::properties::prctl::IReachabilityRewardModelChecker<Type>, + public virtual storm::properties::prctl::ICumulativeRewardModelChecker<Type>, + public virtual storm::properties::prctl::IInstantaneousRewardModelChecker<Type> { public: /*! * Constructs an AbstractModelChecker with the given model. */ - explicit AbstractModelChecker(storm::models::AbstractModel<Type> const& model) : model(model){ + explicit AbstractModelChecker(storm::models::AbstractModel<Type> const& model) : minimumOperatorStack(), model(model) { // Intentionally left empty. } /*! * Copy constructs an AbstractModelChecker from the given model checker. In particular, this means that the newly * constructed model checker will have the model of the given model checker as its associated model. */ - explicit AbstractModelChecker(AbstractModelChecker<Type> const& modelchecker) : model(modelchecker.model) { + explicit AbstractModelChecker(AbstractModelChecker<Type> const& modelchecker) : minimumOperatorStack(), model(modelchecker.model) { // Intentionally left empty. } @@ -120,73 +120,6 @@ public: throw bc; } } - - /*! - * Checks the given abstract prctl formula on the model and prints the result (depending on the actual type of the formula) - * for all initial states, i.e. states that carry the atomic proposition "init". - * - * @param formula The formula to be checked. - */ - void check(storm::property::prctl::AbstractPrctlFormula<Type> const& formula) const { - if (dynamic_cast<storm::property::prctl::AbstractStateFormula<Type> const*>(&formula) != nullptr) { - this->check(static_cast<storm::property::prctl::AbstractStateFormula<Type> const&>(formula)); - } else if (dynamic_cast<storm::property::prctl::AbstractNoBoundOperator<Type> const*>(&formula) != nullptr) { - this->check(static_cast<storm::property::prctl::AbstractNoBoundOperator<Type> const&>(formula)); - } - } - - /*! - * Checks the given state formula on the model and prints the result (true/false) for all initial states, i.e. - * states that carry the atomic proposition "init". - * - * @param stateFormula The formula to be checked. - */ - void check(storm::property::prctl::AbstractStateFormula<Type> const& stateFormula) const { - std::cout << std::endl; - LOG4CPLUS_INFO(logger, "Model checking formula\t" << stateFormula.toString()); - std::cout << "Model checking formula:\t" << stateFormula.toString() << std::endl; - storm::storage::BitVector result; - try { - result = stateFormula.check(*this); - LOG4CPLUS_INFO(logger, "Result for initial states:"); - std::cout << "Result for initial states:" << std::endl; - for (auto initialState : model.getInitialStates()) { - LOG4CPLUS_INFO(logger, "\t" << initialState << ": " << (result.get(initialState) ? "satisfied" : "not satisfied")); - std::cout << "\t" << initialState << ": " << result.get(initialState) << std::endl; - } - } catch (std::exception& e) { - std::cout << "Error during computation: " << e.what() << "Skipping property." << std::endl; - LOG4CPLUS_ERROR(logger, "Error during computation: " << e.what() << "Skipping property."); - } - - std::cout << std::endl << "-------------------------------------------" << std::endl; - } - - /*! - * Checks the given formula (with no bound) on the model and prints the result (probability/rewards) for all - * initial states, i.e. states that carry the atomic proposition "init". - * - * @param noBoundFormula The formula to be checked. - */ - void check(storm::property::prctl::AbstractNoBoundOperator<Type> const& noBoundFormula) const { - std::cout << std::endl; - LOG4CPLUS_INFO(logger, "Model checking formula\t" << noBoundFormula.toString()); - std::cout << "Model checking formula:\t" << noBoundFormula.toString() << std::endl; - std::vector<Type> result; - try { - result = this->checkNoBoundOperator(noBoundFormula); - LOG4CPLUS_INFO(logger, "Result for initial states:"); - std::cout << "Result for initial states:" << std::endl; - for (auto initialState : model.getInitialStates()) { - LOG4CPLUS_INFO(logger, "\t" << initialState << ": " << result[initialState]); - std::cout << "\t" << initialState << ": " << result[initialState] << std::endl; - } - } catch (std::exception& e) { - std::cout << "Error during computation: " << e.what() << " Skipping property." << std::endl; - LOG4CPLUS_ERROR(logger, "Error during computation: " << e.what() << "Skipping property."); - } - std::cout << std::endl << "-------------------------------------------" << std::endl; - } /*! * Checks the given formula consisting of a single atomic proposition. @@ -194,7 +127,7 @@ public: * @param formula The formula to be checked. * @return The set of states satisfying the formula represented by a bit vector. */ - storm::storage::BitVector checkAp(storm::property::prctl::Ap<Type> const& formula) const { + storm::storage::BitVector checkAp(storm::properties::prctl::Ap<Type> const& formula) const { if (formula.getAp() == "true") { return storm::storage::BitVector(model.getNumberOfStates(), true); } else if (formula.getAp() == "false") { @@ -215,9 +148,9 @@ public: * @param formula The formula to be checked. * @return The set of states satisfying the formula represented by a bit vector. */ - storm::storage::BitVector checkAnd(storm::property::prctl::And<Type> const& formula) const { - storm::storage::BitVector result = formula.getLeft().check(*this); - storm::storage::BitVector right = formula.getRight().check(*this); + storm::storage::BitVector checkAnd(storm::properties::prctl::And<Type> const& formula) const { + storm::storage::BitVector result = formula.getLeft()->check(*this); + storm::storage::BitVector right = formula.getRight()->check(*this); result &= right; return result; } @@ -228,9 +161,9 @@ public: * @param formula The formula to check. * @return The set of states satisfying the formula represented by a bit vector. */ - storm::storage::BitVector checkOr(storm::property::prctl::Or<Type> const& formula) const { - storm::storage::BitVector result = formula.getLeft().check(*this); - storm::storage::BitVector right = formula.getRight().check(*this); + storm::storage::BitVector checkOr(storm::properties::prctl::Or<Type> const& formula) const { + storm::storage::BitVector result = formula.getLeft()->check(*this); + storm::storage::BitVector right = formula.getRight()->check(*this); result |= right; return result; } @@ -241,8 +174,8 @@ public: * @param formula The formula to check. * @return The set of states satisfying the formula represented by a bit vector. */ - storm::storage::BitVector checkNot(const storm::property::prctl::Not<Type>& formula) const { - storm::storage::BitVector result = formula.getChild().check(*this); + storm::storage::BitVector checkNot(const storm::properties::prctl::Not<Type>& formula) const { + storm::storage::BitVector result = formula.getChild()->check(*this); result.complement(); return result; } @@ -254,9 +187,9 @@ public: * @param formula The formula to check. * @return The set of states satisfying the formula represented by a bit vector. */ - storm::storage::BitVector checkProbabilisticBoundOperator(storm::property::prctl::ProbabilisticBoundOperator<Type> const& formula) const { + virtual storm::storage::BitVector checkProbabilisticBoundOperator(storm::properties::prctl::ProbabilisticBoundOperator<Type> const& formula) const { // First, we need to compute the probability for satisfying the path formula for each state. - std::vector<Type> quantitativeResult = formula.getPathFormula().check(*this, false); + std::vector<Type> quantitativeResult = formula.getChild()->check(*this, false); // Create resulting bit vector that will hold the yes/no-answer for every state. storm::storage::BitVector result(quantitativeResult.size()); @@ -278,9 +211,9 @@ public: * @param formula The formula to check. * @return The set of states satisfying the formula represented by a bit vector. */ - storm::storage::BitVector checkRewardBoundOperator(const storm::property::prctl::RewardBoundOperator<Type>& formula) const { + virtual storm::storage::BitVector checkRewardBoundOperator(const storm::properties::prctl::RewardBoundOperator<Type>& formula) const { // First, we need to compute the probability for satisfying the path formula for each state. - std::vector<Type> quantitativeResult = formula.getPathFormula().check(*this, false); + std::vector<Type> quantitativeResult = formula.getChild()->check(*this, false); // Create resulting bit vector that will hold the yes/no-answer for every state. storm::storage::BitVector result(quantitativeResult.size()); @@ -296,6 +229,56 @@ public: return result; } + /*! + * Checks the given formula and determines whether minimum or maximum probabilities are to be computed for the formula. + * + * @param formula The formula to check. + * @param optOperator True iff minimum probabilities are to be computed. + * @returns The probabilities to satisfy the formula, represented by a vector. + */ + virtual std::vector<Type> checkOptimizingOperator(storm::properties::prctl::AbstractPathFormula<Type> const & formula, bool optOperator) const { + minimumOperatorStack.push(optOperator); + std::vector<Type> result = formula.check(*this, false); + minimumOperatorStack.pop(); + return result; + } + + /*! + * Checks the given formula and determines whether minimum or maximum rewards are to be computed for the formula. + * + * @param formula The formula to check. + * @param optOperator True iff minimum rewards are to be computed. + * @returns The the rewards accumulated by the formula, represented by a vector. + */ + virtual std::vector<Type> checkOptimizingOperator(storm::properties::prctl::AbstractRewardPathFormula<Type> const & formula, bool optOperator) const { + minimumOperatorStack.push(optOperator); + std::vector<Type> result = formula.check(*this, false); + minimumOperatorStack.pop(); + return result; + } + + /*! + * Checks the given formula and determines whether minimum or maximum probabilities or rewards are to be computed for the formula. + * + * @param formula The formula to check. + * @param optOperator True iff minimum probabilities/rewards are to be computed. + * @returns The set of states satisfying the formula represented by a bit vector. + */ + virtual storm::storage::BitVector checkOptimizingOperator(storm::properties::prctl::AbstractStateFormula<Type> const & formula, bool optOperator) const { + minimumOperatorStack.push(optOperator); + storm::storage::BitVector result = formula.check(*this); + minimumOperatorStack.pop(); + return result; + } + +protected: + + /*! + * A stack used for storing whether we are currently computing min or max probabilities or rewards, respectively. + * The topmost element is true if and only if we are currently computing minimum probabilities or rewards. + */ + mutable std::stack<bool> minimumOperatorStack; + private: /*! diff --git a/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h b/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h index 9d43dfb52..f3d226ac0 100644 --- a/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h +++ b/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h @@ -60,21 +60,6 @@ public: return AbstractModelChecker<Type>::template getModel<storm::models::Dtmc<Type>>(); } - /*! - * Checks the given formula that is a P/R operator without a bound. - * - * @param formula The formula to check. - * @returns The set of states satisfying the formula represented by a bit vector. - */ - std::vector<Type> checkNoBoundOperator(storm::property::prctl::AbstractNoBoundOperator<Type> const& formula) const { - // Check if the operator was an optimality operator and report a warning in that case. - if (formula.isOptimalityOperator()) { - LOG4CPLUS_WARN(logger, "Formula contains min/max operator, which is not meaningful over deterministic models."); - } - return formula.check(*this, false); - } - - /*! * Checks the given formula that is a bounded-until formula. * @@ -86,8 +71,8 @@ public: * @returns The probabilities for the given formula to hold on every state of the model associated with this model * checker. If the qualitative flag is set, exact probabilities might not be computed. */ - virtual std::vector<Type> checkBoundedUntil(storm::property::prctl::BoundedUntil<Type> const& formula, bool qualitative) const { - return this->checkBoundedUntil(formula.getLeft().check(*this), formula.getRight().check(*this), formula.getBound(), qualitative); + virtual std::vector<Type> checkBoundedUntil(storm::properties::prctl::BoundedUntil<Type> const& formula, bool qualitative) const { + return this->checkBoundedUntil(formula.getLeft()->check(*this), formula.getRight()->check(*this), formula.getBound(), qualitative); } /*! @@ -160,9 +145,9 @@ public: * @returns The probabilities for the given formula to hold on every state of the model associated with this model * checker. If the qualitative flag is set, exact probabilities might not be computed. */ - virtual std::vector<Type> checkNext(storm::property::prctl::Next<Type> const& formula, bool qualitative) const { + virtual std::vector<Type> checkNext(storm::properties::prctl::Next<Type> const& formula, bool qualitative) const { // First, we need to compute the states that satisfy the child formula of the next-formula. - storm::storage::BitVector nextStates = formula.getChild().check(*this); + storm::storage::BitVector nextStates = formula.getChild()->check(*this); // Create the vector with which to multiply and initialize it correctly. std::vector<Type> result(this->getModel().getNumberOfStates()); @@ -189,8 +174,8 @@ public: * @returns The probabilities for the given formula to hold on every state of the model associated with this model * checker. If the qualitative flag is set, exact probabilities might not be computed. */ - virtual std::vector<Type> checkBoundedEventually(storm::property::prctl::BoundedEventually<Type> const& formula, bool qualitative) const { - return this->checkBoundedUntil(storm::storage::BitVector(this->getModel().getNumberOfStates(), true), formula.getChild().check(*this), formula.getBound(), qualitative); + virtual std::vector<Type> checkBoundedEventually(storm::properties::prctl::BoundedEventually<Type> const& formula, bool qualitative) const { + return this->checkBoundedUntil(storm::storage::BitVector(this->getModel().getNumberOfStates(), true), formula.getChild()->check(*this), formula.getBound(), qualitative); } /*! @@ -204,9 +189,9 @@ public: * @returns The probabilities for the given formula to hold on every state of the model associated with this model * checker. If the qualitative flag is set, exact probabilities might not be computed. */ - virtual std::vector<Type> checkEventually(storm::property::prctl::Eventually<Type> const& formula, bool qualitative) const { + virtual std::vector<Type> checkEventually(storm::properties::prctl::Eventually<Type> const& formula, bool qualitative) const { // Create equivalent temporary until formula and check it. - storm::property::prctl::Until<Type> temporaryUntilFormula(new storm::property::prctl::Ap<Type>("true"), formula.getChild().clone()); + storm::properties::prctl::Until<Type> temporaryUntilFormula(std::shared_ptr<storm::properties::prctl::Ap<Type>>(new storm::properties::prctl::Ap<Type>("true")), formula.getChild()); return this->checkUntil(temporaryUntilFormula, qualitative); } @@ -221,9 +206,9 @@ public: * @returns The probabilities for the given formula to hold on every state of the model associated with this model * checker. If the qualitative flag is set, exact probabilities might not be computed. */ - virtual std::vector<Type> checkGlobally(storm::property::prctl::Globally<Type> const& formula, bool qualitative) const { + virtual std::vector<Type> checkGlobally(storm::properties::prctl::Globally<Type> const& formula, bool qualitative) const { // Create "equivalent" (equivalent up to negation) temporary eventually formula and check it. - storm::property::prctl::Eventually<Type> temporaryEventuallyFormula(new storm::property::prctl::Not<Type>(formula.getChild().clone())); + storm::properties::prctl::Eventually<Type> temporaryEventuallyFormula(std::shared_ptr<storm::properties::prctl::Not<Type>>(new storm::properties::prctl::Not<Type>(formula.getChild()))); std::vector<Type> result = this->checkEventually(temporaryEventuallyFormula, qualitative); // Now subtract the resulting vector from the constant one vector to obtain final result. @@ -243,8 +228,8 @@ public: * @returns The probabilities for the given formula to hold on every state of the model associated with this model * checker. If the qualitative flag is set, exact probabilities might not be computed. */ - virtual std::vector<Type> checkUntil(storm::property::prctl::Until<Type> const& formula, bool qualitative) const { - return this->checkUntil(formula.getLeft().check(*this), formula.getRight().check(*this), qualitative); + virtual std::vector<Type> checkUntil(storm::properties::prctl::Until<Type> const& formula, bool qualitative) const { + return this->checkUntil(formula.getLeft()->check(*this), formula.getRight()->check(*this), qualitative); } /*! @@ -334,7 +319,7 @@ public: * @returns The reward values for the given formula for every state of the model associated with this model * checker. If the qualitative flag is set, exact values might not be computed. */ - virtual std::vector<Type> checkInstantaneousReward(storm::property::prctl::InstantaneousReward<Type> const& formula, bool qualitative) const { + virtual std::vector<Type> checkInstantaneousReward(storm::properties::prctl::InstantaneousReward<Type> const& formula, bool qualitative) const { // Only compute the result if the model has a state-based reward model. if (!this->getModel().hasStateRewards()) { LOG4CPLUS_ERROR(logger, "Missing (state-based) reward model for formula."); @@ -365,7 +350,7 @@ public: * @returns The reward values for the given formula for every state of the model associated with this model * checker. If the qualitative flag is set, exact values might not be computed. */ - virtual std::vector<Type> checkCumulativeReward(storm::property::prctl::CumulativeReward<Type> const& formula, bool qualitative) const { + virtual std::vector<Type> checkCumulativeReward(storm::properties::prctl::CumulativeReward<Type> const& formula, bool qualitative) const { // Only compute the result if the model has at least one reward model. if (!this->getModel().hasStateRewards() && !this->getModel().hasTransitionRewards()) { LOG4CPLUS_ERROR(logger, "Missing reward model for formula."); @@ -412,7 +397,7 @@ public: * @returns The reward values for the given formula for every state of the model associated with this model * checker. If the qualitative flag is set, exact values might not be computed. */ - virtual std::vector<Type> checkReachabilityReward(storm::property::prctl::ReachabilityReward<Type> const& formula, bool qualitative) const { + virtual std::vector<Type> checkReachabilityReward(storm::properties::prctl::ReachabilityReward<Type> const& formula, bool qualitative) const { // Only compute the result if the model has at least one reward model. if (!this->getModel().hasStateRewards() && !this->getModel().hasTransitionRewards()) { LOG4CPLUS_ERROR(logger, "Missing reward model for formula. Skipping formula"); @@ -420,7 +405,7 @@ public: } // Determine the states for which the target predicate holds. - storm::storage::BitVector targetStates = formula.getChild().check(*this); + storm::storage::BitVector targetStates = formula.getChild()->check(*this); // Determine which states have a reward of infinity by definition. storm::storage::BitVector trueStates(this->getModel().getNumberOfStates(), true); @@ -497,6 +482,42 @@ public: return result; } + /*! + * Checks the given formula. + * @note This methods overrides the method of the base class to give an additional warning that declaring that minimal or maximal probabilities + * should be computed for the formula makes no sense in the context of a deterministic model. + * + * @param formula The formula to check. + * @param optOperator True iff minimum probabilities/rewards are to be computed. + * @returns The probabilities to satisfy the formula or the rewards accumulated by it, represented by a vector. + */ + virtual std::vector<Type> checkOptimizingOperator(storm::properties::prctl::AbstractPathFormula<Type> const & formula, bool optOperator) const override { + + LOG4CPLUS_WARN(logger, "Formula contains min/max operator, which is not meaningful over deterministic models."); + + std::vector<Type> result = formula.check(*this, false); + + return result; + } + + /*! + * Checks the given formula and determines whether minimum or maximum probabilities or rewards are to be computed for the formula. + * @note This methods overrides the method of the base class to give an additional warning that declaring that minimal or maximal probabilities + * should be computed for the formula makes no sense in the context of a deterministic model. + * + * @param formula The formula to check. + * @param optOperator True iff minimum probabilities/rewards are to be computed. + * @returns The set of states satisfying the formula represented by a bit vector. + */ + virtual storm::storage::BitVector checkOptimizingOperator(storm::properties::prctl::AbstractStateFormula<Type> const & formula, bool optOperator) const override { + + LOG4CPLUS_WARN(logger, "Formula contains min/max operator, which is not meaningful over deterministic models."); + + storm::storage::BitVector result = formula.check(*this); + + return result; + } + private: // An object that is used for solving linear equations and performing matrix-vector multiplication. std::unique_ptr<storm::solver::LinearEquationSolver<Type>> linearEquationSolver; diff --git a/src/modelchecker/prctl/SparseMdpPrctlModelChecker.h b/src/modelchecker/prctl/SparseMdpPrctlModelChecker.h index c3e2aec58..10fc04aaf 100644 --- a/src/modelchecker/prctl/SparseMdpPrctlModelChecker.h +++ b/src/modelchecker/prctl/SparseMdpPrctlModelChecker.h @@ -9,7 +9,6 @@ #define STORM_MODELCHECKER_PRCTL_SPARSEMDPPRCTLMODELCHECKER_H_ #include <vector> -#include <stack> #include <fstream> #include "src/modelchecker/prctl/AbstractModelChecker.h" @@ -38,11 +37,11 @@ namespace storm { * * @param model The MDP to be checked. */ - explicit SparseMdpPrctlModelChecker(storm::models::Mdp<Type> const& model) : AbstractModelChecker<Type>(model), minimumOperatorStack(), nondeterministicLinearEquationSolver(storm::utility::solver::getNondeterministicLinearEquationSolver<Type>()) { + explicit SparseMdpPrctlModelChecker(storm::models::Mdp<Type> const& model) : AbstractModelChecker<Type>(model), nondeterministicLinearEquationSolver(storm::utility::solver::getNondeterministicLinearEquationSolver<Type>()) { // Intentionally left empty. } - explicit SparseMdpPrctlModelChecker(storm::models::Mdp<Type> const& model, std::shared_ptr<storm::solver::NondeterministicLinearEquationSolver<Type>> nondeterministicLinearEquationSolver) : AbstractModelChecker<Type>(model), minimumOperatorStack(), nondeterministicLinearEquationSolver(nondeterministicLinearEquationSolver) { + explicit SparseMdpPrctlModelChecker(storm::models::Mdp<Type> const& model, std::shared_ptr<storm::solver::NondeterministicLinearEquationSolver<Type>> nondeterministicLinearEquationSolver) : AbstractModelChecker<Type>(model), nondeterministicLinearEquationSolver(nondeterministicLinearEquationSolver) { // Intentionally left empty. } @@ -51,10 +50,17 @@ namespace storm { * constructed model checker will have the model of the given model checker as its associated model. */ explicit SparseMdpPrctlModelChecker(storm::modelchecker::prctl::SparseMdpPrctlModelChecker<Type> const& modelchecker) - : AbstractModelChecker<Type>(modelchecker), minimumOperatorStack(), nondeterministicLinearEquationSolver(storm::utility::solver::getNondeterministicLinearEquationSolver<Type>()) { + : AbstractModelChecker<Type>(modelchecker), nondeterministicLinearEquationSolver(storm::utility::solver::getNondeterministicLinearEquationSolver<Type>()) { // Intentionally left empty. } + /*! + * Virtual destructor. Needs to be virtual, because this class has virtual methods. + */ + virtual ~SparseMdpPrctlModelChecker() { + // Intentionally left empty. + } + /*! * Returns a constant reference to the MDP associated with this model checker. * @returns A constant reference to the MDP associated with this model checker. @@ -62,25 +68,81 @@ namespace storm { storm::models::Mdp<Type> const& getModel() const { return AbstractModelChecker<Type>::template getModel<storm::models::Mdp<Type>>(); } - - /*! - * Checks the given formula that is a P/R operator without a bound. - * - * @param formula The formula to check. - * @returns The set of states satisfying the formula represented by a bit vector. - */ - virtual std::vector<Type> checkNoBoundOperator(const storm::property::prctl::AbstractNoBoundOperator<Type>& formula) const { - // Check if the operator was an non-optimality operator and report an error in that case. - if (!formula.isOptimalityOperator()) { - LOG4CPLUS_ERROR(logger, "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."); - throw storm::exceptions::InvalidArgumentException() << "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."; - } - minimumOperatorStack.push(formula.isMinimumOperator()); - std::vector<Type> result = formula.check(*this, false); - minimumOperatorStack.pop(); - return result; - } - + + /*! + * Checks the given formula that is a P operator over a path formula featuring a value bound. + * + * @param formula The formula to check. + * @return The set of states satisfying the formula represented by a bit vector. + */ + virtual storm::storage::BitVector checkProbabilisticBoundOperator(storm::properties::prctl::ProbabilisticBoundOperator<Type> const& formula) const override { + + // For P< and P<= the MDP satisfies the formula iff the probability maximizing scheduler is used. + // For P> and P>= " iff the probability minimizing " . + if(formula.getComparisonOperator() == storm::properties::LESS || formula.getComparisonOperator() == storm::properties::LESS_EQUAL) { + this->minimumOperatorStack.push(false); + } + else { + this->minimumOperatorStack.push(true); + } + + // First, we need to compute the probability for satisfying the path formula for each state. + std::vector<Type> quantitativeResult = formula.getChild()->check(*this, false); + + //Remove the minimizing operator entry from the stack. + this->minimumOperatorStack.pop(); + + // Create resulting bit vector that will hold the yes/no-answer for every state. + storm::storage::BitVector result(quantitativeResult.size()); + + // Now, we can compute which states meet the bound specified in this operator and set the + // corresponding bits to true in the resulting vector. + for (uint_fast64_t i = 0; i < quantitativeResult.size(); ++i) { + if (formula.meetsBound(quantitativeResult[i])) { + result.set(i, true); + } + } + + return result; + } + + /*! + * Checks the given formula that is an R operator over a reward formula featuring a value bound. + * + * @param formula The formula to check. + * @return The set of states satisfying the formula represented by a bit vector. + */ + virtual storm::storage::BitVector checkRewardBoundOperator(const storm::properties::prctl::RewardBoundOperator<Type>& formula) const override { + + // For R< and R<= the MDP satisfies the formula iff the reward maximizing scheduler is used. + // For R> and R>= " iff the reward minimizing " . + if(formula.getComparisonOperator() == storm::properties::LESS || formula.getComparisonOperator() == storm::properties::LESS_EQUAL) { + this->minimumOperatorStack.push(false); + } + else { + this->minimumOperatorStack.push(true); + } + + // First, we need to compute the probability for satisfying the path formula for each state. + std::vector<Type> quantitativeResult = formula.getChild()->check(*this, false); + + //Remove the minimizing operator entry from the stack. + this->minimumOperatorStack.pop(); + + // Create resulting bit vector that will hold the yes/no-answer for every state. + storm::storage::BitVector result(quantitativeResult.size()); + + // Now, we can compute which states meet the bound specified in this operator and set the + // corresponding bits to true in the resulting vector. + for (uint_fast64_t i = 0; i < quantitativeResult.size(); ++i) { + if (formula.meetsBound(quantitativeResult[i])) { + result.set(i, true); + } + } + + return result; + } + /*! * Computes the probability to satisfy phi until psi within a limited number of steps for each state. * @@ -95,7 +157,13 @@ namespace storm { * If the qualitative flag is set, exact probabilities might not be computed. */ std::vector<Type> checkBoundedUntil(storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, uint_fast64_t stepBound, bool qualitative) const { - std::vector<Type> result(this->getModel().getNumberOfStates()); + // First test if it is specified if the minimum or maximum probabilities are to be computed. + if(this->minimumOperatorStack.empty()) { + LOG4CPLUS_ERROR(logger, "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."); + throw storm::exceptions::InvalidArgumentException() << "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."; + } + + std::vector<Type> result(this->getModel().getNumberOfStates()); // Determine the states that have 0 probability of reaching the target states. storm::storage::BitVector statesWithProbabilityGreater0; @@ -150,8 +218,8 @@ namespace storm { * @return The probabilities for the given formula to hold on every state of the model associated with this model * checker. If the qualitative flag is set, exact probabilities might not be computed. */ - virtual std::vector<Type> checkBoundedUntil(storm::property::prctl::BoundedUntil<Type> const& formula, bool qualitative) const { - return checkBoundedUntil(formula.getLeft().check(*this), formula.getRight().check(*this), formula.getBound(), qualitative); + virtual std::vector<Type> checkBoundedUntil(storm::properties::prctl::BoundedUntil<Type> const& formula, bool qualitative) const { + return checkBoundedUntil(formula.getLeft()->check(*this), formula.getRight()->check(*this), formula.getBound(), qualitative); } /*! @@ -166,6 +234,12 @@ namespace storm { * qualitative flag is set, exact probabilities might not be computed. */ virtual std::vector<Type> checkNext(storm::storage::BitVector const& nextStates, bool qualitative) const { + // First test if it is specified if the minimum or maximum probabilities are to be computed. + if(this->minimumOperatorStack.empty()) { + LOG4CPLUS_ERROR(logger, "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."); + throw storm::exceptions::InvalidArgumentException() << "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."; + } + // Create the vector with which to multiply and initialize it correctly. std::vector<Type> result(this->getModel().getNumberOfStates()); storm::utility::vector::setVectorValues(result, nextStates, storm::utility::constantOne<Type>()); @@ -186,8 +260,8 @@ namespace storm { * @return The probabilities for the given formula to hold on every state of the model associated with this model * checker. If the qualitative flag is set, exact probabilities might not be computed. */ - virtual std::vector<Type> checkNext(const storm::property::prctl::Next<Type>& formula, bool qualitative) const { - return checkNext(formula.getChild().check(*this), qualitative); + virtual std::vector<Type> checkNext(const storm::properties::prctl::Next<Type>& formula, bool qualitative) const { + return checkNext(formula.getChild()->check(*this), qualitative); } /*! @@ -201,9 +275,9 @@ namespace storm { * @returns The probabilities for the given formula to hold on every state of the model associated with this model * checker. If the qualitative flag is set, exact probabilities might not be computed. */ - virtual std::vector<Type> checkBoundedEventually(const storm::property::prctl::BoundedEventually<Type>& formula, bool qualitative) const { + virtual std::vector<Type> checkBoundedEventually(const storm::properties::prctl::BoundedEventually<Type>& formula, bool qualitative) const { // Create equivalent temporary bounded until formula and check it. - storm::property::prctl::BoundedUntil<Type> temporaryBoundedUntilFormula(new storm::property::prctl::Ap<Type>("true"), formula.getChild().clone(), formula.getBound()); + storm::properties::prctl::BoundedUntil<Type> temporaryBoundedUntilFormula(std::shared_ptr<storm::properties::prctl::Ap<Type>>(new storm::properties::prctl::Ap<Type>("true")), formula.getChild(), formula.getBound()); return this->checkBoundedUntil(temporaryBoundedUntilFormula, qualitative); } @@ -218,9 +292,9 @@ namespace storm { * @returns The probabilities for the given formula to hold on every state of the model associated with this model * checker. If the qualitative flag is set, exact probabilities might not be computed. */ - virtual std::vector<Type> checkEventually(const storm::property::prctl::Eventually<Type>& formula, bool qualitative) const { + virtual std::vector<Type> checkEventually(const storm::properties::prctl::Eventually<Type>& formula, bool qualitative) const { // Create equivalent temporary until formula and check it. - storm::property::prctl::Until<Type> temporaryUntilFormula(new storm::property::prctl::Ap<Type>("true"), formula.getChild().clone()); + storm::properties::prctl::Until<Type> temporaryUntilFormula(std::shared_ptr<storm::properties::prctl::Ap<Type>>(new storm::properties::prctl::Ap<Type>("true")), formula.getChild()); return this->checkUntil(temporaryUntilFormula, qualitative); } @@ -235,9 +309,9 @@ namespace storm { * @returns The probabilities for the given formula to hold on every state of the model associated with this model * checker. If the qualitative flag is set, exact probabilities might not be computed. */ - virtual std::vector<Type> checkGlobally(const storm::property::prctl::Globally<Type>& formula, bool qualitative) const { + virtual std::vector<Type> checkGlobally(const storm::properties::prctl::Globally<Type>& formula, bool qualitative) const { // Create "equivalent" temporary eventually formula and check it. - storm::property::prctl::Eventually<Type> temporaryEventuallyFormula(new storm::property::prctl::Not<Type>(formula.getChild().clone())); + storm::properties::prctl::Eventually<Type> temporaryEventuallyFormula(std::shared_ptr<storm::properties::prctl::Not<Type>>(new storm::properties::prctl::Not<Type>(formula.getChild()))); std::vector<Type> result = this->checkEventually(temporaryEventuallyFormula, qualitative); // Now subtract the resulting vector from the constant one vector to obtain final result. @@ -259,8 +333,14 @@ namespace storm { * @return The probabilities for the given formula to hold on every state of the model associated with this model * checker. If the qualitative flag is set, exact probabilities might not be computed. */ - virtual std::vector<Type> checkUntil(const storm::property::prctl::Until<Type>& formula, bool qualitative) const { - return this->checkUntil(this->minimumOperatorStack.top(), formula.getLeft().check(*this), formula.getRight().check(*this), qualitative).first; + virtual std::vector<Type> checkUntil(const storm::properties::prctl::Until<Type>& formula, bool qualitative) const { + // First test if it is specified if the minimum or maximum probabilities are to be computed. + if(this->minimumOperatorStack.empty()) { + LOG4CPLUS_ERROR(logger, "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."); + throw storm::exceptions::InvalidArgumentException() << "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."; + } + + return this->checkUntil(this->minimumOperatorStack.top(), formula.getLeft()->check(*this), formula.getRight()->check(*this), qualitative).first; } /*! @@ -358,13 +438,19 @@ namespace storm { * @return The reward values for the given formula for every state of the model associated with this model * checker. If the qualitative flag is set, exact values might not be computed. */ - virtual std::vector<Type> checkInstantaneousReward(const storm::property::prctl::InstantaneousReward<Type>& formula, bool qualitative) const { + virtual std::vector<Type> checkInstantaneousReward(const storm::properties::prctl::InstantaneousReward<Type>& formula, bool qualitative) const { // Only compute the result if the model has a state-based reward model. if (!this->getModel().hasStateRewards()) { LOG4CPLUS_ERROR(logger, "Missing (state-based) reward model for formula."); throw storm::exceptions::InvalidPropertyException() << "Missing (state-based) reward model for formula."; } + // Now test whether it is specified if the minimum or maximum probabilities are to be computed. + if(this->minimumOperatorStack.empty()) { + LOG4CPLUS_ERROR(logger, "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."); + throw storm::exceptions::InvalidArgumentException() << "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."; + } + // Initialize result to state rewards of the model. std::vector<Type> result(this->getModel().getStateRewardVector()); @@ -384,13 +470,19 @@ namespace storm { * @return The reward values for the given formula for every state of the model associated with this model * checker. If the qualitative flag is set, exact values might not be computed. */ - virtual std::vector<Type> checkCumulativeReward(const storm::property::prctl::CumulativeReward<Type>& formula, bool qualitative) const { + virtual std::vector<Type> checkCumulativeReward(const storm::properties::prctl::CumulativeReward<Type>& formula, bool qualitative) const { // Only compute the result if the model has at least one reward model. if (!this->getModel().hasStateRewards() && !this->getModel().hasTransitionRewards()) { LOG4CPLUS_ERROR(logger, "Missing reward model for formula."); throw storm::exceptions::InvalidPropertyException() << "Missing reward model for formula."; } + // Now test whether it is specified if the minimum or maximum probabilities are to be computed. + if(this->minimumOperatorStack.empty()) { + LOG4CPLUS_ERROR(logger, "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."); + throw storm::exceptions::InvalidArgumentException() << "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."; + } + // Compute the reward vector to add in each step based on the available reward models. std::vector<Type> totalRewardVector; if (this->getModel().hasTransitionRewards()) { @@ -426,8 +518,14 @@ namespace storm { * @return The reward values for the given formula for every state of the model associated with this model * checker. If the qualitative flag is set, exact values might not be computed. */ - virtual std::vector<Type> checkReachabilityReward(const storm::property::prctl::ReachabilityReward<Type>& formula, bool qualitative) const { - return this->checkReachabilityReward(this->minimumOperatorStack.top(), formula.getChild().check(*this), qualitative).first; + virtual std::vector<Type> checkReachabilityReward(const storm::properties::prctl::ReachabilityReward<Type>& formula, bool qualitative) const { + // First test whether it is specified if the minimum or maximum probabilities are to be computed. + if(this->minimumOperatorStack.empty()) { + LOG4CPLUS_ERROR(logger, "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."); + throw storm::exceptions::InvalidArgumentException() << "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."; + } + + return this->checkReachabilityReward(this->minimumOperatorStack.top(), formula.getChild()->check(*this), qualitative).first; } /*! @@ -452,6 +550,12 @@ namespace storm { throw storm::exceptions::InvalidPropertyException() << "Missing reward model for formula."; } + // Also test whether it is specified if the minimum or maximum probabilities are to be computed. + if(this->minimumOperatorStack.empty()) { + LOG4CPLUS_ERROR(logger, "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."); + throw storm::exceptions::InvalidArgumentException() << "Formula does not specify neither min nor max optimality, which is not meaningful over nondeterministic models."; + } + // Determine which states have a reward of infinity by definition. storm::storage::BitVector infinityStates; storm::storage::BitVector trueStates(this->getModel().getNumberOfStates(), true); @@ -570,13 +674,7 @@ namespace storm { return storm::storage::TotalScheduler(choices); } - - /*! - * A stack used for storing whether we are currently computing min or max probabilities or rewards, respectively. - * The topmost element is true if and only if we are currently computing minimum probabilities or rewards. - */ - mutable std::stack<bool> minimumOperatorStack; - + /*! * A solver that is used for solving systems of linear equations that are the result of nondeterministic choices. */ diff --git a/src/models/Dtmc.h b/src/models/Dtmc.h index eb0e669dd..d1f642e6e 100644 --- a/src/models/Dtmc.h +++ b/src/models/Dtmc.h @@ -133,7 +133,7 @@ public: * Waring: If the vector does not have the correct size, it will be resized. * @return The sub-Dtmc. */ - storm::models::Dtmc<T> getSubDtmc(storm::storage::BitVector& subSysStates) { + storm::models::Dtmc<T> getSubDtmc(storm::storage::BitVector& subSysStates) const { // Is there any state in the subsystem? @@ -159,7 +159,7 @@ public: } // 1. Get all necessary information from the old transition matrix - storm::storage::SparseMatrix<T> const& origMat = this->getTransitionMatrix(); + storm::storage::SparseMatrix<T> const & origMat = this->getTransitionMatrix(); // Iterate over all rows. Count the number of all transitions from the old system to be // transfered to the new one. Also build a mapping from the state number of the old system diff --git a/src/parser/CslParser.cpp b/src/parser/CslParser.cpp index efca04e02..1739ebecd 100644 --- a/src/parser/CslParser.cpp +++ b/src/parser/CslParser.cpp @@ -9,6 +9,14 @@ #include "src/utility/OsDetection.h" #include "src/utility/constants.h" +// The action class headers. +#include "src/properties/actions/AbstractAction.h" +#include "src/properties/actions/BoundAction.h" +#include "src/properties/actions/InvertAction.h" +#include "src/properties/actions/FormulaAction.h" +#include "src/properties/actions/RangeAction.h" +#include "src/properties/actions/SortAction.h" + // If the parser fails due to ill-formed data, this exception is thrown. #include "src/exceptions/WrongFormatException.h" @@ -28,25 +36,30 @@ // Some typedefs and namespace definitions to reduce code size. +#define MAKE(Type, ...) phoenix::construct<std::shared_ptr<Type>>(phoenix::new_<Type>(__VA_ARGS__)) typedef std::string::const_iterator BaseIteratorType; typedef boost::spirit::classic::position_iterator2<BaseIteratorType> PositionIteratorType; namespace qi = boost::spirit::qi; namespace phoenix = boost::phoenix; - +namespace csl = storm::properties::csl; namespace storm { namespace parser { template<typename Iterator, typename Skipper> -struct CslGrammar : qi::grammar<Iterator, storm::property::csl::AbstractCslFormula<double>*(), Skipper > { +struct CslParser::CslGrammar : qi::grammar<Iterator, std::shared_ptr<csl::CslFilter<double>>(), Skipper > { CslGrammar() : CslGrammar::base_type(start) { //This block contains helper rules that may be used several times freeIdentifierName = qi::lexeme[qi::alpha >> *(qi::alnum | qi::char_('_'))]; comparisonType = ( - (qi::lit(">="))[qi::_val = storm::property::GREATER_EQUAL] | - (qi::lit(">"))[qi::_val = storm::property::GREATER] | - (qi::lit("<="))[qi::_val = storm::property::LESS_EQUAL] | - (qi::lit("<"))[qi::_val = storm::property::LESS]); + (qi::lit(">="))[qi::_val = storm::properties::GREATER_EQUAL] | + (qi::lit(">"))[qi::_val = storm::properties::GREATER] | + (qi::lit("<="))[qi::_val = storm::properties::LESS_EQUAL] | + (qi::lit("<"))[qi::_val = storm::properties::LESS]); + sortingCategory = ( + (qi::lit("index"))[qi::_val = storm::properties::action::SortAction<double>::INDEX] | + (qi::lit("value"))[qi::_val = storm::properties::action::SortAction<double>::VALUE] + ); //Comment: Empty line or line starting with "//" comment = (qi::lit("//") >> *(qi::char_))[qi::_val = nullptr]; @@ -54,119 +67,179 @@ struct CslGrammar : qi::grammar<Iterator, storm::property::csl::AbstractCslFormu stateFormula %= orFormula; stateFormula.name("state formula"); orFormula = andFormula[qi::_val = qi::_1] > *(qi::lit("|") > andFormula)[qi::_val = - phoenix::new_<storm::property::csl::Or<double>>(qi::_val, qi::_1)]; - orFormula.name("state formula"); + MAKE(csl::Or<double>, qi::_val, qi::_1)]; + orFormula.name("or formula"); andFormula = notFormula[qi::_val = qi::_1] > *(qi::lit("&") > notFormula)[qi::_val = - phoenix::new_<storm::property::csl::And<double>>(qi::_val, qi::_1)]; - andFormula.name("state formula"); + MAKE(csl::And<double>, qi::_val, qi::_1)]; + andFormula.name("and formula"); notFormula = atomicStateFormula[qi::_val = qi::_1] | (qi::lit("!") > atomicStateFormula)[qi::_val = - phoenix::new_<storm::property::csl::Not<double>>(qi::_1)]; - notFormula.name("state formula"); + MAKE(csl::Not<double>, qi::_1)]; + notFormula.name("not formula"); //This block defines rules for "atomic" state formulas //(Propositions, probabilistic/reward formulas, and state formulas in brackets) - atomicStateFormula %= probabilisticBoundOperator | steadyStateBoundOperator | atomicProposition | qi::lit("(") >> stateFormula >> qi::lit(")"); - atomicStateFormula.name("state formula"); + atomicStateFormula %= probabilisticBoundOperator | steadyStateBoundOperator | atomicProposition | (qi::lit("(") >> stateFormula >> qi::lit(")")) | (qi::lit("[") >> stateFormula >> qi::lit("]")); + atomicStateFormula.name("atomic state formula"); atomicProposition = (freeIdentifierName)[qi::_val = - phoenix::new_<storm::property::csl::Ap<double>>(qi::_1)]; - atomicProposition.name("state formula"); + MAKE(csl::Ap<double>, qi::_1)]; + atomicProposition.name("atomic proposition"); probabilisticBoundOperator = ( - (qi::lit("P") >> comparisonType > qi::double_ > qi::lit("[") > pathFormula > qi::lit("]"))[qi::_val = - phoenix::new_<storm::property::csl::ProbabilisticBoundOperator<double> >(qi::_1, qi::_2, qi::_3)] + (qi::lit("P") >> comparisonType > qi::double_ > pathFormula )[qi::_val = + MAKE(csl::ProbabilisticBoundOperator<double> , qi::_1, qi::_2, qi::_3)] ); - probabilisticBoundOperator.name("state formula"); + probabilisticBoundOperator.name("probabilistic bound operator"); steadyStateBoundOperator = ( - (qi::lit("S") >> comparisonType > qi::double_ > qi::lit("[") > stateFormula > qi::lit("]"))[qi::_val = - phoenix::new_<storm::property::csl::SteadyStateBoundOperator<double> >(qi::_1, qi::_2, qi::_3)] + (qi::lit("S") >> comparisonType > qi::double_ > stateFormula )[qi::_val = + MAKE(csl::SteadyStateBoundOperator<double> , qi::_1, qi::_2, qi::_3)] ); - steadyStateBoundOperator.name("state formula"); - - //This block defines rules for parsing formulas with noBoundOperators - noBoundOperator = (probabilisticNoBoundOperator | steadyStateNoBoundOperator); - noBoundOperator.name("no bound operator"); - probabilisticNoBoundOperator = (qi::lit("P") >> qi::lit("=") >> qi::lit("?") >> qi::lit("[") >> pathFormula >> qi::lit("]"))[qi::_val = - phoenix::new_<storm::property::csl::ProbabilisticNoBoundOperator<double> >(qi::_1)]; - probabilisticNoBoundOperator.name("no bound operator"); - steadyStateNoBoundOperator = (qi::lit("S") >> qi::lit("=") >> qi::lit("?") >> qi::lit("[") >> stateFormula >> qi::lit("]"))[qi::_val = - phoenix::new_<storm::property::csl::SteadyStateNoBoundOperator<double> >(qi::_1)]; - steadyStateNoBoundOperator.name("no bound operator"); + steadyStateBoundOperator.name("steady state bound operator"); //This block defines rules for parsing probabilistic path formulas - pathFormula = (timeBoundedEventually | eventually | globally | next | timeBoundedUntil | until); + pathFormula = (timeBoundedEventually | eventually | globally | next | timeBoundedUntil | until | (qi::lit("(") >> pathFormula >> qi::lit(")")) | (qi::lit("[") >> pathFormula >> qi::lit("]"))); pathFormula.name("path formula"); timeBoundedEventually = ( - (qi::lit("F") >> qi::lit("[") > qi::double_ > qi::lit(",") > qi::double_ > qi::lit("]") > stateFormula)[qi::_val = - phoenix::new_<storm::property::csl::TimeBoundedEventually<double>>(qi::_1, qi::_2, qi::_3)] | + (qi::lit("F") >> qi::lit("[") >> qi::double_ >> qi::lit(",") > qi::double_ > qi::lit("]") > stateFormula)[qi::_val = + MAKE(csl::TimeBoundedEventually<double>, qi::_1, qi::_2, qi::_3)] | (qi::lit("F") >> (qi::lit("<=") | qi::lit("<")) > qi::double_ > stateFormula)[qi::_val = - phoenix::new_<storm::property::csl::TimeBoundedEventually<double>>(0, qi::_1, qi::_2)] | + MAKE(csl::TimeBoundedEventually<double>, 0, qi::_1, qi::_2)] | (qi::lit("F") >> (qi::lit(">=") | qi::lit(">")) > qi::double_ > stateFormula)[qi::_val = - phoenix::new_<storm::property::csl::TimeBoundedEventually<double>>(qi::_1, std::numeric_limits<double>::infinity(), qi::_2)] + MAKE(csl::TimeBoundedEventually<double>, qi::_1, std::numeric_limits<double>::infinity(), qi::_2)] ); - timeBoundedEventually.name("path formula (for probabilistic operator)"); + timeBoundedEventually.name("time bounded eventually"); eventually = (qi::lit("F") > stateFormula)[qi::_val = - phoenix::new_<storm::property::csl::Eventually<double> >(qi::_1)]; - eventually.name("path formula (for probabilistic operator)"); + MAKE(csl::Eventually<double> , qi::_1)]; + eventually.name("eventually"); next = (qi::lit("X") > stateFormula)[qi::_val = - phoenix::new_<storm::property::csl::Next<double> >(qi::_1)]; - next.name("path formula (for probabilistic operator)"); + MAKE(csl::Next<double> , qi::_1)]; + next.name("next"); globally = (qi::lit("G") > stateFormula)[qi::_val = - phoenix::new_<storm::property::csl::Globally<double> >(qi::_1)]; - globally.name("path formula (for probabilistic operator)"); + MAKE(csl::Globally<double> , qi::_1)]; + globally.name("globally"); timeBoundedUntil = ( - (stateFormula[qi::_a = phoenix::construct<std::shared_ptr<storm::property::csl::AbstractStateFormula<double>>>(qi::_1)] >> qi::lit("U") >> qi::lit("[") > qi::double_ > qi::lit(",") > qi::double_ > qi::lit("]") > stateFormula) - [qi::_val = phoenix::new_<storm::property::csl::TimeBoundedUntil<double>>(qi::_2, qi::_3, phoenix::bind(&storm::property::csl::AbstractStateFormula<double>::clone, phoenix::bind(&std::shared_ptr<storm::property::csl::AbstractStateFormula<double>>::get, qi::_a)), qi::_4)] | - (stateFormula[qi::_a = phoenix::construct<std::shared_ptr<storm::property::csl::AbstractStateFormula<double>>>(qi::_1)] >> qi::lit("U") >> (qi::lit("<=") | qi::lit("<")) > qi::double_ > stateFormula) - [qi::_val = phoenix::new_<storm::property::csl::TimeBoundedUntil<double>>(0, qi::_2, phoenix::bind(&storm::property::csl::AbstractStateFormula<double>::clone, phoenix::bind(&std::shared_ptr<storm::property::csl::AbstractStateFormula<double>>::get, qi::_a)), qi::_3)] | - (stateFormula[qi::_a = phoenix::construct<std::shared_ptr<storm::property::csl::AbstractStateFormula<double>>>(qi::_1)] >> qi::lit("U") >> (qi::lit(">=") | qi::lit(">")) > qi::double_ > stateFormula) - [qi::_val = phoenix::new_<storm::property::csl::TimeBoundedUntil<double>>(qi::_2, std::numeric_limits<double>::infinity(), phoenix::bind(&storm::property::csl::AbstractStateFormula<double>::clone, phoenix::bind(&std::shared_ptr<storm::property::csl::AbstractStateFormula<double>>::get, qi::_a)), qi::_3)] + (stateFormula[qi::_a = qi::_1] >> qi::lit("U") >> qi::lit("[") >> qi::double_ >> qi::lit(",") >> qi::double_ >> qi::lit("]") >> stateFormula) + [qi::_val = MAKE(csl::TimeBoundedUntil<double>, qi::_2, qi::_3, qi::_a, qi::_4)] | + (stateFormula[qi::_a = qi::_1] >> qi::lit("U") >> (qi::lit("<=") | qi::lit("<")) > qi::double_ > stateFormula) + [qi::_val = MAKE(csl::TimeBoundedUntil<double>, 0, qi::_2, qi::_a, qi::_3)] | + (stateFormula[qi::_a = qi::_1] >> qi::lit("U") >> (qi::lit(">=") | qi::lit(">")) > qi::double_ > stateFormula) + [qi::_val = MAKE(csl::TimeBoundedUntil<double>, qi::_2, std::numeric_limits<double>::infinity(), qi::_a, qi::_3)] ); - timeBoundedUntil.name("path formula (for probabilistic operator)"); - until = (stateFormula[qi::_a = phoenix::construct<std::shared_ptr<storm::property::csl::AbstractStateFormula<double>>>(qi::_1)] >> qi::lit("U") > stateFormula)[qi::_val = - phoenix::new_<storm::property::csl::Until<double>>(phoenix::bind(&storm::property::csl::AbstractStateFormula<double>::clone, phoenix::bind(&std::shared_ptr<storm::property::csl::AbstractStateFormula<double>>::get, qi::_a)), qi::_2)]; - until.name("path formula (for probabilistic operator)"); + timeBoundedUntil.name("time bounded until"); + until = (stateFormula[qi::_a = qi::_1] >> qi::lit("U") > stateFormula)[qi::_val = + MAKE(csl::Until<double>, qi::_a, qi::_2)]; + until.name("until formula"); - formula = (noBoundOperator | stateFormula); + formula = (pathFormula | stateFormula); formula.name("CSL formula"); - start = (((formula) > (comment | qi::eps))[qi::_val = qi::_1] | - comment - ) > qi::eoi; - start.name("CSL formula"); + //This block defines rules for parsing formulas with noBoundOperators + noBoundOperator = (probabilisticNoBoundOperator | steadyStateNoBoundOperator); + noBoundOperator.name("no bound operator"); + probabilisticNoBoundOperator = + (qi::lit("P") >> qi::lit("min") >> qi::lit("=") > qi::lit("?") >> pathFormula)[qi::_val = + MAKE(csl::CslFilter<double>, qi::_1, storm::properties::MINIMIZE)] | + (qi::lit("P") >> qi::lit("max") >> qi::lit("=") > qi::lit("?") >> pathFormula)[qi::_val = + MAKE(csl::CslFilter<double>, qi::_1, storm::properties::MAXIMIZE)] | + (qi::lit("P") >> qi::lit("=") > qi::lit("?") >> pathFormula)[qi::_val = + MAKE(csl::CslFilter<double>, qi::_1)]; + probabilisticNoBoundOperator.name("probabilistic no bound operator"); + steadyStateNoBoundOperator = (qi::lit("S") >> qi::lit("=") > qi::lit("?") >> stateFormula )[qi::_val = + MAKE(csl::CslFilter<double>, qi::_1, storm::properties::UNDEFINED, true)]; + steadyStateNoBoundOperator.name("steady state no bound operator"); + + // This block defines rules for parsing filter actions. + boundAction = (qi::lit("bound") > qi::lit("(") >> comparisonType >> qi::lit(",") >> qi::double_ >> qi::lit(")"))[qi::_val = + MAKE(storm::properties::action::BoundAction<double> ,qi::_1, qi::_2)]; + boundAction.name("bound action"); + + invertAction = qi::lit("invert")[qi::_val = MAKE(storm::properties::action::InvertAction<double>, )]; + invertAction.name("invert action"); + + formulaAction = (qi::lit("formula") > qi::lit("(") >> stateFormula >> qi::lit(")"))[qi::_val = + MAKE(storm::properties::action::FormulaAction<double>, qi::_1)]; + formulaAction.name("formula action"); + + rangeAction = ( + (qi::lit("range") >> qi::lit("(") >> qi::uint_ >> qi::lit(",") > qi::uint_ >> qi::lit(")"))[qi::_val = + MAKE(storm::properties::action::RangeAction<double>, qi::_1, qi::_2)] | + (qi::lit("range") >> qi::lit("(") >> qi::uint_ >> qi::lit(")"))[qi::_val = + MAKE(storm::properties::action::RangeAction<double>, qi::_1, qi::_1 + 1)] + ); + rangeAction.name("range action"); + + sortAction = ( + (qi::lit("sort") >> qi::lit("(") >> sortingCategory >> qi::lit(")"))[qi::_val = + MAKE(storm::properties::action::SortAction<double>, qi::_1)] | + (qi::lit("sort") >> qi::lit("(") >> sortingCategory >> qi::lit(", ") >> (qi::lit("ascending") | qi::lit("asc")) > qi::lit(")"))[qi::_val = + MAKE(storm::properties::action::SortAction<double>, qi::_1, true)] | + (qi::lit("sort") >> qi::lit("(") >> sortingCategory >> qi::lit(", ") >> (qi::lit("descending") | qi::lit("desc")) > qi::lit(")"))[qi::_val = + MAKE(storm::properties::action::SortAction<double>, qi::_1, false)] + ); + sortAction.name("sort action"); + + abstractAction = (qi::lit(";") | qi::eps) >> (boundAction | invertAction | formulaAction | rangeAction | sortAction) >> (qi::lit(";") | qi::eps); + abstractAction.name("filter action"); + + filter = (qi::lit("filter") >> qi::lit("[") >> +abstractAction >> qi::lit("]") >> qi::lit("(") >> formula >> qi::lit(")"))[qi::_val = + MAKE(csl::CslFilter<double>, qi::_2, qi::_1)] | + (qi::lit("filter") >> qi::lit("[") >> qi::lit("max") > +abstractAction >> qi::lit("]") >> qi::lit("(") >> formula >> qi::lit(")"))[qi::_val = + MAKE(csl::CslFilter<double>, qi::_2, qi::_1, storm::properties::MAXIMIZE)] | + (qi::lit("filter") >> qi::lit("[") >> qi::lit("min") > +abstractAction >> qi::lit("]") >> qi::lit("(") >> formula >> qi::lit(")"))[qi::_val = + MAKE(csl::CslFilter<double>, qi::_2, qi::_1, storm::properties::MINIMIZE)] | + (noBoundOperator)[qi::_val = + qi::_1] | + (formula)[qi::_val = + MAKE(csl::CslFilter<double>, qi::_1)]; + + filter.name("CSL formula filter"); + + start = (((filter) > (comment | qi::eps))[qi::_val = qi::_1] | comment[qi::_val = MAKE(csl::CslFilter<double>, nullptr)] ) > qi::eoi; + start.name("CSL formula filter start"); + } - qi::rule<Iterator, storm::property::csl::AbstractCslFormula<double>*(), Skipper> start; - qi::rule<Iterator, storm::property::csl::AbstractCslFormula<double>*(), Skipper> formula; - qi::rule<Iterator, storm::property::csl::AbstractCslFormula<double>*(), Skipper> comment; + qi::rule<Iterator, std::shared_ptr<csl::CslFilter<double>>(), Skipper> start; + qi::rule<Iterator, std::shared_ptr<csl::CslFilter<double>>(), Skipper> filter; + + qi::rule<Iterator, std::shared_ptr<csl::CslFilter<double>>(), Skipper> noBoundOperator; + qi::rule<Iterator, std::shared_ptr<csl::CslFilter<double>>(), Skipper> probabilisticNoBoundOperator; + qi::rule<Iterator, std::shared_ptr<csl::CslFilter<double>>(), Skipper> steadyStateNoBoundOperator; + + qi::rule<Iterator, std::shared_ptr<storm::properties::action::AbstractAction<double>>(), Skipper> abstractAction; + qi::rule<Iterator, std::shared_ptr<storm::properties::action::BoundAction<double>>(), Skipper> boundAction; + qi::rule<Iterator, std::shared_ptr<storm::properties::action::InvertAction<double>>(), Skipper> invertAction; + qi::rule<Iterator, std::shared_ptr<storm::properties::action::FormulaAction<double>>(), Skipper> formulaAction; + qi::rule<Iterator, std::shared_ptr<storm::properties::action::RangeAction<double>>(), Skipper> rangeAction; + qi::rule<Iterator, std::shared_ptr<storm::properties::action::SortAction<double>>(), Skipper> sortAction; - qi::rule<Iterator, storm::property::csl::AbstractStateFormula<double>*(), Skipper> stateFormula; - qi::rule<Iterator, storm::property::csl::AbstractStateFormula<double>*(), Skipper> atomicStateFormula; + qi::rule<Iterator, std::shared_ptr<csl::AbstractCslFormula<double>>(), Skipper> formula; + qi::rule<Iterator, std::shared_ptr<csl::AbstractCslFormula<double>>(), Skipper> comment; - qi::rule<Iterator, storm::property::csl::AbstractStateFormula<double>*(), Skipper> andFormula; - qi::rule<Iterator, storm::property::csl::AbstractStateFormula<double>*(), Skipper> atomicProposition; - qi::rule<Iterator, storm::property::csl::AbstractStateFormula<double>*(), Skipper> orFormula; - qi::rule<Iterator, storm::property::csl::AbstractStateFormula<double>*(), Skipper> notFormula; - qi::rule<Iterator, storm::property::csl::ProbabilisticBoundOperator<double>*(), Skipper> probabilisticBoundOperator; - qi::rule<Iterator, storm::property::csl::SteadyStateBoundOperator<double>*(), Skipper> steadyStateBoundOperator; + qi::rule<Iterator, std::shared_ptr<csl::AbstractStateFormula<double>>(), Skipper> stateFormula; + qi::rule<Iterator, std::shared_ptr<csl::AbstractStateFormula<double>>(), Skipper> atomicStateFormula; - qi::rule<Iterator, storm::property::csl::AbstractNoBoundOperator<double>*(), Skipper> noBoundOperator; - qi::rule<Iterator, storm::property::csl::AbstractNoBoundOperator<double>*(), Skipper> probabilisticNoBoundOperator; - qi::rule<Iterator, storm::property::csl::AbstractNoBoundOperator<double>*(), Skipper> steadyStateNoBoundOperator; + qi::rule<Iterator, std::shared_ptr<csl::AbstractStateFormula<double>>(), Skipper> andFormula; + qi::rule<Iterator, std::shared_ptr<csl::AbstractStateFormula<double>>(), Skipper> atomicProposition; + qi::rule<Iterator, std::shared_ptr<csl::AbstractStateFormula<double>>(), Skipper> orFormula; + qi::rule<Iterator, std::shared_ptr<csl::AbstractStateFormula<double>>(), Skipper> notFormula; + qi::rule<Iterator, std::shared_ptr<csl::ProbabilisticBoundOperator<double>>(), Skipper> probabilisticBoundOperator; + qi::rule<Iterator, std::shared_ptr<csl::SteadyStateBoundOperator<double>>(), Skipper> steadyStateBoundOperator; - qi::rule<Iterator, storm::property::csl::AbstractPathFormula<double>*(), Skipper> pathFormula; - qi::rule<Iterator, storm::property::csl::TimeBoundedEventually<double>*(), Skipper> timeBoundedEventually; - qi::rule<Iterator, storm::property::csl::Eventually<double>*(), Skipper> eventually; - qi::rule<Iterator, storm::property::csl::Next<double>*(), Skipper> next; - qi::rule<Iterator, storm::property::csl::Globally<double>*(), Skipper> globally; - qi::rule<Iterator, storm::property::csl::TimeBoundedUntil<double>*(), qi::locals< std::shared_ptr<storm::property::csl::AbstractStateFormula<double>>>, Skipper> timeBoundedUntil; - qi::rule<Iterator, storm::property::csl::Until<double>*(), qi::locals< std::shared_ptr<storm::property::csl::AbstractStateFormula<double>>>, Skipper> until; + qi::rule<Iterator, std::shared_ptr<csl::AbstractPathFormula<double>>(), Skipper> pathFormula; + qi::rule<Iterator, std::shared_ptr<csl::TimeBoundedEventually<double>>(), Skipper> timeBoundedEventually; + qi::rule<Iterator, std::shared_ptr<csl::Eventually<double>>(), Skipper> eventually; + qi::rule<Iterator, std::shared_ptr<csl::Next<double>>(), Skipper> next; + qi::rule<Iterator, std::shared_ptr<csl::Globally<double>>(), Skipper> globally; + qi::rule<Iterator, std::shared_ptr<csl::TimeBoundedUntil<double>>(), qi::locals< std::shared_ptr<storm::properties::csl::AbstractStateFormula<double>>>, Skipper> timeBoundedUntil; + qi::rule<Iterator, std::shared_ptr<csl::Until<double>>(), qi::locals< std::shared_ptr<storm::properties::csl::AbstractStateFormula<double>>>, Skipper> until; qi::rule<Iterator, std::string(), Skipper> freeIdentifierName; - qi::rule<Iterator, storm::property::ComparisonType(), Skipper> comparisonType; + qi::rule<Iterator, storm::properties::ComparisonType(), Skipper> comparisonType; + qi::rule<Iterator, storm::properties::action::SortAction<double>::SortingCategory(), Skipper> sortingCategory; }; -storm::property::csl::AbstractCslFormula<double>* CslParser(std::string formulaString) { +std::shared_ptr<storm::properties::csl::CslFilter<double>> CslParser::parseCslFormula(std::string formulaString) { // Prepare iterators to input. BaseIteratorType stringIteratorBegin = formulaString.begin(); BaseIteratorType stringIteratorEnd = formulaString.end(); @@ -175,7 +248,7 @@ storm::property::csl::AbstractCslFormula<double>* CslParser(std::string formulaS // Prepare resulting intermediate representation of input. - storm::property::csl::AbstractCslFormula<double>* result_pointer = nullptr; + std::shared_ptr<storm::properties::csl::CslFilter<double>> result_pointer(nullptr); CslGrammar<PositionIteratorType, BOOST_TYPEOF(boost::spirit::ascii::space)> grammar; @@ -212,7 +285,7 @@ storm::property::csl::AbstractCslFormula<double>* CslParser(std::string formulaS // The syntax can be so wrong that no rule can be matched at all // In that case, no expectation failure is thrown, but the parser just returns nullptr // Then, of course the result is not usable, hence we throw a WrongFormatException, too. - if (result_pointer == nullptr) { + if (!result_pointer) { throw storm::exceptions::WrongFormatException() << "Syntax error in formula"; } diff --git a/src/parser/CslParser.h b/src/parser/CslParser.h index 2ef4c64e3..78b42c844 100644 --- a/src/parser/CslParser.h +++ b/src/parser/CslParser.h @@ -8,28 +8,42 @@ #ifndef STORM_PARSER_CSLPARSER_H_ #define STORM_PARSER_CSLPARSER_H_ -#include "src/formula/Csl.h" +#include "src/properties/Csl.h" +#include "src/properties/csl/CslFilter.h" #include <functional> namespace storm { namespace parser { /*! - * Reads a CSL formula from its string representation and parses it into a formula tree, consisting of - * classes in the namespace storm::property. + * Reads a Csl formula from a string and returns the formula tree. * - * If the string could not be parsed successfully, it will throw a wrongFormatException. - * - * @param formulaString The string representation of the formula - * @throw wrongFormatException If the input could not be parsed successfully + * If you want to read the formula from a file, use the LtlFileParser class instead. */ -storm::property::csl::AbstractCslFormula<double>* CslParser(std::string formulaString); +class CslParser { +public: -/*! - * Struct for the CSL grammar, that Boost::Spirit uses to parse the formulas. - */ -template<typename Iterator, typename Skipper> -struct CslGrammar; + /*! + * Reads a CSL formula from its string representation and parses it into a formula tree, consisting of + * classes in the namespace storm::properties. + * + * If the string could not be parsed successfully, it will throw a wrongFormatException. + * + * @param formulaString The string representation of the formula. + * @throw wrongFormatException If the input could not be parsed successfully. + * @return A CslFilter maintaining the parsed formula. + */ + static std::shared_ptr<storm::properties::csl::CslFilter<double>> parseCslFormula(std::string formulaString); + +private: + + /*! + * Struct for the CSL grammar, that Boost::Spirit uses to parse the formulas. + */ + template<typename Iterator, typename Skipper> + struct CslGrammar; + +}; } /* namespace parser */ } /* namespace storm */ diff --git a/src/parser/LtlFileParser.cpp b/src/parser/LtlFileParser.cpp index a53557b89..c7b056183 100644 --- a/src/parser/LtlFileParser.cpp +++ b/src/parser/LtlFileParser.cpp @@ -15,7 +15,7 @@ namespace storm { namespace parser { -std::list<storm::property::ltl::AbstractLtlFormula<double>*> LtlFileParser(std::string filename) { +std::list<std::shared_ptr<storm::properties::ltl::LtlFilter<double>>> LtlFileParser::parseLtlFile(std::string filename) { // Open file std::ifstream inputFileStream(filename, std::ios::in); @@ -24,13 +24,13 @@ std::list<storm::property::ltl::AbstractLtlFormula<double>*> LtlFileParser(std:: throw storm::exceptions::FileIoException() << message << filename; } - std::list<storm::property::ltl::AbstractLtlFormula<double>*> result; + std::list<std::shared_ptr<storm::properties::ltl::LtlFilter<double>>> result; while(!inputFileStream.eof()) { std::string line; //The while loop reads the input file line by line while (std::getline(inputFileStream, line)) { - result.push_back(storm::parser::LtlParser(line)); + result.push_back(storm::parser::LtlParser::parseLtlFormula(line)); } } diff --git a/src/parser/LtlFileParser.h b/src/parser/LtlFileParser.h index cb187a82f..4caa67d8f 100644 --- a/src/parser/LtlFileParser.h +++ b/src/parser/LtlFileParser.h @@ -8,20 +8,25 @@ #ifndef LTLFILEPARSER_H_ #define LTLFILEPARSER_H_ -#include "formula/Ltl.h" +#include "properties/Ltl.h" +#include "src/properties/ltl/LtlFilter.h" #include <list> namespace storm { namespace parser { -/*! - * Parses each line of a given file as prctl formula and returns a list containing the results of the parsing. - * - * @param filename - * @return The list of parsed formulas - */ -std::list<storm::property::ltl::AbstractLtlFormula<double>*> LtlFileParser(std::string filename); +class LtlFileParser { +public: + + /*! + * Parses each line of a given file as prctl formula and returns a list containing the results of the parsing. + * + * @param filename Name and path to the file in which the formula strings can be found. + * @return The list of parsed formulas. + */ + static std::list<std::shared_ptr<storm::properties::ltl::LtlFilter<double>>> parseLtlFile(std::string filename); +}; } //namespace parser } //namespace storm diff --git a/src/parser/LtlParser.cpp b/src/parser/LtlParser.cpp index 5083837b9..df4d28c9e 100644 --- a/src/parser/LtlParser.cpp +++ b/src/parser/LtlParser.cpp @@ -10,6 +10,13 @@ #include "src/utility/OsDetection.h" #include "src/utility/constants.h" +// The action class headers. +#include "src/properties/actions/AbstractAction.h" +#include "src/properties/actions/BoundAction.h" +#include "src/properties/actions/InvertAction.h" +#include "src/properties/actions/RangeAction.h" +#include "src/properties/actions/SortAction.h" + // If the parser fails due to ill-formed data, this exception is thrown. #include "src/exceptions/WrongFormatException.h" @@ -29,11 +36,12 @@ // Some typedefs and namespace definitions to reduce code size. +#define MAKE(Type, ...) phoenix::construct<std::shared_ptr<Type>>(phoenix::new_<Type>(__VA_ARGS__)) typedef std::string::const_iterator BaseIteratorType; typedef boost::spirit::classic::position_iterator2<BaseIteratorType> PositionIteratorType; namespace qi = boost::spirit::qi; namespace phoenix = boost::phoenix; - +namespace ltl = storm::properties::ltl; namespace storm { @@ -41,94 +49,141 @@ namespace storm { namespace parser { template<typename Iterator, typename Skipper> -struct LtlGrammar : qi::grammar<Iterator, storm::property::ltl::AbstractLtlFormula<double>*(), Skipper > { +struct LtlParser::LtlGrammar : qi::grammar<Iterator, std::shared_ptr<storm::properties::ltl::LtlFilter<double>>(), Skipper > { LtlGrammar() : LtlGrammar::base_type(start) { //This block contains helper rules that may be used several times freeIdentifierName = qi::lexeme[qi::alpha >> *(qi::alnum | qi::char_('_'))]; - //Comment: Empty line or line starting with "//" + comparisonType = ( + (qi::lit(">="))[qi::_val = storm::properties::GREATER_EQUAL] | + (qi::lit(">"))[qi::_val = storm::properties::GREATER] | + (qi::lit("<="))[qi::_val = storm::properties::LESS_EQUAL] | + (qi::lit("<"))[qi::_val = storm::properties::LESS]); + sortingCategory = ( + (qi::lit("index"))[qi::_val = storm::properties::action::SortAction<double>::INDEX] | + (qi::lit("value"))[qi::_val = storm::properties::action::SortAction<double>::VALUE] + ); + // Comment: Empty line or line starting with "//" comment = (qi::lit("//") >> *(qi::char_))[qi::_val = nullptr]; freeIdentifierName = qi::lexeme[+(qi::alpha | qi::char_('_'))]; - //This block defines rules for parsing state formulas - ltlFormula %= orFormula; - ltlFormula.name("LTL formula"); + // This block defines rules for parsing state formulas + formula %= orFormula; + formula.name("LTL formula"); orFormula = andFormula[qi::_val = qi::_1] > *(qi::lit("|") > andFormula)[qi::_val = - phoenix::new_<storm::property::ltl::Or<double>>(qi::_val, qi::_1)]; - orFormula.name("LTL formula"); + MAKE(ltl::Or<double>, qi::_val, qi::_1)]; + orFormula.name("Or"); andFormula = untilFormula[qi::_val = qi::_1] > *(qi::lit("&") > untilFormula)[qi::_val = - phoenix::new_<storm::property::ltl::And<double>>(qi::_val, qi::_1)]; - andFormula.name("LTL formula"); + MAKE(ltl::And<double>, qi::_val, qi::_1)]; + andFormula.name("And"); untilFormula = notFormula[qi::_val = qi::_1] > - *((qi::lit("U") >> qi::lit("<=") > qi::int_ > notFormula)[qi::_val = phoenix::new_<storm::property::ltl::BoundedUntil<double>>(qi::_val, qi::_2, qi::_1)] | - (qi::lit("U") > notFormula)[qi::_val = phoenix::new_<storm::property::ltl::Until<double>>(qi::_val, qi::_1)]); + *((qi::lit("U") >> qi::lit("<=") > qi::int_ > notFormula)[qi::_val = MAKE(ltl::BoundedUntil<double>, qi::_val, qi::_2, qi::_1)] | + (qi::lit("U") > notFormula)[qi::_val = MAKE(ltl::Until<double>, qi::_val, qi::_1)]); + until.name("Until"); notFormula = atomicLtlFormula[qi::_val = qi::_1] | (qi::lit("!") > atomicLtlFormula)[qi::_val = - phoenix::new_<storm::property::ltl::Not<double>>(qi::_1)]; - notFormula.name("LTL formula"); + MAKE(ltl::Not<double>, qi::_1)]; + notFormula.name("Not"); //This block defines rules for "atomic" state formulas //(Propositions, probabilistic/reward formulas, and state formulas in brackets) - atomicLtlFormula %= pathFormula | atomicProposition | qi::lit("(") >> ltlFormula >> qi::lit(")"); - atomicLtlFormula.name("LTL formula"); + atomicLtlFormula %= pathFormula | atomicProposition | qi::lit("(") >> formula >> qi::lit(")")| qi::lit("[") >> formula >> qi::lit("]"); + atomicLtlFormula.name("Atomic LTL formula"); atomicProposition = (freeIdentifierName)[qi::_val = - phoenix::new_<storm::property::ltl::Ap<double>>(qi::_1)]; - atomicProposition.name("LTL formula"); + MAKE(ltl::Ap<double>, qi::_1)]; + atomicProposition.name("Atomic Proposition"); //This block defines rules for parsing probabilistic path formulas pathFormula = (boundedEventually | eventually | globally | next); - pathFormula.name("LTL formula"); - boundedEventually = (qi::lit("F") >> qi::lit("<=") > qi::int_ > ltlFormula)[qi::_val = - phoenix::new_<storm::property::ltl::BoundedEventually<double>>(qi::_2, qi::_1)]; - boundedEventually.name("LTL formula"); - eventually = (qi::lit("F") >> ltlFormula)[qi::_val = - phoenix::new_<storm::property::ltl::Eventually<double> >(qi::_1)]; - eventually.name("LTL formula"); - globally = (qi::lit("G") >> ltlFormula)[qi::_val = - phoenix::new_<storm::property::ltl::Globally<double> >(qi::_1)]; - globally.name("LTL formula"); - next = (qi::lit("X") >> ltlFormula)[qi::_val = - phoenix::new_<storm::property::ltl::Next<double> >(qi::_1)]; - next.name("LTL formula"); - - start = (((ltlFormula) > (comment | qi::eps))[qi::_val = qi::_1] | - comment - ) > qi::eoi; - start.name("LTL formula"); + pathFormula.name("Path Formula"); + boundedEventually = (qi::lit("F") >> qi::lit("<=") > qi::int_ > formula)[qi::_val = + MAKE(ltl::BoundedEventually<double>, qi::_2, qi::_1)]; + boundedEventually.name("Bounded Eventually"); + eventually = (qi::lit("F") >> formula)[qi::_val = + MAKE(ltl::Eventually<double>, qi::_1)]; + eventually.name("Eventually"); + globally = (qi::lit("G") >> formula)[qi::_val = + MAKE(ltl::Globally<double>, qi::_1)]; + globally.name("Globally"); + next = (qi::lit("X") >> formula)[qi::_val = + MAKE(ltl::Next<double>, qi::_1)]; + next.name("Next"); + + // This block defines rules for parsing filter actions. + boundAction = (qi::lit("bound") > qi::lit("(") >> comparisonType >> qi::lit(",") >> qi::double_ >> qi::lit(")"))[qi::_val = + MAKE(storm::properties::action::BoundAction<double> ,qi::_1, qi::_2)]; + boundAction.name("bound action"); + + invertAction = qi::lit("invert")[qi::_val = MAKE(storm::properties::action::InvertAction<double>, )]; + invertAction.name("invert action"); + + rangeAction = ( + (qi::lit("range") >> qi::lit("(") >> qi::uint_ >> qi::lit(",") > qi::uint_ >> qi::lit(")"))[qi::_val = + MAKE(storm::properties::action::RangeAction<double>, qi::_1, qi::_2)] | + (qi::lit("range") >> qi::lit("(") >> qi::uint_ >> qi::lit(")"))[qi::_val = + MAKE(storm::properties::action::RangeAction<double>, qi::_1, qi::_1 + 1)] + ); + rangeAction.name("range action"); + + sortAction = ( + (qi::lit("sort") >> qi::lit("(") >> sortingCategory >> qi::lit(")"))[qi::_val = + MAKE(storm::properties::action::SortAction<double>, qi::_1)] | + (qi::lit("sort") >> qi::lit("(") >> sortingCategory >> qi::lit(", ") >> (qi::lit("ascending") | qi::lit("asc")) > qi::lit(")"))[qi::_val = + MAKE(storm::properties::action::SortAction<double>, qi::_1, true)] | + (qi::lit("sort") >> qi::lit("(") >> sortingCategory >> qi::lit(", ") >> (qi::lit("descending") | qi::lit("desc")) > qi::lit(")"))[qi::_val = + MAKE(storm::properties::action::SortAction<double>, qi::_1, false)] + ); + sortAction.name("sort action"); + + abstractAction = (qi::lit(";") | qi::eps) >> (boundAction | invertAction | rangeAction | sortAction) >> (qi::lit(";") | qi::eps); + abstractAction.name("filter action"); + + filter = (qi::lit("filter") >> qi::lit("[") >> +abstractAction >> qi::lit("]") > qi::lit("(") >> formula >> qi::lit(")"))[qi::_val = + MAKE(ltl::LtlFilter<double>, qi::_2, qi::_1)] | + (qi::lit("filter") >> qi::lit("[") >> qi::lit("max") > +abstractAction >> qi::lit("]") >> qi::lit("(") >> formula >> qi::lit(")"))[qi::_val = + MAKE(ltl::LtlFilter<double>, qi::_2, qi::_1, storm::properties::MAXIMIZE)] | + (qi::lit("filter") >> qi::lit("[") >> qi::lit("min") > +abstractAction >> qi::lit("]") >> qi::lit("(") >> formula >> qi::lit(")"))[qi::_val = + MAKE(ltl::LtlFilter<double>, qi::_2, qi::_1, storm::properties::MINIMIZE)] | + (formula)[qi::_val = + MAKE(ltl::LtlFilter<double>, qi::_1)]; + filter.name("LTL formula filter"); + + start = (((filter) > (comment | qi::eps))[qi::_val = qi::_1] | comment[qi::_val = MAKE(ltl::LtlFilter<double>, nullptr)] ) > qi::eoi; + start.name("start"); } - qi::rule<Iterator, storm::property::ltl::AbstractLtlFormula<double>*(), Skipper> start; - qi::rule<Iterator, storm::property::ltl::AbstractLtlFormula<double>*(), Skipper> comment; - - qi::rule<Iterator, storm::property::ltl::AbstractLtlFormula<double>*(), Skipper> ltlFormula; - qi::rule<Iterator, storm::property::ltl::AbstractLtlFormula<double>*(), Skipper> atomicLtlFormula; - - qi::rule<Iterator, storm::property::ltl::AbstractLtlFormula<double>*(), Skipper> andFormula; - qi::rule<Iterator, storm::property::ltl::AbstractLtlFormula<double>*(), Skipper> untilFormula; - qi::rule<Iterator, storm::property::ltl::AbstractLtlFormula<double>*(), Skipper> atomicProposition; - qi::rule<Iterator, storm::property::ltl::AbstractLtlFormula<double>*(), Skipper> orFormula; - qi::rule<Iterator, storm::property::ltl::AbstractLtlFormula<double>*(), Skipper> notFormula; - //qi::rule<Iterator, storm::property::ltl::ProbabilisticBoundOperator<double>*(), Skipper> probabilisticBoundOperator; - - //qi::rule<Iterator, storm::property::ltl::AbstractNoBoundOperator<double>*(), Skipper> noBoundOperator; - //qi::rule<Iterator, storm::property::ltl::AbstractNoBoundOperator<double>*(), Skipper> probabilisticNoBoundOperator; - - qi::rule<Iterator, storm::property::ltl::AbstractLtlFormula<double>*(), Skipper> pathFormula; - qi::rule<Iterator, storm::property::ltl::BoundedEventually<double>*(), Skipper> boundedEventually; - qi::rule<Iterator, storm::property::ltl::Eventually<double>*(), Skipper> eventually; - qi::rule<Iterator, storm::property::ltl::Globally<double>*(), Skipper> globally; - qi::rule<Iterator, storm::property::ltl::Next<double>*(), Skipper> next; - qi::rule<Iterator, storm::property::ltl::AbstractLtlFormula<double>*(), qi::locals< std::shared_ptr<storm::property::ltl::AbstractLtlFormula<double>>>, Skipper> boundedUntil; - qi::rule<Iterator, storm::property::ltl::AbstractLtlFormula<double>*(), qi::locals< std::shared_ptr<storm::property::ltl::AbstractLtlFormula<double>>>, Skipper> until; + qi::rule<Iterator, std::shared_ptr<storm::properties::ltl::LtlFilter<double>>(), Skipper> start; + qi::rule<Iterator, std::shared_ptr<storm::properties::ltl::LtlFilter<double>>(), Skipper> filter; + + qi::rule<Iterator, std::shared_ptr<storm::properties::action::AbstractAction<double>>(), Skipper> abstractAction; + qi::rule<Iterator, std::shared_ptr<storm::properties::action::BoundAction<double>>(), Skipper> boundAction; + qi::rule<Iterator, std::shared_ptr<storm::properties::action::InvertAction<double>>(), Skipper> invertAction; + qi::rule<Iterator, std::shared_ptr<storm::properties::action::RangeAction<double>>(), Skipper> rangeAction; + qi::rule<Iterator, std::shared_ptr<storm::properties::action::SortAction<double>>(), Skipper> sortAction; + + qi::rule<Iterator, std::shared_ptr<storm::properties::ltl::AbstractLtlFormula<double>>(), Skipper> comment; + qi::rule<Iterator, std::shared_ptr<storm::properties::ltl::AbstractLtlFormula<double>>(), Skipper> formula; + qi::rule<Iterator, std::shared_ptr<storm::properties::ltl::AbstractLtlFormula<double>>(), Skipper> atomicLtlFormula; + + qi::rule<Iterator, std::shared_ptr<storm::properties::ltl::AbstractLtlFormula<double>>(), Skipper> andFormula; + qi::rule<Iterator, std::shared_ptr<storm::properties::ltl::AbstractLtlFormula<double>>(), Skipper> untilFormula; + qi::rule<Iterator, std::shared_ptr<storm::properties::ltl::AbstractLtlFormula<double>>(), Skipper> atomicProposition; + qi::rule<Iterator, std::shared_ptr<storm::properties::ltl::AbstractLtlFormula<double>>(), Skipper> orFormula; + qi::rule<Iterator, std::shared_ptr<storm::properties::ltl::AbstractLtlFormula<double>>(), Skipper> notFormula; + + qi::rule<Iterator, std::shared_ptr<storm::properties::ltl::AbstractLtlFormula<double>>(), Skipper> pathFormula; + qi::rule<Iterator, std::shared_ptr<storm::properties::ltl::BoundedEventually<double>>(), Skipper> boundedEventually; + qi::rule<Iterator, std::shared_ptr<storm::properties::ltl::Eventually<double>>(), Skipper> eventually; + qi::rule<Iterator, std::shared_ptr<storm::properties::ltl::Globally<double>>(), Skipper> globally; + qi::rule<Iterator, std::shared_ptr<storm::properties::ltl::Next<double>>(), Skipper> next; + qi::rule<Iterator, std::shared_ptr<storm::properties::ltl::AbstractLtlFormula<double>>(), qi::locals< std::shared_ptr<storm::properties::ltl::AbstractLtlFormula<double>>>, Skipper> boundedUntil; + qi::rule<Iterator, std::shared_ptr<storm::properties::ltl::AbstractLtlFormula<double>>(), qi::locals< std::shared_ptr<storm::properties::ltl::AbstractLtlFormula<double>>>, Skipper> until; qi::rule<Iterator, std::string(), Skipper> freeIdentifierName; - + qi::rule<Iterator, storm::properties::ComparisonType(), Skipper> comparisonType; + qi::rule<Iterator, storm::properties::action::SortAction<double>::SortingCategory(), Skipper> sortingCategory; }; -} //namespace storm -} //namespace parser - - -storm::property::ltl::AbstractLtlFormula<double>* storm::parser::LtlParser(std::string formulaString) { +std::shared_ptr<storm::properties::ltl::LtlFilter<double>> LtlParser::parseLtlFormula(std::string formulaString) { // Prepare iterators to input. BaseIteratorType stringIteratorBegin = formulaString.begin(); BaseIteratorType stringIteratorEnd = formulaString.end(); @@ -137,7 +192,7 @@ storm::property::ltl::AbstractLtlFormula<double>* storm::parser::LtlParser(std:: // Prepare resulting intermediate representation of input. - storm::property::ltl::AbstractLtlFormula<double>* result_pointer = nullptr; + std::shared_ptr<storm::properties::ltl::LtlFilter<double>> result_pointer(nullptr); LtlGrammar<PositionIteratorType, BOOST_TYPEOF(boost::spirit::ascii::space)> grammar; @@ -174,10 +229,12 @@ storm::property::ltl::AbstractLtlFormula<double>* storm::parser::LtlParser(std:: // The syntax can be so wrong that no rule can be matched at all // In that case, no expectation failure is thrown, but the parser just returns nullptr // Then, of course the result is not usable, hence we throw a WrongFormatException, too. - if (result_pointer == nullptr) { + if (!result_pointer) { throw storm::exceptions::WrongFormatException() << "Syntax error in formula"; } return result_pointer; } +} //namespace parser +} //namespace storm diff --git a/src/parser/LtlParser.h b/src/parser/LtlParser.h index cefcd8f2c..dac3a63ec 100644 --- a/src/parser/LtlParser.h +++ b/src/parser/LtlParser.h @@ -8,27 +8,41 @@ #ifndef STORM_PARSER_LTLPARSER_H_ #define STORM_PARSER_LTLPARSER_H_ -#include "src/formula/Ltl.h" +#include "src/properties/Ltl.h" +#include "src/properties/ltl/LtlFilter.h" namespace storm { namespace parser { /*! + * Reads a LTL formula from a string and return the formula tree. + * + * If you want to read the formula from a file, use the LtlFileParser class instead. + */ +class LtlParser { +public: + + /*! * Reads a LTL formula from its string representation and parses it into a formula tree, consisting of - * classes in the namespace storm::property. + * classes in the namespace storm::properties. * * If the string could not be parsed successfully, it will throw a wrongFormatException. * - * @param formulaString The string representation of the formula - * @throw wrongFormatException If the input could not be parsed successfully + * @param formulaString The string representation of the formula. + * @throw wrongFormatException If the input could not be parsed successfully. + * @return A LtlFilter maintaining the parsed formula. */ -storm::property::ltl::AbstractLtlFormula<double>* LtlParser(std::string formulaString); + static std::shared_ptr<storm::properties::ltl::LtlFilter<double>> parseLtlFormula(std::string formulaString); -/*! - * Struct for the Ltl grammar, that Boost::Spirit uses to parse the formulas. - */ -template<typename Iterator, typename Skipper> -struct LtlGrammar; +private: + + /*! + * Struct for the Ltl grammar, that Boost::Spirit uses to parse the formulas. + */ + template<typename Iterator, typename Skipper> + struct LtlGrammar; + +}; } /* namespace parser */ } /* namespace storm */ diff --git a/src/parser/PrctlFileParser.cpp b/src/parser/PrctlFileParser.cpp index b4f2b3f2e..64abd2b15 100644 --- a/src/parser/PrctlFileParser.cpp +++ b/src/parser/PrctlFileParser.cpp @@ -14,7 +14,7 @@ namespace storm { namespace parser { -std::list<storm::property::prctl::AbstractPrctlFormula<double>*> PrctlFileParser(std::string filename) { +std::list<std::shared_ptr<storm::properties::prctl::PrctlFilter<double>>> PrctlFileParser::parsePrctlFile(std::string filename) { // Open file std::ifstream inputFileStream; inputFileStream.open(filename, std::ios::in); @@ -24,16 +24,16 @@ std::list<storm::property::prctl::AbstractPrctlFormula<double>*> PrctlFileParser throw storm::exceptions::FileIoException() << message << filename; } - std::list<storm::property::prctl::AbstractPrctlFormula<double>*> result; + std::list<std::shared_ptr<storm::properties::prctl::PrctlFilter<double>>> result; std::string line; //The while loop reads the input file line by line while (std::getline(inputFileStream, line)) { - PrctlParser parser(line); - if (!parser.parsedComment()) { + std::shared_ptr<storm::properties::prctl::PrctlFilter<double>> formula = PrctlParser::parsePrctlFormula(line); + if (formula != nullptr) { //lines containing comments will be skipped. - LOG4CPLUS_INFO(logger, "Parsed formula \"" + line + "\" into \"" + parser.getFormula()->toString() + "\""); - result.push_back(parser.getFormula()); + LOG4CPLUS_INFO(logger, "Parsed formula \"" + line + "\" into \"" + formula->toString() + "\""); + result.push_back(formula); } } diff --git a/src/parser/PrctlFileParser.h b/src/parser/PrctlFileParser.h index b2a4335a2..dbf458fbf 100644 --- a/src/parser/PrctlFileParser.h +++ b/src/parser/PrctlFileParser.h @@ -8,20 +8,26 @@ #ifndef STORM_PARSER_PRCTLFILEPARSER_H_ #define STORM_PARSER_PRCTLFILEPARSER_H_ -#include "formula/Prctl.h" +#include "properties/Prctl.h" +#include "src/properties/prctl/PrctlFilter.h" #include <list> namespace storm { namespace parser { -/*! - * Parses each line of a given file as prctl formula and returns a list containing the results of the parsing. - * - * @param filename - * @return The list of parsed formulas - */ -std::list<storm::property::prctl::AbstractPrctlFormula<double>*> PrctlFileParser(std::string filename); +class PrctlFileParser { +public: + + /*! + * Parses each line of a given file as Prctl formula and returns a list containing the results of the parsing. + * + * @param filename Name and path to the file in which the formula strings can be found. + * @return The list of parsed formulas + */ + static std::list<std::shared_ptr<storm::properties::prctl::PrctlFilter<double>>> parsePrctlFile(std::string filename); + +}; } /* namespace parser */ } /* namespace storm */ diff --git a/src/parser/PrctlParser.cpp b/src/parser/PrctlParser.cpp index d929c5ac7..899b71663 100644 --- a/src/parser/PrctlParser.cpp +++ b/src/parser/PrctlParser.cpp @@ -2,6 +2,14 @@ #include "src/utility/OsDetection.h" #include "src/utility/constants.h" +// The action class headers. +#include "src/properties/actions/AbstractAction.h" +#include "src/properties/actions/BoundAction.h" +#include "src/properties/actions/InvertAction.h" +#include "src/properties/actions/FormulaAction.h" +#include "src/properties/actions/RangeAction.h" +#include "src/properties/actions/SortAction.h" + // If the parser fails due to ill-formed data, this exception is thrown. #include "src/exceptions/WrongFormatException.h" @@ -9,6 +17,7 @@ #include <boost/typeof/typeof.hpp> #include <boost/spirit/include/qi.hpp> #include <boost/spirit/include/phoenix.hpp> +#include <boost/spirit/include/phoenix_function.hpp> // Include headers for spirit iterators. Needed for diagnostics and input stream iteration. #include <boost/spirit/include/classic_position_iterator.hpp> @@ -20,12 +29,13 @@ #include <map> -// Some typedefs and namespace definitions to reduce code size. +// Some typedefs, namespace definitions and a macro to reduce code size. +#define MAKE(Type, ...) phoenix::construct<std::shared_ptr<Type>>(phoenix::new_<Type>(__VA_ARGS__)) typedef std::string::const_iterator BaseIteratorType; typedef boost::spirit::classic::position_iterator2<BaseIteratorType> PositionIteratorType; namespace qi = boost::spirit::qi; namespace phoenix = boost::phoenix; - +namespace prctl = storm::properties::prctl; namespace storm { @@ -33,169 +43,214 @@ namespace storm { namespace parser { template<typename Iterator, typename Skipper> -struct PrctlParser::PrctlGrammar : qi::grammar<Iterator, storm::property::prctl::AbstractPrctlFormula<double>*(), Skipper > { +struct PrctlParser::PrctlGrammar : qi::grammar<Iterator, std::shared_ptr<storm::properties::prctl::PrctlFilter<double>>(), Skipper > { PrctlGrammar() : PrctlGrammar::base_type(start) { - //This block contains helper rules that may be used several times + // This block contains helper rules that may be used several times freeIdentifierName = qi::lexeme[qi::alpha >> *(qi::alnum | qi::char_('_'))]; comparisonType = ( - (qi::lit(">="))[qi::_val = storm::property::GREATER_EQUAL] | - (qi::lit(">"))[qi::_val = storm::property::GREATER] | - (qi::lit("<="))[qi::_val = storm::property::LESS_EQUAL] | - (qi::lit("<"))[qi::_val = storm::property::LESS]); - //Comment: Empty line or line starting with "//" + (qi::lit(">="))[qi::_val = storm::properties::GREATER_EQUAL] | + (qi::lit(">"))[qi::_val = storm::properties::GREATER] | + (qi::lit("<="))[qi::_val = storm::properties::LESS_EQUAL] | + (qi::lit("<"))[qi::_val = storm::properties::LESS]); + sortingCategory = ( + (qi::lit("index"))[qi::_val = storm::properties::action::SortAction<double>::INDEX] | + (qi::lit("value"))[qi::_val = storm::properties::action::SortAction<double>::VALUE] + ); + // Comment: Empty line or line starting with "//" comment = (qi::lit("//") >> *(qi::char_))[qi::_val = nullptr]; - //This block defines rules for parsing state formulas + // This block defines rules for parsing state formulas stateFormula %= orFormula; stateFormula.name("state formula"); orFormula = andFormula[qi::_val = qi::_1] > *(qi::lit("|") > andFormula)[qi::_val = - phoenix::new_<storm::property::prctl::Or<double>>(qi::_val, qi::_1)]; - orFormula.name("state formula"); + MAKE(prctl::Or<double>, qi::_val, qi::_1)]; + orFormula.name("or formula"); andFormula = notFormula[qi::_val = qi::_1] > *(qi::lit("&") > notFormula)[qi::_val = - phoenix::new_<storm::property::prctl::And<double>>(qi::_val, qi::_1)]; - andFormula.name("state formula"); + MAKE(prctl::And<double>, qi::_val, qi::_1)]; + andFormula.name("and formula"); notFormula = atomicStateFormula[qi::_val = qi::_1] | (qi::lit("!") > atomicStateFormula)[qi::_val = - phoenix::new_<storm::property::prctl::Not<double>>(qi::_1)]; - notFormula.name("state formula"); + MAKE(prctl::Not<double>, qi::_1)]; + notFormula.name("not formula"); - //This block defines rules for "atomic" state formulas - //(Propositions, probabilistic/reward formulas, and state formulas in brackets) - atomicStateFormula %= probabilisticBoundOperator | rewardBoundOperator | atomicProposition | qi::lit("(") >> stateFormula >> qi::lit(")"); - atomicStateFormula.name("state formula"); + // This block defines rules for "atomic" state formulas + // (Propositions, probabilistic/reward formulas, and state formulas in brackets) + atomicStateFormula %= probabilisticBoundOperator | rewardBoundOperator | atomicProposition | qi::lit("(") >> stateFormula >> qi::lit(")") | qi::lit("[") >> stateFormula >> qi::lit("]"); + atomicStateFormula.name("atomic state formula"); atomicProposition = (freeIdentifierName)[qi::_val = - phoenix::new_<storm::property::prctl::Ap<double>>(qi::_1)]; - atomicProposition.name("state formula"); - probabilisticBoundOperator = ( - (qi::lit("P") >> qi::lit("min") > comparisonType > qi::double_ > qi::lit("[") > pathFormula > qi::lit("]"))[qi::_val = - phoenix::new_<storm::property::prctl::ProbabilisticBoundOperator<double> >(qi::_1, qi::_2, qi::_3, true)] | - (qi::lit("P") >> qi::lit("max") > comparisonType > qi::double_ > qi::lit("[") > pathFormula > qi::lit("]"))[qi::_val = - phoenix::new_<storm::property::prctl::ProbabilisticBoundOperator<double> >(qi::_1, qi::_2, qi::_3, false)] | - (qi::lit("P") >> comparisonType > qi::double_ > qi::lit("[") > pathFormula > qi::lit("]"))[qi::_val = - phoenix::new_<storm::property::prctl::ProbabilisticBoundOperator<double> >(qi::_1, qi::_2, qi::_3)] - ); + MAKE(prctl::Ap<double>, qi::_1)]; + atomicProposition.name("atomic proposition"); + probabilisticBoundOperator = ((qi::lit("P") >> comparisonType > qi::double_ > pathFormula)[qi::_val = + MAKE(prctl::ProbabilisticBoundOperator<double>, qi::_1, qi::_2, qi::_3)]); + probabilisticBoundOperator.name("probabilistic bound operator"); + rewardBoundOperator = ((qi::lit("R") >> comparisonType > qi::double_ > rewardPathFormula)[qi::_val = + MAKE(prctl::RewardBoundOperator<double>, qi::_1, qi::_2, qi::_3)]); + rewardBoundOperator.name("reward bound operator"); + + // This block defines rules for parsing probabilistic path formulas + pathFormula = (boundedEventually | eventually | next | globally | boundedUntil | until | qi::lit("(") >> pathFormula >> qi::lit(")") | qi::lit("[") >> pathFormula >> qi::lit("]")); + pathFormula.name("path formula"); + boundedEventually = (qi::lit("F") >> qi::lit("<=") > qi::int_ > stateFormula)[qi::_val = + MAKE(prctl::BoundedEventually<double>, qi::_2, qi::_1)]; + boundedEventually.name("bounded eventually"); + eventually = (qi::lit("F") > stateFormula)[qi::_val = + MAKE(prctl::Eventually<double>, qi::_1)]; + eventually.name("eventually"); + next = (qi::lit("X") > stateFormula)[qi::_val = + MAKE(prctl::Next<double>, qi::_1)]; + next.name("next"); + globally = (qi::lit("G") > stateFormula)[qi::_val = + MAKE(prctl::Globally<double>, qi::_1)]; + globally.name("globally"); + boundedUntil = (stateFormula[qi::_a = qi::_1] >> qi::lit("U") >> qi::lit("<=") > qi::int_ > stateFormula)[qi::_val = + MAKE(prctl::BoundedUntil<double>, qi::_a, qi::_3, qi::_2)]; + boundedUntil.name("boundedUntil"); + until = (stateFormula[qi::_a = qi::_1] >> qi::lit("U") > stateFormula)[qi::_val = + MAKE(prctl::Until<double>, qi::_a, qi::_2)]; + until.name("until"); + + // This block defines rules for parsing reward path formulas. + rewardPathFormula = (cumulativeReward | reachabilityReward | instantaneousReward | steadyStateReward | qi::lit("(") >> rewardPathFormula >> qi::lit(")") | qi::lit("[") >> rewardPathFormula >> qi::lit("]")); + rewardPathFormula.name("path formula (for reward operator)"); + cumulativeReward = (qi::lit("C") > qi::lit("<=") > qi::double_)[qi::_val = + MAKE(prctl::CumulativeReward<double>, qi::_1)]; + cumulativeReward.name("path formula (for reward operator)"); + reachabilityReward = (qi::lit("F") > stateFormula)[qi::_val = + MAKE(prctl::ReachabilityReward<double>, qi::_1)]; + reachabilityReward.name("path formula (for reward operator)"); + instantaneousReward = (qi::lit("I") > qi::lit("=") > qi::uint_)[qi::_val = + MAKE(prctl::InstantaneousReward<double>, qi::_1)]; + instantaneousReward.name("path formula (for reward operator)"); + steadyStateReward = (qi::lit("S"))[qi::_val = + MAKE(prctl::SteadyStateReward<double>, )]; - probabilisticBoundOperator.name("state formula"); - rewardBoundOperator = ( - (qi::lit("R") >> qi::lit("min") > comparisonType > qi::double_ > qi::lit("[") > rewardPathFormula > qi::lit("]"))[qi::_val = - phoenix::new_<storm::property::prctl::RewardBoundOperator<double> >(qi::_1, qi::_2, qi::_3, true)] | - (qi::lit("R") >> qi::lit("max") > comparisonType > qi::double_ > qi::lit("[") > rewardPathFormula > qi::lit("]"))[qi::_val = - phoenix::new_<storm::property::prctl::RewardBoundOperator<double> >(qi::_1, qi::_2, qi::_3, false)] | - (qi::lit("R") >> comparisonType > qi::double_ > qi::lit("[") > rewardPathFormula > qi::lit("]"))[qi::_val = - phoenix::new_<storm::property::prctl::RewardBoundOperator<double> >(qi::_1, qi::_2, qi::_3)] - ); - rewardBoundOperator.name("state formula"); + formula = (pathFormula | stateFormula); + formula.name("PRCTL formula"); - //This block defines rules for parsing formulas with noBoundOperators + // This block defines rules for parsing formulas with noBoundOperators. + // Note that this is purely for legacy support. + // NoBoundOperators are no longer part of the formula tree and are therefore deprecated. noBoundOperator = (probabilisticNoBoundOperator | rewardNoBoundOperator); noBoundOperator.name("no bound operator"); probabilisticNoBoundOperator = ( - (qi::lit("P") >> qi::lit("min") >> qi::lit("=") >> qi::lit("?") >> qi::lit("[") >> pathFormula >> qi::lit("]"))[qi::_val = - phoenix::new_<storm::property::prctl::ProbabilisticNoBoundOperator<double> >(qi::_1, true)] | - (qi::lit("P") >> qi::lit("max") >> qi::lit("=") >> qi::lit("?") >> qi::lit("[") >> pathFormula >> qi::lit("]"))[qi::_val = - phoenix::new_<storm::property::prctl::ProbabilisticNoBoundOperator<double> >(qi::_1, false)] | - (qi::lit("P") >> qi::lit("=") >> qi::lit("?") > qi::lit("[") > pathFormula > qi::lit("]"))[qi::_val = - phoenix::new_<storm::property::prctl::ProbabilisticNoBoundOperator<double> >(qi::_1)] + (qi::lit("P") >> qi::lit("min") >> qi::lit("=") > qi::lit("?") >> pathFormula )[qi::_val = + MAKE(prctl::PrctlFilter<double>, qi::_1, storm::properties::MINIMIZE)] | + (qi::lit("P") >> qi::lit("max") >> qi::lit("=") > qi::lit("?") >> pathFormula )[qi::_val = + MAKE(prctl::PrctlFilter<double>, qi::_1, storm::properties::MAXIMIZE)] | + (qi::lit("P") >> qi::lit("=") > qi::lit("?") >> pathFormula )[qi::_val = + MAKE(prctl::PrctlFilter<double>, qi::_1)] ); probabilisticNoBoundOperator.name("no bound operator"); rewardNoBoundOperator = ( - (qi::lit("R") >> qi::lit("min") >> qi::lit("=") >> qi::lit("?") >> qi::lit("[") >> rewardPathFormula >> qi::lit("]"))[qi::_val = - phoenix::new_<storm::property::prctl::RewardNoBoundOperator<double> >(qi::_1, true)] | - (qi::lit("R") >> qi::lit("max") >> qi::lit("=") >> qi::lit("?") >> qi::lit("[") >> rewardPathFormula >> qi::lit("]"))[qi::_val = - phoenix::new_<storm::property::prctl::RewardNoBoundOperator<double> >(qi::_1, false)] | - (qi::lit("R") >> qi::lit("=") >> qi::lit("?") >> qi::lit("[") >> rewardPathFormula >> qi::lit("]"))[qi::_val = - phoenix::new_<storm::property::prctl::RewardNoBoundOperator<double> >(qi::_1)] + (qi::lit("R") >> qi::lit("min") >> qi::lit("=") > qi::lit("?") >> rewardPathFormula )[qi::_val = + MAKE(prctl::PrctlFilter<double>, qi::_1, storm::properties::MINIMIZE)] | + (qi::lit("R") >> qi::lit("max") >> qi::lit("=") > qi::lit("?") >> rewardPathFormula )[qi::_val = + MAKE(prctl::PrctlFilter<double>, qi::_1, storm::properties::MAXIMIZE)] | + (qi::lit("R") >> qi::lit("=") > qi::lit("?") >> rewardPathFormula )[qi::_val = + MAKE(prctl::PrctlFilter<double>, qi::_1)] ); rewardNoBoundOperator.name("no bound operator"); - //This block defines rules for parsing probabilistic path formulas - pathFormula = (boundedEventually | eventually | next | globally | boundedUntil | until); - pathFormula.name("path formula"); - boundedEventually = (qi::lit("F") >> qi::lit("<=") > qi::int_ > stateFormula)[qi::_val = - phoenix::new_<storm::property::prctl::BoundedEventually<double>>(qi::_2, qi::_1)]; - boundedEventually.name("path formula (for probabilistic operator)"); - eventually = (qi::lit("F") > stateFormula)[qi::_val = - phoenix::new_<storm::property::prctl::Eventually<double> >(qi::_1)]; - eventually.name("path formula (for probabilistic operator)"); - next = (qi::lit("X") > stateFormula)[qi::_val = - phoenix::new_<storm::property::prctl::Next<double> >(qi::_1)]; - next.name("path formula (for probabilistic operator)"); - globally = (qi::lit("G") > stateFormula)[qi::_val = - phoenix::new_<storm::property::prctl::Globally<double> >(qi::_1)]; - globally.name("path formula (for probabilistic operator)"); - boundedUntil = (stateFormula[qi::_a = phoenix::construct<std::shared_ptr<storm::property::prctl::AbstractStateFormula<double>>>(qi::_1)] >> qi::lit("U") >> qi::lit("<=") > qi::int_ > stateFormula) - [qi::_val = phoenix::new_<storm::property::prctl::BoundedUntil<double>>(phoenix::bind(&storm::property::prctl::AbstractStateFormula<double>::clone, phoenix::bind(&std::shared_ptr<storm::property::prctl::AbstractStateFormula<double>>::get, qi::_a)), qi::_3, qi::_2)]; - boundedUntil.name("path formula (for probabilistic operator)"); - until = (stateFormula[qi::_a = phoenix::construct<std::shared_ptr<storm::property::prctl::AbstractStateFormula<double>>>(qi::_1)] >> qi::lit("U") > stateFormula)[qi::_val = - phoenix::new_<storm::property::prctl::Until<double>>(phoenix::bind(&storm::property::prctl::AbstractStateFormula<double>::clone, phoenix::bind(&std::shared_ptr<storm::property::prctl::AbstractStateFormula<double>>::get, qi::_a)), qi::_2)]; - until.name("path formula (for probabilistic operator)"); - - //This block defines rules for parsing reward path formulas - rewardPathFormula = (cumulativeReward | reachabilityReward | instantaneousReward | steadyStateReward); - rewardPathFormula.name("path formula (for reward operator)"); - cumulativeReward = (qi::lit("C") > qi::lit("<=") > qi::double_) - [qi::_val = phoenix::new_<storm::property::prctl::CumulativeReward<double>>(qi::_1)]; - cumulativeReward.name("path formula (for reward operator)"); - reachabilityReward = (qi::lit("F") > stateFormula)[qi::_val = - phoenix::new_<storm::property::prctl::ReachabilityReward<double>>(qi::_1)]; - reachabilityReward.name("path formula (for reward operator)"); - instantaneousReward = (qi::lit("I") > qi::lit("=") > qi::uint_) - [qi::_val = phoenix::new_<storm::property::prctl::InstantaneousReward<double>>(qi::_1)]; - instantaneousReward.name("path formula (for reward operator)"); - steadyStateReward = (qi::lit("S"))[qi::_val = phoenix::new_<storm::property::prctl::SteadyStateReward<double>>()]; - formula = (noBoundOperator | stateFormula); - formula.name("PRCTL formula"); + // This block defines rules for parsing filter actions. + boundAction = (qi::lit("bound") > qi::lit("(") >> comparisonType >> qi::lit(",") >> qi::double_ >> qi::lit(")"))[qi::_val = + MAKE(storm::properties::action::BoundAction<double> ,qi::_1, qi::_2)]; + boundAction.name("bound action"); + + invertAction = qi::lit("invert")[qi::_val = MAKE(storm::properties::action::InvertAction<double>, )]; + invertAction.name("invert action"); + + formulaAction = (qi::lit("formula") > qi::lit("(") >> stateFormula >> qi::lit(")"))[qi::_val = + MAKE(storm::properties::action::FormulaAction<double>, qi::_1)]; + formulaAction.name("formula action"); + + rangeAction = ( + (qi::lit("range") >> qi::lit("(") >> qi::uint_ >> qi::lit(",") > qi::uint_ >> qi::lit(")"))[qi::_val = + MAKE(storm::properties::action::RangeAction<double>, qi::_1, qi::_2)] | + (qi::lit("range") >> qi::lit("(") >> qi::uint_ >> qi::lit(")"))[qi::_val = + MAKE(storm::properties::action::RangeAction<double>, qi::_1, qi::_1 + 1)] + ); + rangeAction.name("range action"); + + sortAction = ( + (qi::lit("sort") >> qi::lit("(") >> sortingCategory >> qi::lit(")"))[qi::_val = + MAKE(storm::properties::action::SortAction<double>, qi::_1)] | + (qi::lit("sort") >> qi::lit("(") >> sortingCategory >> qi::lit(", ") >> (qi::lit("ascending") | qi::lit("asc")) > qi::lit(")"))[qi::_val = + MAKE(storm::properties::action::SortAction<double>, qi::_1, true)] | + (qi::lit("sort") >> qi::lit("(") >> sortingCategory >> qi::lit(", ") >> (qi::lit("descending") | qi::lit("desc")) > qi::lit(")"))[qi::_val = + MAKE(storm::properties::action::SortAction<double>, qi::_1, false)] + ); + sortAction.name("sort action"); + + abstractAction = (qi::lit(";") | qi::eps) >> (boundAction | invertAction | formulaAction | rangeAction | sortAction) >> (qi::lit(";") | qi::eps); + abstractAction.name("filter action"); + + filter = (qi::lit("filter") >> qi::lit("[") >> +abstractAction >> qi::lit("]") > qi::lit("(") >> formula >> qi::lit(")"))[qi::_val = + MAKE(prctl::PrctlFilter<double>, qi::_2, qi::_1)] | + (qi::lit("filter") >> qi::lit("[") >> qi::lit("max") > +abstractAction >> qi::lit("]") >> qi::lit("(") >> formula >> qi::lit(")"))[qi::_val = + MAKE(prctl::PrctlFilter<double>, qi::_2, qi::_1, storm::properties::MAXIMIZE)] | + (qi::lit("filter") >> qi::lit("[") >> qi::lit("min") > +abstractAction >> qi::lit("]") >> qi::lit("(") >> formula >> qi::lit(")"))[qi::_val = + MAKE(prctl::PrctlFilter<double>, qi::_2, qi::_1, storm::properties::MINIMIZE)] | + (noBoundOperator)[qi::_val = + qi::_1] | + (formula)[qi::_val = + MAKE(prctl::PrctlFilter<double>, qi::_1)]; + filter.name("PRCTL formula filter"); + + start = (((filter) > (comment | qi::eps))[qi::_val = qi::_1] | comment[qi::_val = MAKE(prctl::PrctlFilter<double>, nullptr)]) > qi::eoi; + start.name("start"); - start = (((formula) > (comment | qi::eps))[qi::_val = qi::_1] | - comment - ) > qi::eoi; - start.name("PRCTL formula"); } - qi::rule<Iterator, storm::property::prctl::AbstractPrctlFormula<double>*(), Skipper> start; - qi::rule<Iterator, storm::property::prctl::AbstractPrctlFormula<double>*(), Skipper> formula; - qi::rule<Iterator, storm::property::prctl::AbstractPrctlFormula<double>*(), Skipper> comment; + qi::rule<Iterator, std::shared_ptr<storm::properties::prctl::PrctlFilter<double>>(), Skipper> start; + qi::rule<Iterator, std::shared_ptr<storm::properties::prctl::PrctlFilter<double>>(), Skipper> filter; - qi::rule<Iterator, storm::property::prctl::AbstractStateFormula<double>*(), Skipper> stateFormula; - qi::rule<Iterator, storm::property::prctl::AbstractStateFormula<double>*(), Skipper> atomicStateFormula; + qi::rule<Iterator, std::shared_ptr<storm::properties::prctl::PrctlFilter<double>>(), Skipper> noBoundOperator; + qi::rule<Iterator, std::shared_ptr<storm::properties::prctl::PrctlFilter<double>>(), Skipper> probabilisticNoBoundOperator; + qi::rule<Iterator, std::shared_ptr<storm::properties::prctl::PrctlFilter<double>>(), Skipper> rewardNoBoundOperator; - qi::rule<Iterator, storm::property::prctl::AbstractStateFormula<double>*(), Skipper> andFormula; - qi::rule<Iterator, storm::property::prctl::AbstractStateFormula<double>*(), Skipper> atomicProposition; - qi::rule<Iterator, storm::property::prctl::AbstractStateFormula<double>*(), Skipper> orFormula; - qi::rule<Iterator, storm::property::prctl::AbstractStateFormula<double>*(), Skipper> notFormula; - qi::rule<Iterator, storm::property::prctl::ProbabilisticBoundOperator<double>*(), Skipper> probabilisticBoundOperator; - qi::rule<Iterator, storm::property::prctl::RewardBoundOperator<double>*(), Skipper> rewardBoundOperator; + qi::rule<Iterator, std::shared_ptr<storm::properties::action::AbstractAction<double>>(), Skipper> abstractAction; + qi::rule<Iterator, std::shared_ptr<storm::properties::action::BoundAction<double>>(), Skipper> boundAction; + qi::rule<Iterator, std::shared_ptr<storm::properties::action::InvertAction<double>>(), Skipper> invertAction; + qi::rule<Iterator, std::shared_ptr<storm::properties::action::FormulaAction<double>>(), Skipper> formulaAction; + qi::rule<Iterator, std::shared_ptr<storm::properties::action::RangeAction<double>>(), Skipper> rangeAction; + qi::rule<Iterator, std::shared_ptr<storm::properties::action::SortAction<double>>(), Skipper> sortAction; - qi::rule<Iterator, storm::property::prctl::AbstractNoBoundOperator<double>*(), Skipper> noBoundOperator; - qi::rule<Iterator, storm::property::prctl::AbstractNoBoundOperator<double>*(), Skipper> probabilisticNoBoundOperator; - qi::rule<Iterator, storm::property::prctl::AbstractNoBoundOperator<double>*(), Skipper> rewardNoBoundOperator; + qi::rule<Iterator, std::shared_ptr<storm::properties::prctl::AbstractPrctlFormula<double>>(), Skipper> formula; + qi::rule<Iterator, std::shared_ptr<storm::properties::prctl::AbstractPrctlFormula<double>>(), Skipper> comment; - qi::rule<Iterator, storm::property::prctl::AbstractPathFormula<double>*(), Skipper> pathFormula; - qi::rule<Iterator, storm::property::prctl::BoundedEventually<double>*(), Skipper> boundedEventually; - qi::rule<Iterator, storm::property::prctl::Eventually<double>*(), Skipper> eventually; - qi::rule<Iterator, storm::property::prctl::Next<double>*(), Skipper> next; - qi::rule<Iterator, storm::property::prctl::Globally<double>*(), Skipper> globally; - qi::rule<Iterator, storm::property::prctl::BoundedUntil<double>*(), qi::locals< std::shared_ptr<storm::property::prctl::AbstractStateFormula<double>>>, Skipper> boundedUntil; - qi::rule<Iterator, storm::property::prctl::Until<double>*(), qi::locals< std::shared_ptr<storm::property::prctl::AbstractStateFormula<double>>>, Skipper> until; + qi::rule<Iterator, std::shared_ptr<storm::properties::prctl::AbstractStateFormula<double>>(), Skipper> stateFormula; + qi::rule<Iterator, std::shared_ptr<storm::properties::prctl::AbstractStateFormula<double>>(), Skipper> atomicStateFormula; - qi::rule<Iterator, storm::property::prctl::AbstractPathFormula<double>*(), Skipper> rewardPathFormula; - qi::rule<Iterator, storm::property::prctl::CumulativeReward<double>*(), Skipper> cumulativeReward; - qi::rule<Iterator, storm::property::prctl::ReachabilityReward<double>*(), Skipper> reachabilityReward; - qi::rule<Iterator, storm::property::prctl::InstantaneousReward<double>*(), Skipper> instantaneousReward; - qi::rule<Iterator, storm::property::prctl::SteadyStateReward<double>*(), Skipper> steadyStateReward; + qi::rule<Iterator, std::shared_ptr<storm::properties::prctl::AbstractStateFormula<double>>(), Skipper> andFormula; + qi::rule<Iterator, std::shared_ptr<storm::properties::prctl::AbstractStateFormula<double>>(), Skipper> atomicProposition; + qi::rule<Iterator, std::shared_ptr<storm::properties::prctl::AbstractStateFormula<double>>(), Skipper> orFormula; + qi::rule<Iterator, std::shared_ptr<storm::properties::prctl::AbstractStateFormula<double>>(), Skipper> notFormula; + qi::rule<Iterator, std::shared_ptr<storm::properties::prctl::ProbabilisticBoundOperator<double>>(), Skipper> probabilisticBoundOperator; + qi::rule<Iterator, std::shared_ptr<storm::properties::prctl::RewardBoundOperator<double>>(), Skipper> rewardBoundOperator; + qi::rule<Iterator, std::shared_ptr<storm::properties::prctl::AbstractPathFormula<double>>(), Skipper> pathFormula; + qi::rule<Iterator, std::shared_ptr<storm::properties::prctl::BoundedEventually<double>>(), Skipper> boundedEventually; + qi::rule<Iterator, std::shared_ptr<storm::properties::prctl::Eventually<double>>(), Skipper> eventually; + qi::rule<Iterator, std::shared_ptr<storm::properties::prctl::Next<double>>(), Skipper> next; + qi::rule<Iterator, std::shared_ptr<storm::properties::prctl::Globally<double>>(), Skipper> globally; + qi::rule<Iterator, std::shared_ptr<storm::properties::prctl::BoundedUntil<double>>(), qi::locals< std::shared_ptr<storm::properties::prctl::AbstractStateFormula<double>>>, Skipper> boundedUntil; + qi::rule<Iterator, std::shared_ptr<storm::properties::prctl::Until<double>>(), qi::locals< std::shared_ptr<storm::properties::prctl::AbstractStateFormula<double>>>, Skipper> until; - qi::rule<Iterator, std::string(), Skipper> freeIdentifierName; - qi::rule<Iterator, storm::property::ComparisonType(), Skipper> comparisonType; + qi::rule<Iterator, std::shared_ptr<storm::properties::prctl::AbstractRewardPathFormula<double>>(), Skipper> rewardPathFormula; + qi::rule<Iterator, std::shared_ptr<storm::properties::prctl::CumulativeReward<double>>(), Skipper> cumulativeReward; + qi::rule<Iterator, std::shared_ptr<storm::properties::prctl::ReachabilityReward<double>>(), Skipper> reachabilityReward; + qi::rule<Iterator, std::shared_ptr<storm::properties::prctl::InstantaneousReward<double>>(), Skipper> instantaneousReward; + qi::rule<Iterator, std::shared_ptr<storm::properties::prctl::SteadyStateReward<double>>(), Skipper> steadyStateReward; -}; -} //namespace storm -} //namespace parser + qi::rule<Iterator, std::string(), Skipper> freeIdentifierName; + qi::rule<Iterator, storm::properties::ComparisonType(), Skipper> comparisonType; + qi::rule<Iterator, storm::properties::action::SortAction<double>::SortingCategory(), Skipper> sortingCategory; +}; -storm::parser::PrctlParser::PrctlParser(std::string formulaString) { +std::shared_ptr<storm::properties::prctl::PrctlFilter<double>> PrctlParser::parsePrctlFormula(std::string formulaString) { // Prepare iterators to input. BaseIteratorType stringIteratorBegin = formulaString.begin(); BaseIteratorType stringIteratorEnd = formulaString.end(); @@ -204,7 +259,7 @@ storm::parser::PrctlParser::PrctlParser(std::string formulaString) { // Prepare resulting intermediate representation of input. - storm::property::prctl::AbstractPrctlFormula<double>* result_pointer = nullptr; + std::shared_ptr<storm::properties::prctl::PrctlFilter<double>> result_pointer(nullptr); PrctlGrammar<PositionIteratorType, BOOST_TYPEOF(boost::spirit::ascii::space)> grammar; @@ -238,5 +293,15 @@ storm::parser::PrctlParser::PrctlParser(std::string formulaString) { throw storm::exceptions::WrongFormatException() << msg.str(); } - formula = result_pointer; + // The syntax can be so wrong that no rule can be matched at all + // In that case, no expectation failure is thrown, but the parser just returns nullptr + // Then, of course the result is not usable, hence we throw a WrongFormatException, too. + if (!result_pointer) { + throw storm::exceptions::WrongFormatException() << "Syntax error in formula"; + } + + return result_pointer; } + +} //namespace parser +} //namespace storm diff --git a/src/parser/PrctlParser.h b/src/parser/PrctlParser.h index 3ba8f1998..c1fc798bb 100644 --- a/src/parser/PrctlParser.h +++ b/src/parser/PrctlParser.h @@ -1,8 +1,8 @@ #ifndef STORM_PARSER_PRCTLPARSER_H_ #define STORM_PARSER_PRCTLPARSER_H_ -#include "src/formula/Prctl.h" -//#include <memory> +#include "src/properties/Prctl.h" +#include "src/properties/prctl/PrctlFilter.h" namespace storm { namespace parser { @@ -11,49 +11,29 @@ namespace parser { * Reads a PRCTL formula from a string and return the formula tree. * * If you want to read the formula from a file, use the PrctlFileParser class instead. - * - * @note - * This class creates a PctlFormula object which can be accessed through the getFormula() method (of base - * class PrctlParser). However, it will not delete this object. */ class PrctlParser { - public: - /*! - * Reads a PRCTL formula from its string representation and parses it into a formula tree, consisting of - * classes in the namespace storm::property. - * - * If the string could not be parsed successfully, it will throw a wrongFormatException. - * - * @param formulaString The string representation of the formula - * @throw wrongFormatException If the input could not be parsed successfully - */ - PrctlParser(std::string formulaString); - - /*! - * @return a pointer to the parsed formula object - */ - storm::property::prctl::AbstractPrctlFormula<double>* getFormula() { - return this->formula; - } - - /*! - * Checks whether the line which was parsed was a comment line; also returns true if the line was empty (as the semantics are - * the same) - * - * @return True if the parsed line consisted completely of a (valid) comment, false otherwise. - */ - bool parsedComment() { - return (formula == nullptr); - } - - private: - storm::property::prctl::AbstractPrctlFormula<double>* formula; - - /*! - * Struct for the Prctl grammar, that Boost::Spirit uses to parse the formulas. - */ - template<typename Iterator, typename Skipper> - struct PrctlGrammar; +public: + + /*! + * Reads a Prctl formula from its string representation and parses it into a formula tree, consisting of + * classes in the namespace storm::properties. + * + * If the string could not be parsed successfully, it will throw a wrongFormatException. + * + * @param formulaString The string representation of the formula + * @throw wrongFormatException If the input could not be parsed successfully + * @return A PrctlFilter maintaining the parsed formula. If the line just contained a comment a nullptr will be returned instead. + */ + static std::shared_ptr<storm::properties::prctl::PrctlFilter<double>> parsePrctlFormula(std::string formulaString); + +private: + + /*! + * Struct for the Prctl grammar, that Boost::Spirit uses to parse the formulas. + */ + template<typename Iterator, typename Skipper> + struct PrctlGrammar; }; diff --git a/src/properties/AbstractFilter.h b/src/properties/AbstractFilter.h new file mode 100644 index 000000000..5c8899a09 --- /dev/null +++ b/src/properties/AbstractFilter.h @@ -0,0 +1,223 @@ +/* + * Filter.h + * + * Created on: Apr 26, 2014 + * Author: Manuel Sascha Weiand + */ + +#ifndef STORM_FORMULA_ABSTRACTFILTER_H_ +#define STORM_FORMULA_ABSTRACTFILTER_H_ + +#include <vector> +#include <string> +#include "src/properties/AbstractFormula.h" +#include "src/properties/actions/AbstractAction.h" + +namespace storm { +namespace properties { + +/*! + * This enum contains value indicating which kind of scheduler is to be used + * for path formulas, i.e. probability or reward queries on nondeterministic models. + */ +enum OptimizingOperator {MINIMIZE, MAXIMIZE, UNDEFINED}; + +/*! + * This is the base class for the logic specific filter classes. + * It provides the logic independent functionality concerning the organization of actions and the optimization operator. + * + * The general role of the filter is to twofold. + * + * On the one hand it is meant to be the interface between the control and the formulas and modelchecker. + * It sits one level above the root of the formula tree which is represented by it. + * This gives a distinct class that can be moved through the control functions, thus encapsulating the formula tree and all its classes. + * + * On the other hand, as all modelchecking is initiated through its interface it opens up the opportunity to manipulate the output generated by the modelchecker. + * The manipulation is done by a series of filter actions which are evaluated after the modelchecker has finished. + * Each action has a distinct function that ranges from state selection to sorting. + * The input for the first filter action consists mainly of the modelckecking result. + * Thereafter, the result of each filter action is used as input for the next filter action until all actions have been executed. + * The final result is then used to generate the output. + */ +template <class T> +class AbstractFilter { + +public: + + /*! + * Constructs an empty AbstractFilter. + * If a value for the optimization operator is given it will be set accordingly. + * Otherwise, it will be undefined. The undefined value is intended for deterministic + * models, as the do not need a scheduler resolving the nondeterminism. + * + * @note If a query is executed on a nondeterministic model using an undefined optimization operator + * the modelchecker will throw an exception. + * + * @param opt The value of the optimization operator. + */ + AbstractFilter(OptimizingOperator opt = UNDEFINED) : opt(opt) { + // Intentionally left empty. + } + + /*! + * Constructs an AbstractFilter containing only the specified action. + * + * @note If the shared_ptr to the action is empty (contains a nullptr) the Abstract filter will be created empty. + * + * @param action The action to be executed during evaluation. + * @param opt The value of the optimization operator. + */ + AbstractFilter(std::shared_ptr<action::AbstractAction<T>> const & action, OptimizingOperator opt = UNDEFINED) : opt(opt) { + if(action.get() != nullptr) { + actions.push_back(action); + } + } + + /*! + * Constructs an AbstractFilter containing the given vector of actions as action list. + * The actions will be executed in ascending order of index. + * + * @note Any vector entry containing an empty shared_ptr will be ignored. Thus, giving a + * vector of five actions with two empty shared_ptr will result in a AbstractFilter containing three actions. + * + * @param actions A vector of shared_ptr to the actions to be executed during evaluation. + * @param opt The value of the optimization operator. + */ + AbstractFilter(std::vector<std::shared_ptr<action::AbstractAction<T>>> const & actions, OptimizingOperator opt = UNDEFINED) { + // Filter out all nullptr actions. + // First detect that there is at least one. + uint_fast64_t emptyCount = 0; + for(uint_fast64_t i = 0; i < actions.size(); i++) { + if (actions[i].get() == nullptr) { + emptyCount++; + } + } + + if(emptyCount > 0) { + // There is at least one nullptr action. + // Allocate space for the non null actions. + this->actions.reserve(actions.size() - emptyCount); + + // Fill the vector. Note: For most implementations of the standard there will be no reallocation in the vector while doing this. + for(auto action : actions){ + if(action.get() != nullptr) { + this->actions.push_back(action); + } + } + } else { + this->actions = actions; + } + + this->opt = opt; + } + + /*! + * The virtual destructor. + */ + virtual ~AbstractFilter() { + // Intentionally left empty. + } + + /*! + * Returns a string representation of the filter. + * + * @returns A string representing the filter. + */ + virtual std::string toString() const { + std::string desc = "filter("; + + for(auto action : actions) { + desc += action->toString(); + desc += ", "; + } + + // Remove the last ", ". + if(!actions.empty()) { + desc.pop_back(); + desc.pop_back(); + } + + desc += ")"; + + return desc; + } + + /*! + * Appends the given action to the list of actions to be executed during evaluation. + * + * @note If the argument is an empty shared_ptr nothing will happen. + * + * @param action A shared pointer to the action to be appended. + */ + void addAction(std::shared_ptr<action::AbstractAction<T>> const & action) { + if(action.get() != nullptr) { + actions.push_back(action); + } + } + + /*! + * Removes the last action. + */ + void removeAction() { + actions.pop_back(); + } + + /*! + * Returns the action at the specified position. + * + * @param position The position of the action to be returned within the action list. + * @returns A shared pointer to the specified action. + */ + std::shared_ptr<action::AbstractAction<T>> getAction(uint_fast64_t position) { + // Make sure the chosen position is not beyond the end of the vector. + // If it is so return the last element. + if(position < actions.size()) { + return actions[position]; + } else { + return actions[actions.size()-1]; + } + } + + /*! + * Returns the number of actions to be executed during evaluation. + * + * @returns The number of actions in the action list. + */ + uint_fast64_t getActionCount() const { + return actions.size(); + } + + /*! + * Sets whether a minimizing or a maximizing scheduler is to be used for + * modelchecking of path formulas, i.e. probability and reward queries. + * + * @param opt The new operator specifying the scheduler to be used for path formulas. + */ + void setOptimizingOperator(OptimizingOperator opt) { + this->opt = opt; + } + + /*! + * Returns the current optimization operator. + * + * @return The optimization operator. + */ + OptimizingOperator getOptimizingOperator() const { + return opt; + } + +protected: + + //! The vector containing the actions to be executed during evaluation. + std::vector<std::shared_ptr<action::AbstractAction<T>>> actions; + + //! The optimization operator specifying if and which kind of scheduler is to be used during modelchecking of path formulas on nondeterministic models. + OptimizingOperator opt; +}; + +} //namespace properties +} //namespace storm + + + +#endif /* STORM_FORMULA_ABSTRACTFILTER_H_ */ diff --git a/src/properties/AbstractFormula.h b/src/properties/AbstractFormula.h new file mode 100644 index 000000000..9c55dc370 --- /dev/null +++ b/src/properties/AbstractFormula.h @@ -0,0 +1,70 @@ +/* + * Abstractformula.h + * + * Created on: 19.10.2012 + * Author: Thomas Heinemann + */ + +#ifndef STORM_FORMULA_ABSTRACTFORMULA_H_ +#define STORM_FORMULA_ABSTRACTFORMULA_H_ + +#include <string> +#include <memory> + +namespace storm { +namespace properties { +template <class T> class AbstractFormula; +} //namespace properties +} //namespace storm + +namespace storm { +namespace properties { + +/*! + * This is the abstract base class for every formula class in every logic. + * + * There are currently three implemented logics Ltl, Csl and Pctl. + * The implementation of these logics can be found in the namespaces storm::properties::<logic> + * where <logic> is one of ltl, pctl and csl. + * + * @note While formula classes do have copy constructors using a copy constructor + * will yield a formula objects whose formula subtree consists of the same objects + * as the original formula. The ownership of the formula tree will be shared between + * the original and the copy. + */ +template <class T> +class AbstractFormula { + +public: + + /*! + * The virtual destructor. + */ + virtual ~AbstractFormula() { + // Intentionally left empty. + } + + /*! + * Return string representation of this formula. + * + * @note Every subclass must implement this method. + * + * @returns a string representation of the formula + */ + virtual std::string toString() const = 0; + + /*! + * Returns whether the formula is a propositional logic formula. + * That is, this formula and all its subformulas consist only of And, Or, Not and AP. + * + * @return True iff this is a propositional logic formula. + */ + virtual bool isPropositional() const { + return false; + } +}; + +} // namespace properties +} // namespace storm + +#endif /* STORM_FORMULA_ABSTRACTFORMULA_H_ */ diff --git a/src/formula/ComparisonType.h b/src/properties/ComparisonType.h similarity index 58% rename from src/formula/ComparisonType.h rename to src/properties/ComparisonType.h index 98ee80373..c0eb598bc 100644 --- a/src/formula/ComparisonType.h +++ b/src/properties/ComparisonType.h @@ -9,8 +9,13 @@ #define STORM_FORMULA_COMPARISONTYPE_H_ namespace storm { -namespace property { +namespace properties { +/*! + * An enum representing the greater- and less-than operators in both + * the strict (<, >) and the non strict (<=, >=) variant. + * It is mainly used to represent upper and lower bounds. + */ enum ComparisonType { LESS, LESS_EQUAL, GREATER, GREATER_EQUAL }; } diff --git a/src/properties/Csl.h b/src/properties/Csl.h new file mode 100644 index 000000000..f76385f89 --- /dev/null +++ b/src/properties/Csl.h @@ -0,0 +1,29 @@ +/* + * Csl.h + * + * Created on: 19.04.2013 + * Author: Thomas Heinemann + */ + +#ifndef STORM_FORMULA_CSL_H_ +#define STORM_FORMULA_CSL_H_ + +#include "src/modelchecker/csl/ForwardDeclarations.h" + +#include "csl/And.h" +#include "csl/Ap.h" +#include "csl/Next.h" +#include "csl/Not.h" +#include "csl/Or.h" +#include "csl/ProbabilisticBoundOperator.h" +#include "csl/SteadyStateBoundOperator.h" + +#include "csl/Until.h" +#include "csl/Eventually.h" +#include "csl/Globally.h" +#include "csl/TimeBoundedEventually.h" +#include "csl/TimeBoundedUntil.h" + +#include "modelchecker/csl/AbstractModelChecker.h" + +#endif /* STORM_FORMULA_CSL_H_ */ diff --git a/src/formula/Ltl.h b/src/properties/Ltl.h similarity index 53% rename from src/formula/Ltl.h rename to src/properties/Ltl.h index cac53a8be..69551ff5c 100644 --- a/src/formula/Ltl.h +++ b/src/properties/Ltl.h @@ -10,16 +10,16 @@ #include "src/modelchecker/ltl/ForwardDeclarations.h" -#include "Ltl/And.h" -#include "Ltl/Ap.h" -#include "Ltl/BoundedEventually.h" -#include "Ltl/BoundedUntil.h" -#include "Ltl/Eventually.h" -#include "Ltl/Globally.h" -#include "Ltl/Next.h" -#include "Ltl/Not.h" -#include "Ltl/Or.h" -#include "Ltl/Until.h" +#include "ltl/And.h" +#include "ltl/Ap.h" +#include "ltl/BoundedEventually.h" +#include "ltl/BoundedUntil.h" +#include "ltl/Eventually.h" +#include "ltl/Globally.h" +#include "ltl/Next.h" +#include "ltl/Not.h" +#include "ltl/Or.h" +#include "ltl/Until.h" #include "modelchecker/ltl/AbstractModelChecker.h" diff --git a/src/properties/Prctl.h b/src/properties/Prctl.h new file mode 100644 index 000000000..d66e92e03 --- /dev/null +++ b/src/properties/Prctl.h @@ -0,0 +1,40 @@ +/* + * Prctl.h + * + * Created on: 06.12.2012 + * Author: Christian Dehnert + */ + +#ifndef STORM_FORMULA_PRCTL_H_ +#define STORM_FORMULA_PRCTL_H_ + +#include "modelchecker/prctl/ForwardDeclarations.h" + +#include "prctl/And.h" +#include "prctl/Ap.h" +#include "prctl/BoundedUntil.h" +#include "prctl/BoundedNaryUntil.h" +#include "prctl/Next.h" +#include "prctl/Not.h" +#include "prctl/Or.h" +#include "prctl/ProbabilisticBoundOperator.h" + +#include "prctl/Until.h" +#include "prctl/Eventually.h" +#include "prctl/Globally.h" +#include "prctl/BoundedEventually.h" + +#include "prctl/InstantaneousReward.h" +#include "prctl/CumulativeReward.h" +#include "prctl/ReachabilityReward.h" +#include "prctl/RewardBoundOperator.h" +#include "prctl/SteadyStateReward.h" + +#include "prctl/AbstractPrctlFormula.h" +#include "prctl/AbstractStateFormula.h" +#include "prctl/AbstractPathFormula.h" +#include "prctl/AbstractRewardPathFormula.h" + +#include "modelchecker/prctl/AbstractModelChecker.h" + +#endif /* STORM_FORMULA_PRCTL_H_ */ diff --git a/src/properties/actions/AbstractAction.h b/src/properties/actions/AbstractAction.h new file mode 100644 index 000000000..b0f17bb28 --- /dev/null +++ b/src/properties/actions/AbstractAction.h @@ -0,0 +1,148 @@ +/* + * AbstractAction.h + * + * Created on: Apr 26, 2014 + * Author: Manuel Sascha Weiand + */ + +#ifndef STORM_FORMULA_ACTION_ABSTRACTACTION_H_ +#define STORM_FORMULA_ACTION_ABSTRACTACTION_H_ + +#include <vector> +#include <utility> +#include "src/storage/BitVector.h" +#include "src/modelchecker/prctl/AbstractModelChecker.h" +#include "src/modelchecker/csl/AbstractModelChecker.h" +#include "src/modelchecker/ltl/AbstractModelChecker.h" + +namespace storm { +namespace properties { +namespace action { + +/*! + * This is the abstract base class for all filter actions. + * + * Each action implements a distinct function which executed each time evaluate() is called. + * The input and output for each action is an instance of the Result struct. + * Thus the action is able to manipulate both the selection of output states and the order in which they are returned. + */ +template <class T> +class AbstractAction { + +public: + + /*! + * This is the struct used by all actions to pass along information. + * + * It contains fields for the two possible data structures containing the modelchecking results. + * A value vector for path formulas and a bit vector for state formulas. + * The two other fields are used to describe a selection as well as an ordering of states within the modelchecking results. + * + * @note For each formula the modelchecker will return either a BitVector or a std::vector. + * Thus, either the state- or the pathResult should be set to be empty. + * If both contain a value for at least one state the pathResult will be used. + * + * @note The four vectors should always have the same number of entries. + */ + struct Result { + + /*! + * Constructs an empty Result. + */ + Result() : selection(), stateMap(), pathResult(), stateResult(){ + // Intentionally left empty. + } + + /*! + * Copy constructs a Result. + * + * @param other The Result from which the fields are copied. + */ + Result(Result const & other) : selection(other.selection), stateMap(other.stateMap), pathResult(other.pathResult), stateResult(other.stateResult) { + // Intentionally left empty. + } + + /*! + * Constructs a Result using values for each field. + * + * @param selection A BitVector describing which states are currently selected. + * @param stateMap A vector representing an ordering on the states within the modelchecking results. + * @param pathResult The modelchecking result for a path formula. + * @param stateResult The modelchecking result for a state formula. + */ + Result(storm::storage::BitVector const & selection, std::vector<uint_fast64_t> const & stateMap, std::vector<T> const & pathResult, storm::storage::BitVector const & stateResult) : selection(selection), stateMap(stateMap), pathResult(pathResult), stateResult(stateResult) { + // Intentionally left empty. + } + + //! A BitVector describing which states are currently selected. + //! For state i the i-th bit is true iff state i is selected. + storm::storage::BitVector selection; + + //! A vector representing an ordering on the states within the modelchecking results. + //! The first value of the vector is the index of the state to be returned first. + //! Thus, stateMap[i] is the index of the state that is to be returned at position i. + std::vector<uint_fast64_t> stateMap; + + //! The modelchecking result for a path formula. + std::vector<T> pathResult; + + //! The modelchecking result for a state formula. + storm::storage::BitVector stateResult; + }; + + /*! + * The virtual destructor. + * To ensure that the right destructor is called. + */ + virtual ~AbstractAction() { + //Intentionally left empty + } + + /*! + * Evaluate the action for a Prctl formula. + * + * @param result The Result struct on which the action is to be evaluated. + * @param mc The Prctl modelchecker that computed the path- or stateResult contained in the Result struct. + * @returns A Result struct containing the output of the action. + */ + virtual Result evaluate(Result const & result, storm::modelchecker::prctl::AbstractModelChecker<T> const & mc) const { + return Result(); + } + + /*! + * Evaluate the action for a Csl formula. + * + * @param result The Result struct on which the action is to be evaluated. + * @param mc The Csl modelchecker that computed the path- or stateResult contained in the Result struct. + * @returns A Result struct containing the output of the action. + */ + virtual Result evaluate(Result const & result, storm::modelchecker::csl::AbstractModelChecker<T> const & mc) const { + return Result(); + } + + /*! + * Evaluate the action for an Ltl formula. + * + * @param result The Result struct on which the action is to be evaluated. + * @param mc The Ltl modelchecker that computed the path- or stateResult contained in the Result struct. + * @returns A Result struct containing the output of the action. + */ + virtual Result evaluate(Result const & result, storm::modelchecker::ltl::AbstractModelChecker<T> const & mc) const { + return Result(); + } + + /*! + * Returns a string representation of the action. + * + * @returns A string representing the action. + */ + virtual std::string toString() const = 0; + +}; + +} //namespace action +} //namespace properties +} //namespace storm + + +#endif /* STORM_FORMULA_ACTION_ABSTRACTACTION_H_ */ diff --git a/src/properties/actions/BoundAction.h b/src/properties/actions/BoundAction.h new file mode 100644 index 000000000..7dadc4c37 --- /dev/null +++ b/src/properties/actions/BoundAction.h @@ -0,0 +1,214 @@ +/* + * BoundAction.h + * + * Created on: Jun 22, 2014 + * Author: Manuel Sascha Weiand + */ + +#ifndef STORM_FORMULA_ACTION_BOUNDACTION_H_ +#define STORM_FORMULA_ACTION_BOUNDACTION_H_ + +#include "src/properties/actions/AbstractAction.h" +#include "src/properties/ComparisonType.h" +#include "src/exceptions/InvalidArgumentException.h" + +namespace storm { +namespace properties { +namespace action { + +/*! + * The bound action deselects all states whose modelchecking values do not satisfy the given bound. + * + * Strict and non strict upper and lower bounds can be represented. + * For modelchecking results of state formulas the value is taken to be 1 iff true and 0 otherwise. + */ +template <class T> +class BoundAction : public AbstractAction<T> { + + // Convenience typedef to make the code more readable. + typedef typename AbstractAction<T>::Result Result; + +public: + + /*! + * Constructs an empty BoundAction. + * The bound is set to >= 0. Thus, all states will be selected by the action. + */ + BoundAction() : comparisonOperator(storm::properties::GREATER_EQUAL), bound(0) { + //Intentionally left empty. + } + + /*! + * Constructs a BoundAction using the given values for the comparison operator and the bound. + * + * @param comparisonOperator The operator used to make the comparison between the bound and the modelchecking values for each state. + * @param bound The bound to compare the modelchecking values against. + */ + BoundAction(storm::properties::ComparisonType comparisonOperator, T bound) : comparisonOperator(comparisonOperator), bound(bound) { + //Intentionally left empty. + } + + /*! + * The virtual destructor. + * To ensure that the right destructor is called. + */ + virtual ~BoundAction() { + //Intentionally left empty + } + + /*! + * Evaluate the action for an Prctl formula. + * + * @param result The Result struct on which the action is to be evaluated. + * @param mc The Prctl modelchecker that computed the path- or stateResult contained in the Result struct. + * @returns A Result struct containing the output of the action. + */ + virtual Result evaluate(Result const & result, storm::modelchecker::prctl::AbstractModelChecker<T> const & mc) const override { + return evaluate(result); + } + + /*! + * Evaluate the action for an Csl formula. + * + * @param result The Result struct on which the action is to be evaluated. + * @param mc The Csl modelchecker that computed the path- or stateResult contained in the Result struct. + * @returns A Result struct containing the output of the action. + */ + virtual Result evaluate(Result const & result, storm::modelchecker::csl::AbstractModelChecker<T> const & mc) const override { + return evaluate(result); + } + + /*! + * Evaluate the action for an Ltl formula. + * + * @param result The Result struct on which the action is to be evaluated. + * @param mc The Ltl modelchecker that computed the path- or stateResult contained in the Result struct. + * @returns A Result struct containing the output of the action. + */ + virtual Result evaluate(Result const & result, storm::modelchecker::ltl::AbstractModelChecker<T> const & mc) const override { + return evaluate(result); + } + + /*! + * Returns a string representation of this action. + * + * @returns A string representing this action. + */ + virtual std::string toString() const override { + std::string out = "bound("; + switch (comparisonOperator) { + case LESS: + out += "<"; + break; + case LESS_EQUAL: + out += "<="; + break; + case GREATER: + out += ">"; + break; + case GREATER_EQUAL: + out += ">="; + break; + default: + LOG4CPLUS_ERROR(logger, "Unknown comparison operator of value " << comparisonOperator << "."); + throw storm::exceptions::InvalidArgumentException() << "Unknown comparison operator of value " << comparisonOperator << "."; + break; + } + out += ", "; + out += std::to_string(bound); + out += ")"; + return out; + } + +private: + + /*! + * Evaluate the action. + * + * As the BoundAction does not depend on the model or the formula for which the modelchecking result was computed, + * it does not depend on the modelchecker at all. This internal version of the evaluate method therefore only needs the + * modelchecking result as input. + * + * @param result The Result struct on which the action is to be evaluated. + * @returns A Result struct containing the output of the action. + */ + virtual Result evaluate(Result const & result) const { + + //Initialize the new selection vector. + storm::storage::BitVector out(result.selection.size()); + + if(result.pathResult.size() != 0) { + + if(result.stateResult.size() != 0) { + LOG4CPLUS_WARN(logger, "Both pathResult and stateResult are set. The filter action is applied using only the pathResult."); + std::cout << "Both pathResult and stateResult are set. The filter action is applied using only the pathResult." << std::endl; + } + + //Fill the selection by comparing the values for all previously selected states with the given bound using the comparison operator. + for(uint_fast64_t i = 0; i < result.pathResult.size(); i++) { + if(result.selection[i]) { + switch(comparisonOperator) { + case storm::properties::GREATER_EQUAL: + out.set(i, result.pathResult[i] >= bound); + break; + case storm::properties::GREATER: + out.set(i, result.pathResult[i] > bound); + break; + case storm::properties::LESS_EQUAL: + out.set(i, result.pathResult[i] <= bound); + break; + case storm::properties::LESS: + out.set(i, result.pathResult[i] < bound); + break; + default: + LOG4CPLUS_ERROR(logger, "Unknown comparison operator of value " << comparisonOperator << "."); + throw storm::exceptions::InvalidArgumentException() << "Unknown comparison operator of value " << comparisonOperator << "."; + break; + } + } + } + } else { + + //Fill the selction by comapring the values for all previously selected states with theegiven bound using the comparison operator. + for(uint_fast64_t i = 0; i < result.stateMap.size(); i++) { + if(result.selection[i]) { + switch(comparisonOperator) { + case storm::properties::GREATER_EQUAL: + out.set(i, result.stateResult[i] >= bound); + break; + case storm::properties::GREATER: + out.set(i, result.stateResult[i] > bound); + break; + case storm::properties::LESS_EQUAL: + out.set(i, result.stateResult[i] <= bound); + break; + case storm::properties::LESS: + out.set(i, result.stateResult[i] < bound); + break; + default: + LOG4CPLUS_ERROR(logger, "Unknown comparison operator of value " << comparisonOperator << "."); + throw storm::exceptions::InvalidArgumentException() << "Unknown comparison operator of value " << comparisonOperator << "."; + break; + } + } + } + } + + return Result(out, result.stateMap, result.pathResult, result.stateResult); + } + + // The operator used to make the comparison between the bound and the modelchecking values for each state at time of evaluation. + storm::properties::ComparisonType comparisonOperator; + + // The bound to compare the modelchecking values against during evaluation. + T bound; + +}; + + +} +} +} + + +#endif /* STORM_FORMULA_ACTION_BOUNDACTION_H_ */ diff --git a/src/properties/actions/FormulaAction.h b/src/properties/actions/FormulaAction.h new file mode 100644 index 000000000..744c76038 --- /dev/null +++ b/src/properties/actions/FormulaAction.h @@ -0,0 +1,140 @@ +/* + * PrctlFormulaAction.h + * + * Created on: Jun 6, 2014 + * Author: Manuel Sascha Weiand + */ + +#ifndef STORM_FORMULA_ACTION_FORMULAACTION_H_ +#define STORM_FORMULA_ACTION_FORMULAACTION_H_ + +#include "src/properties/actions/AbstractAction.h" +#include "src/properties/prctl/AbstractStateFormula.h" +#include "src/properties/csl/AbstractStateFormula.h" + + +#include <string> + +namespace storm { +namespace properties { +namespace action { + +/*! + * The Formula action deselects all states that do not satisfy the given state formula. + * + * @note Since there is no modelchecker implemented for Ltl formulas (except the abstract base class) + * the formula action currently only supports Prctl and Csl state formulas. + */ +template <class T> +class FormulaAction : public AbstractAction<T> { + + // Convenience typedef to make the code more readable. + typedef typename AbstractAction<T>::Result Result; + +public: + + + /*! + * Constructs an empty FormulaAction. + * + * The evaluation will do nothing and return the Result as it was put in. + */ + FormulaAction() : prctlFormula(nullptr), cslFormula(nullptr) { + //Intentionally left empty. + } + + /*! + * Constructs a FormulaAction using the given Prctl formula. + * + * @param prctlFormula The Prctl state formula used to filter the selection during evaluation. + */ + FormulaAction(std::shared_ptr<storm::properties::prctl::AbstractStateFormula<T>> const & prctlFormula) : prctlFormula(prctlFormula), cslFormula(nullptr) { + //Intentionally left empty. + } + + /*! + * Constructs a FormulaAction using the given Csl formula. + * + * @param cslFormula The Csl state formula used to filter the selection during evaluation. + */ + FormulaAction(std::shared_ptr<storm::properties::csl::AbstractStateFormula<T>> const & cslFormula) : prctlFormula(nullptr), cslFormula(cslFormula) { + //Intentionally left empty. + } + + /*! + * The virtual destructor. + * To ensure that the right destructor is called. + */ + virtual ~FormulaAction() { + // Intentionally left empty. + } + + /*! + * Evaluate the action for an Prctl formula. + * + * @param result The Result struct on which the action is to be evaluated. + * @param mc The Prctl modelchecker that computed the path- or stateResult contained in the Result struct. + * @returns A Result struct containing the output of the action. + */ + virtual Result evaluate(Result const & result, storm::modelchecker::prctl::AbstractModelChecker<T> const & mc) const override { + + storm::storage::BitVector selection(result.selection); + + //Compute the modelchecking results of the actions state formula and deselect all states that do not satisfy it. + if(prctlFormula.get() != nullptr) { + selection = selection & prctlFormula->check(mc); + } + + return Result(selection, result.stateMap, result.pathResult, result.stateResult); + } + + /*! + * Evaluate the action for an Csl formula. + * + * @param result The Result struct on which the action is to be evaluated. + * @param mc The Csl modelchecker that computed the path- or stateResult contained in the Result struct. + * @returns A Result struct containing the output of the action. + */ + virtual Result evaluate(Result const & result, storm::modelchecker::csl::AbstractModelChecker<T> const & mc) const override { + + storm::storage::BitVector selection(result.selection); + + //Compute the modelchecking results of the actions state formula and deselect all states that do not satisfy it. + if(cslFormula.get() != nullptr) { + selection = selection & cslFormula->check(mc); + } + + return Result(selection, result.stateMap, result.pathResult, result.stateResult); + } + + /*! + * Returns a string representation of this action. + * + * @returns A string representing this action. + */ + virtual std::string toString() const override { + std::string out = "formula("; + if(prctlFormula.get() != nullptr) { + out += prctlFormula->toString(); + } else if(cslFormula.get() != nullptr) { + out += cslFormula->toString(); + } + out += ")"; + return out; + } + +private: + + // The Prctl state formula used during evaluation. + std::shared_ptr<storm::properties::prctl::AbstractStateFormula<T>> prctlFormula; + + // The Csl state formula used during evaluation. + std::shared_ptr<storm::properties::csl::AbstractStateFormula<T>> cslFormula; + +}; + +} //namespace action +} //namespace properties +} //namespace storm + +#endif /* STORM_FORMULA_ACTION_FORMULAACTION_H_ */ diff --git a/src/properties/actions/InvertAction.h b/src/properties/actions/InvertAction.h new file mode 100644 index 000000000..69c7baa23 --- /dev/null +++ b/src/properties/actions/InvertAction.h @@ -0,0 +1,110 @@ +/* + * InvertAction.h + * + * Created on: Jun 22, 2014 + * Author: Manuel Sascha Weiand + */ + +#ifndef STORM_FORMULA_ACTION_INVERTACTION_H_ +#define STORM_FORMULA_ACTION_INVERTACTION_H_ + +#include "src/properties/actions/AbstractAction.h" + +namespace storm { +namespace properties { +namespace action { + +/*! + * The InvertAction inverts the selection, selecting precisely the unselected states. + */ +template <class T> +class InvertAction : public AbstractAction<T> { + + // Convenience typedef to make the code more readable. + typedef typename AbstractAction<T>::Result Result; + +public: + + /*! + * Constructs an InvertAction. + * + * As the simple inversion of the selection does not need any parameters, the empty constructor is the only one needed. + */ + InvertAction() { + //Intentionally left empty. + } + + /*! + * The virtual destructor. + * To ensure that the right destructor is called. + */ + virtual ~InvertAction() { + //Intentionally left empty + } + + /*! + * Evaluate the action for a Prctl formula. + * + * @param result The Result struct on which the action is to be evaluated. + * @param mc The Prctl modelchecker that computed the path- or stateResult contained in the Result struct. + * @returns A Result struct containing the output of the action. + */ + virtual Result evaluate(Result const & result, storm::modelchecker::prctl::AbstractModelChecker<T> const & mc) const override { + return evaluate(result); + } + + /*! + * Evaluate the action for a Csl formula. + * + * @param result The Result struct on which the action is to be evaluated. + * @param mc The Csl modelchecker that computed the path- or stateResult contained in the Result struct. + * @returns A Result struct containing the output of the action. + */ + virtual Result evaluate(Result const & result, storm::modelchecker::csl::AbstractModelChecker<T> const & mc) const override { + return evaluate(result); + } + + /*! + * Evaluate the action for a Ltl formula. + * + * @param result The Result struct on which the action is to be evaluated. + * @param mc The Ltl modelchecker that computed the path- or stateResult contained in the Result struct. + * @returns A Result struct containing the output of the action. + */ + virtual Result evaluate(Result const & result, storm::modelchecker::ltl::AbstractModelChecker<T> const & mc) const override { + return evaluate(result); + } + + /*! + * Returns a string representation of this action. + * + * @returns A string representing this action. + */ + virtual std::string toString() const override { + return "invert"; + } + +private: + + /*! + * Evaluate the action. + * + * As the InvertAction does not depend on the model or the formula for which the modelchecking result was computed, + * it does not depend on the modelchecker at all. This internal version of the evaluate method therefore only needs the + * modelchecking result as input. + * + * @param result The Result struct on which the action is to be evaluated. + * @returns A Result struct containing the output of the action. + */ + virtual Result evaluate(Result const & result) const { + storm::storage::BitVector out(result.selection); + return Result(~out, result.stateMap, result.pathResult, result.stateResult); + } +}; + +} //namespace action +} //namespace properties +} //namespace storm + + +#endif /* STORM_FORMULA_ACTION_INVERTACTION_H_ */ diff --git a/src/properties/actions/RangeAction.h b/src/properties/actions/RangeAction.h new file mode 100644 index 000000000..5647deca4 --- /dev/null +++ b/src/properties/actions/RangeAction.h @@ -0,0 +1,155 @@ +/* + * RangeAction.h + * + * Created on: Apr 26, 2014 + * Author: Manuel Sascha Weiand + */ + +#ifndef STORM_FORMULA_ACTION_RANGEACTION_H_ +#define STORM_FORMULA_ACTION_RANGEACTION_H_ + +#include "src/properties/actions/AbstractAction.h" + +namespace storm { +namespace properties { +namespace action { + +/*! + * The RangeAction deselects all states that are not within the given range. + * + * The bounds of the range given are indices in the result ordering. + * Thus, if the lower bound is 0 and the upper bound is 5 then all states that are not + * at index 0 through 5 (including) in the state ordering will be deselected. + * This action is thought to be used in connection with the SortAction. + */ +template <class T> +class RangeAction : public AbstractAction<T> { + + // Convenience typedef to make the code more readable. + typedef typename AbstractAction<T>::Result Result; + +public: + + /*! + * Construct a RangeAction using the given values. + * + * If no values are given they default to [0,UINT_FAST64_MAX] thus deselecting no state at evaluation. + * + * @note The interval bounds are included in the interval. + */ + RangeAction(uint_fast64_t from = 0, uint_fast64_t to = UINT_FAST64_MAX) : from(from), to(to) { + if(from > to) { + throw storm::exceptions::IllegalArgumentValueException() << "The end of the range is lower than its beginning"; + } + } + + /*! + * The virtual destructor. + * To ensure that the right destructor is called. + */ + virtual ~RangeAction() { + //Intentionally left empty + } + + /*! + * Evaluate the action for a Prctl formula. + * + * @param result The Result struct on which the action is to be evaluated. + * @param mc The Prctl modelchecker that computed the path- or stateResult contained in the Result struct. + * @returns A Result struct containing the output of the action. + */ + virtual Result evaluate(Result const & result, storm::modelchecker::prctl::AbstractModelChecker<T> const & mc) const override { + return evaluate(result); + } + + /*! + * Evaluate the action for a Csl formula. + * + * @param result The Result struct on which the action is to be evaluated. + * @param mc The Csl modelchecker that computed the path- or stateResult contained in the Result struct. + * @returns A Result struct containing the output of the action. + */ + virtual Result evaluate(Result const & result, storm::modelchecker::csl::AbstractModelChecker<T> const & mc) const override { + return evaluate(result); + } + + /*! + * Evaluate the action for a Ltl formula. + * + * @param result The Result struct on which the action is to be evaluated. + * @param mc The Ltl modelchecker that computed the path- or stateResult contained in the Result struct. + * @returns A Result struct containing the output of the action. + */ + virtual Result evaluate(Result const & result, storm::modelchecker::ltl::AbstractModelChecker<T> const & mc) const override { + return evaluate(result); + } + + /*! + * Returns a string representation of this action. + * + * @returns A string representing this action. + */ + virtual std::string toString() const override { + std::string out = "range("; + out += std::to_string(from); + out += ", "; + out += std::to_string(to); + out += ")"; + return out; + } + +private: + + /*! + * Evaluate the action. + * + * As the RangeAction does not depend on the model or the formula for which the modelchecking result was computed, + * it does not depend on the modelchecker at all. This internal version of the evaluate method therefore only needs the + * modelchecking result as input. + * + * @param result The Result struct on which the action is to be evaluated. + * @returns A Result struct containing the output of the action. + */ + virtual Result evaluate(Result const & result) const { + //Initialize the output vector. + storm::storage::BitVector out(result.selection.size()); + + uint_fast64_t end = to - from; + + // Safety check for access bounds. + if(from >= result.stateMap.size()) { + LOG4CPLUS_WARN(logger, "Range begins behind the end of the states by " << to - result.stateMap.size() << ". No state was selected."); + std::cout << "Range begins behind the end of the states by " << to - result.stateMap.size() << ". No state was selected." << std::endl; + + return Result(out, result.stateMap, result.pathResult, result.stateResult); + } + + if(to >= result.stateMap.size()) { + + end = result.selection.size() - from - 1; + + LOG4CPLUS_WARN(logger, "Range ends behind the end of the states by " << to - result.stateMap.size() << ". The range has been cut at the last state."); + std::cout << "Range ends behind the end of the states by " << to - result.stateMap.size() << ". The range has been cut at the last state." << std::endl; + } + + //Fill the output vector. + for(uint_fast64_t i=0; i <= end; i++) { + out.set(result.stateMap[from + i], result.selection[result.stateMap[from + i]]); + } + + return Result(out, result.stateMap, result.pathResult, result.stateResult); + } + + // The lower bound of the interval of states not deselected. + uint_fast64_t from; + + // The upper bound of the interval of states not deselected. + uint_fast64_t to; + +}; + +} //namespace action +} //namespace properties +} //namespace storm + +#endif /* STORM_FORMULA_ACTION_RANGEACTION_H_ */ diff --git a/src/properties/actions/SortAction.h b/src/properties/actions/SortAction.h new file mode 100644 index 000000000..7498eb7bf --- /dev/null +++ b/src/properties/actions/SortAction.h @@ -0,0 +1,231 @@ +/* + * SortAction.h + * + * Created on: Jun 22, 2014 + * Author: Manuel Sascha Weiand + */ + +#ifndef STORM_FORMULA_ACTION_SORTACTION_H_ +#define STORM_FORMULA_ACTION_SORTACTION_H_ + +#include "src/properties/actions/AbstractAction.h" +#include <cctype> + +namespace storm { +namespace properties { +namespace action { + +/*! + * This action manipulates the state ordering by sorting the states by some category. + * + * Currently the states can be sorted either by index or by value; ascending or descending. + * This is done using the standard libraries sort function, thus the action evaluates in O(n*log n) where n is the number of states. + */ +template <class T> +class SortAction : public AbstractAction<T> { + + // Convenience typedef to make the code more readable. + typedef typename AbstractAction<T>::Result Result; + +public: + + //! Enum defining the categories in relation to which the states can be sorted. + enum SortingCategory {INDEX, VALUE}; + + /*! + * Construct a SortAction using the given values. + * + * If no values are given the action will sort by ascending state index. + * + * @param category An enum value identifying the category by which the states are to be ordered. + * @param ascending Determines whether the values are to be sorted in ascending or descending order. + * The parameter is to be set to true iff the values are to be sorted in ascending order. + */ + SortAction(SortingCategory category = INDEX, bool ascending = true) : category(category), ascending(ascending) { + //Intentionally left empty. + } + + /*! + * The virtual destructor. + * To ensure that the right destructor is called. + */ + virtual ~SortAction() { + //Intentionally left empty + } + + /*! + * Evaluate the action for a Prctl formula. + * + * @param result The Result struct on which the action is to be evaluated. + * @param mc The Prctl modelchecker that computed the path- or stateResult contained in the Result struct. + * @returns A Result struct containing the output of the action. + */ + virtual Result evaluate(Result const & result, storm::modelchecker::prctl::AbstractModelChecker<T> const & mc) const override { + return evaluate(result); + } + + /*! + * Evaluate the action for a Csl formula. + * + * @param result The Result struct on which the action is to be evaluated. + * @param mc The Csl modelchecker that computed the path- or stateResult contained in the Result struct. + * @returns A Result struct containing the output of the action. + */ + virtual Result evaluate(Result const & result, storm::modelchecker::csl::AbstractModelChecker<T> const & mc) const override { + return evaluate(result); + } + + /*! + * Evaluate the action for a Ltl formula. + * + * @param result The Result struct on which the action is to be evaluated. + * @param mc The Ltl modelchecker that computed the path- or stateResult contained in the Result struct. + * @returns A Result struct containing the output of the action. + */ + virtual Result evaluate(Result const & result, storm::modelchecker::ltl::AbstractModelChecker<T> const & mc) const override { + return evaluate(result); + } + + /*! + * Returns a string representation of this action. + * + * @returns A string representing this action. + */ + virtual std::string toString() const override { + std::string out = "sort("; + switch (category) { + case INDEX: + out += "index"; + break; + case VALUE: + out += "value"; + break; + default: + LOG4CPLUS_INFO(logger, "Unknown sorting category of value " << category << "."); + std::cout << "Unknown sorting category of value " << category << "." << std::endl; + break; + } + out += ", "; + out += ascending ? "ascending)" : "descending)"; + return out; + } + + +private: + + /*! + * Evaluate the action. + * + * As the SortAction does not depend on the model or the formula for which the modelchecking result was computed, + * it does not depend on the modelchecker at all. This internal version of the evaluate method therefore only needs the + * modelchecking result as input. + * + * @param result The Result struct on which the action is to be evaluated. + * @returns A Result struct containing the output of the action. + */ + Result evaluate(Result const & result) const { + + if(category == VALUE) { + //TODO + + if(result.pathResult.size() != 0) { + return Result(result.selection, sort(result.stateMap, result.pathResult), result.pathResult, result.stateResult); + } else { + return Result(result.selection, sort(result.stateMap, result.stateResult), result.pathResult, result.stateResult); + } + + } else { + return Result(result.selection, sort(result.stateMap.size()), result.pathResult, result.stateResult); + } + } + + /*! + * This method returns a vector of the given length filled with the numbers 0 to length-1 in ascending or descending order, + * depending on the value of the member variable ascending. Thus it sorts by state index. + * + * @param length The length of the generated vector. + * @returns A vector of unsigned integers from 0 to length-1 in ascending or descending order. + */ + std::vector<uint_fast64_t> sort(uint_fast64_t length) const { + + // Project the vector down to its first component. + std::vector<uint_fast64_t> outMap(length); + + // Sort the combined vector. + if(ascending) { + for(uint_fast64_t i = 0; i < length; i++) { + outMap[i] = i; + } + } else { + for(uint_fast64_t i = 0; i < length; i++) { + outMap[i] = length - i - 1; + } + } + + return outMap; + } + + /*! + * Sort the stateMap vector representing the current state ordering by the values in the values vector. + * + * Here the entries in the values vector are assumed to be the modelchecking results of a path formula. + * Hence, the value at index i is associated with state i, i.e the value i in the stateMap. + * The ordering direction (ascending/decending) is given by the member variable ascending, set in the constructor. + * + * @param stateMap A vector representing the current state ordering. + * @param values A vector containing the values by which the stateMap is to be ordered. + * @returns A vector containing the reordered entries of the stateMap. + */ + std::vector<uint_fast64_t> sort(std::vector<uint_fast64_t> const & stateMap, std::vector<T> const & values) const { + + // Prepare the new state map. + std::vector<uint_fast64_t> outMap(stateMap); + + // Sort the state map. + if(ascending) { + std::sort(outMap.begin(), outMap.end(), [&] (uint_fast64_t a, uint_fast64_t b) -> bool { return values[a] == values[b] ? a < b : values[a] < values[b]; }); + } else { + std::sort(outMap.begin(), outMap.end(), [&] (uint_fast64_t a, uint_fast64_t b) -> bool { return values[a] == values[b] ? a < b : values[a] > values[b]; }); + } + + return outMap; + } + + /*! + * Sort the stateMap vector representing the current state ordering by the values in the values vector. + * + * Here the entries in the values vector are assumed to be the modelchecking results of a state formula. + * Hence, the value at index i is associated with state i, i.e the value i in the stateMap. + * The ordering direction (ascending/decending) is given by the member variable ascending, set in the constructor. + * + * @param stateMap A vector representing the current state ordering. + * @param values A vector containing the values by which the stateMap is to be ordered. + * @returns A vector containing the reordered entries of the stateMap. + */ + std::vector<uint_fast64_t> sort(std::vector<uint_fast64_t> const & stateMap, storm::storage::BitVector const & values) const { + + // Prepare the new state map. + std::vector<uint_fast64_t> outMap(stateMap); + + // Sort the state map. + if(ascending) { + std::sort(outMap.begin(), outMap.end(), [&] (uint_fast64_t a, uint_fast64_t b) -> bool { return values[a] == values[b] ? a < b : values[a] < values[b]; }); + } else { + std::sort(outMap.begin(), outMap.end(), [&] (uint_fast64_t a, uint_fast64_t b) -> bool { return values[a] == values[b] ? a < b : values[a] > values[b]; }); + } + + return outMap; + } + + // The category by which the states are to be ordered. + SortingCategory category; + + // Determines whether the values are to be sorted in ascending or descending order. + bool ascending; +}; + +} //namespace action +} //namespace properties +} //namespace storm + +#endif /* STORM_FORMULA_ACTION_SORTACTION_H_ */ diff --git a/src/properties/csl/AbstractCslFormula.h b/src/properties/csl/AbstractCslFormula.h new file mode 100644 index 000000000..4f8694340 --- /dev/null +++ b/src/properties/csl/AbstractCslFormula.h @@ -0,0 +1,89 @@ +/* + * AbstractCslFormula.h + * + * Created on: 19.04.2013 + * Author: Thomas Heinemann + */ + +#ifndef STORM_FORMULA_CSL_ABSTRACTCSLFORMULA_H_ +#define STORM_FORMULA_CSL_ABSTRACTCSLFORMULA_H_ + +#include "src/properties/AbstractFormula.h" + +namespace storm { +namespace properties { +namespace csl { + +// Forward declarations. + +template <class T> class ProbabilisticBoundOperator; +template <class T> class Eventually; +template <class T> class Until; + +} +} +} + +namespace storm { +namespace properties { +namespace csl { + +/*! + * This is the abstract base class for all Csl formulas. + * + * @note While formula classes do have copy constructors using a copy constructor + * will yield a formula objects whose formula subtree consists of the same objects + * as the original formula. The ownership of the formula tree will be shared between + * the original and the copy. + */ +template <class T> +class AbstractCslFormula : public virtual storm::properties::AbstractFormula<T>{ +public: + + /*! + * The virtual destructor. + */ + virtual ~AbstractCslFormula() { + // Intentionally left empty + } + + /*! + * Checks whether the formula is a probabilistic bound reachability formula. + * Returns true iff the formula conforms to the following pattern. + * Pattern: P[<,<=,>,>=]p ([psi U, E] phi) whith psi, phi propositional logic formulas (consisiting only of And, Or, Not and AP). + * That is, a probabilistic bound operator as root with a single until or eventually formula directly below it, whose subformulas are propositional + * (denoting some set of atomic propositions). + * + * @return True iff this is a probabilistic bound reachability formula. + */ + bool isProbEventuallyAP() const { + + // Test if a probabilistic bound operator is at the root. + if(dynamic_cast<storm::properties::csl::ProbabilisticBoundOperator<T> const *>(this) == nullptr) { + return false; + } + + auto probFormula = dynamic_cast<storm::properties::csl::ProbabilisticBoundOperator<T> const *>(this); + + // Check if the direct subformula of the probabilistic bound operator is an eventually or until formula. + if(std::dynamic_pointer_cast<storm::properties::csl::Eventually<T>>(probFormula->getChild()).get() != nullptr) { + + // Get the subformula and check if its subformulas are propositional. + auto eventuallyFormula = std::dynamic_pointer_cast<storm::properties::csl::Eventually<T>>(probFormula->getChild()); + return eventuallyFormula->getChild()->isPropositional(); + } + else if(std::dynamic_pointer_cast<storm::properties::csl::Until<T>>(probFormula->getChild()).get() != nullptr) { + + // Get the subformula and check if its subformulas are propositional. + auto untilFormula = std::dynamic_pointer_cast<storm::properties::csl::Until<T>>(probFormula->getChild()); + return untilFormula->getLeft()->isPropositional() && untilFormula->getRight()->isPropositional(); + } + + return false; + } +}; + +} /* namespace csl */ +} /* namespace properties */ +} /* namespace storm */ +#endif /* STORM_FORMULA_CSL_ABSTRACTCSLFORMULA_H_ */ diff --git a/src/formula/Csl/AbstractPathFormula.h b/src/properties/csl/AbstractPathFormula.h similarity index 50% rename from src/formula/Csl/AbstractPathFormula.h rename to src/properties/csl/AbstractPathFormula.h index a61cab96f..e7aa31e08 100644 --- a/src/formula/Csl/AbstractPathFormula.h +++ b/src/properties/csl/AbstractPathFormula.h @@ -8,15 +8,7 @@ #ifndef STORM_FORMULA_CSL_ABSTRACTPATHFORMULA_H_ #define STORM_FORMULA_CSL_ABSTRACTPATHFORMULA_H_ -namespace storm { -namespace property { -namespace csl { -template<class T> class AbstractPathFormula; -} //namespace csl -} //namespace property -} //namespace storm - -#include "src/formula/abstract/AbstractFormula.h" +#include "src/properties/csl/AbstractCslFormula.h" #include "src/modelchecker/csl/ForwardDeclarations.h" #include <vector> @@ -24,27 +16,22 @@ template<class T> class AbstractPathFormula; #include <typeinfo> namespace storm { -namespace property { +namespace properties { namespace csl { /*! - * @brief - * Abstract base class for Abstract path formulas. - * - * @attention This class is abstract. - * @note Formula classes do not have copy constructors. The parameters of the constructors are usually the subtrees, so - * the syntax conflicts with copy constructors for unary operators. To produce an identical object, use the method - * clone(). + * Abstract base class for Csl path formulas. * - * @note - * This class is intentionally not derived from AbstractCslFormula, as a path formula is not a complete CSL formula. + * @note Differing from the formal definitions of PRCTL a path formula may be the root of a PRCTL formula. + * The result of a modelchecking process on such a formula is a vector representing the satisfaction probabilities for each state of the model. */ template <class T> -class AbstractPathFormula : public virtual storm::property::abstract::AbstractFormula<T> { +class AbstractPathFormula : public virtual storm::properties::csl::AbstractCslFormula<T> { public: + /*! - * empty destructor + * The virtual destructor. */ virtual ~AbstractPathFormula() { // Intentionally left empty @@ -53,12 +40,13 @@ public: /*! * Clones the called object. * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones + * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones. * * @note This function is not implemented in this class. - * @returns a new AND-object that is identical the called object. + * + * @returns A deep copy of the called object. */ - virtual AbstractPathFormula<T>* clone() const = 0; + virtual std::shared_ptr<AbstractPathFormula<T>> clone() const = 0; /*! * Calls the model checker to check this formula. @@ -71,11 +59,11 @@ public: * * @returns A vector indicating the probability that the formula holds for each state. */ - virtual std::vector<T> check(const storm::modelchecker::csl::AbstractModelChecker<T>& modelChecker, bool qualitative) const = 0; + virtual std::vector<T> check(storm::modelchecker::csl::AbstractModelChecker<T> const & modelChecker, bool qualitative) const = 0; }; } //namespace csl -} //namespace property +} //namespace properties } //namespace storm #endif /* STORM_FORMULA_CSL_ABSTRACTPATHFORMULA_H_ */ diff --git a/src/formula/Csl/AbstractStateFormula.h b/src/properties/csl/AbstractStateFormula.h similarity index 58% rename from src/formula/Csl/AbstractStateFormula.h rename to src/properties/csl/AbstractStateFormula.h index c54d318d5..9c48a1007 100644 --- a/src/formula/Csl/AbstractStateFormula.h +++ b/src/properties/csl/AbstractStateFormula.h @@ -8,37 +8,24 @@ #ifndef STORM_FORMULA_CSL_ABSTRACTSTATEFORMULA_H_ #define STORM_FORMULA_CSL_ABSTRACTSTATEFORMULA_H_ -namespace storm { -namespace property { -namespace csl { -template<class T> class AbstractStateFormula; -} -} -} - -#include "AbstractCslFormula.h" +#include "src/properties/csl/AbstractCslFormula.h" #include "src/storage/BitVector.h" #include "src/modelchecker/csl/ForwardDeclarations.h" namespace storm { -namespace property { +namespace properties { namespace csl { /*! - * @brief - * Abstract base class for Abstract state formulas. - * - * @attention This class is abstract. - * @note Formula classes do not have copy constructors. The parameters of the constructors are usually the subtrees, so - * the syntax conflicts with copy constructors for unary operators. To produce an identical object, use the method - * clone(). + * Abstract base class for Csl state formulas. */ template <class T> -class AbstractStateFormula : public AbstractCslFormula<T> { +class AbstractStateFormula : public storm::properties::csl::AbstractCslFormula<T> { public: + /*! - * empty destructor + * Empty virtual destructor. */ virtual ~AbstractStateFormula() { // Intentionally left empty @@ -50,9 +37,10 @@ public: * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones * * @note This function is not implemented in this class. - * @returns a new AND-object that is identical the called object. + * + * @returns A deep copy of the called object. */ - virtual AbstractStateFormula<T>* clone() const = 0; + virtual std::shared_ptr<AbstractStateFormula<T>> clone() const = 0; /*! * Calls the model checker to check this formula. @@ -65,11 +53,11 @@ public: * * @returns A bit vector indicating all states that satisfy the formula represented by the called object. */ - virtual storm::storage::BitVector check(const storm::modelchecker::csl::AbstractModelChecker<T>& modelChecker) const = 0; + virtual storm::storage::BitVector check(storm::modelchecker::csl::AbstractModelChecker<T> const & modelChecker) const = 0; }; } //namespace csl -} //namespace property +} //namespace properties } //namespace storm diff --git a/src/properties/csl/And.h b/src/properties/csl/And.h new file mode 100644 index 000000000..f9aaa1a85 --- /dev/null +++ b/src/properties/csl/And.h @@ -0,0 +1,216 @@ +/* + * And.h + * + * Created on: 19.10.2012 + * Author: Thomas Heinemann + */ + +#ifndef STORM_FORMULA_CSL_AND_H_ +#define STORM_FORMULA_CSL_AND_H_ + +#include "src/properties/csl/AbstractStateFormula.h" +#include "src/modelchecker/csl/ForwardDeclarations.h" +#include <string> + +namespace storm { +namespace properties { +namespace csl { + +// Forward declaration for the interface class. +template <class T> class And; + +/*! + * Interface class for model checkers that support And. + * + * All model checkers that support the formula class And must inherit + * this pure virtual class. + */ +template <class T> +class IAndModelChecker { + public: + + /*! + * Empty virtual destructor. + */ + virtual ~IAndModelChecker() { + // Intentionally left empty + } + + /*! + * Evaluates an And formula within a model checker. + * + * @param obj Formula object with subformulas. + * @return The modelchecking result of the formula for every state. + */ + virtual storm::storage::BitVector checkAnd(const And<T>& obj) const = 0; +}; + +/*! + * Class for a Csl formula tree with an And node as root. + * + * Has two Csl state formulas as sub formulas/trees. + * + * As And is commutative, the order is \e theoretically not important, but will influence the order in which + * the model checker works. + * + * The object has shared ownership of its subtrees. If this object is deleted and no other object has a shared + * ownership of the subtrees they will be deleted as well. + * + * @see AbstractStateFormula + * @see AbstractCslFormula + */ +template <class T> +class And : public AbstractStateFormula<T> { + +public: + + /*! + * Creates an And node without subnodes. + * The resulting object will not represent a complete formula! + */ + And() : left(nullptr), right(nullptr){ + // Intentionally left empty. + } + + /*! + * Creates an And node with the parameters as subtrees. + * + * @param left The left sub formula. + * @param right The right sub formula. + */ + And(std::shared_ptr<AbstractStateFormula<T>> const & left, std::shared_ptr<AbstractStateFormula<T>> const & right) : left(left), right(right) { + // Intentionally left empty. + } + + /*! + * Empty virtual destructor. + */ + virtual ~And() { + // Intentionally left empty. + } + + /*! + * Clones the called object. + * + * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones. + * + * @returns A new And object that is a deep copy of the called object. + */ + virtual std::shared_ptr<AbstractStateFormula<T>> clone() const override { + std::shared_ptr<And<T>> result(new And()); + if (this->isLeftSet()) { + result->setLeft(left->clone()); + } + if (this->isRightSet()) { + result->setRight(right->clone()); + } + return result; + } + + /*! + * Calls the model checker to check this formula. + * Needed to infer the correct type of formula class. + * + * @note This function should only be called in a generic check function of a model checker class. For other uses, + * the methods of the model checker should be used. + * + * @returns A bit vector indicating all states that satisfy the formula represented by the called object. + */ + virtual storm::storage::BitVector check(const storm::modelchecker::csl::AbstractModelChecker<T>& modelChecker) const override { + return modelChecker.template as<IAndModelChecker>()->checkAnd(*this); + } + + /*! + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. + */ + virtual std::string toString() const override { + std::string result = "("; + result += left->toString(); + result += " & "; + result += right->toString(); + result += ")"; + return result; + } + + /*! Returns whether the formula is a propositional logic formula. + * That is, this formula and all its subformulas consist only of And, Or, Not and AP. + * + * @return True iff this is a propositional logic formula. + */ + virtual bool isPropositional() const override { + return left->isPropositional() && right->isPropositional(); + } + + /*! + * Gets the left child node. + * + * @returns The left child node. + */ + std::shared_ptr<AbstractStateFormula<T>> const & getLeft() const { + return left; + } + + /*! + * Gets the right child node. + * + * @returns The right child node. + */ + std::shared_ptr<AbstractStateFormula<T>> const & getRight() const { + return right; + } + + /*! + * Sets the left child node. + * + * @param newLeft The new left child. + */ + void setLeft(std::shared_ptr<AbstractStateFormula<T>> const & newLeft) { + left = newLeft; + } + + /*! + * Sets the right child node. + * + * @param newRight The new right child. + */ + void setRight(std::shared_ptr<AbstractStateFormula<T>> const & newRight) { + right = newRight; + } + + /*! + * Checks if the left child is set, i.e. it does not point to null. + * + * @return True iff the left child is set. + */ + bool isLeftSet() const { + return left.get() != nullptr; + } + + /*! + * Checks if the right child is set, i.e. it does not point to null. + * + * @return True iff the right child is set. + */ + bool isRightSet() const { + return right.get() != nullptr; + } + +private: + + // The left child node. + std::shared_ptr<AbstractStateFormula<T>> left; + + // The right child node. + std::shared_ptr<AbstractStateFormula<T>> right; + +}; + +} //namespace csl + +} //namespace properties + +} //namespace storm + +#endif /* STORM_FORMULA_CSL_AND_H_ */ diff --git a/src/properties/csl/Ap.h b/src/properties/csl/Ap.h new file mode 100644 index 000000000..9dc5f2392 --- /dev/null +++ b/src/properties/csl/Ap.h @@ -0,0 +1,141 @@ +/* + * Ap.h + * + * Created on: 19.10.2012 + * Author: Thomas Heinemann + */ + +#ifndef STORM_FORMULA_CSL_AP_H_ +#define STORM_FORMULA_CSL_AP_H_ + +#include "src/properties/csl/AbstractStateFormula.h" +#include "src/modelchecker/csl/ForwardDeclarations.h" + +namespace storm { +namespace properties { +namespace csl { + +// Forward declaration for the interface class. +template <class T> class Ap; + +/*! + * Interface class for model checkers that support Ap. + * + * All model checkers that support the formula class Ap must inherit + * this pure virtual class. + */ +template <class T> +class IApModelChecker { + public: + + /*! + * Empty virtual destructor. + */ + virtual ~IApModelChecker() { + // Intentionally left empty + } + + /*! + * Evaluates an Ap formula within a model checker. + * + * @param obj Formula object with subformulas. + * @return The modelchecking result of the formula for every state. + */ + virtual storm::storage::BitVector checkAp(const Ap<T>& obj) const = 0; +}; + +/*! + * Class for a Csl formula tree with an atomic proposition as root. + * + * This class represents the leaves in the formula tree. + * + * @see AbstractCslFormula + * @see AbstractStateFormula + */ +template <class T> +class Ap : public AbstractStateFormula<T> { + +public: + + /*! + * Creates a new atomic proposition leaf, with the given label. + * + * @param ap A string representing the atomic proposition. + */ + Ap(std::string ap) : ap(ap) { + // Intentionally left empty. + } + + /*! + * Empty virtual destructor. + */ + virtual ~Ap() { + // Intentionally left empty + } + + /*! + * Clones the called object. + * + * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones. + * + * @returns A new Ap object that is a deep copy of the called object. + */ + virtual std::shared_ptr<AbstractStateFormula<T>> clone() const override { + std::shared_ptr<AbstractStateFormula<T>> result(new Ap(this->getAp())); + return result; + } + + /*! + * Calls the model checker to check this formula. + * Needed to infer the correct type of formula class. + * + * @note This function should only be called in a generic check function of a model checker class. For other uses, + * the methods of the model checker should be used. + * + * @returns A bit vector indicating all states that satisfy the formula represented by the called object. + */ + virtual storm::storage::BitVector check(storm::modelchecker::csl::AbstractModelChecker<T> const & modelChecker) const override { + return modelChecker.template as<IApModelChecker>()->checkAp(*this); + } + + /*! + * A string representing the atomic proposition. + * + * @returns A string representing the leaf. + */ + virtual std::string toString() const override { + return getAp(); + } + + /*! Returns whether the formula is a propositional logic formula. + * That is, this formula and all its subformulas consist only of And, Or, Not and AP. + * + * @return True iff this is a propositional logic formula. + */ + virtual bool isPropositional() const override { + return true; + } + + /*! + * Gets the name of the atomic proposition. + * + * @returns The name of the atomic proposition. + */ + std::string const & getAp() const { + return ap; + } + +private: + + // The atomic proposition referenced by this leaf. + std::string ap; + +}; + +} //namespace abstract + +} //namespace properties + +} //namespace storm + +#endif /* STORM_FORMULA_CSL_AP_H_ */ diff --git a/src/properties/csl/CslFilter.h b/src/properties/csl/CslFilter.h new file mode 100644 index 000000000..560a65faf --- /dev/null +++ b/src/properties/csl/CslFilter.h @@ -0,0 +1,414 @@ +/* + * CslFilter.h + * + * Created on: May 7, 2014 + * Author: Manuel Sascha Weiand + */ + +#ifndef STORM_FORMULA_PRCTL_CSLFILTER_H_ +#define STORM_FORMULA_PRCTL_CSLFILTER_H_ + +#include "src/properties/AbstractFilter.h" +#include "src/properties/csl/AbstractCslFormula.h" +#include "src/properties/csl/AbstractPathFormula.h" +#include "src/properties/csl/AbstractStateFormula.h" +#include "src/modelchecker/csl/AbstractModelChecker.h" + +#include "src/properties/actions/AbstractAction.h" + +namespace storm { +namespace properties { +namespace csl { + +/*! + * This is the Csl specific filter. + * + * It maintains a Csl formula which can be checked against a given model by either calling evaluate() or check(). + * Additionally it maintains a list of filter actions that are used to further manipulate the modelchecking results and prepare them for output. + */ +template <class T> +class CslFilter : public storm::properties::AbstractFilter<T> { + + // Convenience typedef to make the code more readable. + typedef typename storm::properties::action::AbstractAction<T>::Result Result; + +public: + + /*! + * Creates an empty CslFilter, maintaining no Csl formula. + * + * Calling check or evaluate will return an empty result. + */ + CslFilter() : AbstractFilter<T>(UNDEFINED), child(nullptr), steadyStateQuery(false) { + // Intentionally left empty. + } + + /*! + * Creates a CslFilter maintaining a Csl formula but containing no actions. + * + * The modelchecking result will be returned or printed as is. + * + * @param child The Csl formula to be maintained. + * @param opt An enum value indicating which kind of scheduler shall be used for path formulas on nondeterministic models. + * @param steadyStateQuery A flag indicating whether this is a steady state query. + */ + CslFilter(std::shared_ptr<AbstractCslFormula<T>> const & child, OptimizingOperator opt = UNDEFINED, bool steadyStateQuery = false) : AbstractFilter<T>(opt), child(child), steadyStateQuery(steadyStateQuery) { + // Intentionally left empty. + } + + /*! + * Creates a CslFilter maintaining a Csl formula and containing a single action. + * + * The given action will be applied to the modelchecking result during evaluation. + * Further actions can be added later. + * + * @param child The Csl formula to be maintained. + * @param action The single action to be executed during evaluation. + * @param opt An enum value indicating which kind of scheduler shall be used for path formulas on nondeterministic models. + * @param steadyStateQuery A flag indicating whether this is a steady state query. + */ + CslFilter(std::shared_ptr<AbstractCslFormula<T>> const & child, std::shared_ptr<action::AbstractAction<T>> const & action, OptimizingOperator opt = UNDEFINED, bool steadyStateQuery = false) : AbstractFilter<T>(action, opt), child(child), steadyStateQuery(steadyStateQuery) { + // Intentionally left empty + } + + /*! + * Creates a CslFilter using the given parameters. + * + * The given actions will be applied to the modelchecking result in ascending index order during evaluation. + * Further actions can be added later. + * + * @param child The Csl formula to be maintained. + * @param actions A vector conatining the actions that are to be executed during evaluation. + * @param opt An enum value indicating which kind of scheduler shall be used for path formulas on nondeterministic models. + * @param steadyStateQuery A flag indicating whether this is a steady state query. + */ + CslFilter(std::shared_ptr<AbstractCslFormula<T>> const & child, std::vector<std::shared_ptr<action::AbstractAction<T>>> const & actions, OptimizingOperator opt = UNDEFINED, bool steadyStateQuery = false) : AbstractFilter<T>(actions, opt), child(child), steadyStateQuery(steadyStateQuery) { + // Intentionally left empty. + } + + /*! + * Empty virtual destructor. + */ + virtual ~CslFilter() { + // Intentionally left empty. + } + + /*! + * Calls the modelchecker, retrieves the modelchecking result, applies the filter action one by one and prints out the result. + * + * @param modelchecker The modelchecker to be called. + */ + void check(storm::modelchecker::csl::AbstractModelChecker<T> const & modelchecker) const { + + // Write out the formula to be checked. + std::cout << std::endl; + LOG4CPLUS_INFO(logger, "Model checking formula\t" << this->toString()); + std::cout << "Model checking formula:\t" << this->toString() << std::endl; + + writeOut(evaluate(modelchecker), modelchecker); + + } + + /*! + * Calls the modelchecker, retrieves the modelchecking result, applies the filter action one by one and returns the result. + * + * @param modelchecker The modelchecker to be called. + * @returns The result of the sequential application of the filter actions to the modelchecking result. + */ + Result evaluate(storm::modelchecker::csl::AbstractModelChecker<T> const & modelchecker) const { + Result result; + + try { + if(std::dynamic_pointer_cast<AbstractStateFormula<T>>(child).get() != nullptr) { + result = evaluate(modelchecker, std::dynamic_pointer_cast<AbstractStateFormula<T>>(child)); + } else if (std::dynamic_pointer_cast<AbstractPathFormula<T>>(child).get() != nullptr) { + result = evaluate(modelchecker, std::dynamic_pointer_cast<AbstractPathFormula<T>>(child)); + } + } catch (std::exception& e) { + std::cout << "Error during computation: " << e.what() << "Skipping property." << std::endl; + LOG4CPLUS_ERROR(logger, "Error during computation: " << e.what() << "Skipping property."); + } + + return result; + } + + /*! + * Returns a textual representation of the filter. + * + * That includes the actions as well as the maintained formula. + * + * @returns A string representing the filter. + */ + virtual std::string toString() const override { + std::string desc = ""; + + if(!std::dynamic_pointer_cast<AbstractStateFormula<T>>(child)) { + + // The formula is not a state formula so we have a probability query. + if(this->actions.empty()){ + + // Since there are no actions given we do legacy support. + + desc += "P "; + switch(this->opt) { + case MINIMIZE: + desc += "min "; + break; + case MAXIMIZE: + desc += "max "; + break; + default: + break; + } + desc += "= ? "; + + } else { + desc = "filter["; + + switch(this->opt) { + case MINIMIZE: + desc += "min; "; + break; + case MAXIMIZE: + desc += "max; "; + break; + default: + break; + } + + for(auto action : this->actions) { + desc += action->toString(); + desc += "; "; + } + + // Remove the last "; ". + desc.pop_back(); + desc.pop_back(); + + desc += "]"; + } + + } else { + + if(this->actions.empty()) { + + if(steadyStateQuery) { + + // Legacy support for the steady state query. + desc += "S = ? "; + + } else { + + // There are no filter actions but only the raw state formula. So just print that. + return child->toString(); + } + } else { + + desc = "filter["; + + for(auto action : this->actions) { + desc += action->toString(); + desc += "; "; + } + + // Remove the last "; ". + desc.pop_back(); + desc.pop_back(); + + desc += "]"; + } + } + + desc += "("; + desc += child->toString(); + desc += ")"; + + return desc; + } + + /*! + * Gets the child node. + * + * @returns The child node. + */ + std::shared_ptr<AbstractCslFormula<T>> const & getChild() const { + return child; + } + + /*! + * Sets the subtree. + * + * @param child The new child. + */ + void setChild(std::shared_ptr<AbstractCslFormula<T>> const & child) { + this->child = child; + } + + /*! + * Checks if the child is set, i.e. it does not point to null. + * + * @return True iff the child is set. + */ + bool isChildSet() const { + return child.get() != nullptr; + } + +private: + + /*! + * Calls the modelchecker for a state formula, retrieves the modelchecking result, applies the filter action one by one and returns the result. + * + * This an internal version of the evaluate method overloading it for the different Csl formula types. + * + * @param modelchecker The modelchecker to be called. + * @param formula The state formula for which the modelchecker will be called. + * @returns The result of the sequential application of the filter actions to the modelchecking result. + */ + Result evaluate(storm::modelchecker::csl::AbstractModelChecker<T> const & modelchecker, std::shared_ptr<AbstractStateFormula<T>> const & formula) const { + // First, get the model checking result. + Result result; + + //TODO: Once a modelchecker supporting steady state formulas is implemented, call it here in case steadyStateQuery is set. + + if(this->opt != UNDEFINED) { + // If there is an action specifying that min/max probabilities should be computed, call the appropriate method of the model checker. + result.stateResult = modelchecker.checkMinMaxOperator(*formula, this->opt == MINIMIZE ? true : false); + } else { + result.stateResult = formula->check(modelchecker); + } + + + // Now apply all filter actions and return the result. + return evaluateActions(result, modelchecker); + } + + /*! + * Calls the modelchecker for a path formula, retrieves the modelchecking result, applies the filter action one by one and returns the result. + * + * This an internal version of the evaluate method overloading it for the different Csl formula types. + * + * @param modelchecker The modelchecker to be called. + * @param formula The path formula for which the modelchecker will be called. + * @returns The result of the sequential application of the filter actions to the modelchecking result. + */ + Result evaluate(storm::modelchecker::csl::AbstractModelChecker<T> const & modelchecker, std::shared_ptr<AbstractPathFormula<T>> const & formula) const { + // First, get the model checking result. + Result result; + + if(this->opt != UNDEFINED) { + // If there is an action specifying that min/max probabilities should be computed, call the appropriate method of the model checker. + result.pathResult = modelchecker.checkMinMaxOperator(*formula, this->opt == MINIMIZE ? true : false); + } else { + result.pathResult = formula->check(modelchecker, false); + } + + // Now apply all filter actions and return the result. + return evaluateActions(result, modelchecker); + } + + /*! + * Evaluates the filter actions by calling them one by one using the output of each action as the input for the next one. + * + * @param input The modelchecking result in form of a Result struct. + * @param modelchecker The modelchecker that was called to generate the modelchecking result. Needed by some actions. + * @returns The result of the sequential application of the filter actions to the modelchecking result. + */ + Result evaluateActions(Result result, storm::modelchecker::csl::AbstractModelChecker<T> const & modelchecker) const { + + // Init the state selection and state map vectors. + uint_fast64_t size = result.stateResult.size() == 0 ? result.pathResult.size() : result.stateResult.size(); + result.selection = storm::storage::BitVector(size, true); + result.stateMap = std::vector<uint_fast64_t>(size); + for(uint_fast64_t i = 0; i < result.selection.size(); i++) { + result.stateMap[i] = i; + } + + // Now apply all filter actions and return the result. + for(auto action : this->actions) { + result = action->evaluate(result, modelchecker); + } + return result; + } + + /*! + * Writes out the given result. + * + * @param result The result of the sequential application of the filter actions to a modelchecking result. + * @param modelchecker The modelchecker that was called to generate the modelchecking result. Needed for legacy support. + */ + void writeOut(Result const & result, storm::modelchecker::csl::AbstractModelChecker<T> const & modelchecker) const { + + // Test if there is anything to write out. + // The selection size should only be 0 if an error occurred during the evaluation (since a model with 0 states is invalid). + if(result.selection.size() == 0) { + std::cout << std::endl << "-------------------------------------------" << std::endl; + return; + } + + // Test for the kind of result. Values or states. + if(!result.pathResult.empty()) { + + // Write out the selected value results in the order given by the stateMap. + if(this->actions.empty()) { + + // There is no filter action given. So provide legacy support: + // Return the results for all states labeled with "init". + LOG4CPLUS_INFO(logger, "Result for initial states:"); + std::cout << "Result for initial states:" << std::endl; + for (auto initialState : modelchecker.template getModel<storm::models::AbstractModel<T>>().getInitialStates()) { + LOG4CPLUS_INFO(logger, "\t" << initialState << ": " << result.pathResult[initialState]); + std::cout << "\t" << initialState << ": " << result.pathResult[initialState] << std::endl; + } + } else { + LOG4CPLUS_INFO(logger, "Result for " << result.selection.getNumberOfSetBits() << " selected states:"); + std::cout << "Result for " << result.selection.getNumberOfSetBits() << " selected states:" << std::endl; + + for(uint_fast64_t i = 0; i < result.stateMap.size(); i++) { + if(result.selection.get(result.stateMap[i])) { + LOG4CPLUS_INFO(logger, "\t" << result.stateMap[i] << ": " << result.pathResult[result.stateMap[i]]); + std::cout << "\t" << result.stateMap[i] << ": " << result.pathResult[result.stateMap[i]] << std::endl; + } + } + } + + } else { + + // Write out the selected state results in the order given by the stateMap. + if(this->actions.empty()) { + + // There is no filter action given. So provide legacy support: + // Return the results for all states labeled with "init". + LOG4CPLUS_INFO(logger, "Result for initial states:"); + std::cout << "Result for initial states:" << std::endl; + for (auto initialState : modelchecker.template getModel<storm::models::AbstractModel<T>>().getInitialStates()) { + LOG4CPLUS_INFO(logger, "\t" << initialState << ": " << (result.stateResult[initialState] ? "satisfied" : "not satisfied")); + std::cout << "\t" << initialState << ": " << result.stateResult[initialState] << std::endl; + } + } else { + LOG4CPLUS_INFO(logger, "Result for " << result.selection.getNumberOfSetBits() << " selected states:"); + std::cout << "Result for " << result.selection.getNumberOfSetBits() << " selected states:" << std::endl; + + for(uint_fast64_t i = 0; i < result.stateMap.size(); i++) { + if(result.selection.get(result.stateMap[i])) { + LOG4CPLUS_INFO(logger, "\t" << result.stateMap[i] << ": " << (result.stateResult[result.stateMap[i]] ? "satisfied" : "not satisfied")); + std::cout << "\t" << result.stateMap[i] << ": " << (result.stateResult[result.stateMap[i]] ? "satisfied" : "not satisfied") << std::endl; + } + } + } + } + + std::cout << std::endl << "-------------------------------------------" << std::endl; + } + + // The Csl formula maintained by this filter. + std::shared_ptr<AbstractCslFormula<T>> child; + + // A flag indicating whether this is a steady state query. + bool steadyStateQuery; +}; + +} //namespace csl +} //namespace properties +} //namespace storm + +#endif /* STORM_FORMULA_CSL_CSLFILTER_H_ */ diff --git a/src/properties/csl/Eventually.h b/src/properties/csl/Eventually.h new file mode 100644 index 000000000..b156280aa --- /dev/null +++ b/src/properties/csl/Eventually.h @@ -0,0 +1,170 @@ +/* + * Globally.h + * + * Created on: 26.12.2012 + * Author: Christian Dehnert + */ + +#ifndef STORM_FORMULA_CSL_EVENTUALLY_H_ +#define STORM_FORMULA_CSL_EVENTUALLY_H_ + +#include "src/properties/csl/AbstractPathFormula.h" +#include "src/properties/csl/AbstractStateFormula.h" +#include "src/modelchecker/csl/ForwardDeclarations.h" + +namespace storm { +namespace properties { +namespace csl { + +// Forward declaration for the interface class. +template <class T> class Eventually; + +/*! + * Interface class for model checkers that support Eventually. + * + * All model checkers that support the formula class Eventually must inherit + * this pure virtual class. + */ +template <class T> +class IEventuallyModelChecker { + public: + + /*! + * Empty virtual destructor. + */ + virtual ~IEventuallyModelChecker() { + // Intentionally left empty. + } + + /*! + * Evaluates an Eventually formula within a model checker. + * + * @param obj Formula object with subformulas. + * @param qualitative A flag indicating whether the formula only needs to be evaluated qualitatively, i.e. if the + * results are only compared against the bounds 0 and 1. + * @return The modelchecking result of the formula for every state. + */ + virtual std::vector<T> checkEventually(const Eventually<T>& obj, bool qualitative) const = 0; +}; + +/*! + * @brief + * Class for a Csl (path) formula tree with an Eventually node as root. + * + * Has one Csl state formula as sub formula/tree. + * + * @par Semantics + * The formula holds iff eventually formula \e child holds. + * + * The object has shared ownership of its subtree. If this object is deleted and no other object has a shared + * ownership of the subtree it will be deleted as well. + * + * @see AbstractPathFormula + * @see AbstractCslFormula + */ +template <class T> +class Eventually : public AbstractPathFormula<T> { + +public: + + /*! + * Creates an Eventually node without a subnode. + * The resulting object will not represent a complete formula! + */ + Eventually() : child(nullptr) { + // Intentionally left empty. + } + + /*! + * Creates an Eventually node using the given parameter. + * + * @param child The child formula subtree. + */ + Eventually(std::shared_ptr<AbstractStateFormula<T>> const & child) : child(child){ + // Intentionally left empty. + } + + /*! + * Empty virtual destructor. + */ + virtual ~Eventually() { + // Intentionally left empty. + } + + /*! + * Clones the called object. + * + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. + * + * @returns A new Eventually object that is a deep copy of the called object. + */ + virtual std::shared_ptr<AbstractPathFormula<T>> clone() const override { + std::shared_ptr<Eventually<T>> result(new Eventually<T>()); + if (this->isChildSet()) { + result->setChild(child->clone()); + } + return result; + } + + /*! + * Calls the model checker to check this formula. + * Needed to infer the correct type of formula class. + * + * @note This function should only be called in a generic check function of a model checker class. For other uses, + * the methods of the model checker should be used. + * + * @returns A vector indicating the probability that the formula holds for each state. + */ + virtual std::vector<T> check(storm::modelchecker::csl::AbstractModelChecker<T> const & modelChecker, bool qualitative) const override { + return modelChecker.template as<IEventuallyModelChecker>()->checkEventually(*this, qualitative); + } + + /*! + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. + */ + virtual std::string toString() const override { + std::string result = "F "; + result += child->toString(); + return result; + } + + /*! + * Gets the child node. + * + * @returns The child node. + */ + std::shared_ptr<AbstractStateFormula<T>> const & getChild() const { + return child; + } + + /*! + * Sets the subtree. + * + * @param child The new child. + */ + void setChild(std::shared_ptr<AbstractStateFormula<T>> const & child) { + this->child = child; + } + + /*! + * Checks if the child is set, i.e. it does not point to null. + * + * @return True iff the child is set. + */ + bool isChildSet() const { + return child.get() != nullptr; + } + +private: + + // The child node. + std::shared_ptr<AbstractStateFormula<T>> child; +}; + +} //namespace csl +} //namespace properties +} //namespace storm + +#endif /* STORM_FORMULA_CSL_EVENTUALLY_H_ */ diff --git a/src/properties/csl/Globally.h b/src/properties/csl/Globally.h new file mode 100644 index 000000000..52f25ba24 --- /dev/null +++ b/src/properties/csl/Globally.h @@ -0,0 +1,169 @@ +/* + * Globally.h + * + * Created on: 26.12.2012 + * Author: Christian Dehnert + */ + +#ifndef STORM_FORMULA_CSL_GLOBALLY_H_ +#define STORM_FORMULA_CSL_GLOBALLY_H_ + +#include "src/properties/csl/AbstractPathFormula.h" +#include "src/properties/csl/AbstractStateFormula.h" +#include "src/modelchecker/csl/ForwardDeclarations.h" + +namespace storm { +namespace properties { +namespace csl { + +// Forward declaration for the interface class. +template <class T> class Globally; + +/*! + * Interface class for model checkers that support Globally. + * + * All model checkers that support the formula class Globally must inherit + * this pure virtual class. + */ +template <class T> +class IGloballyModelChecker { + public: + + /*! + * Empty virtual destructor. + */ + virtual ~IGloballyModelChecker() { + // Intentionally left empty + } + + /*! + * Evaluates a Globally formula within a model checker. + * + * @param obj Formula object with subformulas. + * @param qualitative A flag indicating whether the formula only needs to be evaluated qualitatively, i.e. if the + * results are only compared against the bounds 0 and 1. + * @return The modelchecking result of the formula for every state. + */ + virtual std::vector<T> checkGlobally(const Globally<T>& obj, bool qualitative) const = 0; +}; + +/*! + * Class for a Csl (path) formula tree with a Globally node as root. + * + * Has one Csl state formula as sub formula/tree. + * + * @par Semantics + * The formula holds iff globally \e child holds. + * + * The object has shared ownership of its subtree. If this object is deleted and no other object has a shared + * ownership of the subtree it will be deleted as well. + * + * @see AbstractPathFormula + * @see AbstractCslFormula + */ +template <class T> +class Globally : public AbstractPathFormula<T> { + +public: + + /*! + * Creates a Globally node without a subnode. + * The resulting object will not represent a complete formula! + */ + Globally() : child(nullptr){ + // Intentionally left empty. + } + + /*! + * Creates a Globally node using the given parameter. + * + * @param child The child formula subtree. + */ + Globally(std::shared_ptr<AbstractStateFormula<T>> const & child) : child(child){ + // Intentionally left empty. + } + + /*! + * Empty virtual destructor. + */ + virtual ~Globally() { + // Intentionally left empty. + } + + /*! + * Clones the called object. + * + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. + * + * @returns A new Globally object that is a deep copy of the called object. + */ + virtual std::shared_ptr<AbstractPathFormula<T>> clone() const override { + std::shared_ptr<Globally<T>> result(new Globally<T>()); + if (this->isChildSet()) { + result->setChild(child->clone()); + } + return result; + } + + /*! + * Calls the model checker to check this formula. + * Needed to infer the correct type of formula class. + * + * @note This function should only be called in a generic check function of a model checker class. For other uses, + * the methods of the model checker should be used. + * + * @returns A vector indicating the probability that the formula holds for each state. + */ + virtual std::vector<T> check(storm::modelchecker::csl::AbstractModelChecker<T> const & modelChecker, bool qualitative) const override { + return modelChecker.template as<IGloballyModelChecker>()->checkGlobally(*this, qualitative); + } + + /*! + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. + */ + virtual std::string toString() const override { + std::string result = "G "; + result += child->toString(); + return result; + } + + /*! + * Gets the child node. + * + * @returns The child node. + */ + AbstractStateFormula<T> const & getChild() const { + return child; + } + + /*! + * Sets the subtree. + * + * @param child The new child. + */ + void setChild(std::shared_ptr<AbstractStateFormula<T>> const & child) { + this->child = child; + } + + /*! + * Checks if the child is set, i.e. it does not point to null. + * + * @return True iff the child is set. + */ + bool isChildSet() const { + return child.get() != nullptr; + } + +private: + + // The child node. + std::shared_ptr<AbstractStateFormula<T>> child; +}; + +} //namespace csl +} //namespace properties +} //namespace storm + +#endif /* STORM_FORMULA_CSL_GLOBALLY_H_ */ diff --git a/src/properties/csl/Next.h b/src/properties/csl/Next.h new file mode 100644 index 000000000..462a5eae4 --- /dev/null +++ b/src/properties/csl/Next.h @@ -0,0 +1,168 @@ +/* + * Next.h + * + * Created on: 19.10.2012 + * Author: Thomas Heinemann + */ + +#ifndef STORM_FORMULA_CSL_NEXT_H_ +#define STORM_FORMULA_CSL_NEXT_H_ + +#include "src/properties/csl/AbstractPathFormula.h" +#include "src/properties/csl/AbstractStateFormula.h" + +namespace storm { +namespace properties { +namespace csl { + +// Forward declaration for the interface class. +template <class T> class Next; + +/*! + * Interface class for model checkers that support Next. + * + * All model checkers that support the formula class Next must inherit + * this pure virtual class. + */ +template <class T> +class INextModelChecker { + public: + + /*! + * Empty virtual destructor. + */ + virtual ~INextModelChecker() { + // Intentionally left empty + } + + /*! + * Evaluates Next formula within a model checker. + * + * @param obj Formula object with subformulas. + * @param qualitative A flag indicating whether the formula only needs to be evaluated qualitatively, i.e. if the + * results are only compared against the bounds 0 and 1. + * @return Result of the formula for every node. + */ + virtual std::vector<T> checkNext(const Next<T>& obj, bool qualitative) const = 0; +}; + +/*! + * Class for a Csl (path) formula tree with a Next node as root. + * + * Has two Csl state formulas as sub formulas/trees. + * + * @par Semantics + * The formula holds iff in the next step, \e child holds + * + * The object has shared ownership of its subtree. If this object is deleted and no other object has a shared + * ownership of the subtree it will be deleted as well. + * + * @see AbstractPathFormula + * @see AbstractCslFormula + */ +template <class T> +class Next : public AbstractPathFormula<T> { + +public: + + /*! + * Creates a Next node without a subnode. + * The resulting object will not represent a complete formula! + */ + Next() : child(nullptr){ + // Intentionally left empty. + } + + /*! + * Creates a Next node using the given parameter. + * + * @param child The child formula subtree. + */ + Next(std::shared_ptr<AbstractStateFormula<T>> const & child) : child(child) { + // Intentionally left empty. + } + + /*! + * Empty virtual destructor. + */ + virtual ~Next() { + // Intetionally left empty. + } + + /*! + * Clones the called object. + * + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. + * + * @returns A new Next object that is a deep copy of the called object. + */ + virtual std::shared_ptr<AbstractPathFormula<T>> clone() const override { + std::shared_ptr<Next<T>> result(new Next<T>()); + if (this->isChildSet()) { + result->setChild(child->clone()); + } + return result; + } + + /*! + * Calls the model checker to check this formula. + * Needed to infer the correct type of formula class. + * + * @note This function should only be called in a generic check function of a model checker class. For other uses, + * the methods of the model checker should be used. + * + * @returns A vector indicating the probability that the formula holds for each state. + */ + virtual std::vector<T> check(storm::modelchecker::csl::AbstractModelChecker<T> const & modelChecker, bool qualitative) const override { + return modelChecker.template as<INextModelChecker>()->checkNext(*this, qualitative); + } + + /*! + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. + */ + virtual std::string toString() const override { + std::string result = "X "; + result += child->toString(); + return result; + } + + /*! + * Gets the child node. + * + * @returns The child node. + */ + std::shared_ptr<AbstractStateFormula<T>> const & getChild() const { + return child; + } + + /*! + * Sets the subtree. + * + * @param child The new child. + */ + void setChild(std::shared_ptr<AbstractStateFormula<T>> const & child) { + this->child = child; + } + + /*! + * Checks if the child is set, i.e. it does not point to null. + * + * @return True iff the child is set. + */ + bool isChildSet() const { + return child.get() != nullptr; + } + +private: + + // The child node. + std::shared_ptr<AbstractStateFormula<T>> child; +}; + +} //namespace csl +} //namespace properties +} //namespace storm + +#endif /* STORM_FORMULA_CSL_NEXT_H_ */ diff --git a/src/properties/csl/Not.h b/src/properties/csl/Not.h new file mode 100644 index 000000000..de2f4acfb --- /dev/null +++ b/src/properties/csl/Not.h @@ -0,0 +1,172 @@ +/* + * Not.h + * + * Created on: 19.10.2012 + * Author: Thomas Heinemann + */ + +#ifndef STORM_FORMULA_CSL_NOT_H_ +#define STORM_FORMULA_CSL_NOT_H_ + +#include "src/properties/csl/AbstractStateFormula.h" +#include "src/modelchecker/csl/ForwardDeclarations.h" + +namespace storm { +namespace properties { +namespace csl { + +// Forward declaration for the interface class. +template <class T> class Not; + +/*! + * Interface class for model checkers that support Not. + * + * All model checkers that support the formula class Not must inherit + * this pure virtual class. + */ +template <class T> +class INotModelChecker { + public: + + /*! + * Empty virtual destructor. + */ + virtual ~INotModelChecker() { + // Intentionally left empty + } + + /*! + * Evaluates Not formulas within a model checker. + * + * @param obj Formula object with subformulas. + * @return Result of the formula for every node. + */ + virtual storm::storage::BitVector checkNot(const Not<T>& obj) const = 0; +}; + +/*! + * Class for a Csl formula tree with Not node as root. + * + * Has one Csl state formula as sub formula/tree. + * + * The object has shared ownership of its subtree. If this object is deleted and no other object has a shared + * ownership of the subtree it will be deleted as well. + * + * @see AbstractStateFormula + * @see AbstractCslFormula + */ +template <class T> +class Not : public AbstractStateFormula<T> { + +public: + + /*! + * Creates a Not node without a subnode. + * The resulting object will not represent a complete formula! + */ + Not() : child(nullptr) { + // Intentionally left empty. + } + + /*! + * Creates a Not node using the given parameter. + * + * @param child The child formula subtree. + */ + Not(std::shared_ptr<AbstractStateFormula<T>> const & child) : child(child) { + // Intentionally left empty. + } + + /*! + * Empty virtual destructor. + */ + virtual ~Not() { + // Intentionally left empty. + } + + /*! + * Clones the called object. + * + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. + * + * @returns A new Not object that is a deep copy of the called object. + */ + virtual std::shared_ptr<AbstractStateFormula<T>> clone() const override { + std::shared_ptr<Not<T>> result(new Not<T>()); + if (this->isChildSet()) { + result->setChild(child->clone()); + } + return result; + } + + /*! + * Calls the model checker to check this formula. + * Needed to infer the correct type of formula class. + * + * @note This function should only be called in a generic check function of a model checker class. For other uses, + * the methods of the model checker should be used. + * + * @returns A bit vector indicating all states that satisfy the formula represented by the called object. + */ + virtual storm::storage::BitVector check(storm::modelchecker::csl::AbstractModelChecker<T> const & modelChecker) const override { + return modelChecker.template as<INotModelChecker>()->checkNot(*this); + } + + /*! + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. + */ + virtual std::string toString() const override { + std::string result = "!"; + result += child->toString(); + return result; + } + + /*! Returns whether the formula is a propositional logic formula. + * That is, this formula and all its subformulas consist only of And, Or, Not and AP. + * + * @return True iff this is a propositional logic formula. + */ + virtual bool isPropositional() const override { + return child->isPropositional(); + } + + /*! + * Gets the child node. + * + * @returns The child node. + */ + std::shared_ptr<AbstractStateFormula<T>> const & getChild() const { + return child; + } + + /*! + * Sets the subtree. + * + * @param child The new child. + */ + void setChild(std::shared_ptr<AbstractStateFormula<T>> const & child) { + this->child = child; + } + + /*! + * Checks if the child is set, i.e. it does not point to null. + * + * @return True iff the child is set. + */ + bool isChildSet() const { + return child.get() != nullptr; + } + +private: + + // The child node. + std::shared_ptr<AbstractStateFormula<T>> child; +}; + +} //namespace csl +} //namespace properties +} //namespace storm + +#endif /* STORM_FORMULA_CSL_NOT_H_ */ diff --git a/src/properties/csl/Or.h b/src/properties/csl/Or.h new file mode 100644 index 000000000..f70144634 --- /dev/null +++ b/src/properties/csl/Or.h @@ -0,0 +1,212 @@ +/* + * Or.h + * + * Created on: 19.10.2012 + * Author: Thomas Heinemann + */ + +#ifndef STORM_FORMULA_CSL_OR_H_ +#define STORM_FORMULA_CSL_OR_H_ + +#include "src/properties/csl/AbstractStateFormula.h" + +namespace storm { +namespace properties { +namespace csl { + +// Forward declaration for the interface class. +template <class T> class Or; + +/*! + * Interface class for model checkers that support Or. + * + * All model checkers that support the formula class Or must inherit + * this pure virtual class. + */ +template <class T> +class IOrModelChecker { + public: + + /*! + * Empty virtual destructor. + */ + virtual ~IOrModelChecker() { + // Intentionally left empty + } + + /*! + * Evaluates Or formula within a model checker. + * + * @param obj Formula object with subformulas. + * @return Result of the formula for every node. + */ + virtual storm::storage::BitVector checkOr(const Or<T>& obj) const = 0; +}; + +/*! + * Class for an Csl formula tree with an Or node as root. + * + * Has two state formulas as sub formulas/trees. + * + * As Or is commutative, the order is \e theoretically not important, but will influence the order in which + * the model checker works. + * + * The object has shared ownership of its subtrees. If this object is deleted and no other object has a shared + * ownership of the subtrees they will be deleted as well. + * + * @see AbstractStateFormula + * @see AbstractCslFormula + */ +template <class T> +class Or : public AbstractStateFormula<T> { + +public: + + /*! + * Creates an Or node without subnodes. + * The resulting object will not represent a complete formula! + */ + Or() : left(nullptr), right(nullptr) { + // Intentionally left empty. + } + + /*! + * Creates an Or node with the parameters as subtrees. + * + * @param left The left sub formula. + * @param right The right sub formula. + */ + Or(std::shared_ptr<AbstractStateFormula<T>> const & left, std::shared_ptr<AbstractStateFormula<T>> const & right) : left(left), right(right) { + // Intentionally left empty. + } + + /*! + * Empty virtual destructor. + */ + virtual ~Or() { + // Intentionally left empty. + } + + /*! + * Clones the called object. + * + * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones. + * + * @returns A new Or object that is a deep copy of the called object. + */ + virtual std::shared_ptr<AbstractStateFormula<T>> clone() const override { + std::shared_ptr<Or<T>> result(new Or()); + if (this->isLeftSet()) { + result->setLeft(left->clone()); + } + if (this->isRightSet()) { + result->setRight(right->clone()); + } + return result; + } + + /*! + * Calls the model checker to check this formula. + * Needed to infer the correct type of formula class. + * + * @note This function should only be called in a generic check function of a model checker class. For other uses, + * the methods of the model checker should be used. + * + * @returns A bit vector indicating all states that satisfy the formula represented by the called object. + */ + virtual storm::storage::BitVector check(storm::modelchecker::csl::AbstractModelChecker<T> const & modelChecker) const override { + return modelChecker.template as<IOrModelChecker>()->checkOr(*this); + } + + /*! + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. + */ + virtual std::string toString() const override { + std::string result = "("; + result += left->toString(); + result += " | "; + result += right->toString(); + result += ")"; + return result; + } + + /*! Returns whether the formula is a propositional logic formula. + * That is, this formula and all its subformulas consist only of And, Or, Not and AP. + * + * @return True iff this is a propositional logic formula. + */ + virtual bool isPropositional() const override { + return left->isPropositional() && right->isPropositional(); + } + + /*! + * Gets the left child node. + * + * @returns The left child node. + */ + std::shared_ptr<AbstractStateFormula<T>> const & getLeft() const { + return left; + } + + /*! + * Gets the right child node. + * + * @returns The right child node. + */ + std::shared_ptr<AbstractStateFormula<T>> const & getRight() const { + return right; + } + + /*! + * Sets the left child node. + * + * @param newLeft The new left child. + */ + void setLeft(std::shared_ptr<AbstractStateFormula<T>> const & newLeft) { + left = newLeft; + } + + /*! + * Sets the right child node. + * + * @param newRight The new right child. + */ + void setRight(std::shared_ptr<AbstractStateFormula<T>> const & newRight) { + right = newRight; + } + + /*! + * Checks if the left child is set, i.e. it does not point to null. + * + * @return True iff the left child is set. + */ + bool isLeftSet() const { + return left.get() != nullptr; + } + + /*! + * Checks if the right child is set, i.e. it does not point to null. + * + * @return True iff the left right is set. + */ + bool isRightSet() const { + return right.get() != nullptr; + } + +private: + + // The left child node. + std::shared_ptr<AbstractStateFormula<T>> left; + + // The right child node. + std::shared_ptr<AbstractStateFormula<T>> right; + +}; + +} //namespace csl +} //namespace properties +} //namespace storm + +#endif /* STORM_FORMULA_CSL_OR_H_ */ diff --git a/src/properties/csl/ProbabilisticBoundOperator.h b/src/properties/csl/ProbabilisticBoundOperator.h new file mode 100644 index 000000000..d8005d2fe --- /dev/null +++ b/src/properties/csl/ProbabilisticBoundOperator.h @@ -0,0 +1,241 @@ +/* + * ProbabilisticBoundOperator.h + * + * Created on: 19.10.2012 + * Author: Thomas Heinemann + */ + +#ifndef STORM_FORMULA_CSL_PROBABILISTICBOUNDOPERATOR_H_ +#define STORM_FORMULA_CSL_PROBABILISTICBOUNDOPERATOR_H_ + +#include "src/properties/csl/AbstractStateFormula.h" +#include "src/properties/csl/AbstractPathFormula.h" +#include "src/properties/ComparisonType.h" +#include "utility/constants.h" + +namespace storm { +namespace properties { +namespace csl { + +// Forward declaration for the interface class. +template <class T> class ProbabilisticBoundOperator; + +/*! + * Interface class for model checkers that support ProbabilisticBoundOperator. + * + * All model checkers that support the formula class PathBoundOperator must inherit + * this pure virtual class. + */ +template <class T> +class IProbabilisticBoundOperatorModelChecker { + public: + + /*! + * Empty virtual destructor. + */ + virtual ~IProbabilisticBoundOperatorModelChecker() { + // Intentionally left empty + } + + /*! + * Evaluates a ProbabilisticBoundOperator within a model checker. + * + * @param obj Formula object with subformulas. + * @return The modelchecking result of the formula for every state. + */ + virtual storm::storage::BitVector checkProbabilisticBoundOperator(const ProbabilisticBoundOperator<T>& obj) const = 0; +}; + +/*! + * Class for a Csl formula tree with a P (probablistic) bound operator node as root. + * + * Has one path formula as sub formula/tree. + * + * @par Semantics + * The formula holds iff the probability that the path formula holds meets the bound + * specified in this operator + * + * The object has shared ownership of its subtree. If this object is deleted and no other object has a shared + * ownership of the subtree it will be deleted as well. + * + * @see AbstractStateFormula + * @see AbstractPathFormula + * @see AbstractCslFormula + */ +template<class T> +class ProbabilisticBoundOperator : public AbstractStateFormula<T> { + +public: + + /*! + * Creates a ProbabilisticBoundOperator node without a subnode. + * The resulting object will not represent a complete formula! + */ + ProbabilisticBoundOperator() : comparisonOperator(LESS), bound(0), child(nullptr) { + // Intentionally left empty. + } + + /*! + * Creates a ProbabilisticBoundOperator node using the given parameters. + * + * @param comparisonOperator The relation for the bound. + * @param bound The bound for the probability. + * @param child The child formula subtree. + */ + ProbabilisticBoundOperator(storm::properties::ComparisonType comparisonOperator, T bound, std::shared_ptr<AbstractPathFormula<T>> const & child) + : comparisonOperator(comparisonOperator), bound(bound), child(child) { + // Intentionally left empty. + } + + /*! + * Empty virtual destructor. + */ + virtual ~ProbabilisticBoundOperator() { + // Intentionally left empty. + } + + /*! + * Clones the called object. + * + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. + * + * @returns A new ProbabilisticBoundOperator object that is a deep copy of the called object. + */ + virtual std::shared_ptr<AbstractStateFormula<T>> clone() const override { + std::shared_ptr<ProbabilisticBoundOperator<T>> result(new ProbabilisticBoundOperator<T>()); + result->setComparisonOperator(comparisonOperator); + result->setBound(bound); + result->setChild(child->clone()); + return result; + } + + /*! + * Calls the model checker to check this formula. + * Needed to infer the correct type of formula class. + * + * @note This function should only be called in a generic check function of a model checker class. For other uses, + * the methods of the model checker should be used. + * + * @returns A bit vector indicating all states that satisfy the formula represented by the called object. + */ + virtual storm::storage::BitVector check(storm::modelchecker::csl::AbstractModelChecker<T> const & modelChecker) const override { + return modelChecker.template as<IProbabilisticBoundOperatorModelChecker>()->checkProbabilisticBoundOperator(*this); + } + + /*! + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. + */ + virtual std::string toString() const override { + std::string result = "P "; + switch (comparisonOperator) { + case LESS: result += "<"; break; + case LESS_EQUAL: result += "<="; break; + case GREATER: result += ">"; break; + case GREATER_EQUAL: result += ">="; break; + } + result += " "; + result += std::to_string(bound); + result += " ("; + result += child->toString(); + result += ")"; + return result; + } + + /*! + * Gets the child node. + * + * @returns The child node. + */ + std::shared_ptr<AbstractPathFormula<T>> const & getChild () const { + return child; + } + + /*! + * Sets the subtree. + * + * @param child The new child. + */ + void setChild(std::shared_ptr<AbstractPathFormula<T>> const & child) { + this->child = child; + } + + /*! + * Checks if the child is set, i.e. it does not point to null. + * + * @return True iff the child is set. + */ + bool isChildSet() const { + return child.get() != nullptr; + } + + /*! + * Gets the comparison operator. + * + * @returns An enum value representing the comparison relation. + */ + storm::properties::ComparisonType const getComparisonOperator() const { + return comparisonOperator; + } + + /*! + * Sets the comparison operator. + * + * @param comparisonOperator An enum value representing the new comparison relation. + */ + void setComparisonOperator(storm::properties::ComparisonType comparisonOperator) { + this->comparisonOperator = comparisonOperator; + } + + /*! + * Gets the bound which the probability that the path formula holds has to obey. + * + * @returns The probability bound. + */ + T const & getBound() const { + return bound; + } + + /*! + * Sets the bound which the probability that the path formula holds has to obey. + * + * @param bound The new probability bound. + */ + void setBound(T const & bound) { + this->bound = bound; + } + + /*! + * Checks if the bound is met by the given value. + * + * @param value The value to test against the bound. + * @returns True iff value <comparisonOperator> bound holds. + */ + bool meetsBound(T const & value) const { + switch (comparisonOperator) { + case LESS: return value < bound; break; + case LESS_EQUAL: return value <= bound; break; + case GREATER: return value > bound; break; + case GREATER_EQUAL: return value >= bound; break; + default: return false; + } + } + +private: + + // The operator used to indicate the kind of bound that is to be met. + storm::properties::ComparisonType comparisonOperator; + + // The probability bound. + T bound; + + // The path formula for which the probability to be satisfied has to meet the bound. + std::shared_ptr<AbstractPathFormula<T>> child; +}; + +} //namespace csl +} //namespace properties +} //namespace storm + +#endif /* STORM_FORMULA_CSL_PROBABILISTICBOUNDOPERATOR_H_ */ diff --git a/src/properties/csl/SteadyStateBoundOperator.h b/src/properties/csl/SteadyStateBoundOperator.h new file mode 100644 index 000000000..141f070b7 --- /dev/null +++ b/src/properties/csl/SteadyStateBoundOperator.h @@ -0,0 +1,234 @@ +/* + * SteadyState.h + * + * Created on: 19.10.2012 + * Author: Thomas Heinemann + */ + +#ifndef STORM_FORMULA_CSL_STEADYSTATEOPERATOR_H_ +#define STORM_FORMULA_CSL_STEADYSTATEOPERATOR_H_ + +#include "AbstractStateFormula.h" +#include "src/properties/ComparisonType.h" + +namespace storm { +namespace properties { +namespace csl { + +// Forward declaration for the interface class. +template <class T> class SteadyStateBoundOperator; + +/*! + * Interface class for model checkers that support SteadyStateOperator. + * + * All model checkers that support the formula class SteadyStateOperator must inherit + * this pure virtual class. + */ +template <class T> +class ISteadyStateBoundOperatorModelChecker { + public: + + /*! + * Empty virtual destructor. + */ + virtual ~ISteadyStateBoundOperatorModelChecker() { + // Intentionally left empty + } + + /*! + * Evaluates a SteadyStateOperator formula within a model checker. + * + * @param obj Formula object with subformulas. + * @return The modelchecking result of the formula for every state. + */ + virtual storm::storage::BitVector checkSteadyStateBoundOperator(const SteadyStateBoundOperator<T>& obj) const = 0; +}; + +/*! + * Class for a Csl formula tree with a SteadyStateOperator node as root. + * + * Has two state formulas as sub formulas/trees. + * + * @par Semantics + * The formula holds iff the long-run probability of being in a state satisfying \e child meets the \e bound specified in this operator. + * + * The object has shared ownership of its subtree. If this object is deleted and no other object has a shared + * ownership of the subtree it will be deleted as well. + * + * @see AbstractPathFormula + * @see AbstractCslFormula + */ +template <class T> +class SteadyStateBoundOperator : public AbstractStateFormula<T> { + +public: + + /*! + * Creates a SteadyStateBoundOperator node without a subnode. + * The resulting object will not represent a complete formula! + */ + SteadyStateBoundOperator() : comparisonOperator(LESS), bound(storm::utility::constantZero<T>()), child(nullptr) { + // Intentionally left empty + } + + /*! + * Creates a SteadyStateBoundOperator node using the given parameters. + * + * @param comparisonOperator The relation for the bound. + * @param bound The bound for the probability. + * @param child The child formula subtree. + */ + SteadyStateBoundOperator(storm::properties::ComparisonType comparisonOperator, T bound, std::shared_ptr<AbstractStateFormula<T>> const & child) + : comparisonOperator(comparisonOperator), bound(bound), child(child) { + // Intentionally left empty + } + + /*! + * Empty virtual destructor. + */ + virtual ~SteadyStateBoundOperator() { + // Intentionally left empty. + } + + /*! + * Clones the called object. + * + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. + * + * @returns A new SteadyStateBoundOperator object that is a deep copy of the called object. + */ + virtual std::shared_ptr<AbstractStateFormula<T>> clone() const override { + std::shared_ptr<SteadyStateBoundOperator<T>> result(new SteadyStateBoundOperator<T>()); + result->setChild(child->clone()); + return result; + } + + /*! + * Calls the model checker to check this formula. + * Needed to infer the correct type of formula class. + * + * @note This function should only be called in a generic check function of a model checker class. For other uses, + * the methods of the model checker should be used. + * + * @returns A vector indicating the probability that the formula holds for each state. + */ + virtual storm::storage::BitVector check(storm::modelchecker::csl::AbstractModelChecker<T> const & modelChecker) const override { + return modelChecker.template as<ISteadyStateBoundOperatorModelChecker>()->checkSteadyStateBoundOperator(*this); + } + + /*! + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. + */ + virtual std::string toString() const override { + std::string result = "S "; + switch (comparisonOperator) { + case LESS: result += "< "; break; + case LESS_EQUAL: result += "<= "; break; + case GREATER: result += "> "; break; + case GREATER_EQUAL: result += ">= "; break; + } + result += std::to_string(bound); + result += " ("; + result += child->toString(); + result += ")"; + return result; + } + + /*! + * Gets the child node. + * + * @returns The child node. + */ + std::shared_ptr<AbstractStateFormula<T>> const & getChild () const { + return child; + } + + /*! + * Sets the subtree. + * + * @param child The new child. + */ + void setChild(std::shared_ptr<AbstractStateFormula<T>> const & child) { + this->child = child; + } + + /*! + * Checks if the child is set, i.e. it does not point to null. + * + * @return True iff the child is set. + */ + bool isChildSet() const { + return child.get() != nullptr; + } + + /*! + * Gets the comparison operator. + * + * @returns An enum value representing the comparison relation. + */ + ComparisonType const getComparisonOperator() const { + return comparisonOperator; + } + + /*! + * Sets the comparison operator. + * + * @param comparisonOperator An enum value representing the new comparison relation. + */ + void setComparisonOperator(ComparisonType comparisonOperator) { + this->comparisonOperator = comparisonOperator; + } + + /*! + * Gets the bound which the steady state probability has to obey. + * + * @returns The probability bound. + */ + T const & getBound() const { + return bound; + } + + /*! + * Sets the bound which the steady state probability has to obey. + * + * @param bound The new probability bound. + */ + void setBound(T const & bound) { + this->bound = bound; + } + + /*! + * Checks if the bound is met by the given value. + * + * @param value The value to test against the bound. + * @returns True iff value <comparisonOperator> bound holds. + */ + bool meetsBound(T value) const { + switch (comparisonOperator) { + case LESS: return value < bound; break; + case LESS_EQUAL: return value <= bound; break; + case GREATER: return value > bound; break; + case GREATER_EQUAL: return value >= bound; break; + default: return false; + } + } + +private: + + // The operator used to indicate the kind of bound that is to be met. + ComparisonType comparisonOperator; + + // The probability bound. + T bound; + + // The state formula for whose state the long-run probability has to meet the bound. + std::shared_ptr<AbstractStateFormula<T>> child; +}; + +} //namespace csl +} //namespace properties +} //namespace storm + +#endif /* STORM_FORMULA_CSL_STEADYSTATEOPERATOR_H_ */ diff --git a/src/properties/csl/TimeBoundedEventually.h b/src/properties/csl/TimeBoundedEventually.h new file mode 100644 index 000000000..3d537a34a --- /dev/null +++ b/src/properties/csl/TimeBoundedEventually.h @@ -0,0 +1,219 @@ +/* + * TimeBoundedEventually.h + * + * Created on: 10.04.2013 + * Author: thomas + */ + +#ifndef STORM_FORMULA_CSL_TIMEBOUNDEDEVENTUALLY_H_ +#define STORM_FORMULA_CSL_TIMEBOUNDEDEVENTUALLY_H_ + +#include "src/properties/csl/AbstractPathFormula.h" +#include "src/properties/csl/AbstractStateFormula.h" + +namespace storm { +namespace properties { +namespace csl { + +// Forward declaration for the interface class. +template<class T> class TimeBoundedEventually; + +/*! + * Interface class for model checkers that support TimeBoundedEventually. + * + * All model checkers that support the formula class TimeBoundedEventually must inherit + * this pure virtual class. + */ +template <class T> +class ITimeBoundedEventuallyModelChecker { + public: + + /*! + * Empty virtual destructor. + */ + virtual ~ITimeBoundedEventuallyModelChecker() { + // Intentionally left empty + } + + /*! + * Evaluates a TimeBoundedEventually formula within a model checker. + * + * @param obj Formula object with subformulas. + * @param qualitative A flag indicating whether the formula only needs to be evaluated qualitatively, i.e. if the + * results are only compared against the bounds 0 and 1. + * @return The modelchecking result of the formula for every state. + */ + virtual std::vector<T> checkTimeBoundedEventually(const TimeBoundedEventually<T>& obj, bool qualitative) const = 0; +}; + +/*! + * Class for a Csl (path) formula tree with a TimeBoundedEventually node as root. + * + * Has one state formula as subformula/tree. + * + * @par Semantics + * The formula holds iff formula \e child holds within the given time interval [lowerBound, upperBound]. + * + * The object has shared ownership of its subtree. If this object is deleted and no other object has a shared + * ownership of the subtree it will be deleted as well. + * + * @see AbstractPathFormula + * @see AbstractCslFormula + */ +template<class T> +class TimeBoundedEventually: public AbstractPathFormula<T> { +public: + + /*! + * Creates a TimeBoundedEventually node without a subnode. + * The resulting object will not represent a complete formula! + */ + TimeBoundedEventually() : child(nullptr), lowerBound(0), upperBound(0) { + // Intentionally left empty. + } + + /*! + * Creates a TimeBoundedEventually node using the given parameters. + * + * @param lowerBound The lower bound of the admissable time interval. + * @param upperBound The upper bound of the admissable time interval. + * @param child The child formula subtree. + */ + TimeBoundedEventually(T lowerBound, T upperBound, std::shared_ptr<AbstractStateFormula<T>> const & child) : child(child) { + setInterval(lowerBound, upperBound); + } + + /*! + * Empty virtual destructor. + */ + virtual ~TimeBoundedEventually() { + // Intentionally left empty. + } + + /*! + * Clones the called object. + * + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. + * + * @returns A new TimeBoundedEventually object that is a deep copy of the called object. + */ + virtual std::shared_ptr<AbstractPathFormula<T>> clone() const override { + auto result = std::make_shared<TimeBoundedEventually<T>>(); + result->setInterval(lowerBound, upperBound); + if (this->isChildSet()) { + result->setChild(child->clone()); + } + return result; + } + + /*! + * Calls the model checker to check this formula. + * Needed to infer the correct type of formula class. + * + * @note This function should only be called in a generic check function of a model checker class. For other uses, + * the methods of the model checker should be used. + * + * @returns A vector indicating the probability that the formula holds for each state. + */ + virtual std::vector<T> check(storm::modelchecker::csl::AbstractModelChecker<T> const & modelChecker, bool qualitative) const override { + return modelChecker.template as<ITimeBoundedEventuallyModelChecker>()->checkTimeBoundedEventually(*this, qualitative); + } + + /*! + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. + */ + virtual std::string toString() const override { + std::string result = "F"; + if (upperBound == std::numeric_limits<double>::infinity()) { + result += ">=" + std::to_string(lowerBound); + } else { + result += "["; + result += std::to_string(lowerBound); + result += ","; + result += std::to_string(upperBound); + result += "]"; + } + result += " "; + result += child->toString(); + return result; + } + + /*! + * Gets the child node. + * + * @returns The child node. + */ + std::shared_ptr<AbstractStateFormula<T>> const & getChild() const { + return child; + } + + /*! + * Sets the subtree. + * + * @param child The new child. + */ + void setChild(std::shared_ptr<AbstractStateFormula<T>> const & child) { + this->child = child; + } + + /*! + * Checks if the child is set, i.e. it does not point to null. + * + * @return True iff the child is set. + */ + bool isChildSet() const { + return child.get() != nullptr; + } + + /*! + * Get the lower time bound. + * + * @return The lower time bound. + */ + T const & getLowerBound() const { + return lowerBound; + } + + /*! + * Get the upper time bound. + * + * @return The upper time bound. + */ + T const & getUpperBound() const { + return upperBound; + } + + /*! + * Set the time interval for the time bounded operator. + * + * @param lowerBound The new lower time bound. + * @param upperBound The new upper time bound. + * @throw InvalidArgumentException if the lower bound is larger than the upper bound. + */ + void setInterval(T lowerBound, T upperBound) { + if (lowerBound > upperBound) { + throw new storm::exceptions::InvalidArgumentException("Lower bound is larger than upper bound"); + } + this->lowerBound = lowerBound; + this->upperBound = upperBound; + } + +private: + + // The child node. + std::shared_ptr<AbstractStateFormula<T>> child; + + // The lower time bound. + T lowerBound; + + // The upper time bound. + T upperBound; +}; + +} /* namespace csl */ +} /* namespace properties */ +} /* namespace storm */ + +#endif /* STORM_FORMULA_CSL_TIMEBOUNDEDEVENTUALLY_H_ */ diff --git a/src/properties/csl/TimeBoundedUntil.h b/src/properties/csl/TimeBoundedUntil.h new file mode 100644 index 000000000..c224f93df --- /dev/null +++ b/src/properties/csl/TimeBoundedUntil.h @@ -0,0 +1,256 @@ +/* + * TimeBoundedUntil.h + * + * Created on: 10.04.2013 + * Author: thomas + */ + +#ifndef STORM_FORMULA_CSL_TIMEBOUNDEDUNTIL_H_ +#define STORM_FORMULA_CSL_TIMEBOUNDEDUNTIL_H_ + +#include "src/properties/csl/AbstractPathFormula.h" +#include "src/properties/csl/AbstractStateFormula.h" + +namespace storm { +namespace properties { +namespace csl { + +// Forward declaration for the interface class. +template <class T> class TimeBoundedUntil; + +/*! + * Interface class for model checkers that support TimeBoundedUntil. + * + * All model checkers that support the formula class TimeBoundedUntil must inherit + * this pure virtual class. + */ +template <class T> +class ITimeBoundedUntilModelChecker { + public: + + /*! + * Empty virtual destructor. + */ + virtual ~ITimeBoundedUntilModelChecker() { + // Intentionally left empty + } + + /*! + * Evaluates a TimeBoundedUntil formula within a model checker. + * + * @param obj Formula object with subformulas. + * @param qualitative A flag indicating whether the formula only needs to be evaluated qualitatively, i.e. if the + * results are only compared against the bounds 0 and 1. + * @return The modelchecking result of the formula for every state. + */ + virtual std::vector<T> checkTimeBoundedUntil(const TimeBoundedUntil<T>& obj, bool qualitative) const = 0; +}; + + +/*! + * Class for a Csl (path) formula tree with a TimeBoundedUntil node as root. + * + * Has two state formulas as subformulas/trees. + * + * @par Semantics + * The formula holds iff formula \e right holds within the given time interval [lowerBound, upperBound] and \e left holds + * in each point in time before that. + * + * The object has shared ownership of its subtree. If this object is deleted and no other object has a shared + * ownership of the subtree it will be deleted as well. + * + * @see AbstractPathFormula + * @see AbstractCslFormula + */ +template <class T> +class TimeBoundedUntil: public AbstractPathFormula<T> { +public: + + /*! + * Creates a TimeBoundedUntil node without a subnode. + * The resulting object will not represent a complete formula! + */ + TimeBoundedUntil() : left(nullptr), right(nullptr), lowerBound(0), upperBound(0) { + // Intentionally left empty. + } + + /*! + * Creates a TimeBoundedUntil node using the given parameters. + * + * @param lowerBound The lower bound of the admissable time interval. + * @param upperBound The upper bound of the admissable time interval. + * @param child The child formula subtree. + */ + TimeBoundedUntil(T lowerBound, T upperBound, std::shared_ptr<AbstractStateFormula<T>> const & left, std::shared_ptr<AbstractStateFormula<T>> const & right) : left(left), right(right) { + setInterval(lowerBound, upperBound); + } + + /*! + * Empty virtual destructor. + */ + virtual ~TimeBoundedUntil() { + // Intentionally left empty. + } + + /*! + * Clones the called object. + * + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. + * + * @returns A new TimeBoundedUntil object that is a deep copy of the called object. + */ + virtual std::shared_ptr<AbstractPathFormula<T>> clone() const override { + auto result = std::make_shared<TimeBoundedUntil<T>>(); + result->setInterval(lowerBound, upperBound); + if (this->isLeftSet()) { + result->setLeft(left->clone()); + } + if (this->isRightSet()) { + result->setRight(right->clone()); + } + return result; + } + + + /*! + * Calls the model checker to check this formula. + * Needed to infer the correct type of formula class. + * + * @note This function should only be called in a generic check function of a model checker class. For other uses, + * the methods of the model checker should be used. + * + * @returns A vector indicating the probability that the formula holds for each state. + */ + virtual std::vector<T> check(storm::modelchecker::csl::AbstractModelChecker<T> const & modelChecker, bool qualitative) const override { + return modelChecker.template as<ITimeBoundedUntilModelChecker>()->checkTimeBoundedUntil(*this, qualitative); + } + + /*! + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. + */ + virtual std::string toString() const override { + std::string result = left->toString(); + result += " U"; + if (upperBound == std::numeric_limits<double>::infinity()) { + result += ">=" + std::to_string(lowerBound); + } else { + result += "["; + result += std::to_string(lowerBound); + result += ","; + result += std::to_string(upperBound); + result += "]"; + } + result += " "; + result += right->toString(); + return result; + } + + /*! + * Gets the left child node. + * + * @returns The left child node. + */ + std::shared_ptr<AbstractStateFormula<T>> const & getLeft() const { + return left; + } + + /*! + * Gets the right child node. + * + * @returns The right child node. + */ + std::shared_ptr<AbstractStateFormula<T>> const & getRight() const { + return right; + } + + /*! + * Sets the left child node. + * + * @param newLeft The new left child. + */ + void setLeft(std::shared_ptr<AbstractStateFormula<T>> const & newLeft) { + left = newLeft; + } + + /*! + * Sets the right child node. + * + * @param newRight The new right child. + */ + void setRight(std::shared_ptr<AbstractStateFormula<T>> const & newRight) { + right = newRight; + } + + /*! + * Checks if the left child is set, i.e. it does not point to null. + * + * @return True iff the left child is set. + */ + bool isLeftSet() const { + return left.get() != nullptr; + } + + /*! + * Checks if the right child is set, i.e. it does not point to null. + * + * @return True iff the right child is set. + */ + bool isRightSet() const { + return right.get() != nullptr; + } + + /*! + * Get the lower time bound. + * + * @return The lower time bound. + */ + T const & getLowerBound() const { + return lowerBound; + } + + /*! + * Get the upper time bound. + * + * @return The upper time bound. + */ + T const & getUpperBound() const { + return upperBound; + } + + /** + * Set the time interval for the time bounded operator + * + * @param lowerBound The new lower time bound. + * @param upperBound The new upper time bound. + * @throw InvalidArgumentException if the lower bound is larger than the upper bound. + */ + void setInterval(T lowerBound, T upperBound) { + if (lowerBound > upperBound) { + throw new storm::exceptions::InvalidArgumentException("Lower bound is larger than upper bound"); + } + this->lowerBound = lowerBound; + this->upperBound = upperBound; + } + +private: + + // The left child node. + std::shared_ptr<AbstractStateFormula<T>> left; + + // The right child node. + std::shared_ptr<AbstractStateFormula<T>> right; + + // The lower time bound. + T lowerBound; + + // The upper time bound. + T upperBound; +}; + +} /* namespace csl */ +} /* namespace properties */ +} /* namespace storm */ + +#endif /* STORM_FORMULA_CSL_TIMEBOUNDEDUNTIL_H_ */ diff --git a/src/properties/csl/Until.h b/src/properties/csl/Until.h new file mode 100644 index 000000000..b709a1d82 --- /dev/null +++ b/src/properties/csl/Until.h @@ -0,0 +1,205 @@ +/* + * Until.h + * + * Created on: 19.10.2012 + * Author: Thomas Heinemann + */ + +#ifndef STORM_FORMULA_CSL_UNTIL_H_ +#define STORM_FORMULA_CSL_UNTIL_H_ + +#include "src/properties/csl/AbstractPathFormula.h" +#include "src/properties/csl/AbstractStateFormula.h" + +namespace storm { +namespace properties { +namespace csl { + +// Forward declaration for the interface class. +template <class T> class Until; + +/*! + * Interface class for model checkers that support Until. + * + * All model checkers that support the formula class Until must inherit + * this pure virtual class. + */ +template <class T> +class IUntilModelChecker { + public: + + /*! + * Empty virtual destructor. + */ + virtual ~IUntilModelChecker() { + // Intentionally left empty + } + + /*! + * Evaluates an Until formula within a model checker. + * + * @param obj Formula object with subformulas. + * @param qualitative A flag indicating whether the formula only needs to be evaluated qualitatively, i.e. if the + * results are only compared against the bounds 0 and 1. + * @return The modelchecking result of the formula for every state. + */ + virtual std::vector<T> checkUntil(const Until<T>& obj, bool qualitative) const = 0; +}; + +/*! + * @brief + * Class for a Csl (path) formula tree with an Until node as root. + * + * Has two state formulas as sub formulas/trees. + * + * @par Semantics + * The formula holds iff eventually, formula \e right (the right subtree) holds, and before, + * \e left holds always. + * + * The object has shared ownership of its subtrees. If this object is deleted and no other object has a shared + * ownership of the subtrees they will be deleted as well. + * + * @see AbstractPathFormula + * @see AbstractCslFormula + */ +template <class T> +class Until : public AbstractPathFormula<T> { + +public: + + /*! + * Creates an Until node without subnodes. + * The resulting object will not represent a complete formula! + */ + Until() : left(nullptr), right(nullptr){ + // Intentionally left empty. + } + + /*! + * Creates an Until node using the given parameters. + * + * @param left The left formula subtree. + * @param right The right formula subtree. + */ + Until(std::shared_ptr<AbstractStateFormula<T>> const & left, std::shared_ptr<AbstractStateFormula<T>> const & right) : left(left), right(right){ + // Intentionally left empty. + } + + /*! + * Empty virtual destructor. + */ + virtual ~Until() { + // Intentionally left empty. + } + + /*! + * Clones the called object. + * + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. + * + * @returns A new Until object that is a deep copy of the called object. + */ + virtual std::shared_ptr<AbstractPathFormula<T>> clone() const override { + std::shared_ptr<Until<T>> result(new Until()); + if (this->isLeftSet()) { + result->setLeft(left->clone()); + } + if (this->isRightSet()) { + result->setRight(left->clone()); + } + return result; + } + + /*! + * Calls the model checker to check this formula. + * Needed to infer the correct type of formula class. + * + * @note This function should only be called in a generic check function of a model checker class. For other uses, + * the methods of the model checker should be used. + * + * @returns A vector indicating the probability that the formula holds for each state. + */ + virtual std::vector<T> check(storm::modelchecker::csl::AbstractModelChecker<T> const & modelChecker, bool qualitative) const override { + return modelChecker.template as<IUntilModelChecker>()->checkUntil(*this, qualitative); + } + + /*! + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. + */ + virtual std::string toString() const override { + std::string result = left->toString(); + result += " U "; + result += right->toString(); + return result; + } + + /*! + * Gets the left child node. + * + * @returns The left child node. + */ + std::shared_ptr<AbstractStateFormula<T>> const & getLeft() const { + return left; + } + + /*! + * Gets the right child node. + * + * @returns The right child node. + */ + std::shared_ptr<AbstractStateFormula<T>> const & getRight() const { + return right; + } + + /*! + * Sets the left child node. + * + * @param newLeft The new left child. + */ + void setLeft(std::shared_ptr<AbstractStateFormula<T>> const & newLeft) { + left = newLeft; + } + + /*! + * Sets the right child node. + * + * @param newRight The new right child. + */ + void setRight(std::shared_ptr<AbstractStateFormula<T>> const & newRight) { + right = newRight; + } + + /*! + * Checks if the left child is set, i.e. it does not point to null. + * + * @return True iff the left child is set. + */ + bool isLeftSet() const { + return left.get() != nullptr; + } + + /*! + * Checks if the right child is set, i.e. it does not point to null. + * + * @return True iff the right child is set. + */ + bool isRightSet() const { + return right.get() != nullptr; + } + +private: + + // The left child node. + std::shared_ptr<AbstractStateFormula<T>> left; + + // The right child node. + std::shared_ptr<AbstractStateFormula<T>> right; +}; + +} //namespace csl +} //namespace properties +} //namespace storm + +#endif /* STORM_FORMULA_CSL_UNTIL_H_ */ diff --git a/src/formula/Ltl/AbstractLtlFormula.h b/src/properties/ltl/AbstractLtlFormula.h similarity index 53% rename from src/formula/Ltl/AbstractLtlFormula.h rename to src/properties/ltl/AbstractLtlFormula.h index 65c31bdef..c4ff5ad5a 100644 --- a/src/formula/Ltl/AbstractLtlFormula.h +++ b/src/properties/ltl/AbstractLtlFormula.h @@ -10,79 +10,55 @@ #include <vector> #include "src/modelchecker/ltl/ForwardDeclarations.h" -#include "src/formula/abstract/AbstractFormula.h" +#include "src/properties/AbstractFormula.h" -// Forward declaration for formula visitor namespace storm { -namespace property { -namespace ltl { - -template <class T> -class AbstractLtlFormula; - -} -} -} - -#include "visitor/AbstractLtlFormulaVisitor.h" - - -namespace storm { -namespace property { +namespace properties { namespace ltl { /*! - * Interface class for all LTL root formulas. + * This is the abstract base class for all Ltl formulas. + * + * @note While formula classes do have copy constructors using a copy constructor + * will yield a formula objects whose formula subtree consists of the same objects + * as the original formula. The ownership of the formula tree will be shared between + * the original and the copy. */ template <class T> -class AbstractLtlFormula : public virtual storm::property::abstract::AbstractFormula<T> { +class AbstractLtlFormula : public virtual storm::properties::AbstractFormula<T> { public: - /** - * Empty destructor + + /*! + * The virtual destructor. */ virtual ~AbstractLtlFormula() { // Intentionally left empty } - /*! - * Calls the model checker to check this formula. - * Needed to infer the correct type of formula class. - * - * @note This function should only be called in a generic check function of a model checker class. For other uses, - * the methods of the model checker should be used. - * - * @note This function is not implemented in this class. - * - * @returns A vector indicating the probability that the formula holds for each state. - */ - virtual std::vector<T> check(const storm::modelchecker::ltl::AbstractModelChecker<T>& modelChecker) const = 0; - /*! * Clones the called object. * * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones * - * @returns a new AND-object that is identical the called object. + * @returns A deep copy of the called object. */ - virtual AbstractLtlFormula<T>* clone() const = 0; + virtual std::shared_ptr<AbstractLtlFormula<T>> clone() const = 0; /*! - * @brief Visits all nodes of a formula tree. - * - * @note Every subclass must implement this method. - * - * This method is given a visitor that visits each node to perform some - * task on it (e.g. Validity checks, conversion, ...). The subclasses are to + * Calls the model checker to check this formula. + * Needed to infer the correct type of formula class. * + * @note This function should only be called in a generic check function of a model checker class. For other uses, + * the methods of the model checker should be used. * + * @note This function is not implemented in this class. * - * @param visitor The visitor object. - * @return true iff all subtrees are valid. + * @returns A vector indicating the probability that the formula holds for each state. */ - virtual void visit(visitor::AbstractLtlFormulaVisitor<T>& visitor) const = 0; + virtual std::vector<T> check(const storm::modelchecker::ltl::AbstractModelChecker<T>& modelChecker) const = 0; }; } /* namespace ltl */ -} /* namespace property */ +} /* namespace properties */ } /* namespace storm */ #endif /* STORM_LTL_ABSTRACTLTLFORMULA_H_ */ diff --git a/src/properties/ltl/And.h b/src/properties/ltl/And.h new file mode 100644 index 000000000..51c88651b --- /dev/null +++ b/src/properties/ltl/And.h @@ -0,0 +1,216 @@ +/* + * And.h + * + * Created on: 19.10.2012 + * Author: Thomas Heinemann + */ + +#ifndef STORM_FORMULA_LTL_AND_H_ +#define STORM_FORMULA_LTL_AND_H_ + +#include "AbstractLtlFormula.h" +#include "src/modelchecker/ltl/ForwardDeclarations.h" +#include <string> + +namespace storm { +namespace properties { +namespace ltl { + +// Forward declaration for the interface class. +template <class T> class And; + +/*! + * Interface class for model checkers that support And. + * + * All model checkers that support the formula class And must inherit + * this pure virtual class. + */ +template <class T> +class IAndModelChecker { + public: + + /*! + * Empty virtual destructor. + */ + virtual ~IAndModelChecker() { + // Intentionally left empty + } + + /*! + * @brief Evaluates And formula within a model checker. + * + * @param obj Formula object with subformulas. + * @return Result of the formula for every node. + */ + virtual std::vector<T> checkAnd(const And<T>& obj) const = 0; +}; + +/*! + * Class for an Ltl formula tree with And node as root. + * + * Has two Ltl formulas as sub formulas/trees. + * + * As And is commutative, the order is \e theoretically not important, but will influence the order in which + * the model checker works. + * + * The object has shared ownership of its subtrees. If this object is deleted and no other object has a shared + * ownership of the subtrees they will be deleted as well. + * + * @see AbstractLtlFormula + */ +template <class T> +class And : public AbstractLtlFormula<T> { + +public: + + /*! + * Creates an And node without subnodes. + * The resulting object will not represent a complete formula! + */ + And() : left(nullptr), right(nullptr){ + // Intentionally left empty. + } + + /*! + * Creates an And node with the parameters as subtrees. + * + * @param left The left sub formula. + * @param right The right sub formula. + */ + And(std::shared_ptr<AbstractLtlFormula<T>> left, std::shared_ptr<AbstractLtlFormula<T>> right) : left(left), right(right) { + // Intentionally left empty. + } + + /*! + * Empty virtual destructor. + */ + virtual ~And() { + // Intentionally left empty. + } + + /*! + * Clones the called object. + * + * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones. + * + * @returns A new And object that is a deep copy of the called object. + */ + virtual std::shared_ptr<AbstractLtlFormula<T>> clone() const override { + std::shared_ptr<And<T>> result(new And()); + if (this->isLeftSet()) { + result->setLeft(left->clone()); + } + if (this->isRightSet()) { + result->setRight(right->clone()); + } + return result; + } + + /*! + * Calls the model checker to check this formula. + * Needed to infer the correct type of formula class. + * + * @note This function should only be called in a generic check function of a model checker class. For other uses, + * the methods of the model checker should be used. + * + * @returns A bit vector indicating all states that satisfy the formula represented by the called object. + */ + virtual std::vector<T> check(const storm::modelchecker::ltl::AbstractModelChecker<T>& modelChecker) const override { + return modelChecker.template as<IAndModelChecker>()->checkAnd(*this); + } + + /*! + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. + */ + virtual std::string toString() const override { + std::string result = "("; + result += left->toString(); + result += " & "; + result += right->toString(); + result += ")"; + return result; + } + + /*! + * Returns whether the formula is a propositional logic formula. + * That is, this formula and all its subformulas consist only of And, Or, Not and AP. + * + * @return True iff this is a propositional logic formula. + */ + virtual bool isPropositional() const override { + return left->isPropositional() && right->isPropositional(); + } + + /*! + * Gets the left child node. + * + * @returns The left child node. + */ + std::shared_ptr<AbstractLtlFormula<T>> const & getLeft() const { + return left; + } + + /*! + * Gets the right child node. + * + * @returns The right child node. + */ + std::shared_ptr<AbstractLtlFormula<T>> const & getRight() const { + return right; + } + + /*! + * Sets the left child node. + * + * @param newLeft The new left child. + */ + void setLeft(std::shared_ptr<AbstractLtlFormula<T>> const & newLeft) { + left = newLeft; + } + + /*! + * Sets the right child node. + * + * @param newRight The new right child. + */ + void setRight(std::shared_ptr<AbstractLtlFormula<T>> const & newRight) { + right = newRight; + } + + /*! + * Checks if the left child is set, i.e. it does not point to null. + * + * @return True iff the left child is set. + */ + bool isLeftSet() const { + return left.get() != nullptr; + } + + /*! + * Checks if the right child is set, i.e. it does not point to null. + * + * @return True iff the right child is set. + */ + bool isRightSet() const { + return right.get() != nullptr; + } + +private: + + // The left child node. + std::shared_ptr<AbstractLtlFormula<T>> left; + + // The right child node. + std::shared_ptr<AbstractLtlFormula<T>> right; + +}; + +} //namespace ltl + +} //namespace properties + +} //namespace storm + +#endif /* STORM_FORMULA_LTL_AND_H_ */ diff --git a/src/properties/ltl/Ap.h b/src/properties/ltl/Ap.h new file mode 100644 index 000000000..ed5356720 --- /dev/null +++ b/src/properties/ltl/Ap.h @@ -0,0 +1,136 @@ +/* + * Ap.h + * + * Created on: 22.04.2013 + * Author: thomas + */ + +#ifndef STORM_FORMULA_LTL_AP_H_ +#define STORM_FORMULA_LTL_AP_H_ + +#include "AbstractLtlFormula.h" + +namespace storm { +namespace properties { +namespace ltl { + +// Forward declaration for the interface class. +template <class T> class Ap; + +/*! + * Interface class for model checkers that support Ap. + * + * All model checkers that support the formula class Ap must inherit + * this pure virtual class. + */ +template <class T> +class IApModelChecker { + public: + + /*! + * Empty virtual destructor. + */ + virtual ~IApModelChecker() { + // Intentionally left empty + } + + /*! + * Evaluates an Ap formula within a model checker. + * + * @param obj Formula object with subformulas. + * @return The modelchecking result of the formula for every state. + */ + virtual std::vector<T> checkAp(const Ap<T>& obj) const = 0; +}; + +/*! + * Class for an Ltl formula tree with an atomic proposition as root. + * + * This class represents the leaves in the formula tree. + * + * @see AbstractLtlFormula + */ +template <class T> +class Ap: public storm::properties::ltl::AbstractLtlFormula<T> { + +public: + + /*! + * Creates a new atomic proposition leaf, with the given label. + * + * @param ap A string representing the atomic proposition. + */ + Ap(std::string ap) : ap(ap) { + // Intentionally left empty. + } + + /*! + * Empty virtual destructor. + */ + virtual ~Ap() { + // Intentionally left empty + } + + /*! + * Clones the called object. + * + * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones. + * + * @returns A new Ap object that is a deep copy of the called object. + */ + virtual std::shared_ptr<AbstractLtlFormula<T>> clone() const override { + auto result = std::make_shared<Ap<T>>(this->getAp()); + return result; + } + + /*! + * Calls the model checker to check this formula. + * Needed to infer the correct type of formula class. + * + * @note This function should only be called in a generic check function of a model checker class. For other uses, + * the methods of the model checker should be used. + * + * @returns A vector indicating the probability that the formula holds for each state. + */ + virtual std::vector<T> check(const storm::modelchecker::ltl::AbstractModelChecker<T>& modelChecker) const override { + return modelChecker.template as<IApModelChecker>()->checkAp(*this); + } + + /*! + * A string representing the atomic proposition. + * + * @returns A string representing the leaf. + */ + virtual std::string toString() const override { + return getAp(); + } + + /*! + * Returns whether the formula is a propositional logic formula. + * That is, this formula and all its subformulas consist only of And, Or, Not and AP. + * + * @return True iff this is a propositional logic formula. + */ + virtual bool isPropositional() const override { + return true; + } + + /*! + * Gets the name of the atomic proposition. + * + * @returns The name of the atomic proposition. + */ + std::string const & getAp() const { + return ap; + } + +private: + + // The atomic proposition referenced by this leaf. + std::string ap; +}; + +} /* namespace ltl */ +} /* namespace properties */ +} /* namespace storm */ +#endif /* STORM_FORMULA_LTL_AP_H_ */ diff --git a/src/properties/ltl/BoundedEventually.h b/src/properties/ltl/BoundedEventually.h new file mode 100644 index 000000000..120dec759 --- /dev/null +++ b/src/properties/ltl/BoundedEventually.h @@ -0,0 +1,196 @@ +/* + * BoundedUntil.h + * + * Created on: 27.11.2012 + * Author: Christian Dehnert + */ + +#ifndef STORM_FORMULA_LTL_BOUNDEDEVENTUALLY_H_ +#define STORM_FORMULA_LTL_BOUNDEDEVENTUALLY_H_ + +#include "AbstractLtlFormula.h" +#include <cstdint> +#include <string> +#include "src/modelchecker/ltl/ForwardDeclarations.h" + +namespace storm { +namespace properties { +namespace ltl { + +// Forward declaration for the interface class. +template <class T> class BoundedEventually; + +/*! + * Interface class for model checkers that support BoundedEventually. + * + * All model checkers that support the formula class BoundedEventually must inherit + * this pure virtual class. + */ +template <class T> +class IBoundedEventuallyModelChecker { + public: + + /*! + * Empty virtual destructor. + */ + virtual ~IBoundedEventuallyModelChecker() { + // Intentionally left empty + } + + /*! + * Evaluates a BoundedEventually formula within a model checker. + * + * @param obj Formula object with subformulas. + * @return The modelchecking result of the formula for every state. + */ + virtual std::vector<T> checkBoundedEventually(const BoundedEventually<T>& obj) const = 0; +}; + +/*! + * Class for a Ltl formula tree with a BoundedEventually node as root. + * + * Has one Ltl formula as subformula/tree. + * + * @par Semantics + * The formula holds iff in at most \e bound steps, formula \e child holds. + * + * The object has shared ownership of its subtree. If this object is deleted and no other object has a shared + * ownership of the subtree it will be deleted as well. + * + * @see AbstractLtlFormula + */ +template <class T> +class BoundedEventually : public AbstractLtlFormula<T> { + +public: + + /*! + * Creates a BoundedEventually node without a subnode. + * The resulting object will not represent a complete formula! + */ + BoundedEventually() : child(nullptr), bound(0) { + // Intentionally left empty. + } + + /*! + * Creates a BoundedEventually node using the given parameters. + * + * @param child The child formula subtree. + * @param bound The maximal number of steps within which the subformula must hold. + */ + BoundedEventually(std::shared_ptr<AbstractLtlFormula<T>> child, uint_fast64_t bound) : child(child), bound(bound) { + // Intentionally left empty. + } + + /*! + * Empty virtual destructor. + */ + virtual ~BoundedEventually() { + // Intentionally left empty. + } + + + /*! + * Clones the called object. + * + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. + * + * @returns A new BoundedEventually object that is a deep copy of the called object. + */ + virtual std::shared_ptr<AbstractLtlFormula<T>> clone() const override { + std::shared_ptr<BoundedEventually<T>> result(new BoundedEventually<T>()); + result->setBound(bound); + if (this->isChildSet()) { + result->setChild(child->clone()); + } + return result; + } + + + /*! + * Calls the model checker to check this formula. + * Needed to infer the correct type of formula class. + * + * @note This function should only be called in a generic check function of a model checker class. For other uses, + * the methods of the model checker should be used. + * + * @returns A vector indicating the probability that the formula holds for each state. + */ + virtual std::vector<T> check(storm::modelchecker::ltl::AbstractModelChecker<T> const & modelChecker) const override { + return modelChecker.template as<IBoundedEventuallyModelChecker>()->checkBoundedEventually(*this); + } + + /*! + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. + */ + virtual std::string toString() const override { + std::string result = "F<="; + result += std::to_string(bound); + result += " "; + result += child->toString(); + return result; + } + + /*! + * Gets the child node. + * + * @returns The child node. + */ + std::shared_ptr<AbstractLtlFormula<T>> const & getChild() const { + return child; + } + + /*! + * Sets the subtree. + * + * @param child The new child. + */ + void setChild(std::shared_ptr<AbstractLtlFormula<T>> const & child) { + this->child = child; + } + + /*! + * Checks if the child is set, i.e. it does not point to null. + * + * @return True iff the child is set. + */ + bool isChildSet() const { + return child.get() != nullptr; + } + + /*! + * Gets the maximally allowed number of steps for the bounded eventually operator. + * + * @returns The bound. + */ + uint_fast64_t getBound() const { + return bound; + } + + /*! + * Sets the maximally allowed number of steps for the bounded eventually operator. + * + * @param bound The new bound. + */ + void setBound(uint_fast64_t bound) { + this->bound = bound; + } + + +private: + + // The child node. + std::shared_ptr<AbstractLtlFormula<T>> child; + + // The maximal number of steps within which the subformula must hold. + uint_fast64_t bound; + +}; + +} //namespace ltl +} //namespace properties +} //namespace storm + +#endif /* STORM_FORMULA_LTL_BOUNDEDUNTIL_H_ */ diff --git a/src/properties/ltl/BoundedUntil.h b/src/properties/ltl/BoundedUntil.h new file mode 100644 index 000000000..01e7dd14b --- /dev/null +++ b/src/properties/ltl/BoundedUntil.h @@ -0,0 +1,229 @@ +/* + * BoundedUntil.h + * + * Created on: 19.10.2012 + * Author: Thomas Heinemann + */ + +#ifndef STORM_FORMULA_LTL_BOUNDEDUNTIL_H_ +#define STORM_FORMULA_LTL_BOUNDEDUNTIL_H_ + +#include "src/properties/ltl/AbstractLtlFormula.h" +#include <cstdint> +#include <string> +#include "src/modelchecker/ltl/ForwardDeclarations.h" + +namespace storm { +namespace properties { +namespace ltl { + +// Forward declaration for the interface class. +template <class T> class BoundedUntil; + +/*! + * Interface class for model checkers that support BoundedUntil. + * + * All model checkers that support the formula class BoundedUntil must inherit + * this pure virtual class. + */ +template <class T> +class IBoundedUntilModelChecker { + public: + + /*! + * Empty virtual destructor. + */ + virtual ~IBoundedUntilModelChecker() { + // Intentionally left empty + } + + /*! + * Evaluates a BoundedUntil formula within a model checker. + * + * @param obj Formula object with subformulas. + * @return The modelchecking result of the formula for every state. + */ + virtual std::vector<T> checkBoundedUntil(const BoundedUntil<T>& obj) const = 0; +}; + +/*! + * Class for an Ltl formula tree with a BoundedUntil node as root. + * + * Has two Ltl formulas as sub formulas/trees. + * + * @par Semantics + * The formula holds iff in at most \e bound steps, formula \e right (the right subtree) holds, and before, + * \e left holds. + * + * The object has shared ownership of its subtrees. If this object is deleted and no other object has a shared + * ownership of the subtrees they will be deleted as well. + * + * @see AbstractLtlFormula + */ +template <class T> +class BoundedUntil : public AbstractLtlFormula<T> { + +public: + + /*! + * Creates a BoundedUntil node without subnodes. + * The resulting object will not represent a complete formula! + */ + BoundedUntil() : left(nullptr), right(nullptr), bound(0) { + // Intentionally left empty. + } + + /*! + * Creates a BoundedUntil node using the given parameters. + * + * @param left The left formula subtree. + * @param right The right formula subtree. + * @param bound The maximal number of steps within which the right subformula must hold. + */ + BoundedUntil(std::shared_ptr<AbstractLtlFormula<T>> const & left, std::shared_ptr<AbstractLtlFormula<T>> const & right, uint_fast64_t bound) : left(left), right(right), bound(bound) { + // Intentionally left empty. + } + + /*! + * Empty virtual destructor. + */ + virtual ~BoundedUntil() { + // Intentionally left empty. + } + + /*! + * Clones the called object. + * + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. + * + * @returns A new BoundedUntil object that is a deep copy of the called object. + */ + virtual std::shared_ptr<AbstractLtlFormula<T>> clone() const override { + std::shared_ptr<BoundedUntil<T>> result(new BoundedUntil<T>()); + result->setBound(bound); + if (this->isLeftSet()) { + result->setLeft(left->clone()); + } + if (this->isRightSet()) { + result->setRight(right->clone()); + } + return result; + } + + + /*! + * Calls the model checker to check this formula. + * Needed to infer the correct type of formula class. + * + * @note This function should only be called in a generic check function of a model checker class. For other uses, + * the methods of the model checker should be used. + * + * @returns A vector indicating the probability that the formula holds for each state. + */ + virtual std::vector<T> check(const storm::modelchecker::ltl::AbstractModelChecker<T>& modelChecker) const { + return modelChecker.template as<IBoundedUntilModelChecker>()->checkBoundedUntil(*this); + } + + /*! + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. + */ + virtual std::string toString() const override { + std::string result = "(" + left->toString(); + result += " U<="; + result += std::to_string(bound); + result += " "; + result += right->toString() + ")"; + return result; + } + + /*! + * Gets the left child node. + * + * @returns The left child node. + */ + std::shared_ptr<AbstractLtlFormula<T>> const & getLeft() const { + return left; + } + + /*! + * Gets the right child node. + * + * @returns The right child node. + */ + std::shared_ptr<AbstractLtlFormula<T>> const & getRight() const { + return right; + } + + /*! + * Sets the left child node. + * + * @param newLeft The new left child. + */ + void setLeft(std::shared_ptr<AbstractLtlFormula<T>> const & newLeft) { + left = newLeft; + } + + /*! + * Sets the right child node. + * + * @param newRight The new right child. + */ + void setRight(std::shared_ptr<AbstractLtlFormula<T>> const & newRight) { + right = newRight; + } + + /*! + * Checks if the left child is set, i.e. it does not point to null. + * + * @return True iff the left child is set. + */ + bool isLeftSet() const { + return left.get() != nullptr; + } + + /*! + * Checks if the right child is set, i.e. it does not point to null. + * + * @return True iff the right child is set. + */ + bool isRightSet() const { + return right.get() != nullptr; + } + + /*! + * Gets the maximally allowed number of steps for the bounded until operator. + * + * @returns The bound. + */ + uint_fast64_t getBound() const { + return bound; + } + + /*! + * Sets the maximally allowed number of steps for the bounded until operator. + * + * @param bound The new bound. + */ + void setBound(uint_fast64_t bound) { + this->bound = bound; + } + +private: + + // The left child node. + std::shared_ptr<AbstractLtlFormula<T>> left; + + // The right child node. + std::shared_ptr<AbstractLtlFormula<T>> right; + + // The maximal number of steps within which the subformulas must hold. + uint_fast64_t bound; +}; + +} //namespace ltl +} //namespace properties +} //namespace storm + +#endif /* STORM_FORMULA_LTL_BOUNDEDUNTIL_H_ */ diff --git a/src/properties/ltl/Eventually.h b/src/properties/ltl/Eventually.h new file mode 100644 index 000000000..6c2ac2940 --- /dev/null +++ b/src/properties/ltl/Eventually.h @@ -0,0 +1,165 @@ +/* + * Eventually.h + * + * Created on: 26.12.2012 + * Author: Christian Dehnert + */ + +#ifndef STORM_FORMULA_LTL_EVENTUALLY_H_ +#define STORM_FORMULA_LTL_EVENTUALLY_H_ + +#include "src/properties/ltl/AbstractLtlFormula.h" +#include "src/modelchecker/ltl/ForwardDeclarations.h" + +namespace storm { +namespace properties { +namespace ltl { + +// Forward declaration for the interface class. +template <class T> class Eventually; + +/*! + * Interface class for model checkers that support Eventually. + * + * All model checkers that support the formula class Eventually must inherit + * this pure virtual class. + */ +template <class T> +class IEventuallyModelChecker { + public: + + /*! + * Empty virtual destructor. + */ + virtual ~IEventuallyModelChecker() { + // Intentionally left empty. + } + + /*! + * Evaluates an Eventually formula within a model checker. + * + * @param obj Formula object with subformulas. + * @return The modelchecking result of the formula for every state. + */ + virtual std::vector<T> checkEventually(const Eventually<T>& obj) const = 0; +}; + +/*! + * Class for an Ltl formula tree with an Eventually node as root. + * + * Has one Abstract Ltl formula as sub formula/tree. + * + * @par Semantics + * The formula holds iff eventually \e child holds. + * + * The object has shared ownership of its subtree. If this object is deleted and no other object has a shared + * ownership of the subtree it will be deleted as well. + * + * @see AbstractLtlFormula + */ +template <class T> +class Eventually : public AbstractLtlFormula<T> { + +public: + + /*! + * Creates an Eventually node without a subnode. + * The resulting object will not represent a complete formula! + */ + Eventually() : child(nullptr) { + // Intentionally left empty. + } + + /*! + * Creates an Eventually node using the given parameter. + * + * @param child The child formula subtree. + */ + Eventually(std::shared_ptr<AbstractLtlFormula<T>> const & child) : child(child) { + // Intentionally left empty. + } + + /*! + * Empty virtual destructor. + */ + virtual ~Eventually() { + // Intentionally left empty. + } + + /*! + * Clones the called object. + * + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. + * + * @returns A new Eventually object that is a deep copy of the called object. + */ + virtual std::shared_ptr<AbstractLtlFormula<T>> clone() const override { + std::shared_ptr<Eventually<T>> result(new Eventually<T>()); + if (this->isChildSet()) { + result->setChild(child->clone()); + } + return result; + } + + /*! + * Calls the model checker to check this formula. + * Needed to infer the correct type of formula class. + * + * @note This function should only be called in a generic check function of a model checker class. For other uses, + * the methods of the model checker should be used. + * + * @returns A vector indicating the probability that the formula holds for each state. + */ + virtual std::vector<T> check(const storm::modelchecker::ltl::AbstractModelChecker<T>& modelChecker) const { + return modelChecker.template as<IEventuallyModelChecker>()->checkEventually(*this); + } + + /*! + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. + */ + virtual std::string toString() const override { + std::string result = "F "; + result += child->toString(); + return result; + } + + /*! + * Gets the child node. + * + * @returns The child node. + */ + std::shared_ptr<AbstractLtlFormula<T>> const & getChild() const { + return child; + } + + /*! + * Sets the subtree. + * + * @param child The new child. + */ + void setChild(std::shared_ptr<AbstractLtlFormula<T>> const & child) { + this->child = child; + } + + /*! + * Checks if the child is set, i.e. it does not point to null. + * + * @return True iff the child is set. + */ + bool isChildSet() const { + return child.get() != nullptr; + } + +private: + + // The child node. + std::shared_ptr<AbstractLtlFormula<T>> child; +}; + +} //namespace ltl +} //namespace properties +} //namespace storm + +#endif /* STORM_FORMULA_LTL_EVENTUALLY_H_ */ diff --git a/src/properties/ltl/Globally.h b/src/properties/ltl/Globally.h new file mode 100644 index 000000000..443ac20bb --- /dev/null +++ b/src/properties/ltl/Globally.h @@ -0,0 +1,165 @@ +/* + * Globally.h + * + * Created on: 26.12.2012 + * Author: Christian Dehnert + */ + +#ifndef STORM_FORMULA_LTL_GLOBALLY_H_ +#define STORM_FORMULA_LTL_GLOBALLY_H_ + +#include "AbstractLtlFormula.h" +#include "src/modelchecker/ltl/ForwardDeclarations.h" + +namespace storm { +namespace properties { +namespace ltl { + +// Forward declaration for the interface class. +template <class T> class Globally; + +/*! + * Interface class for model checkers that support Globally. + * + * All model checkers that support the formula class Globally must inherit + * this pure virtual class. + */ +template <class T> +class IGloballyModelChecker { + public: + + /*! + * Empty virtual destructor. + */ + virtual ~IGloballyModelChecker() { + // Intentionally left empty + } + + /*! + * Evaluates a Globally formula within a model checker. + * + * @param obj Formula object with subformulas. + * @return The modelchecking result of the formula for every state. + */ + virtual std::vector<T> checkGlobally(const Globally<T>& obj) const = 0; +}; + +/*! + * Class for an Ltl formula tree with a Globally node as root. + * + * Has one Ltl formula as sub formula/tree. + * + * @par Semantics + * The formula holds iff always formula \e child holds. + * + * The object has shared ownership of its subtree. If this object is deleted and no other object has a shared + * ownership of the subtree it will be deleted as well. + * + * @see AbstractLtlFormula + */ +template <class T> +class Globally : public AbstractLtlFormula<T> { + +public: + + /*! + * Creates a Globally node without a subnode. + * The resulting object will not represent a complete formula! + */ + Globally() : child(nullptr) { + // Intentionally left empty. + } + + /*! + * Creates a Globally node using the given parameter. + * + * @param child The child formula subtree. + */ + Globally(std::shared_ptr<AbstractLtlFormula<T>> const & child) : child(child) { + // Intentionally left empty. + } + + /*! + * Empty virtual destructor. + */ + virtual ~Globally() { + // Intentionally left empty. + } + + /*! + * Clones the called object. + * + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. + * + * @returns A new Globally object that is a deep copy of the called object. + */ + virtual std::shared_ptr<AbstractLtlFormula<T>> clone() const override { + std::shared_ptr<Globally<T>> result(new Globally<T>()); + if (this->isChildSet()) { + result->setChild(child->clone()); + } + return result; + } + + /*! + * Calls the model checker to check this formula. + * Needed to infer the correct type of formula class. + * + * @note This function should only be called in a generic check function of a model checker class. For other uses, + * the methods of the model checker should be used. + * + * @returns A vector indicating the probability that the formula holds for each state. + */ + virtual std::vector<T> check(const storm::modelchecker::ltl::AbstractModelChecker<T>& modelChecker) const { + return modelChecker.template as<IGloballyModelChecker>()->checkGlobally(*this); + } + + /*! + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. + */ + virtual std::string toString() const override { + std::string result = "G "; + result += child->toString(); + return result; + } + + /*! + * Gets the child node. + * + * @returns The child node. + */ + std::shared_ptr<AbstractLtlFormula<T>> const & getChild() const { + return *child; + } + + /*! + * Sets the subtree. + * + * @param child The new child. + */ + void setChild(std::shared_ptr<AbstractLtlFormula<T>> const & child) { + this->child = child; + } + + /*! + * Checks if the child is set, i.e. it does not point to null. + * + * @return True iff the child is set. + */ + bool isChildSet() const { + return child.get() != nullptr; + } + +private: + + // The child node. + std::shared_ptr<AbstractLtlFormula<T>> child; +}; + +} //namespace ltl +} //namespace properties +} //namespace storm + +#endif /* STORM_FORMULA_LTL_GLOBALLY_H_ */ diff --git a/src/properties/ltl/LtlFilter.h b/src/properties/ltl/LtlFilter.h new file mode 100644 index 000000000..5e4760fa2 --- /dev/null +++ b/src/properties/ltl/LtlFilter.h @@ -0,0 +1,281 @@ +/* + * LtlFilter.h + * + * Created on: May 7, 2014 + * Author: Manuel Sascha Weiand + */ + +#ifndef STORM_FORMULA_LTL_LTLFILTER_H_ +#define STORM_FORMULA_LTL_LTLFILTER_H_ + +#include "src/properties/AbstractFilter.h" +#include "src/modelchecker/ltl/AbstractModelChecker.h" +#include "src/properties/ltl/AbstractLtlFormula.h" +#include "src/properties/actions/AbstractAction.h" +#include "src/exceptions/NotImplementedException.h" + +namespace storm { +namespace properties { +namespace ltl { + +/*! + * This is the Ltl specific filter. + * + * It maintains a Ltl formula which can be checked against a given model by either calling evaluate() or check(). + * Additionally it maintains a list of filter actions that are used to further manipulate the modelchecking results and prepare them for output. + */ +template <class T> +class LtlFilter : public storm::properties::AbstractFilter<T> { + + // Convenience typedef to make the code more readable. + typedef typename storm::properties::action::AbstractAction<T>::Result Result; + +public: + + /*! + * Creates an empty LtlFilter, maintaining no Ltl formula. + * + * Calling check or evaluate will return an empty result. + */ + LtlFilter() : AbstractFilter<T>(UNDEFINED), child(nullptr) { + // Intentionally left empty. + } + + /*! + * Creates an LtlFilter maintaining an Ltl formula but containing no actions. + * + * The modelchecking result will be returned or printed as is. + * + * @param child The Ltl formula to be maintained. + * @param opt An enum value indicating which kind of scheduler shall be used for path formulas on nondeterministic models. + */ + LtlFilter(std::shared_ptr<AbstractLtlFormula<T>> const & child, OptimizingOperator opt = UNDEFINED) : AbstractFilter<T>(opt), child(child) { + // Intentionally left empty. + } + + /*! + * Creates an LtlFilter maintaining a Ltl formula and containing a single action. + * + * The given action will be applied to the modelchecking result during evaluation. + * Further actions can be added later. + * + * @param child The Ltl formula to be maintained. + * @param action The single action to be executed during evaluation. + * @param opt An enum value indicating which kind of scheduler shall be used for path formulas on nondeterministic models. + */ + LtlFilter(std::shared_ptr<AbstractLtlFormula<T>> const & child, std::shared_ptr<action::AbstractAction<T>> const & action, OptimizingOperator opt = UNDEFINED) : AbstractFilter<T>(action, opt), child(child) { + // Intentionally left empty. + } + + /*! + * Creates an LtlFilter using the given parameters. + * + * The given actions will be applied to the modelchecking result in ascending index order during evaluation. + * Further actions can be added later. + * + * @param child The Ltl formula to be maintained. + * @param actions A vector conatining the actions that are to be executed during evaluation. + * @param opt An enum value indicating which kind of scheduler shall be used for path formulas on nondeterministic models. + */ + LtlFilter(std::shared_ptr<AbstractLtlFormula<T>> const & child, std::vector<std::shared_ptr<action::AbstractAction<T>>> const & actions, OptimizingOperator opt = UNDEFINED) : AbstractFilter<T>(actions, opt), child(child) { + // Intentionally left empty. + } + + /*! + * Empty virtual destructor. + */ + virtual ~LtlFilter() { + // Intentionally left empty. + } + + + /*! + * Calls the modelchecker, retrieves the modelchecking result, applies the filter action one by one and prints out the result. + * + * @param modelchecker The modelchecker to be called. + */ + void check(storm::modelchecker::ltl::AbstractModelChecker<T> const & modelchecker) const { + + // Write out the formula to be checked. + std::cout << std::endl; + LOG4CPLUS_INFO(logger, "Model checking formula\t" << this->toString()); + std::cout << "Model checking formula:\t" << this->toString() << std::endl; + + Result result; + + try { + result = evaluate(modelchecker); + } catch (std::exception& e) { + std::cout << "Error during computation: " << e.what() << "Skipping property." << std::endl; + LOG4CPLUS_ERROR(logger, "Error during computation: " << e.what() << "Skipping property."); + std::cout << std::endl << "-------------------------------------------" << std::endl; + + return; + } + + writeOut(result, modelchecker); + + } + + /*! + * Calls the modelchecker, retrieves the modelchecking result, applies the filter action one by one and returns the result. + * + * @param modelchecker The modelchecker to be called. + * @returns The result of the sequential application of the filter actions to the modelchecking result. + */ + Result evaluate(storm::modelchecker::ltl::AbstractModelChecker<T> const & modelchecker) const { + // First, get the model checking result. + Result result; + + if(this->opt != UNDEFINED) { + // If it is specified that min/max probabilities/rewards should be computed, call the appropriate method of the model checker. + LOG4CPLUS_ERROR(logger, "Calculation of minimizing and maximizing schedulers for LTL-formula model checking is not yet implemented."); + throw storm::exceptions::NotImplementedException() << "Calculation of minimizing and maximizing schedulers for LTL-formula model checking is not yet implemented."; + } else { + result.pathResult = child->check(modelchecker); + } + + // Now apply all filter actions and return the result. + + // Init the state selection and state map vectors. + result.selection = storm::storage::BitVector(result.stateResult.size(), true); + result.stateMap = std::vector<uint_fast64_t>(result.selection.size()); + for(uint_fast64_t i = 0; i < result.selection.size(); i++) { + result.stateMap[i] = i; + } + + // Now apply all filter actions and return the result. + for(auto action : this->actions) { + result = action->evaluate(result, modelchecker); + } + + return result; + } + + /*! + * Returns a textual representation of the filter. + * + * That includes the actions as well as the maintained formula. + * + * @returns A string representing the filter. + */ + std::string toString() const override { + std::string desc = ""; + + if(this->actions.empty()){ + // There are no filter actions but only the raw state formula. So just print that. + return child->toString(); + } + + desc = "filter["; + + switch(this->opt) { + case MINIMIZE: + desc += "min; "; + break; + case MAXIMIZE: + desc += "max; "; + break; + default: + break; + } + + for(auto action : this->actions) { + desc += action->toString(); + desc += "; "; + } + + // Remove the last "; ". + desc.pop_back(); + desc.pop_back(); + + desc += "]"; + + desc += "("; + desc += child->toString(); + desc += ")"; + + return desc; + } + + /*! + * Gets the child node. + * + * @returns The child node. + */ + std::shared_ptr<AbstractLtlFormula<T>> const & getChild() const { + return child; + } + + /*! + * Sets the subtree. + * + * @param child The new child. + */ + void setChild(std::shared_ptr<AbstractLtlFormula<T>> const & child) { + this->child = child; + } + + /*! + * Checks if the child is set, i.e. it does not point to null. + * + * @return True iff the child is set. + */ + bool isChildSet() const { + return child.get() != nullptr; + } + +private: + + /*! + * Writes out the given result. + * + * @param result The result of the sequential application of the filter actions to a modelchecking result. + * @param modelchecker The modelchecker that was called to generate the modelchecking result. Needed for legacy support. + */ + void writeOut(Result const & result, storm::modelchecker::ltl::AbstractModelChecker<T> const & modelchecker) const { + + // Test for the kind of result. Values or states. + if(!result.pathResult.empty()) { + + // Write out the selected value results in the order given by the stateMap. + if(this->actions.empty()) { + + // There is no filter action given. So provide legacy support: + // Return the results for all states labeled with "init". + LOG4CPLUS_INFO(logger, "Result for initial states:"); + std::cout << "Result for initial states:" << std::endl; + for (auto initialState : modelchecker.template getModel<storm::models::AbstractModel<T>>().getInitialStates()) { + LOG4CPLUS_INFO(logger, "\t" << initialState << ": " << result.pathResult[initialState]); + std::cout << "\t" << initialState << ": " << result.pathResult[initialState] << std::endl; + } + } else { + LOG4CPLUS_INFO(logger, "Result for " << result.selection.getNumberOfSetBits() << " selected states:"); + std::cout << "Result for " << result.selection.getNumberOfSetBits() << " selected states:" << std::endl; + + for(uint_fast64_t i = 0; i < result.stateMap.size(); i++) { + if(result.selection.get(result.stateMap[i])) { + LOG4CPLUS_INFO(logger, "\t" << result.stateMap[i] << ": " << result.pathResult[result.stateMap[i]]); + std::cout << "\t" << result.stateMap[i] << ": " << result.pathResult[result.stateMap[i]] << std::endl; + } + } + } + + } else { + LOG4CPLUS_WARN(logger, "No results could be computed."); + std::cout << "No results could be computed." << std::endl; + } + + std::cout << std::endl << "-------------------------------------------" << std::endl; + } + + // The Ltl formula maintained by this filter. + std::shared_ptr<AbstractLtlFormula<T>> child; +}; + + +} //namespace ltl +} //namespace properties +} //namespace storm + +#endif /* STORM_FORMULA_LTL_LTLFILTER_H_ */ diff --git a/src/properties/ltl/Next.h b/src/properties/ltl/Next.h new file mode 100644 index 000000000..40ad52b0c --- /dev/null +++ b/src/properties/ltl/Next.h @@ -0,0 +1,164 @@ +/* + * Next.h + * + * Created on: 19.10.2012 + * Author: Thomas Heinemann + */ + +#ifndef STORM_FORMULA_LTL_NEXT_H_ +#define STORM_FORMULA_LTL_NEXT_H_ + +#include "AbstractLtlFormula.h" + +namespace storm { +namespace properties { +namespace ltl { + +// Forward declaration for the interface class. +template <class T> class Next; + +/*! + * Interface class for model checkers that support Next. + * + * All model checkers that support the formula class Next must inherit + * this pure virtual class. + */ +template <class T> +class INextModelChecker { + public: + + /*! + * Empty virtual destructor. + */ + virtual ~INextModelChecker() { + // Intentionally left empty + } + + /*! + * Evaluates Next formula within a model checker. + * + * @param obj Formula object with subformulas. + * @return Result of the formula for every node. + */ + virtual std::vector<T> checkNext(const Next<T>& obj) const = 0; +}; + +/*! + * Class for an Ltl formula tree with a Next node as root. + * + * Has two LTL formulas as sub formulas/trees. + * + * @par Semantics + * The formula holds iff in the next step, formula \e child holds + * + * The object has shared ownership of its subtree. If this object is deleted and no other object has a shared + * ownership of the subtree it will be deleted as well. + * + * @see AbstractLtlFormula + */ +template <class T> +class Next : public AbstractLtlFormula<T> { + +public: + + /*! + * Creates a Next node without a subnode. + * The resulting object will not represent a complete formula! + */ + Next() : child(nullptr) { + // Intentionally left empty. + } + + /*! + * Creates a Next node using the given parameter. + * + * @param child The child formula subtree. + */ + Next(std::shared_ptr<AbstractLtlFormula<T>> const & child) : child(child) { + // Intentionally left empty. + } + + /*! + * Empty virtual destructor. + */ + virtual ~Next() { + // Intentionally left empty. + } + + /*! + * Clones the called object. + * + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. + * + * @returns A new Next object that is a deep copy of the called object. + */ + virtual std::shared_ptr<AbstractLtlFormula<T>> clone() const override { + std::shared_ptr<Next<T>> result(new Next<T>()); + if (this->isChildSet()) { + result->setChild(child->clone()); + } + return result; + } + + /*! + * Calls the model checker to check this formula. + * Needed to infer the correct type of formula class. + * + * @note This function should only be called in a generic check function of a model checker class. For other uses, + * the methods of the model checker should be used. + * + * @returns A vector indicating the probability that the formula holds for each state. + */ + virtual std::vector<T> check(storm::modelchecker::ltl::AbstractModelChecker<T> const & modelChecker) const { + return modelChecker.template as<INextModelChecker>()->checkNext(*this); + } + + /*! + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. + */ + virtual std::string toString() const override { + std::string result = "X "; + result += child->toString(); + return result; + } + + /*! + * Gets the child node. + * + * @returns The child node. + */ + std::shared_ptr<AbstractLtlFormula<T>> const & getChild() const { + return child; + } + + /*! + * Sets the subtree. + * + * @param child The new child. + */ + void setChild(std::shared_ptr<AbstractLtlFormula<T>> const & child) { + this->child = child; + } + + /*! + * Checks if the child is set, i.e. it does not point to null. + * + * @return True iff the child is set. + */ + bool isChildSet() const { + return child.get() != nullptr; + } + +private: + + // The child node. + std::shared_ptr<AbstractLtlFormula<T>> child; +}; + +} //namespace ltl +} //namespace properties +} //namespace storm + +#endif /* STORM_FORMULA_LTL_NEXT_H_ */ diff --git a/src/properties/ltl/Not.h b/src/properties/ltl/Not.h new file mode 100644 index 000000000..e0accc91f --- /dev/null +++ b/src/properties/ltl/Not.h @@ -0,0 +1,171 @@ +/* + * Not.h + * + * Created on: 19.10.2012 + * Author: Thomas Heinemann + */ + +#ifndef STORM_FORMULA_LTL_NOT_H_ +#define STORM_FORMULA_LTL_NOT_H_ + +#include "AbstractLtlFormula.h" + +namespace storm { +namespace properties { +namespace ltl { + +// Forward declaration for the interface class. +template <class T> class Not; + +/*! + * Interface class for model checkers that support Not. + * + * All model checkers that support the formula class Not must inherit + * this pure virtual class. + */ +template <class T> +class INotModelChecker { + public: + + /*! + * Empty virtual destructor. + */ + virtual ~INotModelChecker() { + // Intentionally left empty + } + + /*! + * Evaluates Not formula within a model checker. + * + * @param obj Formula object with subformulas. + * @return Result of the formula for every node. + */ + virtual std::vector<T> checkNot(const Not<T>& obj) const = 0; +}; + +/*! + * Class for an Ltl formula tree with a Not node as root. + * + * Has one Ltl formula as sub formula/tree. + * + * The object has shared ownership of its subtree. If this object is deleted and no other object has a shared + * ownership of the subtree it will be deleted as well. + * + * @see AbstractLtlFormula + */ +template <class T> +class Not : public AbstractLtlFormula<T> { + +public: + + /*! + * Creates a Not node without a subnode. + * The resulting object will not represent a complete formula! + */ + Not() : child(nullptr) { + // Intentionally left empty. + } + + /*! + * Creates a Not node using the given parameter. + * + * @param child The child formula subtree. + */ + Not(std::shared_ptr<AbstractLtlFormula<T>> const & child) : child(child) { + // Intentionally left empty. + } + + /*! + * Empty virtual destructor. + */ + virtual ~Not() { + // Intentionally left empty. + } + + /*! + * Clones the called object. + * + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. + * + * @returns A new Not object that is a deep copy of the called object. + */ + virtual std::shared_ptr<AbstractLtlFormula<T>> clone() const override { + std::shared_ptr<Not<T>> result(new Not<T>()); + if (this->isChildSet()) { + result->setChild(child->clone()); + } + return result; + } + + /*! + * Calls the model checker to check this formula. + * Needed to infer the correct type of formula class. + * + * @note This function should only be called in a generic check function of a model checker class. For other uses, + * the methods of the model checker should be used. + * + * @returns A bit vector indicating all states that satisfy the formula represented by the called object. + */ + virtual std::vector<T> check(storm::modelchecker::ltl::AbstractModelChecker<T> const & modelChecker) const override { + return modelChecker.template as<INotModelChecker>()->checkNot(*this); + } + + /*! + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. + */ + virtual std::string toString() const override { + std::string result = "!"; + result += child->toString(); + return result; + } + + /*! + * Returns whether the formula is a propositional logic formula. + * That is, this formula and all its subformulas consist only of And, Or, Not and AP. + * + * @return True iff this is a propositional logic formula. + */ + virtual bool isPropositional() const override { + return child->isPropositional(); + } + + /*! + * Gets the child node. + * + * @returns The child node. + */ + std::shared_ptr<AbstractLtlFormula<T>> const & getChild() const { + return child; + } + + /*! + * Sets the subtree. + * + * @param child The new child. + */ + void setChild(std::shared_ptr<AbstractLtlFormula<T>> const & child) { + this->child = child; + } + + /*! + * Checks if the child is set, i.e. it does not point to null. + * + * @return True iff the child is set. + */ + bool isChildSet() const { + return child.get() != nullptr; + } + +private: + + // The child node. + std::shared_ptr<AbstractLtlFormula<T>> child; +}; + +} //namespace ltl +} //namespace properties +} //namespace storm + +#endif /* STORM_FORMULA_LTL_NOT_H_ */ diff --git a/src/properties/ltl/Or.h b/src/properties/ltl/Or.h new file mode 100644 index 000000000..5a2f20ab6 --- /dev/null +++ b/src/properties/ltl/Or.h @@ -0,0 +1,210 @@ +/* + * Or.h + * + * Created on: 22.04.2013 + * Author: thomas + */ + +#ifndef STORM_FORMULA_LTL_OR_H_ +#define STORM_FORMULA_LTL_OR_H_ + +#include "AbstractLtlFormula.h" + +namespace storm { +namespace properties { +namespace ltl { + +// Forward declaration for the interface class. +template <class T> class Or; + +/*! + * Interface class for model checkers that support Or. + * + * All model checkers that support the formula class Or must inherit + * this pure virtual class. + */ +template <class T> +class IOrModelChecker { + public: + + /*! + * Empty virtual destructor. + */ + virtual ~IOrModelChecker() { + // Intentionally left empty + } + + /*! + * Evaluates Or formula within a model checker. + * + * @param obj Formula object with subformulas. + * @return Result of the formula for every node. + */ + virtual std::vector<T> checkOr(const Or<T>& obj) const = 0; +}; + +/*! + * Class for an abstract formula tree with an Or node as root. + * + * Has two Ltl formulas as sub formulas/trees. + * + * As Or is commutative, the order is \e theoretically not important, but will influence the order in which + * the model checker works. + * + * The object has shared ownership of its subtrees. If this object is deleted and no other object has a shared + * ownership of the subtrees they will be deleted as well. + * + * @see AbstractLtlFormula + */ +template <class T> +class Or: public storm::properties::ltl::AbstractLtlFormula<T> { + +public: + + /*! + * Creates an Or node without subnodes. + * The resulting object will not represent a complete formula! + */ + Or() : left(nullptr), right(nullptr) { + // Intentionally left empty. + } + + /*! + * Creates an Or node with the parameters as subtrees. + * + * @param left The left sub formula. + * @param right The right sub formula. + */ + Or(std::shared_ptr<AbstractLtlFormula<T>> const & left, std::shared_ptr<AbstractLtlFormula<T>> const & right) : left(left), right(right) { + // Intentionally left empty. + } + + /*! + * Empty virtual destructor. + */ + virtual ~Or() { + // Intentionally left empty. + } + + /*! + * Clones the called object. + * + * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones. + * + * @returns A new Or object that is a deep copy of the called object. + */ + virtual std::shared_ptr<AbstractLtlFormula<T>> clone() const override { + std::shared_ptr<Or<T>> result(new Or<T>()); + if (this->isLeftSet()) { + result->setLeft(left->clone()); + } + if (this->isRightSet()) { + result->setRight(right->clone()); + } + return result; + } + + /*! + * Calls the model checker to check this formula. + * Needed to infer the correct type of formula class. + * + * @note This function should only be called in a generic check function of a model checker class. For other uses, + * the methods of the model checker should be used. + * + * @returns A bit vector indicating all states that satisfy the formula represented by the called object. + */ + virtual std::vector<T> check(storm::modelchecker::ltl::AbstractModelChecker<T> const & modelChecker) const override { + return modelChecker.template as<IOrModelChecker>()->checkOr(*this); + } + + /*! + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. + */ + virtual std::string toString() const override { + std::string result = "("; + result += left->toString(); + result += " | "; + result += right->toString(); + result += ")"; + return result; + } + + /*! + * Returns whether the formula is a propositional logic formula. + * That is, this formula and all its subformulas consist only of And, Or, Not and AP. + * + * @return True iff this is a propositional logic formula. + */ + virtual bool isPropositional() const override { + return left->isPropositional() && right->isPropositional(); + } + + /*! + * Gets the left child node. + * + * @returns The left child node. + */ + std::shared_ptr<AbstractLtlFormula<T>> const & getLeft() const { + return left; + } + + /*! + * Gets the right child node. + * + * @returns The right child node. + */ + std::shared_ptr<AbstractLtlFormula<T>> const & getRight() const { + return right; + } + + /*! + * Sets the left child node. + * + * @param newLeft The new left child. + */ + void setLeft(std::shared_ptr<AbstractLtlFormula<T>> const & newLeft) { + left = newLeft; + } + + /*! + * Sets the right child node. + * + * @param newRight The new right child. + */ + void setRight(std::shared_ptr<AbstractLtlFormula<T>> const & newRight) { + right = newRight; + } + + /*! + * Checks if the left child is set, i.e. it does not point to null. + * + * @return True iff the left child is set. + */ + bool isLeftSet() const { + return left.get() != nullptr; + } + + /*! + * Checks if the right child is set, i.e. it does not point to null. + * + * @return True iff the left right is set. + */ + bool isRightSet() const { + return right.get() != nullptr; + } + +private: + + // The left child node. + std::shared_ptr<AbstractLtlFormula<T>> left; + + // The right child node. + std::shared_ptr<AbstractLtlFormula<T>> right; +}; + +} /* namespace ltl */ +} /* namespace properties */ +} /* namespace storm */ +#endif /* OR_H_ */ diff --git a/src/properties/ltl/Until.h b/src/properties/ltl/Until.h new file mode 100644 index 000000000..2d415aeac --- /dev/null +++ b/src/properties/ltl/Until.h @@ -0,0 +1,200 @@ +/* + * Until.h + * + * Created on: 19.10.2012 + * Author: Thomas Heinemann + */ + +#ifndef STORM_FORMULA_LTL_UNTIL_H_ +#define STORM_FORMULA_LTL_UNTIL_H_ + +#include "AbstractLtlFormula.h" + +namespace storm { +namespace properties { +namespace ltl { + +// Forward declaration for the interface class. +template <class T> class Until; + +/*! + * Interface class for model checkers that support Until. + * + * All model checkers that support the formula class Until must inherit + * this pure virtual class. + */ +template <class T> +class IUntilModelChecker { + public: + + /*! + * Empty virtual destructor. + */ + virtual ~IUntilModelChecker() { + // Intentionally left empty + } + + /*! + * Evaluates an Until formula within a model checker. + * + * @param obj Formula object with subformulas. + * @return The modelchecking result of the formula for every state. + */ + virtual std::vector<T> checkUntil(const Until<T>& obj) const = 0; +}; + +/*! + * Class for an Ltl formula tree with an Until node as root. + * + * Has two Ltl formulas as sub formulas/trees. + * + * @par Semantics + * The formula holds iff eventually, formula \e right (the right subtree) holds, and before, + * \e left holds always. + * + * The object has shared ownership of its subtrees. If this object is deleted and no other object has a shared + * ownership of the subtrees they will be deleted as well. + * + * @see AbstractLtlFormula + */ +template <class T> +class Until : public AbstractLtlFormula<T> { + +public: + + /*! + * Creates an Until node without subnodes. + * The resulting object will not represent a complete formula! + */ + Until() : left(nullptr), right(nullptr) { + // Intentionally left empty. + } + + /*! + * Creates an Until node using the given parameters. + * + * @param left The left formula subtree. + * @param right The right formula subtree. + */ + Until(std::shared_ptr<AbstractLtlFormula<T>> const & left, std::shared_ptr<AbstractLtlFormula<T>> const & right) : left(left), right(right) { + // Intentionally left empty. + } + + /*! + * Empty virtual destructor. + */ + virtual ~Until() { + // Intentionally left empty. + } + + /*! + * Clones the called object. + * + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. + * + * @returns A new Until object that is a deep copy of the called object. + */ + virtual std::shared_ptr<AbstractLtlFormula<T>> clone() const override { + std::shared_ptr<Until<T>> result(new Until<T>()); + if (this->isLeftSet()) { + result->setLeft(left->clone()); + } + if (this->isRightSet()) { + result->setRight(right->clone()); + } + return result; + } + + /*! + * Calls the model checker to check this formula. + * Needed to infer the correct type of formula class. + * + * @note This function should only be called in a generic check function of a model checker class. For other uses, + * the methods of the model checker should be used. + * + * @returns A vector indicating the probability that the formula holds for each state. + */ + virtual std::vector<T> check(storm::modelchecker::ltl::AbstractModelChecker<T> const & modelChecker) const { + return modelChecker.template as<IUntilModelChecker>()->checkUntil(*this); + } + + /*! + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. + */ + virtual std::string toString() const { + std::string result = "(" + left->toString(); + result += " U "; + result += right->toString() + ")"; + return result; + } + + /*! + * Gets the left child node. + * + * @returns The left child node. + */ + std::shared_ptr<AbstractLtlFormula<T>> const & getLeft() const { + return left; + } + + /*! + * Gets the right child node. + * + * @returns The right child node. + */ + std::shared_ptr<AbstractLtlFormula<T>> const & getRight() const { + return right; + } + + /*! + * Sets the left child node. + * + * @param newLeft The new left child. + */ + void setLeft(std::shared_ptr<AbstractLtlFormula<T>> const & newLeft) { + left = newLeft; + } + + /*! + * Sets the right child node. + * + * @param newRight The new right child. + */ + void setRight(std::shared_ptr<AbstractLtlFormula<T>> const & newRight) { + right = newRight; + } + + /*! + * Checks if the left child is set, i.e. it does not point to null. + * + * @return True iff the left child is set. + */ + bool isLeftSet() const { + return left.get() != nullptr; + } + + /*! + * Checks if the right child is set, i.e. it does not point to null. + * + * @return True iff the right child is set. + */ + bool isRightSet() const { + return right.get() != nullptr; + } + +private: + + // The left child node. + std::shared_ptr<AbstractLtlFormula<T>> left; + + // The right child node. + std::shared_ptr<AbstractLtlFormula<T>> right; +}; + +} //namespace ltl +} //namespace properties +} //namespace storm + +#endif /* STORM_FORMULA_LTL_UNTIL_H_ */ diff --git a/src/formula/Prctl/AbstractPathFormula.h b/src/properties/prctl/AbstractPathFormula.h similarity index 58% rename from src/formula/Prctl/AbstractPathFormula.h rename to src/properties/prctl/AbstractPathFormula.h index c3c2cfc1b..98ba51f19 100644 --- a/src/formula/Prctl/AbstractPathFormula.h +++ b/src/properties/prctl/AbstractPathFormula.h @@ -8,11 +8,7 @@ #ifndef STORM_FORMULA_PRCTL_ABSTRACTPATHFORMULA_H_ #define STORM_FORMULA_PRCTL_ABSTRACTPATHFORMULA_H_ -namespace storm { namespace property { namespace prctl { -template <class T> class AbstractPathFormula; -}}} - -#include "src/formula/abstract/AbstractFormula.h" +#include "src/properties/prctl/AbstractPrctlFormula.h" #include "src/modelchecker/prctl/ForwardDeclarations.h" #include <vector> @@ -20,26 +16,22 @@ template <class T> class AbstractPathFormula; #include <typeinfo> namespace storm { -namespace property { +namespace properties { namespace prctl { /*! - * @brief - * Abstract base class for Abstract path formulas. - * - * @attention This class is abstract. - * @note Formula classes do not have copy constructors. The parameters of the constructors are usually the subtrees, so - * the syntax conflicts with copy constructors for unary operators. To produce an identical object, use the method - * clone(). + * Abstract base class for Prctl path formulas. * - * @note This class is intentionally not derived from AbstractPrctlFormula, as path formulas are not complete PRCTL formulas. + * @note Differing from the formal definitions of PRCTL a path formula may be the root of a PRCTL formula. + * The result of a modelchecking process on such a formula is a vector representing the satisfaction probabilities for each state of the model. */ template <class T> -class AbstractPathFormula : public virtual storm::property::abstract::AbstractFormula<T> { +class AbstractPathFormula : public virtual storm::properties::prctl::AbstractPrctlFormula<T> { public: + /*! - * empty destructor + * The virtual destructor. */ virtual ~AbstractPathFormula() { // Intentionally left empty @@ -48,12 +40,13 @@ public: /*! * Clones the called object. * - * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones + * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones. * * @note This function is not implemented in this class. - * @returns a new AND-object that is identical the called object. + * + * @returns A deep copy of the called object. */ - virtual AbstractPathFormula<T>* clone() const = 0; + virtual std::shared_ptr<AbstractPathFormula<T>> clone() const = 0; /*! * Calls the model checker to check this formula. @@ -70,7 +63,7 @@ public: }; } //namespace prctl -} //namespace property +} //namespace properties } //namespace storm #endif /* STORM_FORMULA_PRCTL_ABSTRACTPATHFORMULA_H_ */ diff --git a/src/properties/prctl/AbstractPrctlFormula.h b/src/properties/prctl/AbstractPrctlFormula.h new file mode 100644 index 000000000..cefe91e4b --- /dev/null +++ b/src/properties/prctl/AbstractPrctlFormula.h @@ -0,0 +1,89 @@ +/* + * AbstractPrctlFormula.h + * + * Created on: 16.04.2013 + * Author: thomas + */ + +#ifndef STORM_FORMULA_PRCTL_ABSTRACTPRCTLFORMULA_H_ +#define STORM_FORMULA_PRCTL_ABSTRACTPRCTLFORMULA_H_ + +#include "src/properties/AbstractFormula.h" + +namespace storm { +namespace properties { +namespace prctl { + +// Forward declarations. + +template <class T> class ProbabilisticBoundOperator; +template <class T> class Eventually; +template <class T> class Until; + +} +} +} + +namespace storm { +namespace properties { +namespace prctl { + +/*! + * This is the abstract base class for all Prctl formulas. + * + * @note While formula classes do have copy constructors using a copy constructor + * will yield a formula objects whose formula subtree consists of the same objects + * as the original formula. The ownership of the formula tree will be shared between + * the original and the copy. + */ +template<class T> +class AbstractPrctlFormula : public virtual storm::properties::AbstractFormula<T> { +public: + + /*! + * The virtual destructor. + */ + virtual ~AbstractPrctlFormula() { + // Intentionally left empty + } + + /*! + * Checks whether the formula is a probabilistic bound reachability formula. + * Returns true iff the formula conforms to the following pattern. + * Pattern: P[<,<=,>,>=]p ([psi U, E] phi) whith psi, phi propositional logic formulas (consisiting only of And, Or, Not and AP). + * That is, a probabilistic bound operator as root with a single until or eventually formula directly below it, whose subformulas are propositional + * (denoting some set of atomic propositions). + * + * @return True iff this is a probabilistic bound reachability formula. + */ + bool isProbEventuallyAP() const { + + // Test if a probabilistic bound operator is at the root. + if(dynamic_cast<storm::properties::prctl::ProbabilisticBoundOperator<T> const *>(this) == nullptr) { + return false; + } + + auto probFormula = dynamic_cast<storm::properties::prctl::ProbabilisticBoundOperator<T> const *>(this); + + // Check if the direct subformula of the probabilistic bound operator is an eventually or until formula. + if(std::dynamic_pointer_cast<storm::properties::prctl::Eventually<T>>(probFormula->getChild()).get() != nullptr) { + + // Get the subformula and check if its subformulas are propositional. + auto eventuallyFormula = std::dynamic_pointer_cast<storm::properties::prctl::Eventually<T>>(probFormula->getChild()); + return eventuallyFormula->getChild()->isPropositional(); + } + else if(std::dynamic_pointer_cast<storm::properties::prctl::Until<T>>(probFormula->getChild()).get() != nullptr) { + + // Get the subformula and check if its subformulas are propositional. + auto untilFormula = std::dynamic_pointer_cast<storm::properties::prctl::Until<T>>(probFormula->getChild()); + return untilFormula->getLeft()->isPropositional() && untilFormula->getRight()->isPropositional(); + } + + return false; + } +}; + +} /* namespace prctl */ +} /* namespace properties */ +} /* namespace storm */ +#endif /* ABSTRACTPRCTLFORMULA_H_ */ diff --git a/src/properties/prctl/AbstractRewardPathFormula.h b/src/properties/prctl/AbstractRewardPathFormula.h new file mode 100644 index 000000000..e19523679 --- /dev/null +++ b/src/properties/prctl/AbstractRewardPathFormula.h @@ -0,0 +1,70 @@ +/* + * AbstractRewardPathFormula.h + * + * Created on: May 15, 2014 + * Author: Manuel S. Weiand + */ + +#ifndef STORM_FORMULA_PRCTL_ABSTRACTREWARDPATHFORMULA_H_ +#define STORM_FORMULA_PRCTL_ABSTRACTREWARDPATHFORMULA_H_ + +#include "src/properties/prctl/AbstractPrctlFormula.h" + +namespace storm { +namespace properties { +namespace prctl { + +/*! + * Abstract base class for Prctl reward path formulas. + * + * Reward path formulas may not be subformulas of a probabilitic bound operator, as they describe rewards along paths not probabilities. + * + * @note Differing from the formal definitions of PRCTL a reward path formula may be the root of a PRCTL formula. + * The result of a modelchecking process on such a formula is a vector representing the rewards for each state of the model. + * + * @see AbstractPrctlFormula + */ +template <class T> +class AbstractRewardPathFormula : public virtual storm::properties::prctl::AbstractPrctlFormula<T> { + +public: + + /*! + * Empty virtual destructor. + */ + virtual ~AbstractRewardPathFormula() { + // Intentionally left empty + } + + /*! + * Clones the called object. + * + * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones + * + * @note This function is not implemented in this class. + * + * @returns A deep copy of the called object. + */ + virtual std::shared_ptr<AbstractRewardPathFormula<T>> clone() const = 0; + + /*! + * Calls the model checker to check this formula. + * Needed to infer the correct type of formula class. + * + * @note This function should only be called in a generic check function of a model checker class. For other uses, + * the methods of the model checker should be used. + * + * @note This function is not implemented in this class. + * + * @returns A vector indicating the probability that the formula holds for each state. + */ + virtual std::vector<T> check(const storm::modelchecker::prctl::AbstractModelChecker<T>& modelChecker, bool qualitative) const = 0; +}; + +} //namespace prctl +} //namespace properties +} //namespace storm + + + +#endif /* STORM_FORMULA_PRCTL_ABSTRACTREWARDPATHFORMULA_H_ */ diff --git a/src/formula/Prctl/AbstractStateFormula.h b/src/properties/prctl/AbstractStateFormula.h similarity index 64% rename from src/formula/Prctl/AbstractStateFormula.h rename to src/properties/prctl/AbstractStateFormula.h index 0a313bfd1..2e088d88e 100644 --- a/src/formula/Prctl/AbstractStateFormula.h +++ b/src/properties/prctl/AbstractStateFormula.h @@ -8,33 +8,24 @@ #ifndef STORM_FORMULA_PRCTL_ABSTRACTSTATEFORMULA_H_ #define STORM_FORMULA_PRCTL_ABSTRACTSTATEFORMULA_H_ -namespace storm { namespace property { namespace prctl { -template <class T> class AbstractStateFormula; -}}} - -#include "AbstractPrctlFormula.h" +#include "src/properties/prctl/AbstractPrctlFormula.h" #include "src/storage/BitVector.h" #include "src/modelchecker/prctl/ForwardDeclarations.h" namespace storm { -namespace property { +namespace properties { namespace prctl { /*! - * @brief - * Abstract base class for Abstract state formulas. - * - * @attention This class is abstract. - * @note Formula classes do not have copy constructors. The parameters of the constructors are usually the subtrees, so - * the syntax conflicts with copy constructors for unary operators. To produce an identical object, use the method - * clone(). + * Abstract base class for Prctl state formulas. */ template <class T> -class AbstractStateFormula : public AbstractPrctlFormula<T> { +class AbstractStateFormula : public storm::properties::prctl::AbstractPrctlFormula<T> { public: + /*! - * empty destructor + * Empty virtual destructor. */ virtual ~AbstractStateFormula() { // Intentionally left empty @@ -46,9 +37,10 @@ public: * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones * * @note This function is not implemented in this class. - * @returns a new AND-object that is identical the called object. + * + * @returns A deep copy of the called object. */ - virtual AbstractStateFormula<T>* clone() const = 0; + virtual std::shared_ptr<AbstractStateFormula<T>> clone() const = 0; /*! * Calls the model checker to check this formula. @@ -65,7 +57,7 @@ public: }; } //namespace prctl -} //namespace property +} //namespace properties } //namespace storm diff --git a/src/properties/prctl/And.h b/src/properties/prctl/And.h new file mode 100644 index 000000000..adbff8c92 --- /dev/null +++ b/src/properties/prctl/And.h @@ -0,0 +1,217 @@ +/* + * And.h + * + * Created on: 19.10.2012 + * Author: Thomas Heinemann + */ + +#ifndef STORM_FORMULA_PRCTL_AND_H_ +#define STORM_FORMULA_PRCTL_AND_H_ + +#include "src/properties/prctl/AbstractStateFormula.h" +#include "src/modelchecker/prctl/ForwardDeclarations.h" +#include <string> + +namespace storm { +namespace properties { +namespace prctl { + +// Forward declaration for the interface class. +template <class T> class And; + +/*! + * Interface class for model checkers that support And. + * + * All model checkers that support the formula class And must inherit + * this pure virtual class. + */ +template <class T> +class IAndModelChecker { + public: + + /*! + * Empty virtual destructor. + */ + virtual ~IAndModelChecker() { + // Intentionally left empty + } + + /*! + * Evaluates an And formula within a model checker. + * + * @param obj Formula object with subformulas. + * @return The modelchecking result of the formula for every state. + */ + virtual storm::storage::BitVector checkAnd(const And<T>& obj) const = 0; +}; + +/*! + * Class for a Prctl formula tree with an And node as root. + * + * It has two state formulas as sub formulas/trees. + * + * As And is commutative, the order is \e theoretically not important, but will influence the order in which + * the model checker works. + * + * The object has shared ownership of its subtrees. If this object is deleted and no other object has a shared + * ownership of the subtrees they will be deleted as well. + * + * @see AbstractStateFormula + * @see AbstractPrctlFormula + */ +template <class T> +class And : public AbstractStateFormula<T> { + +public: + + /*! + * Creates an And node without subnodes. + * The resulting object will not represent a complete formula! + */ + And() : left(nullptr), right(nullptr) { + // Intentionally left empty. + } + + /*! + * Creates an And node with the parameters as subtrees. + * + * @param left The left sub formula. + * @param right The right sub formula. + */ + And(std::shared_ptr<AbstractStateFormula<T>> const & left, std::shared_ptr<AbstractStateFormula<T>> const & right) : left(left), right(right) { + // Intentionally left empty. + } + + /*! + * Empty virtual destructor. + */ + virtual ~And() { + // Intentionally left empty. + } + + /*! + * Clones the called object. + * + * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones. + * + * @returns A new And object that is a deep copy of the called object. + */ + virtual std::shared_ptr<AbstractStateFormula<T>> clone() const override { + std::shared_ptr<And<T>> result(new And()); + if (this->isLeftSet()) { + result->setLeft(left->clone()); + } + if (this->isRightSet()) { + result->setRight(right->clone()); + } + return result; + } + + /*! + * Calls the model checker to check this formula. + * Needed to infer the correct type of formula class. + * + * @note This function should only be called in a generic check function of a model checker class. For other uses, + * the methods of the model checker should be used. + * + * @returns A bit vector indicating all states that satisfy the formula represented by the called object. + */ + virtual storm::storage::BitVector check(const storm::modelchecker::prctl::AbstractModelChecker<T>& modelChecker) const override { + return modelChecker.template as<IAndModelChecker>()->checkAnd(*this); + } + + /*! + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. + */ + virtual std::string toString() const override { + std::string result = "("; + result += left->toString(); + result += " & "; + result += right->toString(); + result += ")"; + return result; + } + + /*! + * Returns whether the formula is a propositional logic formula. + * That is, this formula and all its subformulas consist only of And, Or, Not and AP. + * + * @return True iff this is a propositional logic formula. + */ + virtual bool isPropositional() const override { + return left->isPropositional() && right->isPropositional(); + } + + /*! + * Gets the left child node. + * + * @returns The left child node. + */ + std::shared_ptr<AbstractStateFormula<T>> const & getLeft() const { + return left; + } + + /*! + * Gets the right child node. + * + * @returns The right child node. + */ + std::shared_ptr<AbstractStateFormula<T>> const & getRight() const { + return right; + } + + /*! + * Sets the left child node. + * + * @param newLeft The new left child. + */ + void setLeft(std::shared_ptr<AbstractStateFormula<T>> const & newLeft) { + left = newLeft; + } + + /*! + * Sets the right child node. + * + * @param newRight The new right child. + */ + void setRight(std::shared_ptr<AbstractStateFormula<T>> const & newRight) { + right = newRight; + } + + /*! + * Checks if the left child is set, i.e. it does not point to null. + * + * @return True iff the left child is set. + */ + bool isLeftSet() const { + return left.get() != nullptr; + } + + /*! + * Checks if the right child is set, i.e. it does not point to null. + * + * @return True iff the right child is set. + */ + bool isRightSet() const { + return right.get() != nullptr; + } + +private: + + // The left child node. + std::shared_ptr<AbstractStateFormula<T>> left; + + // The right child node. + std::shared_ptr<AbstractStateFormula<T>> right; + +}; + +} //namespace prctl + +} //namespace properties + +} //namespace storm + +#endif /* STORM_FORMULA_PRCTL_AND_H_ */ diff --git a/src/properties/prctl/Ap.h b/src/properties/prctl/Ap.h new file mode 100644 index 000000000..fb9fe1361 --- /dev/null +++ b/src/properties/prctl/Ap.h @@ -0,0 +1,141 @@ +/* + * Ap.h + * + * Created on: 19.10.2012 + * Author: Thomas Heinemann + */ + +#ifndef STORM_FORMULA_PRCTL_AP_H_ +#define STORM_FORMULA_PRCTL_AP_H_ + +#include "src/properties/prctl/AbstractStateFormula.h" +#include "src/modelchecker/prctl/ForwardDeclarations.h" + +namespace storm { +namespace properties { +namespace prctl { + +// Forward declaration for the interface class. +template <class T> class Ap; + +/*! + * Interface class for model checkers that support Ap. + * + * All model checkers that support the formula class Ap must inherit + * this pure virtual class. + */ +template <class T> +class IApModelChecker { + public: + + /*! + * Empty virtual destructor. + */ + virtual ~IApModelChecker() { + // Intentionally left empty + } + + /*! + * Evaluates an Ap formula within a model checker. + * + * @param obj Formula object with subformulas. + * @return The modelchecking result of the formula for every state. + */ + virtual storm::storage::BitVector checkAp(const Ap<T>& obj) const = 0; +}; + +/*! + * Class for a Prctl formula tree with an atomic proposition as root. + * + * This class represents leaves in the formula tree. + * + * @see AbstractPrctlFormula + * @see AbstractStateFormula + */ +template <class T> +class Ap : public AbstractStateFormula<T> { + +public: + + /*! + * Creates a new atomic proposition leaf, with the given label. + * + * @param ap A string representing the atomic proposition. + */ + Ap(std::string ap) : ap(ap) { + // Intentionally left empty. + } + + /*! + * Empty virtual destructor. + */ + virtual ~Ap() { + // Intentionally left empty + } + + /*! + * Clones the called object. + * + * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones. + * + * @returns A new Ap object that is a deep copy of the called object. + */ + virtual std::shared_ptr<AbstractStateFormula<T>> clone() const override { + auto result = std::make_shared<Ap<T>>(this->getAp()); + return result; + } + + /*! + * Calls the model checker to check this formula. + * Needed to infer the correct type of formula class. + * + * @note This function should only be called in a generic check function of a model checker class. For other uses, + * the methods of the model checker should be used. + * + * @returns A bit vector indicating all states that satisfy the formula represented by the called object. + */ + virtual storm::storage::BitVector check(const storm::modelchecker::prctl::AbstractModelChecker<T>& modelChecker) const override { + return modelChecker.template as<IApModelChecker>()->checkAp(*this); + } + + /*! + * A string representing the atomic proposition. + * + * @returns A string representing the leaf. + */ + virtual std::string toString() const override { + return getAp(); + } + + /*! + * Returns whether the formula is a propositional logic formula. + * That is, this formula and all its subformulas consist only of And, Or, Not and AP. + * + * @return True iff this is a propositional logic formula. + */ + virtual bool isPropositional() const override { + return true; + } + + /*! + * Gets the name of the atomic proposition. + * + * @returns The name of the atomic proposition. + */ + std::string const & getAp() const { + return ap; + } + +private: + + // The atomic proposition referenced by this leaf. + std::string ap; +}; + +} //namespace abstract + +} //namespace properties + +} //namespace storm + +#endif /* STORM_FORMULA_PRCTL_AP_H_ */ diff --git a/src/properties/prctl/BoundedEventually.h b/src/properties/prctl/BoundedEventually.h new file mode 100644 index 000000000..980717cfa --- /dev/null +++ b/src/properties/prctl/BoundedEventually.h @@ -0,0 +1,197 @@ +/* + * BoundedUntil.h + * + * Created on: 27.11.2012 + * Author: Christian Dehnert + */ + +#ifndef STORM_FORMULA_PRCTL_BOUNDEDEVENTUALLY_H_ +#define STORM_FORMULA_PRCTL_BOUNDEDEVENTUALLY_H_ + +#include "src/properties/prctl/AbstractPathFormula.h" +#include "src/properties/prctl/AbstractStateFormula.h" +#include <cstdint> +#include <string> +#include "src/modelchecker/prctl/ForwardDeclarations.h" + +namespace storm { +namespace properties { +namespace prctl{ + +// Forward declaration for the interface class. +template <class T> class BoundedEventually; + +/*! + * Interface class for model checkers that support BoundedEventually. + * + * All model checkers that support the formula class BoundedEventually must inherit + * this pure virtual class. + */ +template <class T> +class IBoundedEventuallyModelChecker { + public: + + /*! + * Empty virtual destructor. + */ + virtual ~IBoundedEventuallyModelChecker() { + // Intentionally left empty + } + + /*! + * Evaluates a BoundedEventually formula within a model checker. + * + * @param obj Formula object with subformulas. + * @param qualitative A flag indicating whether the formula only needs to be evaluated qualitatively, i.e. if the + * results are only compared against the bounds 0 and 1. + * @return The modelchecking result of the formula for every state. + */ + virtual std::vector<T> checkBoundedEventually(const BoundedEventually<T>& obj, bool qualitative) const = 0; +}; + +/*! + * Class for a Prctl (path) formula tree with a BoundedEventually node as root. + * + * Has one state formula as subformula/tree. + * + * @par Semantics + * The formula holds iff in at most \e bound steps, formula \e child holds. + * + * The object has shared ownership of its subtree. If this object is deleted and no other object has a shared + * ownership of the subtree it will be deleted as well. + * + * @see AbstractPathFormula + * @see AbstractPrctlFormula + */ +template <class T> +class BoundedEventually : public AbstractPathFormula<T> { + +public: + + /*! + * Creates a BoundedEventually node without a subnode. + * The resulting object will not represent a complete formula! + */ + BoundedEventually() : child(nullptr), bound(0) { + // Intentionally left empty. + } + + /*! + * Creates a BoundedEventually node using the given parameters. + * + * @param child The child formula subtree. + * @param bound The maximal number of steps within which the subformula must hold. + */ + BoundedEventually(std::shared_ptr<AbstractStateFormula<T>> child, uint_fast64_t bound) : child(child), bound(bound) { + // Intentionally left empty. + } + + /*! + * Empty virtual destructor. + */ + virtual ~BoundedEventually() { + // Intentionally left empty. + } + + /*! + * Clones the called object. + * + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. + * + * @returns A new BoundedEventually object that is a deep copy of the called object. + */ + virtual std::shared_ptr<AbstractPathFormula<T>> clone() const override { + std::shared_ptr<BoundedEventually<T>> result(new BoundedEventually<T>()); + result->setBound(bound); + if (this->isChildSet()) { + result->setChild(child->clone()); + } + return result; + } + + + /*! + * Calls the model checker to check this formula. + * Needed to infer the correct type of formula class. + * + * @note This function should only be called in a generic check function of a model checker class. For other uses, + * the methods of the model checker should be used. + * + * @returns A vector indicating the probability that the formula holds for each state. + */ + virtual std::vector<T> check(const storm::modelchecker::prctl::AbstractModelChecker<T>& modelChecker, bool qualitative) const override { + return modelChecker.template as<IBoundedEventuallyModelChecker>()->checkBoundedEventually(*this, qualitative); + } + + /*! + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. + */ + virtual std::string toString() const override { + std::string result = "F<="; + result += std::to_string(bound); + result += " "; + result += child->toString(); + return result; + } + + /*! + * Gets the child node. + * + * @returns The child node. + */ + std::shared_ptr<AbstractStateFormula<T>> const & getChild() const { + return child; + } + + /*! + * Sets the subtree. + * + * @param child The new child. + */ + void setChild(std::shared_ptr<AbstractStateFormula<T>> const & child) { + this->child = child; + } + + /*! + * Checks if the child is set, i.e. it does not point to null. + * + * @return True iff the child is set. + */ + bool isChildSet() const { + return child.get() != nullptr; + } + + /*! + * Gets the maximally allowed number of steps for the bounded eventually operator. + * + * @returns The bound. + */ + uint_fast64_t getBound() const { + return bound; + } + + /*! + * Sets the maximally allowed number of steps for the bounded eventually operator. + * + * @param bound The new bound. + */ + void setBound(uint_fast64_t bound) { + this->bound = bound; + } + +private: + + // The child node. + std::shared_ptr<AbstractStateFormula<T>> child; + + // The maximal number of steps within which the subformula must hold. + uint_fast64_t bound; +}; + +} //namespace prctl +} //namespace properties +} //namespace storm + +#endif /* STORM_FORMULA_PRCTL_BOUNDEDUNTIL_H_ */ diff --git a/src/properties/prctl/BoundedNaryUntil.h b/src/properties/prctl/BoundedNaryUntil.h new file mode 100644 index 000000000..526c236ad --- /dev/null +++ b/src/properties/prctl/BoundedNaryUntil.h @@ -0,0 +1,232 @@ +/* + * BoundedNaryUntil.h + * + * Created on: 19.10.2012 + * Author: Thomas Heinemann + */ + +#ifndef STORM_FORMULA_PRCTL_BOUNDEDNARYUNTIL_H_ +#define STORM_FORMULA_PRCTL_BOUNDEDNARYUNTIL_H_ + +#include "src/properties/prctl/AbstractPathFormula.h" +#include "src/properties/prctl/AbstractStateFormula.h" +#include <cstdint> +#include <string> +#include <vector> +#include <tuple> +#include <sstream> +#include "src/modelchecker/prctl/ForwardDeclarations.h" + +namespace storm { +namespace properties { +namespace prctl { + +// Forward declaration for the interface class. +template <class T> class BoundedNaryUntil; + +/*! + * Interface class for model checkers that support BoundedNaryUntil. + * + * All model checkers that support the formula class BoundedNaryUntil must inherit + * this pure virtual class. + */ +template <class T> +class IBoundedNaryUntilModelChecker { + public: + + /*! + * Empty virtual destructor. + */ + virtual ~IBoundedNaryUntilModelChecker() { + // Intentionally left empty + } + + /*! + * Evaluates BoundedNaryUntil formula within a model checker. + * + * @param obj Formula object with subformulas. + * @param qualitative A flag indicating whether the formula only needs to be evaluated qualitatively, i.e. if the + * results are only compared against the bounds 0 and 1. + * @return Result of the formula for every state. + */ + virtual std::vector<T> checkBoundedNaryUntil(const BoundedNaryUntil<T>& obj, bool qualitative) const = 0; +}; + +/*! + * Class for a Prctl (path) formula tree with a BoundedNaryUntil node as root. + * + * Has at least two state formulas as sub formulas and an interval + * associated with all but the first sub formula. We will call the first one + * \e left and all other one \e right. + * + * @par Semantics + * The formula holds iff \e left holds until eventually any of the \e right + * formulas holds after a number of steps contained in the interval + * associated with this formula. + * + * The object has shared ownership of its subtrees. If this object is deleted and no other object has a shared + * ownership of the subtrees they will be deleted as well. + * + * @see AbstractPathFormula + * @see AbstractPrctlFormula + */ +template <class T> +class BoundedNaryUntil : public AbstractPathFormula<T> { + +public: + + /*! + * Creates a BoundedNaryUntil node without subnodes. + * The resulting object will not represent a complete formula! + */ + BoundedNaryUntil() : left(nullptr), right() { + // Intentionally left empty. + } + + /*! + * Creates a BoundedNaryUntil node with the parameters as subtrees. + * + * @param left The left formula subtree. + * @param right The right formula subtrees with their associated intervals. + */ + BoundedNaryUntil(std::shared_ptr<AbstractStateFormula<T>> const & left, std::vector<std::tuple<std::shared_ptr<AbstractStateFormula<T>>,T,T>> const & right) : left(left), right(right) { + // Intentionally left empty. + } + + /*! + * Empty virtual destructor. + */ + virtual ~BoundedNaryUntil() { + // Intentionally left empty. + } + + /*! + * Clones the called object. + * + * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones. + * + * @returns A new BoundedNaryUntil object that is a deep copy of the called object. + */ + virtual std::shared_ptr<AbstractPathFormula<T>> clone() const override { + std::shared_ptr<BoundedNaryUntil<T>> result(new BoundedNaryUntil<T>()); + if (this->isLeftSet()) { + result->setLeft(left->clone()); + } + if (this->isRightSet()) { + std::vector<std::tuple<std::shared_ptr<AbstractStateFormula<T>>,T,T>> newright; + for (auto it = right->begin(); it != right->end(); ++it) { + newright.push_back(std::tuple<std::shared_ptr<AbstractStateFormula<T>>,T,T>(std::get<0>(*it)->clone(), std::get<1>(*it), std::get<2>(*it))); + } + result->setRight(newright); + } + return result; + } + + + /*! + * Calls the model checker to check this formula. + * Needed to infer the correct type of formula class. + * + * @note This function should only be called in a generic check function of a model checker class. For other uses, + * the methods of the model checker should be used. + * + * @returns A vector indicating the probability that the formula holds for each state. + */ + virtual std::vector<T> check(const storm::modelchecker::prctl::AbstractModelChecker<T>& modelChecker, bool qualitative) const override { + return modelChecker.template as<IBoundedNaryUntilModelChecker>()->checkBoundedNaryUntil(*this, qualitative); + } + + /*! + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. + */ + virtual std::string toString() const override { + std::stringstream result; + result << "( " << left->toString(); + for (auto it = right->begin(); it != right->end(); ++it) { + result << " U(" << std::get<1>(*it) << "," << std::get<2>(*it) << ") " << std::get<0>(*it)->toString(); + } + result << ")"; + return result.str(); + } + + /*! + * Gets the left child node. + * + * @returns The left child node. + */ + std::shared_ptr<AbstractStateFormula<T>> const & getLeft() const { + return left; + } + + /*! + * Gets the right child nodes and their associated intervals. + * + * @returns A vector containing the right children as well as the associated intervals. + */ + std::vector<std::tuple<std::shared_ptr<AbstractStateFormula<T>>,T,T>> const & getRight() const { + return right; + } + + /*! + * Sets the left child node. + * + * @param newLeft The new left child. + */ + void setLeft(std::shared_ptr<AbstractStateFormula<T>> const & newLeft) { + left = newLeft; + } + + /*! + * Sets the right child nodes. + * + * @param newRight A vector containing the new right children as well as the associated intervals. + */ + void setRight(std::vector<std::tuple<std::shared_ptr<AbstractStateFormula<T>>,T,T>> const & newRight) { + right = newRight; + } + + /*! + * Adds a new rightmost child node. + * + * @param newRight The new child. + * @param upperBound The upper bound of the associated interval. + * @param lowerBound The lower bound of the associated interval. + */ + void addRight(std::shared_ptr<AbstractStateFormula<T>> const & newRight, T upperBound, T lowerBound) { + right.push_back(std::tuple<std::shared_ptr<AbstractStateFormula<T>>,T,T>(newRight, upperBound, lowerBound)); + } + + /*! + * Checks if the left child is set, i.e. it does not point to null. + * + * @return True iff the left child is set. + */ + bool isLeftSet() const { + return left != nullptr; + } + + /*! + * Checks if the right child is set, i.e. it contains at least one entry. + * + * @return True iff the right child is set. + */ + bool isRightSet() const { + return !(right.empty()); + } + +private: + + // The left formula subtree. + std::shared_ptr<AbstractStateFormula<T>> left; + + // The right formula subtrees with their associated intervals. + std::vector<std::tuple<std::shared_ptr<AbstractStateFormula<T>>,T,T>> right; +}; + +} //namespace prctl +} //namespace properties +} //namespace storm + +#endif /* STORM_FORMULA_PRCTL_BOUNDEDNARYUNTIL_H_ */ diff --git a/src/properties/prctl/BoundedUntil.h b/src/properties/prctl/BoundedUntil.h new file mode 100644 index 000000000..b52fffe55 --- /dev/null +++ b/src/properties/prctl/BoundedUntil.h @@ -0,0 +1,233 @@ +/* + * BoundedUntil.h + * + * Created on: 19.10.2012 + * Author: Thomas Heinemann + */ + +#ifndef STORM_FORMULA_PRCTL_BOUNDEDUNTIL_H_ +#define STORM_FORMULA_PRCTL_BOUNDEDUNTIL_H_ + +#include "src/properties/prctl/AbstractPathFormula.h" +#include "src/properties/prctl/AbstractStateFormula.h" +#include <cstdint> +#include <string> +#include "src/modelchecker/prctl/ForwardDeclarations.h" + +namespace storm { +namespace properties { +namespace prctl { + +// Forward declaration for the interface class. +template <class T> class BoundedUntil; + +/*! + * Interface class for model checkers that support BoundedUntil. + * + * All model checkers that support the formula class BoundedUntil must inherit + * this pure virtual class. + */ +template <class T> +class IBoundedUntilModelChecker { + public: + + /*! + * Empty virtual destructor. + */ + virtual ~IBoundedUntilModelChecker() { + // Intentionally left empty + } + + /*! + * Evaluates a BoundedUntil formula within a model checker. + * + * @param obj Formula object with subformulas. + * @param qualitative A flag indicating whether the formula only needs to be evaluated qualitatively, i.e. if the + * results are only compared against the bounds 0 and 1. + * @return The modelchecking result of the formula for every state. + */ + virtual std::vector<T> checkBoundedUntil(const BoundedUntil<T>& obj, bool qualitative) const = 0; +}; + +/*! + * Class for a Prctl (path) formula tree with a BoundedUntil node as root. + * + * Has two Prctl state formulas as sub formulas/trees. + * + * @par Semantics + * The formula holds iff in at most \e bound steps, formula \e right (the right subtree) holds, and before, + * \e left holds. + * + * The object has shared ownership of its subtrees. If this object is deleted and no other object has a shared + * ownership of the subtrees they will be deleted as well. + * + * @see AbstractPathFormula + * @see AbstractPrctlFormula + */ +template <class T> +class BoundedUntil : public AbstractPathFormula<T> { + +public: + + /*! + * Creates a BoundedUntil node without subnodes. + * The resulting object will not represent a complete formula! + */ + BoundedUntil() : left(nullptr), right(nullptr), bound(0) { + // Intentionally left empty. + } + + /*! + * Creates a BoundedUntil node using the given parameters. + * + * @param left The left formula subtree. + * @param right The right formula subtree. + * @param bound The maximal number of steps within which the right subformula must hold. + */ + BoundedUntil(std::shared_ptr<AbstractStateFormula<T>> const & left, std::shared_ptr<AbstractStateFormula<T>> const & right, uint_fast64_t bound) : left(left), right(right), bound(bound) { + // Intentionally left empty. + } + + /*! + * Empty virtual destructor. + */ + virtual ~BoundedUntil() { + // Intentionally left empty. + } + + /*! + * Clones the called object. + * + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. + * + * @returns A new BoundedUntil object that is a deep copy of the called object. + */ + virtual std::shared_ptr<AbstractPathFormula<T>> clone() const override { + std::shared_ptr<BoundedUntil<T>> result(new BoundedUntil<T>()); + result->setBound(bound); + if (this->isLeftSet()) { + result->setLeft(left->clone()); + } + if (this->isRightSet()) { + result->setRight(right->clone()); + } + return result; + } + + + /*! + * Calls the model checker to check this formula. + * Needed to infer the correct type of formula class. + * + * @note This function should only be called in a generic check function of a model checker class. For other uses, + * the methods of the model checker should be used. + * + * @returns A vector indicating the probability that the formula holds for each state. + */ + virtual std::vector<T> check(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelChecker, bool qualitative) const override { + return modelChecker.template as<IBoundedUntilModelChecker>()->checkBoundedUntil(*this, qualitative); + } + + /*! + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. + */ + virtual std::string toString() const override { + std::string result = left->toString(); + result += " U<="; + result += std::to_string(bound); + result += " "; + result += right->toString(); + return result; + } + + /*! + * Gets the left child node. + * + * @returns The left child node. + */ + std::shared_ptr<AbstractStateFormula<T>> const & getLeft() const { + return left; + } + + /*! + * Gets the right child node. + * + * @returns The right child node. + */ + std::shared_ptr<AbstractStateFormula<T>> const & getRight() const { + return right; + } + + /*! + * Sets the left child node. + * + * @param newLeft The new left child. + */ + void setLeft(std::shared_ptr<AbstractStateFormula<T>> const & newLeft) { + left = newLeft; + } + + /*! + * Sets the right child node. + * + * @param newRight The new right child. + */ + void setRight(std::shared_ptr<AbstractStateFormula<T>> const & newRight) { + right = newRight; + } + + /*! + * Checks if the left child is set, i.e. it does not point to null. + * + * @return True iff the left child is set. + */ + bool isLeftSet() const { + return left.get() != nullptr; + } + + /*! + * Checks if the right child is set, i.e. it does not point to null. + * + * @return True iff the right child is set. + */ + bool isRightSet() const { + return right.get() != nullptr; + } + + /*! + * Gets the maximally allowed number of steps for the bounded until operator. + * + * @returns The bound. + */ + uint_fast64_t getBound() const { + return bound; + } + + /*! + * Sets the maximally allowed number of steps for the bounded until operator. + * + * @param bound The new bound. + */ + void setBound(uint_fast64_t bound) { + this->bound = bound; + } + +private: + + // The left child node. + std::shared_ptr<AbstractStateFormula<T>> left; + + // The right child node. + std::shared_ptr<AbstractStateFormula<T>> right; + + // The maximal number of steps within which the subformulas must hold. + uint_fast64_t bound; +}; + +} //namespace prctl +} //namespace properties +} //namespace storm + +#endif /* STORM_FORMULA_PRCTL_BOUNDEDUNTIL_H_ */ diff --git a/src/properties/prctl/CumulativeReward.h b/src/properties/prctl/CumulativeReward.h new file mode 100644 index 000000000..9b27aefd6 --- /dev/null +++ b/src/properties/prctl/CumulativeReward.h @@ -0,0 +1,148 @@ +/* + * InstantaneousReward.h + * + * Created on: 26.12.2012 + * Author: Christian Dehnert + */ + +#ifndef STORM_FORMULA_PRCTL_CUMULATIVEREWARD_H_ +#define STORM_FORMULA_PRCTL_CUMULATIVEREWARD_H_ + +#include "AbstractRewardPathFormula.h" +#include <string> + +namespace storm { +namespace properties { +namespace prctl { + +// Forward declaration for the interface class. +template <class T> class CumulativeReward; + +/*! + * Interface class for model checkers that support CumulativeReward. + * + * All model checkers that support the formula class CumulativeReward must inherit + * this pure virtual class. + */ +template <class T> +class ICumulativeRewardModelChecker { + public: + + /*! + * Empty virtual destructor. + */ + virtual ~ICumulativeRewardModelChecker() { + // Intentionally left empty + } + + /*! + * Evaluates CumulativeReward formula within a model checker. + * + * @param obj Formula object with subformulas. + * @param qualitative A flag indicating whether the formula only needs to be evaluated qualitatively, i.e. if the + * results are only compared against the bounds 0 and 1. + * @return Result of the formula for every node. + */ + virtual std::vector<T> checkCumulativeReward(const CumulativeReward<T>& obj, bool qualitative) const = 0; +}; + +/*! + * Class for a Prctl (reward path) formula tree with a Cumulative Reward node as root. + * + * Given a path of finite length. + * The sum of all rewards received upon entering each state of the path is the cumulative reward of the path. + * The cumulative reward for a state s at time \e bound is the expected cumulative reward of a path of length \e bound starting in s. + * In the continuous case all paths that need at most time \e bound are considered. + * + * @see AbstractPathFormula + * @see AbstractPrctlFormula + */ +template <class T> +class CumulativeReward : public AbstractRewardPathFormula<T> { + +public: + + /*! + * Creates a CumulativeReward node with the given bound. + * + * If no bound is given it defaults to 0, referencing the state reward received upon entering the state s itself. + * + * @param bound The time instance of the reward formula. + */ + CumulativeReward(T bound = 0) : bound(bound){ + // Intentionally left empty. + } + + /*! + * Empty destructor. + */ + virtual ~CumulativeReward() { + // Intentionally left empty. + } + + /*! + * Clones the called object. + * + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. + * + * @returns A new CumulativeReward object that is a deep copy of the called object. + */ + virtual std::shared_ptr<AbstractRewardPathFormula<T>> clone() const override { + std::shared_ptr<CumulativeReward<T>> result(new CumulativeReward(this->getBound())); + return result; + } + + + /*! + * Calls the model checker to check this formula. + * Needed to infer the correct type of formula class. + * + * @note This function should only be called in a generic check function of a model checker class. For other uses, + * the methods of the model checker should be used. + * + * @returns A vector indicating the probability that the formula holds for each state. + */ + virtual std::vector<T> check(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelChecker, bool qualitative) const override { + return modelChecker.template as<ICumulativeRewardModelChecker>()->checkCumulativeReward(*this, qualitative); + } + + /*! + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. + */ + virtual std::string toString() const override { + std::string result = "C <= "; + result += std::to_string(bound); + return result; + } + + /*! + * Gets the time bound for the paths considered. + * + * @returns The time bound for the paths considered. + */ + T getBound() const { + return bound; + } + + /*! + * Sets the time bound for the paths considered. + * + * @param bound The new bound. + */ + void setBound(T bound) { + this->bound = bound; + } + +private: + + // The time bound for the paths considered. + T bound; +}; + +} //namespace prctl +} //namespace properties +} //namespace storm + +#endif /* STORM_FORMULA_PRCTL_INSTANTANEOUSREWARD_H_ */ diff --git a/src/properties/prctl/Eventually.h b/src/properties/prctl/Eventually.h new file mode 100644 index 000000000..01ed2150b --- /dev/null +++ b/src/properties/prctl/Eventually.h @@ -0,0 +1,169 @@ +/* + * Eventually.h + * + * Created on: 26.12.2012 + * Author: Christian Dehnert + */ + +#ifndef STORM_FORMULA_PRCTL_EVENTUALLY_H_ +#define STORM_FORMULA_PRCTL_EVENTUALLY_H_ + +#include "src/properties/prctl/AbstractPathFormula.h" +#include "src/properties/prctl/AbstractStateFormula.h" +#include "src/modelchecker/prctl/ForwardDeclarations.h" + +namespace storm { +namespace properties { +namespace prctl { + +// Forward declaration for the interface class. +template <class T> class Eventually; + +/*! + * Interface class for model checkers that support Eventually. + * + * All model checkers that support the formula class Eventually must inherit + * this pure virtual class. + */ +template <class T> +class IEventuallyModelChecker { + public: + + /*! + * Empty virtual destructor. + */ + virtual ~IEventuallyModelChecker() { + // Intentionally left empty. + } + + /*! + * Evaluates an Eventually formula within a model checker. + * + * @param obj Formula object with subformulas. + * @param qualitative A flag indicating whether the formula only needs to be evaluated qualitatively, i.e. if the + * results are only compared against the bounds 0 and 1. + * @return The modelchecking result of the formula for every state. + */ + virtual std::vector<T> checkEventually(const Eventually<T>& obj, bool qualitative) const = 0; +}; + +/*! + * Class for a Prctl (path) formula tree with an Eventually node as root. + * + * Has one state formula as sub formula/tree. + * + * @par Semantics + * The formula holds iff eventually formula \e child holds. + * + * The object has shared ownership of its subtree. If this object is deleted and no other object has a shared + * ownership of the subtree it will be deleted as well. + * + * @see AbstractPathFormula + * @see AbstractPrctlFormula + */ +template <class T> +class Eventually : public AbstractPathFormula<T> { + +public: + + /*! + * Creates an Eventually node without a subnode. + * The resulting object will not represent a complete formula! + */ + Eventually() : child(nullptr) { + // Intentionally left empty. + } + + /*! + * Creates an Eventually node using the given parameter. + * + * @param child The child formula subtree. + */ + Eventually(std::shared_ptr<AbstractStateFormula<T>> const & child) : child(child){ + // Intentionally left empty. + } + + /*! + * Empty virtual destructor. + */ + virtual ~Eventually() { + // Intentionally left empty. + } + + /*! + * Clones the called object. + * + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. + * + * @returns A new Eventually object that is a deep copy of the called object. + */ + virtual std::shared_ptr<AbstractPathFormula<T>> clone() const override { + std::shared_ptr<Eventually<T>> result(new Eventually<T>()); + if (this->isChildSet()) { + result->setChild(child->clone()); + } + return result; + } + + /*! + * Calls the model checker to check this formula. + * Needed to infer the correct type of formula class. + * + * @note This function should only be called in a generic check function of a model checker class. For other uses, + * the methods of the model checker should be used. + * + * @returns A vector indicating the probability that the formula holds for each state. + */ + virtual std::vector<T> check(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelChecker, bool qualitative) const override { + return modelChecker.template as<IEventuallyModelChecker>()->checkEventually(*this, qualitative); + } + + /*! + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. + */ + virtual std::string toString() const override { + std::string result = "F "; + result += child->toString(); + return result; + } + + /*! + * Gets the child node. + * + * @returns The child node. + */ + std::shared_ptr<AbstractStateFormula<T>> const & getChild() const { + return child; + } + + /*! + * Sets the subtree. + * + * @param child The new child. + */ + void setChild(std::shared_ptr<AbstractStateFormula<T>> const & child) { + this->child = child; + } + + /*! + * Checks if the child is set, i.e. it does not point to null. + * + * @return True iff the child is set. + */ + bool isChildSet() const { + return child.get() != nullptr; + } + +private: + + // The child node. + std::shared_ptr<AbstractStateFormula<T>> child; +}; + +} //namespace prctl +} //namespace properties +} //namespace storm + +#endif /* STORM_FORMULA_PRCTL_EVENTUALLY_H_ */ diff --git a/src/properties/prctl/Globally.h b/src/properties/prctl/Globally.h new file mode 100644 index 000000000..2a1f85dec --- /dev/null +++ b/src/properties/prctl/Globally.h @@ -0,0 +1,169 @@ +/* + * Globally.h + * + * Created on: 26.12.2012 + * Author: Christian Dehnert + */ + +#ifndef STORM_FORMULA_PRCTL_GLOBALLY_H_ +#define STORM_FORMULA_PRCTL_GLOBALLY_H_ + +#include "src/properties/prctl/AbstractPathFormula.h" +#include "src/properties/prctl/AbstractStateFormula.h" +#include "src/modelchecker/prctl/ForwardDeclarations.h" + +namespace storm { +namespace properties { +namespace prctl { + +// Forward declaration for the interface class. +template <class T> class Globally; + +/*! + * Interface class for model checkers that support Globally. + * + * All model checkers that support the formula class Globally must inherit + * this pure virtual class. + */ +template <class T> +class IGloballyModelChecker { + public: + + /*! + * Empty virtual destructor. + */ + virtual ~IGloballyModelChecker() { + // Intentionally left empty + } + + /*! + * Evaluates a Globally formula within a model checker. + * + * @param obj Formula object with subformulas. + * @param qualitative A flag indicating whether the formula only needs to be evaluated qualitatively, i.e. if the + * results are only compared against the bounds 0 and 1. + * @return The modelchecking result of the formula for every state. + */ + virtual std::vector<T> checkGlobally(const Globally<T>& obj, bool qualitative) const = 0; +}; + +/*! + * Class for an Prctl (path) formula tree with a Globally node as root. + * + * Has one state formula as sub formula/tree. + * + * @par Semantics + * The formula holds iff globally formula \e child holds. + * + * The object has shared ownership of its subtree. If this object is deleted and no other object has a shared + * ownership of the subtree it will be deleted as well. + * + * @see AbstractPathFormula + * @see AbstractPrctlFormula + */ +template <class T> +class Globally : public AbstractPathFormula<T> { + +public: + + /*! + * Creates a Globally node without a subnode. + * The resulting object will not represent a complete formula! + */ + Globally() : child(nullptr){ + // Intentionally left empty. + } + + /*! + * Creates a Globally node using the given parameter. + * + * @param child The child formula subtree. + */ + Globally(std::shared_ptr<AbstractStateFormula<T>> const & child) : child(child){ + // Intentionally left empty. + } + + /*! + * Empty virtual destructor. + */ + virtual ~Globally() { + // Intentionally left empty. + } + + /*! + * Clones the called object. + * + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. + * + * @returns A new Globally object that is a deep copy of the called object. + */ + virtual std::shared_ptr<AbstractPathFormula<T>> clone() const override { + std::shared_ptr<Globally<T>> result(new Globally<T>()); + if (this->isChildSet()) { + result->setChild(child->clone()); + } + return result; + } + + /*! + * Calls the model checker to check this formula. + * Needed to infer the correct type of formula class. + * + * @note This function should only be called in a generic check function of a model checker class. For other uses, + * the methods of the model checker should be used. + * + * @returns A vector indicating the probability that the formula holds for each state. + */ + virtual std::vector<T> check(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelChecker, bool qualitative) const override { + return modelChecker.template as<IGloballyModelChecker>()->checkGlobally(*this, qualitative); + } + + /*! + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. + */ + virtual std::string toString() const override { + std::string result = "G "; + result += child->toString(); + return result; + } + + /*! + * Gets the child node. + * + * @returns The child node. + */ + std::shared_ptr<AbstractStateFormula<T>> const & getChild() const { + return child; + } + + /*! + * Sets the subtree. + * + * @param child The new child. + */ + void setChild(std::shared_ptr<AbstractStateFormula<T>> const & child) { + this->child = child; + } + + /*! + * Checks if the child is set, i.e. it does not point to null. + * + * @return True iff the child is set. + */ + bool isChildSet() const { + return child.get() != nullptr; + } + +private: + + // The child node. + std::shared_ptr<AbstractStateFormula<T>> child; +}; + +} //namespace prctl +} //namespace properties +} //namespace storm + +#endif /* STORM_FORMULA_PRCTL_GLOBALLY_H_ */ diff --git a/src/properties/prctl/InstantaneousReward.h b/src/properties/prctl/InstantaneousReward.h new file mode 100644 index 000000000..d2f6d21a6 --- /dev/null +++ b/src/properties/prctl/InstantaneousReward.h @@ -0,0 +1,149 @@ +/* + * InstantaneousReward.h + * + * Created on: 26.12.2012 + * Author: Christian Dehnert + */ + +#ifndef STORM_FORMULA_PRCTL_INSTANTANEOUSREWARD_H_ +#define STORM_FORMULA_PRCTL_INSTANTANEOUSREWARD_H_ + +#include "AbstractRewardPathFormula.h" +#include <cstdint> +#include <string> + +namespace storm { +namespace properties { +namespace prctl { + +// Forward declaration for the interface class. +template <class T> class InstantaneousReward; + +/*! + * Interface class for model checkers that support InstantaneousReward. + * + * All model checkers that support the formula class InstantaneousReward must inherit + * this pure virtual class. + */ +template <class T> +class IInstantaneousRewardModelChecker { + public: + + /*! + * Empty virtual destructor. + */ + virtual ~IInstantaneousRewardModelChecker() { + // Intentionally left empty + } + + /*! + * Evaluates an InstantaneousReward formula within a model checker. + * + * @param obj Formula object with subformulas. + * @param qualitative A flag indicating whether the formula only needs to be evaluated qualitatively, i.e. if the + * results are only compared against the bounds 0 and 1. + * @return The modelchecking result of the formula for every state. + */ + virtual std::vector<T> checkInstantaneousReward(const InstantaneousReward<T>& obj, bool qualitative) const = 0; +}; + +/*! + * Class for an Instantaneous Reward formula. + * This class represents a possible leaf in a reward formula tree. + * + * Given a path of finite length. + * The reward received upon entering the last state of the path is the instantaneous reward of the path. + * The instantaneous reward for a state s at time \e bound is the expected instantaneous reward of a path of length \e bound starting in s. + * + * @see AbstractPathFormula + * @see AbstractPrctlFormula + */ +template <class T> +class InstantaneousReward : public AbstractRewardPathFormula<T> { + +public: + + /*! + * Creates an InstantaneousReward node with the given bound. + * + * If no bound is given it defaults to 0, referencing the state reward received upon entering the state s itself. + * + * @param bound The time instance of the reward formula. + */ + InstantaneousReward(uint_fast64_t bound = 0) : bound(bound) { + // Intentionally left empty. + } + + /*! + * Empty virtual destructor. + */ + virtual ~InstantaneousReward() { + // Intentionally left empty. + } + + /*! + * Clones the called object. + * + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. + * + * @returns A new InstantaneousReward object that is a deep copy of the called object. + */ + virtual std::shared_ptr<AbstractRewardPathFormula<T>> clone() const override { + std::shared_ptr<InstantaneousReward<T>> result(new InstantaneousReward(bound)); + return result; + } + + + /*! + * Calls the model checker to check this formula. + * Needed to infer the correct type of formula class. + * + * @note This function should only be called in a generic check function of a model checker class. For other uses, + * the methods of the model checker should be used. + * + * @returns A vector indicating the probability that the formula holds for each state. + */ + virtual std::vector<T> check(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelChecker, bool qualitative) const override { + return modelChecker.template as<IInstantaneousRewardModelChecker>()->checkInstantaneousReward(*this, qualitative); + } + + /*! + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. + */ + virtual std::string toString() const override { + std::string result = "I="; + result += std::to_string(bound); + return result; + } + + /*! + * Gets the time instance for the instantaneous reward operator. + * + * @returns The time instance for the instantaneous reward operator. + */ + uint_fast64_t getBound() const { + return bound; + } + + /*! + * Sets the the time instance for the instantaneous reward operator. + * + * @param bound The new time instance. + */ + void setBound(uint_fast64_t bound) { + this->bound = bound; + } + +private: + + // The time instance of the reward formula. + uint_fast64_t bound; +}; + +} //namespace prctl +} //namespace properties +} //namespace storm + +#endif /* STORM_FORMULA_PRCTL_INSTANTANEOUSREWARD_H_ */ diff --git a/src/properties/prctl/Next.h b/src/properties/prctl/Next.h new file mode 100644 index 000000000..642754ec1 --- /dev/null +++ b/src/properties/prctl/Next.h @@ -0,0 +1,168 @@ +/* + * Next.h + * + * Created on: 19.10.2012 + * Author: Thomas Heinemann + */ + +#ifndef STORM_FORMULA_PRCTL_NEXT_H_ +#define STORM_FORMULA_PRCTL_NEXT_H_ + +#include "src/properties/prctl/AbstractPathFormula.h" +#include "src/properties/prctl/AbstractStateFormula.h" + +namespace storm { +namespace properties { +namespace prctl { + +// Forward declaration for the interface class. +template <class T> class Next; + +/*! + * Interface class for model checkers that support Next. + * + * All model checkers that support the formula class Next must inherit + * this pure virtual class. + */ +template <class T> +class INextModelChecker { + public: + + /*! + * Empty virtual destructor. + */ + virtual ~INextModelChecker() { + // Intentionally left empty + } + + /*! + * Evaluates Next formula within a model checker. + * + * @param obj Formula object with subformulas. + * @param qualitative A flag indicating whether the formula only needs to be evaluated qualitatively, i.e. if the + * results are only compared against the bounds 0 and 1. + * @return Result of the formula for every node. + */ + virtual std::vector<T> checkNext(const Next<T>& obj, bool qualitative) const = 0; +}; + +/*! + * Class for a Prctl (path) formula tree with a Next node as root. + * + * Has two Prctl state formulas as sub formulas/trees. + * + * @par Semantics + * The formula holds iff in the next step, formula \e child holds + * + * The object has shared ownership of its subtree. If this object is deleted and no other object has a shared + * ownership of the subtree it will be deleted as well. + * + * @see AbstractPathFormula + * @see AbstractPrctlFormula + */ +template <class T> +class Next : public AbstractPathFormula<T> { + +public: + + /*! + * Creates a Next node without a subnode. + * The resulting object will not represent a complete formula! + */ + Next() : child(nullptr){ + // Intentionally left empty. + } + + /*! + * Creates a Next node using the given parameter. + * + * @param child The child formula subtree. + */ + Next(std::shared_ptr<AbstractStateFormula<T>> const & child) : child(child){ + // Intentionally left empty. + } + + /*! + * Empty virtual destructor. + */ + virtual ~Next() { + // Intentionally left empty. + } + + /*! + * Clones the called object. + * + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. + * + * @returns A new Next object that is a deep copy of the called object. + */ + virtual std::shared_ptr<AbstractPathFormula<T>> clone() const override { + std::shared_ptr<Next<T>> result(new Next<T>()); + if (this->isChildSet()) { + result->setChild(child->clone()); + } + return result; + } + + /*! + * Calls the model checker to check this formula. + * Needed to infer the correct type of formula class. + * + * @note This function should only be called in a generic check function of a model checker class. For other uses, + * the methods of the model checker should be used. + * + * @returns A vector indicating the probability that the formula holds for each state. + */ + virtual std::vector<T> check(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelChecker, bool qualitative) const override { + return modelChecker.template as<INextModelChecker>()->checkNext(*this, qualitative); + } + + /*! + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. + */ + virtual std::string toString() const override { + std::string result = "X "; + result += child->toString(); + return result; + } + + /*! + * Gets the child node. + * + * @returns The child node. + */ + std::shared_ptr<AbstractStateFormula<T>> const & getChild() const { + return child; + } + + /*! + * Sets the subtree. + * + * @param child The new child. + */ + void setChild(std::shared_ptr<AbstractStateFormula<T>> const & child) { + this->child = child; + } + + /*! + * Checks if the child is set, i.e. it does not point to null. + * + * @return True iff the child is set. + */ + bool isChildSet() const { + return child.get() != nullptr; + } + +private: + + // The child node. + std::shared_ptr<AbstractStateFormula<T>> child; +}; + +} //namespace prctl +} //namespace properties +} //namespace storm + +#endif /* STORM_FORMULA_PRCTL_NEXT_H_ */ diff --git a/src/properties/prctl/Not.h b/src/properties/prctl/Not.h new file mode 100644 index 000000000..db3e2ce7d --- /dev/null +++ b/src/properties/prctl/Not.h @@ -0,0 +1,173 @@ +/* + * Not.h + * + * Created on: 19.10.2012 + * Author: Thomas Heinemann + */ + +#ifndef STORM_FORMULA_PRCTL_NOT_H_ +#define STORM_FORMULA_PRCTL_NOT_H_ + +#include "AbstractStateFormula.h" +#include "src/modelchecker/prctl/ForwardDeclarations.h" + +namespace storm { +namespace properties { +namespace prctl { + +// Forward declaration for the interface class. +template <class T> class Not; + +/*! + * Interface class for model checkers that support Not. + * + * All model checkers that support the formula class Not must inherit + * this pure virtual class. + */ +template <class T> +class INotModelChecker { + public: + + /*! + * Empty virtual destructor. + */ + virtual ~INotModelChecker() { + // Intentionally left empty + } + + /*! + * Evaluates Not formulas within a model checker. + * + * @param obj Formula object with subformulas. + * @return Result of the formula for every node. + */ + virtual storm::storage::BitVector checkNot(const Not<T>& obj) const = 0; +}; + +/*! + * Class for an Prctl formula tree with Not node as root. + * + * Has one state formula as sub formula/tree. + * + * The object has shared ownership of its subtree. If this object is deleted and no other object has a shared + * ownership of the subtree it will be deleted as well. + * + * @see AbstractStateFormula + * @see AbstractPrctlFormula + */ +template <class T> +class Not : public AbstractStateFormula<T> { + +public: + + /*! + * Creates a Not node without a subnode. + * The resulting object will not represent a complete formula! + */ + Not() : child(nullptr) { + // Intentionally left empty. + } + + /*! + * Creates a Not node using the given parameter. + * + * @param child The child formula subtree. + */ + Not(std::shared_ptr<AbstractStateFormula<T>> child) : child(child) { + // Intentionally left empty. + } + + /*! + * Empty virtual destructor. + */ + virtual ~Not() { + // Intentionally left empty. + } + + /*! + * Clones the called object. + * + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. + * + * @returns A new Not object that is a deep copy of the called object. + */ + virtual std::shared_ptr<AbstractStateFormula<T>> clone() const override { + std::shared_ptr<Not<T>> result(new Not<T>()); + if (this->isChildSet()) { + result->setChild(child->clone()); + } + return result; + } + + /*! + * Calls the model checker to check this formula. + * Needed to infer the correct type of formula class. + * + * @note This function should only be called in a generic check function of a model checker class. For other uses, + * the methods of the model checker should be used. + * + * @returns A bit vector indicating all states that satisfy the formula represented by the called object. + */ + virtual storm::storage::BitVector check(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelChecker) const override { + return modelChecker.template as<INotModelChecker>()->checkNot(*this); + } + + /*! + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. + */ + virtual std::string toString() const override { + std::string result = "!"; + result += child->toString(); + return result; + } + + /*! + * Returns whether the formula is a propositional logic formula. + * That is, this formula and all its subformulas consist only of And, Or, Not and AP. + * + * @return True iff this is a propositional logic formula. + */ + virtual bool isPropositional() const override { + return child->isPropositional(); + } + + /*! + * Gets the child node. + * + * @returns The child node. + */ + std::shared_ptr<AbstractStateFormula<T>> const & getChild() const { + return child; + } + + /*! + * Sets the subtree. + * + * @param child The new child. + */ + void setChild(std::shared_ptr<AbstractStateFormula<T>> const & child) { + this->child = child; + } + + /*! + * Checks if the child is set, i.e. it does not point to null. + * + * @return True iff the child is set. + */ + bool isChildSet() const { + return child.get() != nullptr; + } + +private: + + // The child node. + std::shared_ptr<AbstractStateFormula<T>> child; +}; + +} //namespace prctl +} //namespace properties +} //namespace storm + +#endif /* STORM_FORMULA_PRCTL_NOT_H_ */ diff --git a/src/properties/prctl/Or.h b/src/properties/prctl/Or.h new file mode 100644 index 000000000..3a897ec6f --- /dev/null +++ b/src/properties/prctl/Or.h @@ -0,0 +1,213 @@ +/* + * Or.h + * + * Created on: 19.10.2012 + * Author: Thomas Heinemann + */ + +#ifndef STORM_FORMULA_PRCTL_OR_H_ +#define STORM_FORMULA_PRCTL_OR_H_ + +#include "src/properties/prctl/AbstractStateFormula.h" + +namespace storm { +namespace properties { +namespace prctl { + +// Forward declaration for the interface class. +template <class T> class Or; + +/*! + * Interface class for model checkers that support Or. + * + * All model checkers that support the formula class Or must inherit + * this pure virtual class. + */ +template <class T> +class IOrModelChecker { + public: + + /*! + * Empty virtual destructor. + */ + virtual ~IOrModelChecker() { + // Intentionally left empty + } + + /*! + * Evaluates Or formula within a model checker. + * + * @param obj Formula object with subformulas. + * @return Result of the formula for every node. + */ + virtual storm::storage::BitVector checkOr(const Or<T>& obj) const = 0; +}; + +/*! + * Class for a Prctl formula tree with an Or node as root. + * + * Has two state formulas as sub formulas/trees. + * + * As Or is commutative, the order is \e theoretically not important, but will influence the order in which + * the model checker works. + * + * The object has shared ownership of its subtrees. If this object is deleted and no other object has a shared + * ownership of the subtrees they will be deleted as well. + * + * @see AbstractStateFormula + * @see AbstractPrctlFormula + */ +template <class T> +class Or : public AbstractStateFormula<T> { + +public: + + /*! + * Creates an Or node without subnodes. + * The resulting object will not represent a complete formula! + */ + Or() : left(nullptr), right(nullptr) { + // Intentionally left empty. + } + + /*! + * Creates an Or node with the parameters as subtrees. + * + * @param left The left sub formula. + * @param right The right sub formula. + */ + Or(std::shared_ptr<AbstractStateFormula<T>> left, std::shared_ptr<AbstractStateFormula<T>> right) : left(left), right(right) { + // Intentionally left empty. + } + + /*! + * Empty virtual destructor. + */ + virtual ~Or() { + // Intentionally left empty. + } + + /*! + * Clones the called object. + * + * Performs a "deep copy", i.e. the subtrees of the new object are clones of the original ones. + * + * @returns A new Or object that is a deep copy of the called object. + */ + virtual std::shared_ptr<AbstractStateFormula<T>> clone() const override { + std::shared_ptr<Or<T>> result(new Or()); + if (this->isLeftSet()) { + result->setLeft(left->clone()); + } + if (this->isRightSet()) { + result->setRight(right->clone()); + } + return result; + } + + /*! + * Calls the model checker to check this formula. + * Needed to infer the correct type of formula class. + * + * @note This function should only be called in a generic check function of a model checker class. For other uses, + * the methods of the model checker should be used. + * + * @returns A bit vector indicating all states that satisfy the formula represented by the called object. + */ + virtual storm::storage::BitVector check(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelChecker) const override { + return modelChecker.template as<IOrModelChecker>()->checkOr(*this); + } + + /*! + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. + */ + virtual std::string toString() const override { + std::string result = "("; + result += left->toString(); + result += " | "; + result += right->toString(); + result += ")"; + return result; + } + + /*! + * Returns whether the formula is a propositional logic formula. + * That is, this formula and all its subformulas consist only of And, Or, Not and AP. + * + * @return True iff this is a propositional logic formula. + */ + virtual bool isPropositional() const override { + return left->isPropositional() && right->isPropositional(); + } + + /*! + * Gets the left child node. + * + * @returns The left child node. + */ + std::shared_ptr<AbstractStateFormula<T>> const & getLeft() const { + return left; + } + + /*! + * Gets the right child node. + * + * @returns The right child node. + */ + std::shared_ptr<AbstractStateFormula<T>> const & getRight() const { + return right; + } + + /*! + * Sets the left child node. + * + * @param newLeft The new left child. + */ + void setLeft(std::shared_ptr<AbstractStateFormula<T>> const & newLeft) { + left = newLeft; + } + + /*! + * Sets the right child node. + * + * @param newRight The new right child. + */ + void setRight(std::shared_ptr<AbstractStateFormula<T>> const & newRight) { + right = newRight; + } + + /*! + * Checks if the left child is set, i.e. it does not point to null. + * + * @return True iff the left child is set. + */ + bool isLeftSet() const { + return left.get() != nullptr; + } + + /*! + * Checks if the right child is set, i.e. it does not point to null. + * + * @return True iff the left right is set. + */ + bool isRightSet() const { + return right.get() != nullptr; + } + +private: + + // The left child node. + std::shared_ptr<AbstractStateFormula<T>> left; + + // The right child node. + std::shared_ptr<AbstractStateFormula<T>> right; + +}; + +} //namespace prctl +} //namespace properties +} //namespace storm + +#endif /* STORM_FORMULA_PRCTL_OR_H_ */ diff --git a/src/properties/prctl/PrctlFilter.h b/src/properties/prctl/PrctlFilter.h new file mode 100644 index 000000000..1e742a515 --- /dev/null +++ b/src/properties/prctl/PrctlFilter.h @@ -0,0 +1,436 @@ +/* + * PrctlFilter.h + * + * Created on: Apr 26, 2014 + * Author: Manuel Sascha Weiand + */ + +#ifndef STORM_FORMULA_PRCTL_PRCTLFILTER_H_ +#define STORM_FORMULA_PRCTL_PRCTLFILTER_H_ + +#include "src/properties/AbstractFilter.h" +#include "src/properties/prctl/AbstractPrctlFormula.h" +#include "src/properties/prctl/AbstractPathFormula.h" +#include "src/properties/prctl/AbstractStateFormula.h" +#include "src/modelchecker/prctl/AbstractModelChecker.h" +#include "src/properties/actions/AbstractAction.h" + +#include <algorithm> +#include <memory> + +namespace storm { +namespace properties { +namespace prctl { + +/*! + * This is the Prctl specific filter. + * + * It maintains a Prctl formula which can be checked against a given model by either calling evaluate() or check(). + * Additionally it maintains a list of filter actions that are used to further manipulate the modelchecking results and prepare them for output. + */ +template <class T> +class PrctlFilter : public storm::properties::AbstractFilter<T> { + + // Convenience typedef to make the code more readable. + typedef typename storm::properties::action::AbstractAction<T>::Result Result; + +public: + + /*! + * Creates an empty PrctlFilter, maintaining no Prctl formula. + * + * Calling check or evaluate will return an empty result. + */ + PrctlFilter() : AbstractFilter<T>(UNDEFINED), child(nullptr) { + // Intentionally left empty. + } + + /*! + * Creates a PrctlFilter maintaining a Prctl formula but containing no actions. + * + * The modelchecking result will be returned or printed as is. + * + * @param child The Prctl formula to be maintained. + * @param opt An enum value indicating which kind of scheduler shall be used for path formulas on nondeterministic models. + */ + PrctlFilter(std::shared_ptr<AbstractPrctlFormula<T>> const & child, OptimizingOperator opt = UNDEFINED) : AbstractFilter<T>(opt), child(child) { + // Intentionally left empty. + } + + /*! + * Creates a PrctlFilter maintaining a Prctl formula and containing a single action. + * + * The given action will be applied to the modelchecking result during evaluation. + * Further actions can be added later. + * + * @param child The Prctl formula to be maintained. + * @param action The single action to be executed during evaluation. + * @param opt An enum value indicating which kind of scheduler shall be used for path formulas on nondeterministic models. + */ + PrctlFilter(std::shared_ptr<AbstractPrctlFormula<T>> const & child, std::shared_ptr<action::AbstractAction<T>> const & action, OptimizingOperator opt = UNDEFINED) : AbstractFilter<T>(action, opt), child(child) { + // Intentionally left empty. + } + + /*! + * Creates a PrctlFilter using the given parameters. + * + * The given actions will be applied to the modelchecking result in ascending index order during evaluation. + * Further actions can be added later. + * + * @param child The Prctl formula to be maintained. + * @param actions A vector conatining the actions that are to be executed during evaluation. + * @param opt An enum value indicating which kind of scheduler shall be used for path formulas on nondeterministic models. + */ + PrctlFilter(std::shared_ptr<AbstractPrctlFormula<T>> const & child, std::vector<std::shared_ptr<action::AbstractAction<T>>> const & actions, OptimizingOperator opt = UNDEFINED) : AbstractFilter<T>(actions, opt), child(child) { + // Intentionally left empty. + } + + /*! + * Empty virtual destructor. + */ + virtual ~PrctlFilter() { + // Intentionally left empty. + } + + /*! + * Calls the modelchecker, retrieves the modelchecking result, applies the filter action one by one and prints out the result. + * + * @param modelchecker The modelchecker to be called. + */ + void check(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelchecker) const { + + // Write out the formula to be checked. + std::cout << std::endl; + LOG4CPLUS_INFO(logger, "Model checking formula\t" << this->toString()); + std::cout << "Model checking formula:\t" << this->toString() << std::endl; + + writeOut(evaluate(modelchecker), modelchecker); + } + + /*! + * Calls the modelchecker, retrieves the modelchecking result, applies the filter action one by one and returns the result. + * + * @param modelchecker The modelchecker to be called. + * @returns The result of the sequential application of the filter actions to the modelchecking result. + */ + Result evaluate(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelchecker) const { + + Result result; + + try { + if(dynamic_cast<AbstractStateFormula<T> *>(child.get()) != nullptr) { + result = evaluate(modelchecker, std::dynamic_pointer_cast<AbstractStateFormula<T>>(child)); + } else if (dynamic_cast<AbstractPathFormula<T> *>(child.get()) != nullptr) { + result = evaluate(modelchecker, std::dynamic_pointer_cast<AbstractPathFormula<T>>(child)); + } else if (dynamic_cast<AbstractRewardPathFormula<T> *>(child.get()) != nullptr) { + result = evaluate(modelchecker, std::dynamic_pointer_cast<AbstractRewardPathFormula<T>>(child)); + } + } catch (std::exception& e) { + std::cout << "Error during computation: " << e.what() << "Skipping property." << std::endl; + LOG4CPLUS_ERROR(logger, "Error during computation: " << e.what() << "Skipping property."); + } + + return result; + } + + /*! + * Returns a textual representation of the filter. + * + * That includes the actions as well as the maintained formula. + * + * @returns A string representing the filter. + */ + virtual std::string toString() const override { + std::string desc = ""; + + if(!std::dynamic_pointer_cast<AbstractStateFormula<T>>(child)) { + + // The formula is not a state formula so we either have a probability query or a reward query. + if(this->actions.empty()){ + + // There is exactly one action in the list, the minmax action. Again, we do legacy support- + + if(std::dynamic_pointer_cast<AbstractPathFormula<T>>(child)) { + // It is a probability query. + desc += "P "; + + } else { + // It is a reward query. + desc += "R "; + } + + switch(this->opt) { + case MINIMIZE: + desc += "min "; + break; + case MAXIMIZE: + desc += "max "; + break; + default: + break; + } + + desc += "= ? "; + + } else { + desc = "filter["; + + switch(this->opt) { + case MINIMIZE: + desc += "min; "; + break; + case MAXIMIZE: + desc += "max; "; + break; + default: + break; + } + + for(auto action : this->actions) { + desc += action->toString(); + desc += "; "; + } + + // Remove the last "; ". + desc.pop_back(); + desc.pop_back(); + + desc += "]"; + } + + } else { + + if(this->actions.empty()) { + + // There are no filter actions but only the raw state formula. So just print that. + return child->toString(); + } + + desc = "filter["; + + for(auto action : this->actions) { + desc += action->toString(); + desc += "; "; + } + + // Remove the last "; ". + desc.pop_back(); + desc.pop_back(); + + desc += "]"; + } + + desc += "("; + desc += child->toString(); + desc += ")"; + + return desc; + } + + /*! + * Gets the child node. + * + * @returns The child node. + */ + std::shared_ptr<AbstractPrctlFormula<T>> const & getChild() const { + return child; + } + + /*! + * Sets the subtree. + * + * @param child The new child. + */ + void setChild(std::shared_ptr<AbstractPrctlFormula<T>> const & child) { + this->child = child; + } + + /*! + * Checks if the child is set, i.e. it does not point to null. + * + * @return True iff the child is set. + */ + bool isChildSet() const { + return child.get() != nullptr; + } + +private: + + /*! + * Calls the modelchecker for a state formula, retrieves the modelchecking result, applies the filter action one by one and returns the result. + * + * This an internal version of the evaluate method overloading it for the different Prctl formula types. + * + * @param modelchecker The modelchecker to be called. + * @param formula The state formula for which the modelchecker will be called. + * @returns The result of the sequential application of the filter actions to the modelchecking result. + */ + Result evaluate(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelchecker, std::shared_ptr<AbstractStateFormula<T>> const & formula) const { + // First, get the model checking result. + Result result; + + if(this->opt != UNDEFINED) { + // If it is specified that min/max probabilities/rewards should be computed, call the appropriate method of the model checker. + result.stateResult = modelchecker.checkOptimizingOperator(*formula, this->opt == storm::properties::MINIMIZE ? true : false); + } else { + result.stateResult = formula->check(modelchecker); + } + + // Now apply all filter actions and return the result. + return evaluateActions(result, modelchecker); + } + + /*! + * Calls the modelchecker for a path formula, retrieves the modelchecking result, applies the filter action one by one and returns the result. + * + * This an internal version of the evaluate method overloading it for the different Prctl formula types. + * + * @param modelchecker The modelchecker to be called. + * @param formula The path formula for which the modelchecker will be called. + * @returns The result of the sequential application of the filter actions to the modelchecking result. + */ + Result evaluate(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelchecker, std::shared_ptr<AbstractPathFormula<T>> const & formula) const { + // First, get the model checking result. + Result result; + + if(this->opt != UNDEFINED) { + // If it is specified that min/max probabilities/rewards should be computed, call the appropriate method of the model checker. + result.pathResult = modelchecker.checkOptimizingOperator(*formula, this->opt == storm::properties::MINIMIZE ? true : false); + } else { + result.pathResult = formula->check(modelchecker, false); + } + + // Now apply all filter actions and return the result. + return evaluateActions(result, modelchecker); + } + + /*! + * Calls the modelchecker for a reward formula, retrieves the modelchecking result, applies the filter action one by one and returns the result. + * + * This an internal version of the evaluate method overloading it for the different Prctl formula types. + * + * @param modelchecker The modelchecker to be called. + * @param formula The reward formula for which the modelchecker will be called. + * @returns The result of the sequential application of the filter actions to the modelchecking result. + */ + Result evaluate(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelchecker, std::shared_ptr<AbstractRewardPathFormula<T>> const & formula) const { + // First, get the model checking result. + Result result; + + if(this->opt != UNDEFINED) { + // If it is specified that min/max probabilities/rewards should be computed, call the appropriate method of the model checker. + result.pathResult = modelchecker.checkOptimizingOperator(*formula, this->opt == storm::properties::MINIMIZE ? true : false); + } else { + result.pathResult = formula->check(modelchecker, false); + } + + // Now apply all filter actions and return the result. + return evaluateActions(result, modelchecker); + } + + /*! + * Evaluates the filter actions by calling them one by one using the output of each action as the input for the next one. + * + * @param input The modelchecking result in form of a Result struct. + * @param modelchecker The modelchecker that was called to generate the modelchecking result. Needed by some actions. + * @returns The result of the sequential application of the filter actions to the modelchecking result. + */ + Result evaluateActions(Result const & input, storm::modelchecker::prctl::AbstractModelChecker<T> const & modelchecker) const { + + // Init the state selection and state map vectors. + Result result = input; + uint_fast64_t size = result.stateResult.size() == 0 ? result.pathResult.size() : result.stateResult.size(); + result.selection = storm::storage::BitVector(size, true); + result.stateMap = std::vector<uint_fast64_t>(size); + for(uint_fast64_t i = 0; i < size; i++) { + result.stateMap[i] = i; + } + + // Now apply all filter actions and return the result. + for(auto action : this->actions) { + result = action->evaluate(result, modelchecker); + } + return result; + } + + /*! + * Writes out the given result. + * + * @param result The result of the sequential application of the filter actions to a modelchecking result. + * @param modelchecker The modelchecker that was called to generate the modelchecking result. Needed for legacy support. + */ + void writeOut(Result const & result, storm::modelchecker::prctl::AbstractModelChecker<T> const & modelchecker) const { + + // Test if there is anything to write out. + // The selection size should only be 0 if an error occurred during the evaluation (since a model with 0 states is invalid). + if(result.selection.size() == 0) { + std::cout << std::endl << "-------------------------------------------" << std::endl; + return; + } + + // Test for the kind of result. Values or states. + if(!result.pathResult.empty()) { + + // Write out the selected value results in the order given by the stateMap. + if(this->actions.empty()) { + + // There is no filter action given. So provide legacy support: + // Return the results for all states labeled with "init". + LOG4CPLUS_INFO(logger, "Result for initial states:"); + std::cout << "Result for initial states:" << std::endl; + for (auto initialState : modelchecker.template getModel<storm::models::AbstractModel<T>>().getInitialStates()) { + LOG4CPLUS_INFO(logger, "\t" << initialState << ": " << result.pathResult[initialState]); + std::cout << "\t" << initialState << ": " << result.pathResult[initialState] << std::endl; + } + } else { + LOG4CPLUS_INFO(logger, "Result for " << result.selection.getNumberOfSetBits() << " selected states:"); + std::cout << "Result for " << result.selection.getNumberOfSetBits() << " selected states:" << std::endl; + + for(uint_fast64_t i = 0; i < result.stateMap.size(); i++) { + if(result.selection.get(result.stateMap[i])) { + LOG4CPLUS_INFO(logger, "\t" << result.stateMap[i] << ": " << result.pathResult[result.stateMap[i]]); + std::cout << "\t" << result.stateMap[i] << ": " << result.pathResult[result.stateMap[i]] << std::endl; + } + } + } + + } else { + + // Write out the selected state results in the order given by the stateMap. + if(this->actions.empty()) { + + // There is no filter action given. So provide legacy support: + // Return the results for all states labeled with "init". + LOG4CPLUS_INFO(logger, "Result for initial states:"); + std::cout << "Result for initial states:" << std::endl; + for (auto initialState : modelchecker.template getModel<storm::models::AbstractModel<T>>().getInitialStates()) { + LOG4CPLUS_INFO(logger, "\t" << initialState << ": " << (result.stateResult[initialState] ? "satisfied" : "not satisfied")); + std::cout << "\t" << initialState << ": " << result.stateResult[initialState] << std::endl; + } + } else { + LOG4CPLUS_INFO(logger, "Result for " << result.selection.getNumberOfSetBits() << " selected states:"); + std::cout << "Result for " << result.selection.getNumberOfSetBits() << " selected states:" << std::endl; + + for(uint_fast64_t i = 0; i < result.stateMap.size(); i++) { + if(result.selection.get(result.stateMap[i])) { + LOG4CPLUS_INFO(logger, "\t" << result.stateMap[i] << ": " << (result.stateResult[result.stateMap[i]] ? "satisfied" : "not satisfied")); + std::cout << "\t" << result.stateMap[i] << ": " << (result.stateResult[result.stateMap[i]] ? "satisfied" : "not satisfied") << std::endl; + } + } + } + } + + std::cout << std::endl << "-------------------------------------------" << std::endl; + } + + // The Prctl formula maintained by this filter. + std::shared_ptr<AbstractPrctlFormula<T>> child; +}; + +} //namespace prctl +} //namespace properties +} //namespace storm + + + +#endif /* STORM_FORMULA_PRCTL_PRCTLFILTER_H_ */ diff --git a/src/properties/prctl/ProbabilisticBoundOperator.h b/src/properties/prctl/ProbabilisticBoundOperator.h new file mode 100644 index 000000000..c7b4e075a --- /dev/null +++ b/src/properties/prctl/ProbabilisticBoundOperator.h @@ -0,0 +1,242 @@ +/* + * ProbabilisticBoundOperator.h + * + * Created on: 19.10.2012 + * Author: Thomas Heinemann + */ + +#ifndef STORM_FORMULA_PRCTL_PROBABILISTICBOUNDOPERATOR_H_ +#define STORM_FORMULA_PRCTL_PROBABILISTICBOUNDOPERATOR_H_ + +#include "AbstractStateFormula.h" +#include "AbstractPathFormula.h" +#include "utility/constants.h" +#include "src/properties/ComparisonType.h" + +namespace storm { +namespace properties { +namespace prctl { + +// Forward declaration for the interface class. +template <class T> class ProbabilisticBoundOperator; + +/*! + * Interface class for model checkers that support ProbabilisticBoundOperator. + * + * All model checkers that support the formula class PathBoundOperator must inherit + * this pure virtual class. + */ +template <class T> +class IProbabilisticBoundOperatorModelChecker { + public: + + /*! + * Empty virtual destructor. + */ + virtual ~IProbabilisticBoundOperatorModelChecker() { + // Intentionally left empty + } + + /*! + * Evaluates a ProbabilisticBoundOperator within a model checker. + * + * @param obj Formula object with subformulas. + * @return The modelchecking result of the formula for every state. + */ + virtual storm::storage::BitVector checkProbabilisticBoundOperator(const ProbabilisticBoundOperator<T>& obj) const = 0; +}; + +/*! + * Class for a Prctl formula tree with a P (probablistic) bound operator node as root. + * + * Has one path formula as sub formula/tree. + * + * @par Semantics + * The formula holds iff the probability that the path formula holds meets the bound + * specified in this operator. + * + * The object has shared ownership of its subtree. If this object is deleted and no other object has a shared + * ownership of the subtree it will be deleted as well. + * + * @see AbstractStateFormula + * @see AbstractPathFormula + * @see AbstractPrctlFormula + * @see RewardBoundOperator + */ +template<class T> +class ProbabilisticBoundOperator : public AbstractStateFormula<T> { + +public: + + /*! + * Creates a ProbabilisticBoundOperator node without a subnode. + * The resulting object will not represent a complete formula! + */ + ProbabilisticBoundOperator() : comparisonOperator(LESS), bound(0), child(nullptr) { + // Intentionally left empty. + } + + /*! + * Creates a ProbabilisticBoundOperator node using the given parameters. + * + * @param comparisonOperator The relation for the bound. + * @param bound The bound for the probability. + * @param child The child formula subtree. + */ + ProbabilisticBoundOperator(storm::properties::ComparisonType comparisonOperator, T bound, std::shared_ptr<AbstractPathFormula<T>> const & child) + : comparisonOperator(comparisonOperator), bound(bound), child(child) { + // Intentionally left empty. + } + + /*! + * Empty virtual destructor. + */ + virtual ~ProbabilisticBoundOperator() { + // Intentionally left empty. + } + + /*! + * Clones the called object. + * + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. + * + * @returns A new ProbabilisticBoundOperator object that is a deep copy of the called object. + */ + virtual std::shared_ptr<AbstractStateFormula<T>> clone() const override { + std::shared_ptr<ProbabilisticBoundOperator<T>> result(new ProbabilisticBoundOperator<T>()); + result->setComparisonOperator(comparisonOperator); + result->setBound(bound); + result->setChild(child->clone()); + return result; + } + + /*! + * Calls the model checker to check this formula. + * Needed to infer the correct type of formula class. + * + * @note This function should only be called in a generic check function of a model checker class. For other uses, + * the methods of the model checker should be used. + * + * @returns A bit vector indicating all states that satisfy the formula represented by the called object. + */ + virtual storm::storage::BitVector check(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelChecker) const override { + return modelChecker.template as<IProbabilisticBoundOperatorModelChecker>()->checkProbabilisticBoundOperator(*this); + } + + /*! + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. + */ + virtual std::string toString() const override { + std::string result = "P "; + switch (comparisonOperator) { + case LESS: result += "<"; break; + case LESS_EQUAL: result += "<="; break; + case GREATER: result += ">"; break; + case GREATER_EQUAL: result += ">="; break; + } + result += " "; + result += std::to_string(bound); + result += " ("; + result += child->toString(); + result += ")"; + return result; + } + + /*! + * Gets the child node. + * + * @returns The child node. + */ + std::shared_ptr<AbstractPathFormula<T>> const & getChild () const { + return child; + } + + /*! + * Sets the subtree. + * + * @param child The new child. + */ + void setChild(std::shared_ptr<AbstractPathFormula<T>> const & child) { + this->child = child; + } + + /*! + * Checks if the child is set, i.e. it does not point to null. + * + * @return True iff the child is set. + */ + bool isChildSet() const { + return child.get() != nullptr; + } + + /*! + * Gets the comparison operator. + * + * @returns An enum value representing the comparison relation. + */ + storm::properties::ComparisonType const getComparisonOperator() const { + return comparisonOperator; + } + + /*! + * Sets the comparison operator. + * + * @param comparisonOperator An enum value representing the new comparison relation. + */ + void setComparisonOperator(storm::properties::ComparisonType comparisonOperator) { + this->comparisonOperator = comparisonOperator; + } + + /*! + * Gets the bound which the probability that the path formula holds has to obey. + * + * @returns The probability bound. + */ + T const & getBound() const { + return bound; + } + + /*! + * Sets the bound which the probability that the path formula holds has to obey. + * + * @param bound The new probability bound. + */ + void setBound(T bound) { + this->bound = bound; + } + + /*! + * Checks if the bound is met by the given value. + * + * @param value The value to test against the bound. + * @returns True iff value <comparisonOperator> bound holds. + */ + bool meetsBound(T value) const { + switch (comparisonOperator) { + case LESS: return value < bound; break; + case LESS_EQUAL: return value <= bound; break; + case GREATER: return value > bound; break; + case GREATER_EQUAL: return value >= bound; break; + default: return false; + } + } + +private: + + // The operator used to indicate the kind of bound that is to be met. + storm::properties::ComparisonType comparisonOperator; + + // The probability bound. + T bound; + + // The path formula for which the probability to be satisfied has to meet the bound. + std::shared_ptr<AbstractPathFormula<T>> child; +}; + +} //namespace prctl +} //namespace properties +} //namespace storm + +#endif /* STORM_FORMULA_PRCTL_PROBABILISTICBOUNDOPERATOR_H_ */ diff --git a/src/properties/prctl/ReachabilityReward.h b/src/properties/prctl/ReachabilityReward.h new file mode 100644 index 000000000..3b20fe7f5 --- /dev/null +++ b/src/properties/prctl/ReachabilityReward.h @@ -0,0 +1,170 @@ +/* + * Next.h + * + * Created on: 26.12.2012 + * Author: Christian Dehnert + */ + +#ifndef STORM_FORMULA_PRCTL_REACHABILITYREWARD_H_ +#define STORM_FORMULA_PRCTL_REACHABILITYREWARD_H_ + +#include "AbstractRewardPathFormula.h" +#include "AbstractStateFormula.h" + +namespace storm { +namespace properties { +namespace prctl { + +// Forward declaration for the interface class. +template <class T> class ReachabilityReward; + +/*! + * Interface class for model checkers that support ReachabilityReward. + * + * All model checkers that support the formula class ReachabilityReward must inherit + * this pure virtual class. + */ +template <class T> +class IReachabilityRewardModelChecker { + public: + + /*! + * Empty virtual destructor. + */ + virtual ~IReachabilityRewardModelChecker() { + // Intentionally left empty + } + + /*! + * Evaluates a ReachabilityReward formula within a model checker. + * + * @param obj Formula object with subformulas. + * @param qualitative A flag indicating whether the formula only needs to be evaluated qualitatively, i.e. if the + * results are only compared against the bounds 0 and 1. + * @return The modelchecking result of the formula for every state. + */ + virtual std::vector<T> checkReachabilityReward(const ReachabilityReward<T>& obj, bool qualitative) const = 0; +}; + +/*! + * Class for an Prctl (reward path) formula tree with an Reachability Reward node as root. + * + * Has one state formula as sub formula/tree. + * + * This formula expresses the rewards received or costs needed to reach a state satisfying the formula \e child. + * In case the state under consiteration itself satisfies the formula \e child the rewards are zero. + * In case that there is a non zero probability of not reaching any of the target states the rewards are infinite. + * Also note that for this formula both state and transition rewards are considered and use if available in the model. + * + * The object has shared ownership of its subtree. If this object is deleted and no other object has a shared + * ownership of the subtree it will be deleted as well. + * + * @see AbstractRewardPathFormula + * @see AbstractPrctlFormula + */ +template <class T> +class ReachabilityReward : public AbstractRewardPathFormula<T> { + +public: + + /*! + * Creates a ReachabilityReward node without a subnode. + * The resulting object will not represent a complete formula! + */ + ReachabilityReward() : child(nullptr){ + // Intentionally left empty + } + + /*! + * Creates an Eventually node using the given parameter. + * + * @param child The child formula subtree. + */ + ReachabilityReward(std::shared_ptr<AbstractStateFormula<T>> child) : child(child){ + // Intentionally left empty + } + + /*! + * Empty virtual destructor. + */ + virtual ~ReachabilityReward() { + // Intentionally left empty. + } + + /*! + * Clones the called object. + * + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. + * + * @returns A new ReachabilityReward object that is a deep copy of the called object. + */ + virtual std::shared_ptr<AbstractRewardPathFormula<T>> clone() const override { + std::shared_ptr<ReachabilityReward<T>> result(new ReachabilityReward<T>()); + if (this->isChildSet()) { + result->setChild(child->clone()); + } + return result; + } + + /*! + * Calls the model checker to check this formula. + * Needed to infer the correct type of formula class. + * + * @note This function should only be called in a generic check function of a model checker class. For other uses, + * the methods of the model checker should be used. + * + * @returns A vector indicating the probability that the formula holds for each state. + */ + virtual std::vector<T> check(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelChecker, bool qualitative) const override { + return modelChecker.template as<IReachabilityRewardModelChecker>()->checkReachabilityReward(*this, qualitative); + } + + /*! + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. + */ + virtual std::string toString() const override { + std::string result = "F "; + result += child->toString(); + return result; + } + + /*! + * Gets the child node. + * + * @returns The child node. + */ + std::shared_ptr<AbstractStateFormula<T>> const & getChild() const { + return child; + } + + /*! + * Sets the subtree. + * + * @param child The new child. + */ + void setChild(std::shared_ptr<AbstractStateFormula<T>> const & child) { + this->child = child; + } + + /*! + * Checks if the child is set, i.e. it does not point to null. + * + * @return True iff the child is set. + */ + bool isChildSet() const { + return child.get() != nullptr; + } + +private: + + // The child node. + std::shared_ptr<AbstractStateFormula<T>> child; +}; + +} //namespace prctl +} //namespace properties +} //namespace storm + +#endif /* STORM_FORMULA_PRCTL_REACHABILITYREWARD_H_ */ diff --git a/src/properties/prctl/RewardBoundOperator.h b/src/properties/prctl/RewardBoundOperator.h new file mode 100644 index 000000000..30322f2be --- /dev/null +++ b/src/properties/prctl/RewardBoundOperator.h @@ -0,0 +1,243 @@ +/* + * RewardBoundOperator.h + * + * Created on: 19.10.2012 + * Author: Thomas Heinemann + */ + +#ifndef STORM_FORMULA_PRCTL_REWARDBOUNDOPERATOR_H_ +#define STORM_FORMULA_PRCTL_REWARDBOUNDOPERATOR_H_ + +#include "AbstractRewardPathFormula.h" +#include "AbstractStateFormula.h" +#include "utility/constants.h" +#include "src/properties/ComparisonType.h" + +namespace storm { +namespace properties { +namespace prctl { + +// Forward declaration for the interface class. +template <class T> class RewardBoundOperator; + +/*! + * Interface class for model checkers that support RewardBoundOperator. + * + * All model checkers that support the formula class PathBoundOperator must inherit + * this pure virtual class. + */ +template <class T> +class IRewardBoundOperatorModelChecker { + public: + + /*! + * Empty virtual destructor. + */ + virtual ~IRewardBoundOperatorModelChecker() { + // Intentionally left empty + } + + /*! + * Evaluates a RewardBoundOperator within a model checker. + * + * @param obj Formula object with subformulas. + * @return The modelchecking result of the formula for every state. + */ + virtual storm::storage::BitVector checkRewardBoundOperator(const RewardBoundOperator<T>& obj) const = 0; +}; + +/*! + * Class for a Prctl formula tree with an R (reward) operator node as root. + * + * Has a reward path formula as sub formula/tree. + * + * @par Semantics + * The formula holds iff the reward of the reward path formula meets the bound + * specified in this operator. + * + * The object has shared ownership of its subtree. If this object is deleted and no other object has a shared + * ownership of the subtree it will be deleted as well. + * + * + * @see AbstractStateFormula + * @see AbstractRewardPathFormula + * @see AbstractPrctlFormula + * @see ProbabilisticBoundOperator + */ +template<class T> +class RewardBoundOperator : public AbstractStateFormula<T> { + +public: + + /*! + * Creates a RewardBoundOperator node without a subnode. + * The resulting object will not represent a complete formula! + */ + RewardBoundOperator() : comparisonOperator(LESS), bound(0), child(nullptr){ + // Intentionally left empty + } + + /*! + * Creates a ProbabilisticBoundOperator node using the given parameters. + * + * @param comparisonOperator The relation for the bound. + * @param bound The bound for the rewards. + * @param child The child formula subtree. + */ + RewardBoundOperator(storm::properties::ComparisonType comparisonOperator, T bound, std::shared_ptr<AbstractRewardPathFormula<T>> const & child) + : comparisonOperator(comparisonOperator), bound(bound), child(child) { + // Intentionally left empty + } + + /*! + * Empty virtual destructor. + */ + virtual ~RewardBoundOperator() { + // Intentionally left empty. + } + + /*! + * Clones the called object. + * + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. + * + * @returns A new RewardBoundOperator object that is a deep copy of the called object. + */ + virtual std::shared_ptr<AbstractStateFormula<T>> clone() const override { + std::shared_ptr<RewardBoundOperator<T>> result(new RewardBoundOperator<T>()); + result->setComparisonOperator(comparisonOperator); + result->setBound(bound); + result->setChild(child->clone()); + return result; + } + + /*! + * Calls the model checker to check this formula. + * Needed to infer the correct type of formula class. + * + * @note This function should only be called in a generic check function of a model checker class. For other uses, + * the methods of the model checker should be used. + * + * @returns A bit vector indicating all states that satisfy the formula represented by the called object. + */ + virtual storm::storage::BitVector check(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelChecker) const override { + return modelChecker.template as<IRewardBoundOperatorModelChecker>()->checkRewardBoundOperator(*this); + } + + /*! + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. + */ + virtual std::string toString() const override { + std::string result = "R "; + switch (comparisonOperator) { + case LESS: result += "<"; break; + case LESS_EQUAL: result += "<="; break; + case GREATER: result += ">"; break; + case GREATER_EQUAL: result += ">="; break; + } + result += " "; + result += std::to_string(bound); + result += " ("; + result += child->toString(); + result += ")"; + return result; + } + + /*! + * Gets the child node. + * + * @returns The child node. + */ + std::shared_ptr<AbstractRewardPathFormula<T>> const & getChild () const { + return child; + } + + /*! + * Sets the subtree. + * + * @param child The new child. + */ + void setChild(std::shared_ptr<AbstractRewardPathFormula<T>> const & child) { + this->child = child; + } + + /*! + * Checks if the child is set, i.e. it does not point to null. + * + * @return True iff the child is set. + */ + bool isChildSet() const { + return child.get() != nullptr; + } + + /*! + * Gets the comparison operator. + * + * @returns An enum value representing the comparison relation. + */ + storm::properties::ComparisonType const getComparisonOperator() const { + return comparisonOperator; + } + + /*! + * Sets the comparison operator. + * + * @param comparisonOperator An enum value representing the new comparison relation. + */ + void setComparisonOperator(storm::properties::ComparisonType comparisonOperator) { + this->comparisonOperator = comparisonOperator; + } + + /*! + * Gets the bound which is to be obeyed by the rewards of the reward path formula. + * + * @returns The probability bound. + */ + T const & getBound() const { + return bound; + } + + /*! + * Sets the bound which is to be obeyed by the rewards of the reward path formula + * + * @param bound The new reward bound. + */ + void setBound(T bound) { + this->bound = bound; + } + + /*! + * Checks if the bound is met by the given value. + * + * @param value The value to test against the bound. + * @returns True iff value <comparisonOperator> bound holds. + */ + bool meetsBound(T value) const { + switch (comparisonOperator) { + case LESS: return value < bound; break; + case LESS_EQUAL: return value <= bound; break; + case GREATER: return value > bound; break; + case GREATER_EQUAL: return value >= bound; break; + default: return false; + } + } + +private: + + // The operator used to indicate the kind of bound that is to be met. + storm::properties::ComparisonType comparisonOperator; + + // The reward bound. + T bound; + + // The reward path formula whose rewards have to meet the bound. + std::shared_ptr<AbstractRewardPathFormula<T>> child; +}; + +} //namespace prctl +} //namespace properties +} //namespace storm + +#endif /* STORM_FORMULA_PRCTL_REWARDBOUNDOPERATOR_H_ */ diff --git a/src/properties/prctl/SteadyStateReward.h b/src/properties/prctl/SteadyStateReward.h new file mode 100644 index 000000000..0143c91a1 --- /dev/null +++ b/src/properties/prctl/SteadyStateReward.h @@ -0,0 +1,114 @@ +/* + * SteadyStateReward.h + * + * Created on: 08.04.2013 + * Author: Thomas Heinemann + */ + +#ifndef STORM_FORMULA_PRCTL_STEADYSTATEREWARD_H_ +#define STORM_FORMULA_PRCTL_STEADYSTATEREWARD_H_ + +#include "AbstractRewardPathFormula.h" +#include <string> + +namespace storm { +namespace properties { +namespace prctl { + +// Forward declaration for the interface class. +template <class T> class SteadyStateReward; + +/*! + * Interface class for model checkers that support SteadyStateReward. + * + * All model checkers that support the formula class SteadyStateReward must inherit + * this pure virtual class. + */ +template <class T> +class ISteadyStateRewardModelChecker { + public: + + /*! + * Empty virtual destructor. + */ + virtual ~ISteadyStateRewardModelChecker() { + // Intentionally left empty + } + + /*! + * Evaluates a SteadyStateReward formula within a model checker. + * + * @param obj Formula object with subformulas. + * @param qualitative A flag indicating whether the formula only needs to be evaluated qualitatively, i.e. if the + * results are only compared against the bounds 0 and 1. + * @return The modelchecking result of the formula for every state. + */ + virtual std::vector<T> checkSteadyStateReward(const SteadyStateReward<T>& obj, bool qualitative) const = 0; +}; + +/*! + * Class for a Steady State Reward formula. + * This class represents a possible leaf in a reward formula tree. + * + * This formula expresses the expected long-run rewards for each state in the model. + * + * @see AbstractRewardPathFormula + * @see AbstractPrctlFormula + */ +template <class T> +class SteadyStateReward: public AbstractRewardPathFormula<T> { +public: + + /*! + * Creates a new SteadyStateReward node. + */ + SteadyStateReward() { + // Intentionally left empty. + } + + /*! + * Empty virtual destructor. + */ + virtual ~SteadyStateReward() { + // Intentionally left empty. + } + + /*! + * Clones the called object. + * + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. + * + * @returns A new SteadyStateReward object that is a deep copy of the called object. + */ + virtual std::shared_ptr<AbstractRewardPathFormula<T>> clone() const override { + auto result = std::make_shared<SteadyStateReward<T>>(); + return result; + } + + /*! + * Calls the model checker to check this formula. + * Needed to infer the correct type of formula class. + * + * @note This function should only be called in a generic check function of a model checker class. For other uses, + * the methods of the model checker should be used. + * + * @returns A vector indicating the probability that the formula holds for each state. + */ + virtual std::vector<T> check(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelChecker, bool qualitative) const override { + return modelChecker.template as<ISteadyStateRewardModelChecker>()->checkSteadyStateReward(*this, qualitative); + } + + /*! + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. + */ + virtual std::string toString() const override { + return "S"; + } +}; + +} //namespace prctl +} //namespace properties +} //namespace storm +#endif /* STORM_FORMULA_PRCTL_STEADYSTATEREWARD_H_ */ diff --git a/src/properties/prctl/Until.h b/src/properties/prctl/Until.h new file mode 100644 index 000000000..f9e19955b --- /dev/null +++ b/src/properties/prctl/Until.h @@ -0,0 +1,205 @@ +/* + * Until.h + * + * Created on: 19.10.2012 + * Author: Thomas Heinemann + */ + +#ifndef STORM_FORMULA_PRCTL_UNTIL_H_ +#define STORM_FORMULA_PRCTL_UNTIL_H_ + +#include "AbstractPathFormula.h" +#include "AbstractStateFormula.h" + +namespace storm { +namespace properties { +namespace prctl { + +// Forward declaration for the interface class. +template <class T> class Until; + +/*! + * Interface class for model checkers that support Until. + * + * All model checkers that support the formula class Until must inherit + * this pure virtual class. + */ +template <class T> +class IUntilModelChecker { + public: + + /*! + * Empty virtual destructor. + */ + virtual ~IUntilModelChecker() { + // Intentionally left empty + } + + /*! + * Evaluates an Until formula within a model checker. + * + * @param obj Formula object with subformulas. + * @param qualitative A flag indicating whether the formula only needs to be evaluated qualitatively, i.e. if the + * results are only compared against the bounds 0 and 1. + * @return The modelchecking result of the formula for every state. + */ + virtual std::vector<T> checkUntil(const Until<T>& obj, bool qualitative) const = 0; +}; + +/*! + * Class for a Prctl (path) formula tree with an Until node as root. + * + * Has two state formulas as sub formulas/trees. + * + * @par Semantics + * The formula holds iff eventually, formula \e right (the right subtree) holds, and before, + * \e left holds always. + * + * The object has shared ownership of its subtrees. If this object is deleted and no other object has a shared + * ownership of the subtrees they will be deleted as well. + * + * @see AbstractPathFormula + * @see AbstractPrctlFormula + * @see BoundedUntil + */ +template <class T> +class Until : public AbstractPathFormula<T> { + +public: + + /*! + * Creates an Until node without subnodes. + * The resulting object will not represent a complete formula! + */ + Until() : left(nullptr), right(nullptr) { + // Intentionally left empty. + } + + /*! + * Creates an Until node using the given parameters. + * + * @param left The left formula subtree. + * @param right The right formula subtree. + */ + Until(std::shared_ptr<AbstractStateFormula<T>> const & left, std::shared_ptr<AbstractStateFormula<T>> const & right) : left(left), right(right) { + // Intentionally left empty. + } + + /*! + * Empty virtual destructor. + */ + virtual ~Until() { + // Intentionally left empty. + } + + /*! + * Clones the called object. + * + * Performs a "deep copy", i.e. the subnodes of the new object are clones of the original ones. + * + * @returns A new Until object that is a deep copy of the called object. + */ + virtual std::shared_ptr<AbstractPathFormula<T>> clone() const override { + std::shared_ptr<Until<T>> result(new Until()); + if (this->isLeftSet()) { + result->setLeft(left->clone()); + } + if (this->isRightSet()) { + result->setRight(right->clone()); + } + return result; + } + + /*! + * Calls the model checker to check this formula. + * Needed to infer the correct type of formula class. + * + * @note This function should only be called in a generic check function of a model checker class. For other uses, + * the methods of the model checker should be used. + * + * @returns A vector indicating the probability that the formula holds for each state. + */ + virtual std::vector<T> check(storm::modelchecker::prctl::AbstractModelChecker<T> const & modelChecker, bool qualitative) const override { + return modelChecker.template as<IUntilModelChecker>()->checkUntil(*this, qualitative); + } + + /*! + * Returns a textual representation of the formula tree with this node as root. + * + * @returns A string representing the formula tree. + */ + virtual std::string toString() const override { + std::string result = left->toString(); + result += " U "; + result += right->toString(); + return result; + } + + /*! + * Gets the left child node. + * + * @returns The left child node. + */ + std::shared_ptr<AbstractStateFormula<T>> const & getLeft() const { + return left; + } + + /*! + * Gets the right child node. + * + * @returns The right child node. + */ + std::shared_ptr<AbstractStateFormula<T>> const & getRight() const { + return right; + } + + /*! + * Sets the left child node. + * + * @param newLeft The new left child. + */ + void setLeft(std::shared_ptr<AbstractStateFormula<T>> const & newLeft) { + left = newLeft; + } + + /*! + * Sets the right child node. + * + * @param newRight The new right child. + */ + void setRight(std::shared_ptr<AbstractStateFormula<T>> const & newRight) { + right = newRight; + } + + /*! + * Checks if the left child is set, i.e. it does not point to null. + * + * @return True iff the left child is set. + */ + bool isLeftSet() const { + return left.get() != nullptr; + } + + /*! + * Checks if the right child is set, i.e. it does not point to null. + * + * @return True iff the right child is set. + */ + bool isRightSet() const { + return right.get() != nullptr; + } + +private: + + // The left child node. + std::shared_ptr<AbstractStateFormula<T>> left; + + // The right child node. + std::shared_ptr<AbstractStateFormula<T>> right; +}; + +} //namespace prctl +} //namespace properties +} //namespace storm + +#endif /* STORM_FORMULA_PRCTL_UNTIL_H_ */ diff --git a/src/storage/SparseMatrix.h b/src/storage/SparseMatrix.h index b60cbdc16..46eaa0860 100644 --- a/src/storage/SparseMatrix.h +++ b/src/storage/SparseMatrix.h @@ -13,6 +13,8 @@ #include "src/exceptions/InvalidArgumentException.h" #include "src/exceptions/OutOfRangeException.h" +#include <boost/functional/hash.hpp> + // Forward declaration for adapter classes. namespace storm { namespace adapters { diff --git a/src/storm.cpp b/src/storm.cpp index 2287e9b37..6337bb29a 100644 --- a/src/storm.cpp +++ b/src/storm.cpp @@ -37,13 +37,13 @@ #include "src/solver/GmmxxNondeterministicLinearEquationSolver.h" #include "src/solver/GurobiLpSolver.h" #include "src/counterexamples/MILPMinimalLabelSetGenerator.h" -#include "src/counterexamples/SMTMinimalCommandSetGenerator.h" +// #include "src/counterexamples/SMTMinimalCommandSetGenerator.h" #include "src/counterexamples/PathBasedSubsystemGenerator.h" #include "src/parser/AutoParser.h" #include "src/parser/MarkovAutomatonParser.h" #include "src/parser/PrctlParser.h" #include "src/utility/ErrorHandling.h" -#include "src/formula/Prctl.h" +#include "src/properties/Prctl.h" #include "src/utility/vector.h" #include "src/utility/OsDetection.h" @@ -301,12 +301,11 @@ void checkPrctlFormulae(storm::modelchecker::prctl::AbstractModelChecker<double> if (s->isSet("prctl")) { std::string const chosenPrctlFile = s->getOptionByLongName("prctl").getArgument(0).getValueAsString(); LOG4CPLUS_INFO(logger, "Parsing prctl file: " << chosenPrctlFile << "."); - std::list<storm::property::prctl::AbstractPrctlFormula<double>*> formulaList = storm::parser::PrctlFileParser(chosenPrctlFile); + std::list<std::shared_ptr<storm::properties::prctl::PrctlFilter<double>>> formulaList = storm::parser::PrctlFileParser::parsePrctlFile(chosenPrctlFile); for (auto formula : formulaList) { std::chrono::high_resolution_clock::time_point startTime = std::chrono::high_resolution_clock::now(); - modelchecker.check(*formula); - delete formula; + formula->check(modelchecker); std::chrono::high_resolution_clock::time_point endTime = std::chrono::high_resolution_clock::now(); std::cout << "Checking the formula took " << std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime).count() << "ms." << std::endl; } @@ -358,7 +357,7 @@ void checkPrctlFormulae(storm::modelchecker::prctl::AbstractModelChecker<double> std::string const chosenPrctlFile = s->getOptionByLongName("prctl").getArgument(0).getValueAsString(); LOG4CPLUS_INFO(logger, "Parsing prctl file: " << chosenPrctlFile << "."); - std::list<storm::property::prctl::AbstractPrctlFormula<double>*> formulaList = storm::parser::PrctlFileParser(chosenPrctlFile); + std::list<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) { @@ -388,13 +387,12 @@ void checkPrctlFormulae(storm::modelchecker::prctl::AbstractModelChecker<double> for (auto formula : formulaList) { // First check if it is a formula type for which a counterexample can be generated. - if (dynamic_cast<storm::property::prctl::AbstractStateFormula<double> const*>(formula) == nullptr) { + if (std::dynamic_pointer_cast<storm::properties::prctl::AbstractStateFormula<double>>(formula->getChild()).get() == nullptr) { LOG4CPLUS_ERROR(logger, "Unexpected kind of formula. Expected a state formula."); - delete formula; continue; } - storm::property::prctl::AbstractStateFormula<double> const& stateForm = static_cast<storm::property::prctl::AbstractStateFormula<double> const&>(*formula); + std::shared_ptr<storm::properties::prctl::AbstractStateFormula<double>> stateForm = std::static_pointer_cast<storm::properties::prctl::AbstractStateFormula<double>>(formula->getChild()); // Do some output std::cout << "Generating counterexample for formula " << fIndex << ":" << std::endl; @@ -408,13 +406,12 @@ void checkPrctlFormulae(storm::modelchecker::prctl::AbstractModelChecker<double> // Also raise the logger threshold for the log file, so that the model check infos aren't logged (useless and there are lots of them) // Lower it again after the model check. logger.getAppender("mainFileAppender")->setThreshold(log4cplus::WARN_LOG_LEVEL); - storm::storage::BitVector result = stateForm.check(*createPrctlModelChecker(dtmc)); + storm::storage::BitVector result = stateForm->check(*createPrctlModelChecker(dtmc)); logger.getAppender("mainFileAppender")->setThreshold(log4cplus::INFO_LOG_LEVEL); if((result & dtmc.getInitialStates()).getNumberOfSetBits() == dtmc.getInitialStates().getNumberOfSetBits()) { std::cout << "Formula is satisfied. Can not generate counterexample.\n\n" << std::endl; LOG4CPLUS_INFO(logger, "Formula is satisfied. Can not generate counterexample."); - delete formula; continue; } @@ -437,7 +434,6 @@ void checkPrctlFormulae(storm::modelchecker::prctl::AbstractModelChecker<double> } fIndex++; - delete formula; } } @@ -597,14 +593,14 @@ int main(const int argc, const char* argv[]) { // Now parse the property file and receive the list of parsed formulas. std::string const& propertyFile = s->getOptionByLongName("mincmd").getArgumentByName("propertyFile").getValueAsString(); - std::list<storm::property::prctl::AbstractPrctlFormula<double>*> formulaList = storm::parser::PrctlFileParser(propertyFile); + std::list<std::shared_ptr<storm::properties::prctl::PrctlFilter<double>>> formulaList = storm::parser::PrctlFileParser::parsePrctlFile(propertyFile); // Now generate the counterexamples for each formula. - for (storm::property::prctl::AbstractPrctlFormula<double>* formulaPtr : formulaList) { + for (auto formulaPtr : formulaList) { if (useMILP) { - storm::counterexamples::MILPMinimalLabelSetGenerator<double>::computeCounterexample(program, *mdp, formulaPtr); + storm::counterexamples::MILPMinimalLabelSetGenerator<double>::computeCounterexample(program, *mdp, formulaPtr->getChild()); } else { - storm::counterexamples::SMTMinimalCommandSetGenerator<double>::computeCounterexample(program, constants, *mdp, formulaPtr); + storm::counterexamples::SMTMinimalCommandSetGenerator<double>::computeCounterexample(program, constants, *mdp, formulaPtr->getChild()); } // Once we are done with the formula, delete it. diff --git a/test/functional/modelchecker/ActionTest.cpp b/test/functional/modelchecker/ActionTest.cpp new file mode 100644 index 000000000..83113a614 --- /dev/null +++ b/test/functional/modelchecker/ActionTest.cpp @@ -0,0 +1,573 @@ +/* + * ActionTest.cpp + * + * Created on: Jun 27, 2014 + * Author: Manuel Sascha Weiand + */ + +#include "gtest/gtest.h" +#include "storm-config.h" + +#include "src/properties/actions/BoundAction.h" +#include "src/properties/actions/FormulaAction.h" +#include "src/properties/actions/InvertAction.h" +#include "src/properties/actions/RangeAction.h" +#include "src/properties/actions/SortAction.h" + +#include "src/parser/MarkovAutomatonParser.h" +#include "src/parser/DeterministicModelParser.h" +#include "src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h" +#include "src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h" +#include "src/solver/GmmxxLinearEquationSolver.h" +#include "src/exceptions/InvalidArgumentException.h" + +typedef typename storm::properties::action::AbstractAction<double>::Result Result; + +TEST(ActionTest, BoundActionFunctionality) { + + // Setup the modelchecker. + storm::models::Dtmc<double> model = storm::parser::DeterministicModelParser::parseDtmc(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_actionTest.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/dtmc_actionTest.lab"); + storm::modelchecker::prctl::SparseDtmcPrctlModelChecker<double> mc(model, new storm::solver::GmmxxLinearEquationSolver<double>()); + + // Build the filter input. + // Basically the modelchecking result of "F a" on the used DTMC. + std::vector<double> pathResult = mc.checkEventually(storm::properties::prctl::Eventually<double>(std::make_shared<storm::properties::prctl::Ap<double>>("a")), false); + std::vector<uint_fast64_t> stateMap(pathResult.size()); + for(uint_fast64_t i = 0; i < pathResult.size(); i++) { + stateMap[i] = i; + } + Result input(storm::storage::BitVector(pathResult.size(), true), stateMap, pathResult, storm::storage::BitVector()); + + // Test the action. + // First test that the boundAction build by the empty constructor does not change the selection. + storm::properties::action::BoundAction<double> action; + Result result = action.evaluate(input, mc); + + for(auto value : result.selection) { + ASSERT_TRUE(input.selection[value]); + } + + // Test that using a strict bound can give different results than using a non-strict bound. + action = storm::properties::action::BoundAction<double>(storm::properties::GREATER, 0); + result = action.evaluate(input, mc); + + for(uint_fast64_t i = 0; i < result.selection.size()-2; i++) { + ASSERT_TRUE(result.selection[i]); + } + ASSERT_FALSE(result.selection[6]); + ASSERT_FALSE(result.selection[7]); + + // Test whether the filter actually uses the selection given by the input. + action = storm::properties::action::BoundAction<double>(storm::properties::LESS, 0.5); + result = action.evaluate(result, mc); + + ASSERT_FALSE(result.selection[0]); + ASSERT_TRUE(result.selection[1]); + ASSERT_FALSE(result.selection[6]); + ASSERT_FALSE(result.selection[7]); + + // Check whether the state order has any effect on the selected states, which it should not. + for(uint_fast64_t i = 0; i < pathResult.size(); i++) { + stateMap[i] = pathResult.size() - i - 1; + } + + action = storm::properties::action::BoundAction<double>(storm::properties::GREATER, 0); + result = action.evaluate(input, mc); + + for(uint_fast64_t i = 0; i < result.selection.size()-2; i++) { + ASSERT_TRUE(result.selection[i]); + } + ASSERT_FALSE(result.selection[6]); + ASSERT_FALSE(result.selection[7]); + + // Test the functionality for state formulas instead. + input.pathResult = std::vector<double>(); + input.stateResult = mc.checkAp(storm::properties::prctl::Ap<double>("a")); + action = storm::properties::action::BoundAction<double>(storm::properties::GREATER, 0.5); + result = action.evaluate(input, mc); + + for(uint_fast64_t i = 0; i < result.selection.size(); i++) { + if(i == 5) { + ASSERT_TRUE(result.selection[i]); + } else { + ASSERT_FALSE(result.selection[i]); + } + } + + // Make sure that the modelchecker has no influence on the result. + storm::models::MarkovAutomaton<double> ma = storm::parser::MarkovAutomatonParser::parseMarkovAutomaton(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/ma_general.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/ma_general.lab"); + storm::modelchecker::csl::SparseMarkovAutomatonCslModelChecker<double> cslMc(ma); + result = action.evaluate(input, cslMc); + + for(uint_fast64_t i = 0; i < result.selection.size(); i++) { + if(i == 5) { + ASSERT_TRUE(result.selection[i]); + } else { + ASSERT_FALSE(result.selection[i]); + } + } +} + +TEST(ActionTest, BoundActionSafety) { + + // Setup the modelchecker. + storm::models::Dtmc<double> model = storm::parser::DeterministicModelParser::parseDtmc(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_actionTest.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/dtmc_actionTest.lab"); + storm::modelchecker::prctl::SparseDtmcPrctlModelChecker<double> mc(model, new storm::solver::GmmxxLinearEquationSolver<double>()); + + // Build the filter input. + // Basically the modelchecking result of "F a" on the used DTMC. + std::vector<double> pathResult = mc.checkEventually(storm::properties::prctl::Eventually<double>(std::make_shared<storm::properties::prctl::Ap<double>>("a")), false); + storm::storage::BitVector stateResult = mc.checkAp(storm::properties::prctl::Ap<double>("a")); + std::vector<uint_fast64_t> stateMap(pathResult.size()); + for(uint_fast64_t i = 0; i < pathResult.size(); i++) { + stateMap[i] = i; + } + Result input(storm::storage::BitVector(pathResult.size(), true), stateMap, pathResult, storm::storage::BitVector()); + + // First, test unusual bounds. + storm::properties::action::BoundAction<double> action(storm::properties::LESS, -2044); + Result result; + + ASSERT_NO_THROW(result = action.evaluate(input, mc)); + ASSERT_EQ(0, result.selection.getNumberOfSetBits()); + + action = storm::properties::action::BoundAction<double>(storm::properties::GREATER_EQUAL, 5879); + + ASSERT_NO_THROW(result = action.evaluate(input, mc)); + ASSERT_EQ(0, result.selection.getNumberOfSetBits()); + + action = storm::properties::action::BoundAction<double>(storm::properties::LESS_EQUAL, 5879); + + ASSERT_NO_THROW(result = action.evaluate(input, mc)); + ASSERT_EQ(result.selection.size(), result.selection.getNumberOfSetBits()); + + // Now, check the behavior under a undefined comparison type. + action = storm::properties::action::BoundAction<double>(static_cast<storm::properties::ComparisonType>(10), 5879); + ASSERT_THROW(action.toString(), storm::exceptions::InvalidArgumentException); + ASSERT_THROW(action.evaluate(input, mc), storm::exceptions::InvalidArgumentException); + + // Test for a result input with both results filled. + // It should put out a warning and use the pathResult. + action = storm::properties::action::BoundAction<double>(storm::properties::GREATER_EQUAL, 0.5); + input.stateResult = stateResult; + + // To capture the warning, redirect cout and test the written buffer content. + std::stringstream buffer; + std::streambuf *sbuf = std::cout.rdbuf(); + std::cout.rdbuf(buffer.rdbuf()); + + ASSERT_NO_THROW(result = action.evaluate(input, mc)); + std::cout.rdbuf(sbuf); + + ASSERT_FALSE(buffer.str().empty()); + ASSERT_TRUE(result.selection[0]); + ASSERT_FALSE(result.selection[1]); + ASSERT_TRUE(result.selection[2]); + ASSERT_TRUE(result.selection[5]); + + // Check for empty input. + ASSERT_NO_THROW(result = action.evaluate(Result(), mc)); +} + +TEST(ActionTest, FormulaActionFunctionality) { + + // Setup the modelchecker. + storm::models::Dtmc<double> model = storm::parser::DeterministicModelParser::parseDtmc(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_actionTest.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/dtmc_actionTest.lab"); + storm::modelchecker::prctl::SparseDtmcPrctlModelChecker<double> mc(model, new storm::solver::GmmxxLinearEquationSolver<double>()); + + // Build the filter input. + // Basically the modelchecking result of "F a" on the used DTMC. + std::vector<double> pathResult = mc.checkEventually(storm::properties::prctl::Eventually<double>(std::make_shared<storm::properties::prctl::Ap<double>>("a")), false); + storm::storage::BitVector stateResult = mc.checkAp(storm::properties::prctl::Ap<double>("c")); + std::vector<uint_fast64_t> stateMap(pathResult.size()); + for(uint_fast64_t i = 0; i < pathResult.size(); i++) { + stateMap[i] = i; + } + Result input(storm::storage::BitVector(pathResult.size(), true), stateMap, pathResult, storm::storage::BitVector()); + Result result; + + // Test the action. + // First test that the empty action does no change to the input. + storm::properties::action::FormulaAction<double> action; + input.selection.set(0,false); + ASSERT_NO_THROW(result = action.evaluate(input, mc)); + for(uint_fast64_t i = 0; i < pathResult.size(); i++) { + if(i != 0) { + ASSERT_TRUE(result.selection[i]); + } else { + ASSERT_FALSE(result.selection[i]); + } + ASSERT_EQ(i, result.stateMap[i]); + ASSERT_EQ(input.pathResult[i], result.pathResult[i]); + } + ASSERT_TRUE(result.stateResult.size() == 0); + input.selection.set(0,true); + + // Now test the general functionality. + action = storm::properties::action::FormulaAction<double>(std::make_shared<storm::properties::prctl::ProbabilisticBoundOperator<double>>(storm::properties::LESS, 0.5, std::make_shared<storm::properties::prctl::Eventually<double>>(std::make_shared<storm::properties::prctl::Ap<double>>("b")))); + ASSERT_NO_THROW(result = action.evaluate(input, mc)); + ASSERT_TRUE(result.selection[0]); + ASSERT_TRUE(result.selection[1]); + ASSERT_TRUE(result.selection[2]); + ASSERT_FALSE(result.selection[3]); + ASSERT_FALSE(result.selection[4]); + ASSERT_TRUE(result.selection[5]); + ASSERT_FALSE(result.selection[6]); + ASSERT_FALSE(result.selection[7]); + + // Check that the actual modelchecking results are not touched. + ASSERT_EQ(input.stateResult.size(), result.stateResult.size()); + ASSERT_EQ(input.pathResult.size(), result.pathResult.size()); + for(uint_fast64_t i = 0; i < input.pathResult.size(); i++) { + ASSERT_EQ(input.pathResult[i], result.pathResult[i]); + } + + // Do the same but this time using a state result instead of a path result. + input.pathResult = std::vector<double>(); + input.stateResult = stateResult; + ASSERT_NO_THROW(result = action.evaluate(input, mc)); + ASSERT_TRUE(result.selection[0]); + ASSERT_TRUE(result.selection[1]); + ASSERT_TRUE(result.selection[2]); + ASSERT_FALSE(result.selection[3]); + ASSERT_FALSE(result.selection[4]); + ASSERT_TRUE(result.selection[5]); + ASSERT_FALSE(result.selection[6]); + ASSERT_FALSE(result.selection[7]); + + ASSERT_EQ(input.stateResult.size(), result.stateResult.size()); + ASSERT_EQ(input.pathResult.size(), result.pathResult.size()); + for(uint_fast64_t i = 0; i < input.stateResult.size(); i++) { + ASSERT_EQ(input.stateResult[i], result.stateResult[i]); + } +} + +TEST(ActionTest, FormulaActionSafety){ + // Setup the modelchecker. + storm::models::Dtmc<double> model = storm::parser::DeterministicModelParser::parseDtmc(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_actionTest.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/dtmc_actionTest.lab"); + storm::modelchecker::prctl::SparseDtmcPrctlModelChecker<double> mc(model, new storm::solver::GmmxxLinearEquationSolver<double>()); + + // Build the filter input. + // Basically the modelchecking result of "F a" on the used DTMC. + std::vector<double> pathResult = mc.checkEventually(storm::properties::prctl::Eventually<double>(std::make_shared<storm::properties::prctl::Ap<double>>("a")), false); + std::vector<uint_fast64_t> stateMap(pathResult.size()); + for(uint_fast64_t i = 0; i < pathResult.size(); i++) { + stateMap[i] = i; + } + Result input(storm::storage::BitVector(pathResult.size(), true), stateMap, pathResult, storm::storage::BitVector()); + Result result; + + // Check that constructing the action using a nullptr and using an empty constructor leads to the same behavior. + storm::properties::action::FormulaAction<double> action(std::shared_ptr<storm::properties::csl::AbstractStateFormula<double>>(nullptr)); + input.selection.set(0,false); + ASSERT_NO_THROW(result = action.evaluate(input, mc)); + for(uint_fast64_t i = 0; i < pathResult.size(); i++) { + if(i != 0) { + ASSERT_TRUE(result.selection[i]); + } else { + ASSERT_FALSE(result.selection[i]); + } + ASSERT_EQ(i, result.stateMap[i]); + ASSERT_EQ(input.pathResult[i], result.pathResult[i]); + } + ASSERT_TRUE(result.stateResult.size() == 0); + input.selection.set(0,true); + ASSERT_NO_THROW(action.toString()); +} + +TEST(ActionTest, InvertActionFunctionality){ + // Setup the modelchecker. + storm::models::Dtmc<double> model = storm::parser::DeterministicModelParser::parseDtmc(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_actionTest.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/dtmc_actionTest.lab"); + storm::modelchecker::prctl::SparseDtmcPrctlModelChecker<double> mc(model, new storm::solver::GmmxxLinearEquationSolver<double>()); + + // Build the filter input. + // Basically the modelchecking result of "F a" on the used DTMC. + std::vector<double> pathResult = mc.checkEventually(storm::properties::prctl::Eventually<double>(std::make_shared<storm::properties::prctl::Ap<double>>("a")), false); + storm::storage::BitVector stateResult = mc.checkAp(storm::properties::prctl::Ap<double>("c")); + std::vector<uint_fast64_t> stateMap(pathResult.size()); + for(uint_fast64_t i = 0; i < pathResult.size(); i++) { + stateMap[i] = pathResult.size()-i-1; + } + Result input(storm::storage::BitVector(pathResult.size(), true), stateMap, pathResult, storm::storage::BitVector()); + Result result; + + // Check whether the selection becomes inverted while the rest stays the same. + storm::properties::action::InvertAction<double> action; + input.selection.set(0,false); + ASSERT_NO_THROW(result = action.evaluate(input, mc)); + for(uint_fast64_t i = 0; i < pathResult.size(); i++) { + if(i != 0) { + ASSERT_FALSE(result.selection[i]); + } else { + ASSERT_TRUE(result.selection[i]); + } + ASSERT_EQ(pathResult.size()-i-1, result.stateMap[i]); + ASSERT_EQ(input.pathResult[i], result.pathResult[i]); + } + ASSERT_TRUE(result.stateResult.size() == 0); + input.selection.set(0,true); + ASSERT_NO_THROW(action.toString()); +} + +TEST(ActionTest, RangeActionFunctionality){ + // Setup the modelchecker. + storm::models::Dtmc<double> model = storm::parser::DeterministicModelParser::parseDtmc(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_actionTest.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/dtmc_actionTest.lab"); + storm::modelchecker::prctl::SparseDtmcPrctlModelChecker<double> mc(model, new storm::solver::GmmxxLinearEquationSolver<double>()); + + // Build the filter input. + // Basically the modelchecking result of "F a" on the used DTMC. + std::vector<double> pathResult = mc.checkEventually(storm::properties::prctl::Eventually<double>(std::make_shared<storm::properties::prctl::Ap<double>>("a")), false); + storm::storage::BitVector stateResult = mc.checkAp(storm::properties::prctl::Ap<double>("c")); + std::vector<uint_fast64_t> stateMap(pathResult.size()); + for(uint_fast64_t i = 0; i < pathResult.size(); i++) { + stateMap[i] = i; + } + Result input(storm::storage::BitVector(pathResult.size(), true), stateMap, pathResult, storm::storage::BitVector()); + Result result; + + // Test if the action selects the first 3 states in relation to the order given by the stateMap. + // First in index order. + storm::properties::action::RangeAction<double> action(0,2); + ASSERT_NO_THROW(result = action.evaluate(input, mc)); + for(uint_fast64_t i = 0; i < result.selection.size(); i++) { + ASSERT_EQ(input.stateMap[i], result.stateMap[i]); + } + for(uint_fast64_t i = 0; i < 3; i++) { + ASSERT_TRUE(result.selection[i]); + } + for(uint_fast64_t i = 3; i < result.selection.size(); i++) { + ASSERT_FALSE(result.selection[i]); + } + input.selection.clear(); + input.selection.complement(); + + // Now against index order. + for(uint_fast64_t i = 0; i < input.pathResult.size(); i++) { + input.stateMap[i] = input.pathResult.size()-i-1; + } + ASSERT_NO_THROW(result = action.evaluate(input, mc)); + for(uint_fast64_t i = 0; i < result.selection.size(); i++) { + ASSERT_EQ(input.stateMap[i], result.stateMap[i]); + } + for(uint_fast64_t i = 0; i < 3; i++) { + ASSERT_TRUE(result.selection[result.selection.size()-i-1]); + } + for(uint_fast64_t i = 3; i < result.selection.size(); i++) { + ASSERT_FALSE(result.selection[result.selection.size()-i-1]); + } + input.selection.clear(); + input.selection.complement(); + + // Finally test a random order. + std::srand(time(nullptr)); + uint_fast64_t pos1, pos2, temp; + for(uint_fast64_t i = 0; i < 100; i++) { + // Randomly select two positions. + pos1 = rand() % result.selection.size(); + pos2 = rand() % result.selection.size(); + + // Swap the values there. + temp = input.stateMap[pos1]; + input.stateMap[pos1] = input.stateMap[pos2]; + input.stateMap[pos2] = temp; + } + ASSERT_NO_THROW(result = action.evaluate(input, mc)); + for(uint_fast64_t i = 0; i < 8; i++) { + ASSERT_EQ(input.stateMap[i], result.stateMap[i]); + } + for(uint_fast64_t i = 0; i < 3; i++) { + ASSERT_TRUE(result.selection[result.stateMap[i]]); + } + for(uint_fast64_t i = 3; i < result.selection.size(); i++) { + ASSERT_FALSE(result.selection[result.stateMap[i]]); + } + + // Test that specifying and interval of (i,i) selects only state i. + for(uint_fast64_t i = 0; i < input.selection.size(); i++) { + action = storm::properties::action::RangeAction<double>(i,i); + ASSERT_NO_THROW(result = action.evaluate(input, mc)); + ASSERT_EQ(1, result.selection.getNumberOfSetBits()); + ASSERT_TRUE(result.selection[result.stateMap[i]]); + } +} + +TEST(ActionTest, RangeActionSafety){ + // Setup the modelchecker. + storm::models::Dtmc<double> model = storm::parser::DeterministicModelParser::parseDtmc(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_actionTest.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/dtmc_actionTest.lab"); + storm::modelchecker::prctl::SparseDtmcPrctlModelChecker<double> mc(model, new storm::solver::GmmxxLinearEquationSolver<double>()); + + // Build the filter input. + // Basically the modelchecking result of "F a" on the used DTMC. + std::vector<double> pathResult = mc.checkEventually(storm::properties::prctl::Eventually<double>(std::make_shared<storm::properties::prctl::Ap<double>>("a")), false); + storm::storage::BitVector stateResult = mc.checkAp(storm::properties::prctl::Ap<double>("c")); + std::vector<uint_fast64_t> stateMap(pathResult.size()); + for(uint_fast64_t i = 0; i < pathResult.size(); i++) { + stateMap[i] = i; + } + Result input(storm::storage::BitVector(pathResult.size(), true), stateMap, pathResult, storm::storage::BitVector()); + Result result; + + // Test invalid ranges. + + // To capture the warning, redirect cout and test the written buffer content. + std::stringstream buffer; + std::streambuf * sbuf = std::cout.rdbuf(); + std::cout.rdbuf(buffer.rdbuf()); + + storm::properties::action::RangeAction<double> action(0,42); + ASSERT_NO_THROW(result = action.evaluate(input, mc)); + ASSERT_TRUE(result.selection.full()); + + ASSERT_FALSE(buffer.str().empty()); + buffer.str(""); + + action = storm::properties::action::RangeAction<double>(42,98); + ASSERT_NO_THROW(result = action.evaluate(input, mc)); + ASSERT_TRUE(result.selection.empty()); + + ASSERT_FALSE(buffer.str().empty()); + std::cout.rdbuf(sbuf); + + ASSERT_THROW(storm::properties::action::RangeAction<double>(3,1), storm::exceptions::IllegalArgumentValueException); +} + +TEST(ActionTest, SortActionFunctionality){ + // Setup the modelchecker. + storm::models::Dtmc<double> model = storm::parser::DeterministicModelParser::parseDtmc(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_actionTest.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/dtmc_actionTest.lab"); + storm::modelchecker::prctl::SparseDtmcPrctlModelChecker<double> mc(model, new storm::solver::GmmxxLinearEquationSolver<double>()); + + // Build the filter input. + // Basically the modelchecking result of "F a" on the used DTMC. + std::vector<double> pathResult = mc.checkEventually(storm::properties::prctl::Eventually<double>(std::make_shared<storm::properties::prctl::Ap<double>>("a")), false); + storm::storage::BitVector stateResult = mc.checkAp(storm::properties::prctl::Ap<double>("c")); + std::vector<uint_fast64_t> stateMap(pathResult.size()); + for(uint_fast64_t i = 0; i < pathResult.size(); i++) { + stateMap[i] = pathResult.size()-i-1; + } + Result input(storm::storage::BitVector(pathResult.size(), true), stateMap, pathResult, storm::storage::BitVector()); + Result result; + + // Test that sorting preserves everything except the state map. + storm::properties::action::SortAction<double> action; + ASSERT_NO_THROW(action.toString()); + input.selection.set(0,false); + ASSERT_NO_THROW(result = action.evaluate(input, mc)); + for(uint_fast64_t i = 0; i < pathResult.size(); i++) { + if(i != 0) { + ASSERT_TRUE(result.selection[i]); + } else { + ASSERT_FALSE(result.selection[i]); + } + ASSERT_EQ(i, result.stateMap[i]); + ASSERT_EQ(input.pathResult[i], result.pathResult[i]); + } + ASSERT_TRUE(result.stateResult.size() == 0); + input.selection.set(0,true); + + // Test sorting cases. Note that the input selection should be irrelevant for the resulting state order. + // 1) index, ascending -> see above + // 2) index descending + input.selection.set(3,false); + action = storm::properties::action::SortAction<double>(storm::properties::action::SortAction<double>::INDEX, false); + ASSERT_NO_THROW(result = action.evaluate(input, mc)); + for(uint_fast64_t i = 0; i < pathResult.size(); i++) { + ASSERT_EQ(pathResult.size()-i-1, result.stateMap[i]); + } + + // 3) value, ascending + action = storm::properties::action::SortAction<double>(storm::properties::action::SortAction<double>::VALUE); + ASSERT_NO_THROW(result = action.evaluate(input, mc)); + ASSERT_EQ(6, result.stateMap[0]); + ASSERT_EQ(7, result.stateMap[1]); + ASSERT_EQ(3, result.stateMap[2]); + ASSERT_EQ(4, result.stateMap[3]); + ASSERT_EQ(1, result.stateMap[4]); + ASSERT_EQ(0, result.stateMap[5]); + ASSERT_EQ(2, result.stateMap[6]); + ASSERT_EQ(5, result.stateMap[7]); + + // 3) value, decending + action = storm::properties::action::SortAction<double>(storm::properties::action::SortAction<double>::VALUE, false); + ASSERT_NO_THROW(result = action.evaluate(input, mc)); + ASSERT_EQ(5, result.stateMap[0]); + ASSERT_EQ(2, result.stateMap[1]); + ASSERT_EQ(0, result.stateMap[2]); + ASSERT_EQ(1, result.stateMap[3]); + ASSERT_EQ(4, result.stateMap[4]); + ASSERT_EQ(3, result.stateMap[5]); + ASSERT_EQ(6, result.stateMap[6]); + ASSERT_EQ(7, result.stateMap[7]); + + // Check that this also works for state results instead. + input.pathResult = std::vector<double>(); + input.stateResult = stateResult; + + action = storm::properties::action::SortAction<double>(storm::properties::action::SortAction<double>::VALUE); + ASSERT_NO_THROW(result = action.evaluate(input, mc)); + ASSERT_EQ(5, result.stateMap[0]); + ASSERT_EQ(6, result.stateMap[1]); + ASSERT_EQ(7, result.stateMap[2]); + ASSERT_EQ(0, result.stateMap[3]); + ASSERT_EQ(1, result.stateMap[4]); + ASSERT_EQ(2, result.stateMap[5]); + ASSERT_EQ(3, result.stateMap[6]); + ASSERT_EQ(4, result.stateMap[7]); + + action = storm::properties::action::SortAction<double>(storm::properties::action::SortAction<double>::VALUE, false); + ASSERT_NO_THROW(result = action.evaluate(input, mc)); + ASSERT_EQ(0, result.stateMap[0]); + ASSERT_EQ(1, result.stateMap[1]); + ASSERT_EQ(2, result.stateMap[2]); + ASSERT_EQ(3, result.stateMap[3]); + ASSERT_EQ(4, result.stateMap[4]); + ASSERT_EQ(5, result.stateMap[5]); + ASSERT_EQ(6, result.stateMap[6]); + ASSERT_EQ(7, result.stateMap[7]); + + // Test if the resulting order does not depend on the input order. + input.stateResult = storm::storage::BitVector(); + input.pathResult = pathResult; + + action = storm::properties::action::SortAction<double>(storm::properties::action::SortAction<double>::INDEX); + ASSERT_NO_THROW(input = action.evaluate(input, mc)); + action = storm::properties::action::SortAction<double>(storm::properties::action::SortAction<double>::VALUE); + ASSERT_NO_THROW(result = action.evaluate(input, mc)); + ASSERT_EQ(6, result.stateMap[0]); + ASSERT_EQ(7, result.stateMap[1]); + ASSERT_EQ(3, result.stateMap[2]); + ASSERT_EQ(4, result.stateMap[3]); + ASSERT_EQ(1, result.stateMap[4]); + ASSERT_EQ(0, result.stateMap[5]); + ASSERT_EQ(2, result.stateMap[6]); + ASSERT_EQ(5, result.stateMap[7]); + +} + +TEST(ActionTest, SortActionSafety){ + // Check that the path result has priority over the state result if for some erronous reason both are given. + // Setup the modelchecker. + storm::models::Dtmc<double> model = storm::parser::DeterministicModelParser::parseDtmc(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_actionTest.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/dtmc_actionTest.lab"); + storm::modelchecker::prctl::SparseDtmcPrctlModelChecker<double> mc(model, new storm::solver::GmmxxLinearEquationSolver<double>()); + + // Build the filter input. + // Basically the modelchecking result of "F a" on the used DTMC. + std::vector<double> pathResult = mc.checkEventually(storm::properties::prctl::Eventually<double>(std::make_shared<storm::properties::prctl::Ap<double>>("a")), false); + storm::storage::BitVector stateResult = mc.checkAp(storm::properties::prctl::Ap<double>("c")); + std::vector<uint_fast64_t> stateMap(pathResult.size()); + for(uint_fast64_t i = 0; i < pathResult.size(); i++) { + stateMap[i] = pathResult.size()-i-1; + } + Result input(storm::storage::BitVector(pathResult.size(), true), stateMap, pathResult, stateResult); + Result result; + + storm::properties::action::SortAction<double> action(storm::properties::action::SortAction<double>::VALUE); + ASSERT_NO_THROW(result = action.evaluate(input, mc)); + ASSERT_EQ(6, result.stateMap[0]); + ASSERT_EQ(7, result.stateMap[1]); + ASSERT_EQ(3, result.stateMap[2]); + ASSERT_EQ(4, result.stateMap[3]); + ASSERT_EQ(1, result.stateMap[4]); + ASSERT_EQ(0, result.stateMap[5]); + ASSERT_EQ(2, result.stateMap[6]); + ASSERT_EQ(5, result.stateMap[7]); +} diff --git a/test/functional/modelchecker/EigenDtmcPrctlModelCheckerTest.cpp b/test/functional/modelchecker/EigenDtmcPrctlModelCheckerTest.cpp index 0d36a1d77..8cb8d131d 100644 --- a/test/functional/modelchecker/EigenDtmcPrctlModelCheckerTest.cpp +++ b/test/functional/modelchecker/EigenDtmcPrctlModelCheckerTest.cpp @@ -21,9 +21,9 @@ TEST(EigenDtmcPrctlModelCheckerTest, Die) { storm::modelChecker::EigenDtmcPrctlModelChecker<double> mc(*dtmc); - storm::property::Ap<double>* apFormula = new storm::property::Ap<double>("one"); - storm::property::Eventually<double>* eventuallyFormula = new storm::property::Eventually<double>(apFormula); - storm::property::ProbabilisticNoBoundOperator<double>* probFormula = new storm::property::ProbabilisticNoBoundOperator<double>(eventuallyFormula); + storm::properties::Ap<double>* apFormula = new storm::properties::Ap<double>("one"); + storm::properties::Eventually<double>* eventuallyFormula = new storm::properties::Eventually<double>(apFormula); + storm::properties::ProbabilisticNoBoundOperator<double>* probFormula = new storm::properties::ProbabilisticNoBoundOperator<double>(eventuallyFormula); std::vector<double>* result = probFormula->check(mc); @@ -32,9 +32,9 @@ TEST(EigenDtmcPrctlModelCheckerTest, Die) { delete probFormula; delete result; - apFormula = new storm::property::Ap<double>("two"); - eventuallyFormula = new storm::property::Eventually<double>(apFormula); - probFormula = new storm::property::ProbabilisticNoBoundOperator<double>(eventuallyFormula); + apFormula = new storm::properties::Ap<double>("two"); + eventuallyFormula = new storm::properties::Eventually<double>(apFormula); + probFormula = new storm::properties::ProbabilisticNoBoundOperator<double>(eventuallyFormula); result = probFormula->check(mc); @@ -43,9 +43,9 @@ TEST(EigenDtmcPrctlModelCheckerTest, Die) { delete probFormula; delete result; - apFormula = new storm::property::Ap<double>("three"); - eventuallyFormula = new storm::property::Eventually<double>(apFormula); - probFormula = new storm::property::ProbabilisticNoBoundOperator<double>(eventuallyFormula); + apFormula = new storm::properties::Ap<double>("three"); + eventuallyFormula = new storm::properties::Eventually<double>(apFormula); + probFormula = new storm::properties::ProbabilisticNoBoundOperator<double>(eventuallyFormula); result = probFormula->check(mc); @@ -54,9 +54,9 @@ TEST(EigenDtmcPrctlModelCheckerTest, Die) { delete probFormula; delete result; - storm::property::Ap<double>* done = new storm::property::Ap<double>("done"); - storm::property::ReachabilityReward<double>* reachabilityRewardFormula = new storm::property::ReachabilityReward<double>(done); - storm::property::RewardNoBoundOperator<double>* rewardFormula = new storm::property::RewardNoBoundOperator<double>(reachabilityRewardFormula); + storm::properties::Ap<double>* done = new storm::properties::Ap<double>("done"); + storm::properties::ReachabilityReward<double>* reachabilityRewardFormula = new storm::properties::ReachabilityReward<double>(done); + storm::properties::RewardNoBoundOperator<double>* rewardFormula = new storm::properties::RewardNoBoundOperator<double>(reachabilityRewardFormula); result = rewardFormula->check(mc); @@ -82,9 +82,9 @@ TEST(EigenDtmcPrctlModelCheckerTest, Crowds) { storm::modelChecker::EigenDtmcPrctlModelChecker<double> mc(*dtmc); - storm::property::Ap<double>* apFormula = new storm::property::Ap<double>("observe0Greater1"); - storm::property::Eventually<double>* eventuallyFormula = new storm::property::Eventually<double>(apFormula); - storm::property::ProbabilisticNoBoundOperator<double>* probFormula = new storm::property::ProbabilisticNoBoundOperator<double>(eventuallyFormula); + storm::properties::Ap<double>* apFormula = new storm::properties::Ap<double>("observe0Greater1"); + storm::properties::Eventually<double>* eventuallyFormula = new storm::properties::Eventually<double>(apFormula); + storm::properties::ProbabilisticNoBoundOperator<double>* probFormula = new storm::properties::ProbabilisticNoBoundOperator<double>(eventuallyFormula); std::vector<double>* result = probFormula->check(mc); @@ -93,9 +93,9 @@ TEST(EigenDtmcPrctlModelCheckerTest, Crowds) { delete probFormula; delete result; - apFormula = new storm::property::Ap<double>("observeIGreater1"); - eventuallyFormula = new storm::property::Eventually<double>(apFormula); - probFormula = new storm::property::ProbabilisticNoBoundOperator<double>(eventuallyFormula); + apFormula = new storm::properties::Ap<double>("observeIGreater1"); + eventuallyFormula = new storm::properties::Eventually<double>(apFormula); + probFormula = new storm::properties::ProbabilisticNoBoundOperator<double>(eventuallyFormula); result = probFormula->check(mc); @@ -104,9 +104,9 @@ TEST(EigenDtmcPrctlModelCheckerTest, Crowds) { delete probFormula; delete result; - apFormula = new storm::property::Ap<double>("observeOnlyTrueSender"); - eventuallyFormula = new storm::property::Eventually<double>(apFormula); - probFormula = new storm::property::ProbabilisticNoBoundOperator<double>(eventuallyFormula); + apFormula = new storm::properties::Ap<double>("observeOnlyTrueSender"); + eventuallyFormula = new storm::properties::Eventually<double>(apFormula); + probFormula = new storm::properties::ProbabilisticNoBoundOperator<double>(eventuallyFormula); result = probFormula->check(mc); @@ -131,9 +131,9 @@ TEST(EigenDtmcPrctlModelCheckerTest, SynchronousLeader) { storm::modelChecker::EigenDtmcPrctlModelChecker<double> mc(*dtmc); - storm::property::Ap<double>* apFormula = new storm::property::Ap<double>("elected"); - storm::property::Eventually<double>* eventuallyFormula = new storm::property::Eventually<double>(apFormula); - storm::property::ProbabilisticNoBoundOperator<double>* probFormula = new storm::property::ProbabilisticNoBoundOperator<double>(eventuallyFormula); + storm::properties::Ap<double>* apFormula = new storm::properties::Ap<double>("elected"); + storm::properties::Eventually<double>* eventuallyFormula = new storm::properties::Eventually<double>(apFormula); + storm::properties::ProbabilisticNoBoundOperator<double>* probFormula = new storm::properties::ProbabilisticNoBoundOperator<double>(eventuallyFormula); std::vector<double>* result = probFormula->check(mc); @@ -142,9 +142,9 @@ TEST(EigenDtmcPrctlModelCheckerTest, SynchronousLeader) { delete probFormula; delete result; - apFormula = new storm::property::Ap<double>("elected"); - storm::property::BoundedUntil<double>* boundedUntilFormula = new storm::property::BoundedUntil<double>(new storm::property::Ap<double>("true"), apFormula, 20); - probFormula = new storm::property::ProbabilisticNoBoundOperator<double>(boundedUntilFormula); + apFormula = new storm::properties::Ap<double>("elected"); + storm::properties::BoundedUntil<double>* boundedUntilFormula = new storm::properties::BoundedUntil<double>(new storm::properties::Ap<double>("true"), apFormula, 20); + probFormula = new storm::properties::ProbabilisticNoBoundOperator<double>(boundedUntilFormula); result = probFormula->check(mc); @@ -153,9 +153,9 @@ TEST(EigenDtmcPrctlModelCheckerTest, SynchronousLeader) { delete probFormula; delete result; - apFormula = new storm::property::Ap<double>("elected"); - storm::property::ReachabilityReward<double>* reachabilityRewardFormula = new storm::property::ReachabilityReward<double>(apFormula); - storm::property::RewardNoBoundOperator<double>* rewardFormula = new storm::property::RewardNoBoundOperator<double>(reachabilityRewardFormula); + apFormula = new storm::properties::Ap<double>("elected"); + storm::properties::ReachabilityReward<double>* reachabilityRewardFormula = new storm::properties::ReachabilityReward<double>(apFormula); + storm::properties::RewardNoBoundOperator<double>* rewardFormula = new storm::properties::RewardNoBoundOperator<double>(reachabilityRewardFormula); result = rewardFormula->check(mc); diff --git a/test/functional/modelchecker/FilterTest.cpp b/test/functional/modelchecker/FilterTest.cpp new file mode 100644 index 000000000..f85382bbb --- /dev/null +++ b/test/functional/modelchecker/FilterTest.cpp @@ -0,0 +1,360 @@ +/* + * FilterTest.cpp + * + * Created on: Aug 6, 2014 + * Author: Manuel Sascha Weiand + */ + +#include "gtest/gtest.h" +#include "storm-config.h" +#include "src/models/Dtmc.h" +#include "src/parser/DeterministicModelParser.h" +#include "src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h" +#include "src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h" +#include "src/solver/GmmxxLinearEquationSolver.h" +#include "src/solver/GmmxxNondeterministicLinearEquationSolver.h" +#include "src/properties/prctl/PrctlFilter.h" +#include "src/properties/csl/CslFilter.h" +#include "src/properties/ltl/LtlFilter.h" +#include "src/parser/PrctlParser.h" +#include "src/parser/CslParser.h" +#include "src/parser/MarkovAutomatonParser.h" +#include "src/properties/actions/InvertAction.h" + +#include <memory> + +typedef typename storm::properties::action::AbstractAction<double>::Result Result; + +TEST(PrctlFilterTest, generalFunctionality) { + // Test filter queries of increasing complexity. + + // Setup model and modelchecker. + storm::models::Dtmc<double> model = storm::parser::DeterministicModelParser::parseDtmc(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_actionTest.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/dtmc_actionTest.lab"); + storm::modelchecker::prctl::SparseDtmcPrctlModelChecker<double> mc(model, new storm::solver::GmmxxLinearEquationSolver<double>()); + + // Find the best valued state to finally reach a 'b' state. + std::string input = "filter[sort(value, descending); range(0,0)](F b)"; + std::shared_ptr<storm::properties::prctl::PrctlFilter<double>> formula(nullptr); + ASSERT_NO_THROW( + formula = storm::parser::PrctlParser::parsePrctlFormula(input) + ); + + // Here we test if the check method gives the correct result. + // To capture the output, redirect cout and test the written buffer content. + std::stringstream buffer; + std::streambuf *sbuf = std::cout.rdbuf(); + std::cout.rdbuf(buffer.rdbuf()); + + formula->check(mc); + + // Reset cout to the original buffer. + std::cout.rdbuf(sbuf); + + std::string output = buffer.str(); + ASSERT_NE(std::string::npos, output.find("\t6: 1")); + + // The remaining queries use evaluate directly as its easier to work with in a test environment. + // Get the probability to reach a b state for all states but those that cannot reach a 'b' state or are 'b' states themselves. + // Sorted by value; highest first. + input = "filter[formula(P<=0(F b) | b); invert; sort(value, desc)](F b)"; + ASSERT_NO_THROW( + formula = storm::parser::PrctlParser::parsePrctlFormula(input) + ); + + Result result = formula->evaluate(mc); + + // Test the selection. + ASSERT_EQ(5, result.selection.getNumberOfSetBits()); + ASSERT_TRUE(result.selection[0]); + ASSERT_TRUE(result.selection[1]); + ASSERT_TRUE(result.selection[2]); + ASSERT_TRUE(result.selection[3]); + ASSERT_TRUE(result.selection[4]); + ASSERT_FALSE(result.selection[5]); + ASSERT_FALSE(result.selection[6]); + ASSERT_FALSE(result.selection[7]); + + // Test the sorting. + ASSERT_EQ(6, result.stateMap[0]); + ASSERT_EQ(7, result.stateMap[1]); + ASSERT_EQ(3, result.stateMap[2]); + ASSERT_EQ(4, result.stateMap[3]); + ASSERT_EQ(1, result.stateMap[4]); + ASSERT_EQ(0, result.stateMap[5]); + ASSERT_EQ(2, result.stateMap[6]); + ASSERT_EQ(5, result.stateMap[7]); + + // Get the probability for reaching a 'd' state only for those states that have a probability to do so of at most 0.5. + // Sorted by value; lowest first. + input = "filter[bound(<, 0.5); sort(value, ascending)](F d)"; + ASSERT_NO_THROW( + formula = storm::parser::PrctlParser::parsePrctlFormula(input) + ); + + result = formula->evaluate(mc); + + // Test the selection. + ASSERT_EQ(4, result.selection.getNumberOfSetBits()); + ASSERT_FALSE(result.selection[0]); + ASSERT_FALSE(result.selection[1]); + ASSERT_FALSE(result.selection[2]); + ASSERT_TRUE(result.selection[3]); + ASSERT_FALSE(result.selection[4]); + ASSERT_TRUE(result.selection[5]); + ASSERT_TRUE(result.selection[6]); + ASSERT_TRUE(result.selection[7]); + + // Test the sorting. + ASSERT_EQ(5, result.stateMap[0]); + ASSERT_EQ(6, result.stateMap[1]); + ASSERT_EQ(7, result.stateMap[2]); + ASSERT_EQ(3, result.stateMap[3]); + ASSERT_EQ(4, result.stateMap[4]); + ASSERT_EQ(1, result.stateMap[5]); + ASSERT_EQ(0, result.stateMap[6]); + ASSERT_EQ(2, result.stateMap[7]); + + // Get the three highest indexed states reaching an 'a' state with probability at most 0.3. + input = "filter[sort(value); range(5,7); sort(index, descending)](P<=0.3(F a))"; + ASSERT_NO_THROW( + formula = storm::parser::PrctlParser::parsePrctlFormula(input) + ); + + result = formula->evaluate(mc); + + // Test the selection. + ASSERT_EQ(3, result.selection.getNumberOfSetBits()); + ASSERT_FALSE(result.selection[0]); + ASSERT_FALSE(result.selection[1]); + ASSERT_FALSE(result.selection[2]); + ASSERT_TRUE(result.selection[3]); + ASSERT_FALSE(result.selection[4]); + ASSERT_FALSE(result.selection[5]); + ASSERT_TRUE(result.selection[6]); + ASSERT_TRUE(result.selection[7]); + + // Test the sorting. + ASSERT_EQ(7, result.stateMap[0]); + ASSERT_EQ(6, result.stateMap[1]); + ASSERT_EQ(5, result.stateMap[2]); + ASSERT_EQ(4, result.stateMap[3]); + ASSERT_EQ(3, result.stateMap[4]); + ASSERT_EQ(2, result.stateMap[5]); + ASSERT_EQ(1, result.stateMap[6]); + ASSERT_EQ(0, result.stateMap[7]); + +} + +TEST(PrctlFilterTest, Safety) { + // Setup model and modelchecker. + storm::models::Dtmc<double> model = storm::parser::DeterministicModelParser::parseDtmc(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_actionTest.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/dtmc_actionTest.lab"); + storm::modelchecker::prctl::SparseDtmcPrctlModelChecker<double> mc(model, new storm::solver::GmmxxLinearEquationSolver<double>()); + + // Make a stub formula as child. + auto apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("a"); + + // Test the filter for nullptr action handling. + auto formula = std::make_shared<storm::properties::prctl::PrctlFilter<double>>(apFormula, nullptr); + + ASSERT_EQ(0, formula->getActionCount()); + ASSERT_NO_THROW(formula->evaluate(mc)); + + // Repeat with vector containing only one action but three nullptr. + std::vector<std::shared_ptr<storm::properties::action::AbstractAction<double>>> actions(4, nullptr); + actions[1] = std::make_shared<storm::properties::action::InvertAction<double>>(); + + formula = std::make_shared<storm::properties::prctl::PrctlFilter<double>>(apFormula, actions); + + ASSERT_EQ(1, formula->getActionCount()); + ASSERT_NO_THROW(formula->evaluate(mc)); + + // Test the filter for nullptr child formula handling. + // It sholud not write anything to the standard out and return an empty result. + formula = std::make_shared<storm::properties::prctl::PrctlFilter<double>>(); + Result result; + + // To capture the output, redirect cout and test the written buffer content. + std::stringstream buffer; + std::streambuf *sbuf = std::cout.rdbuf(); + std::cout.rdbuf(buffer.rdbuf()); + + ASSERT_NO_THROW(result = formula->evaluate(mc)); + + // Reset cout to the original buffer. + std::cout.rdbuf(sbuf); + + ASSERT_EQ(0, buffer.str().length()); + + ASSERT_EQ(0, result.pathResult.size()); + ASSERT_EQ(0, result.stateResult.size()); + ASSERT_EQ(0, result.selection.size()); + ASSERT_EQ(0, result.stateMap.size()); +} + +TEST(CslFilterTest, generalFunctionality) { + // Test filter queries of increasing complexity. + + // Setup model and modelchecker. + storm::models::MarkovAutomaton<double> model = storm::parser::MarkovAutomatonParser::parseMarkovAutomaton(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/ma_cslFilterTest.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/ma_cslFilterTest.lab"); + storm::modelchecker::csl::SparseMarkovAutomatonCslModelChecker<double> mc(model, std::make_shared<storm::solver::GmmxxNondeterministicLinearEquationSolver<double>>()); + + // Find the best valued state to finally reach a 'r1' state. + std::string input = "filter[max; sort(value, descending); range(0,0)](F r1)"; + std::shared_ptr<storm::properties::csl::CslFilter<double>> formula(nullptr); + ASSERT_NO_THROW( + formula = storm::parser::CslParser::parseCslFormula(input) + ); + + + // Here we test if the check method gives the correct result. + // To capture the output, redirect cout and test the written buffer content. + std::stringstream buffer; + std::streambuf *sbuf = std::cout.rdbuf(); + std::cout.rdbuf(buffer.rdbuf()); + + formula->check(mc); + + // Reset cout to the original buffer. + std::cout.rdbuf(sbuf); + + std::string output = buffer.str(); + ASSERT_NE(std::string::npos, output.find("\t6: 1")); + + // The remaining queries use evaluate directly as its easier to work with in a test environment. + // Get the maximum probability to reach an 'r1' state for all states but those that cannot reach an 'r1' state or are 'r1' states themselves. + // Sorted by value; highest first. + input = "filter[max; formula(P<=0(F r1) | r1); invert; sort(value, desc)](F r1)"; + ASSERT_NO_THROW( + formula = storm::parser::CslParser::parseCslFormula(input) + ); + + Result result = formula->evaluate(mc); + + // Test the selection. + ASSERT_EQ(6, result.selection.getNumberOfSetBits()); + ASSERT_TRUE(result.selection[0]); + ASSERT_TRUE(result.selection[1]); + ASSERT_TRUE(result.selection[2]); + ASSERT_TRUE(result.selection[3]); + ASSERT_TRUE(result.selection[4]); + ASSERT_TRUE(result.selection[5]); + ASSERT_FALSE(result.selection[6]); + ASSERT_FALSE(result.selection[7]); + + // Test the sorting. + ASSERT_EQ(6, result.stateMap[0]); + ASSERT_EQ(5, result.stateMap[1]); + ASSERT_EQ(2, result.stateMap[2]); + ASSERT_EQ(3, result.stateMap[3]); + ASSERT_EQ(0, result.stateMap[4]); + ASSERT_EQ(4, result.stateMap[5]); + ASSERT_EQ(1, result.stateMap[6]); + ASSERT_EQ(7, result.stateMap[7]); + + // Get the minimum probability for reaching an 'err' state only for those states that have a probability to do so of at most 0.2. + // Sorted by value; lowest first. + input = "filter[min; bound(<, 0.2); sort(value, ascending)](F err)"; + ASSERT_NO_THROW( + formula = storm::parser::CslParser::parseCslFormula(input) + ); + + result = formula->evaluate(mc); + + // Test the selection. + ASSERT_EQ(5, result.selection.getNumberOfSetBits()); + ASSERT_FALSE(result.selection[0]); + ASSERT_TRUE(result.selection[1]); + ASSERT_FALSE(result.selection[2]); + ASSERT_FALSE(result.selection[3]); + ASSERT_TRUE(result.selection[4]); + ASSERT_TRUE(result.selection[5]); + ASSERT_TRUE(result.selection[6]); + ASSERT_TRUE(result.selection[7]); + + // Test the sorting. + ASSERT_EQ(6, result.stateMap[0]); + ASSERT_EQ(7, result.stateMap[1]); + ASSERT_EQ(5, result.stateMap[2]); + ASSERT_EQ(4, result.stateMap[3]); + ASSERT_EQ(1, result.stateMap[4]); + ASSERT_EQ(0, result.stateMap[5]); + ASSERT_EQ(2, result.stateMap[6]); + ASSERT_EQ(3, result.stateMap[7]); + + // Get the three highest indexed states reaching an 'r2' state with probability at most 0.3. + input = "filter[sort(value); range(5,7); sort(index, descending)](P<=0.3(F r2))"; + ASSERT_NO_THROW( + formula = storm::parser::CslParser::parseCslFormula(input) + ); + + result = formula->evaluate(mc); + + // Test the selection. + ASSERT_EQ(3, result.selection.getNumberOfSetBits()); + ASSERT_FALSE(result.selection[0]); + ASSERT_FALSE(result.selection[1]); + ASSERT_FALSE(result.selection[2]); + ASSERT_TRUE(result.selection[3]); + ASSERT_FALSE(result.selection[4]); + ASSERT_TRUE(result.selection[5]); + ASSERT_TRUE(result.selection[6]); + ASSERT_FALSE(result.selection[7]); + + // Test the sorting. + ASSERT_EQ(7, result.stateMap[0]); + ASSERT_EQ(6, result.stateMap[1]); + ASSERT_EQ(5, result.stateMap[2]); + ASSERT_EQ(4, result.stateMap[3]); + ASSERT_EQ(3, result.stateMap[4]); + ASSERT_EQ(2, result.stateMap[5]); + ASSERT_EQ(1, result.stateMap[6]); + ASSERT_EQ(0, result.stateMap[7]); +} + +TEST(CslFilterTest, Safety) { + // Setup model and modelchecker. + storm::models::MarkovAutomaton<double> model = storm::parser::MarkovAutomatonParser::parseMarkovAutomaton(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/ma_cslFilterTest.tra", STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/ma_cslFilterTest.lab"); + storm::modelchecker::csl::SparseMarkovAutomatonCslModelChecker<double> mc(model, std::make_shared<storm::solver::GmmxxNondeterministicLinearEquationSolver<double>>()); + + // Make a stub formula as child. + auto apFormula = std::make_shared<storm::properties::csl::Ap<double>>("r1"); + + // Test the filter for nullptr action handling. + auto formula = std::make_shared<storm::properties::csl::CslFilter<double>>(apFormula, nullptr, storm::properties::MAXIMIZE); + + ASSERT_NO_THROW(formula->evaluate(mc)); + ASSERT_EQ(0, formula->getActionCount()); + + // Repeat with vector containing only one action but three nullptr. + std::vector<std::shared_ptr<storm::properties::action::AbstractAction<double>>> actions(4, nullptr); + actions[1] = std::make_shared<storm::properties::action::InvertAction<double>>(); + + formula = std::make_shared<storm::properties::csl::CslFilter<double>>(apFormula, actions, storm::properties::MAXIMIZE); + + ASSERT_EQ(1, formula->getActionCount()); + ASSERT_NO_THROW(formula->evaluate(mc)); + + // Test the filter for nullptr child formula handling. + // It sholud not write anything to the standard out and return an empty result. + formula = std::make_shared<storm::properties::csl::CslFilter<double>>(); + Result result; + + // To capture the output, redirect cout and test the written buffer content. + std::stringstream buffer; + std::streambuf *sbuf = std::cout.rdbuf(); + std::cout.rdbuf(buffer.rdbuf()); + + ASSERT_NO_THROW(result = formula->evaluate(mc)); + + // Reset cout to the original buffer. + std::cout.rdbuf(sbuf); + + ASSERT_EQ(0, buffer.str().length()); + + ASSERT_EQ(0, result.pathResult.size()); + ASSERT_EQ(0, result.stateResult.size()); + ASSERT_EQ(0, result.selection.size()); + ASSERT_EQ(0, result.stateMap.size()); +} + +// TODO Set up the LtlFilterTest once an Ltl modelchecker has been implemented. diff --git a/test/functional/modelchecker/GmmxxDtmcPrctlModelCheckerTest.cpp b/test/functional/modelchecker/GmmxxDtmcPrctlModelCheckerTest.cpp index dc2d6d703..8de0d05f6 100644 --- a/test/functional/modelchecker/GmmxxDtmcPrctlModelCheckerTest.cpp +++ b/test/functional/modelchecker/GmmxxDtmcPrctlModelCheckerTest.cpp @@ -22,45 +22,33 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, Die) { storm::modelchecker::prctl::SparseDtmcPrctlModelChecker<double> mc(*dtmc, new storm::solver::GmmxxLinearEquationSolver<double>()); - storm::property::prctl::Ap<double>* apFormula = new storm::property::prctl::Ap<double>("one"); - storm::property::prctl::Eventually<double>* eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); - storm::property::prctl::ProbabilisticNoBoundOperator<double>* probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula); + auto apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("one"); + auto eventuallyFormula = std::make_shared<storm::properties::prctl::Eventually<double>>(apFormula); - std::vector<double> result = probFormula->check(mc); + std::vector<double> result = eventuallyFormula->check(mc, false); ASSERT_LT(std::abs(result[0] - ((double)1.0/6.0)), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; + apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("two"); + eventuallyFormula = std::make_shared<storm::properties::prctl::Eventually<double>>(apFormula); - apFormula = new storm::property::prctl::Ap<double>("two"); - eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); - probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula); - - result = probFormula->check(mc); + result = eventuallyFormula->check(mc, false); ASSERT_LT(std::abs(result[0] - ((double)1.0/6.0)), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; - - apFormula = new storm::property::prctl::Ap<double>("three"); - eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); - probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula); + apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("three"); + eventuallyFormula = std::make_shared<storm::properties::prctl::Eventually<double>>(apFormula); - result = probFormula->check(mc); + result = eventuallyFormula->check(mc, false); ASSERT_LT(std::abs(result[0] - ((double)1.0/6.0)), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; - - storm::property::prctl::Ap<double>* done = new storm::property::prctl::Ap<double>("done"); - storm::property::prctl::ReachabilityReward<double>* reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward<double>(done); - storm::property::prctl::RewardNoBoundOperator<double>* rewardFormula = new storm::property::prctl::RewardNoBoundOperator<double>(reachabilityRewardFormula); + auto done = std::make_shared<storm::properties::prctl::Ap<double>>("done"); + auto reachabilityRewardFormula = std::make_shared<storm::properties::prctl::ReachabilityReward<double>>(done); - result = rewardFormula->check(mc); + result = reachabilityRewardFormula->check(mc, false); ASSERT_LT(std::abs(result[0] - ((double)11/3)), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - - delete rewardFormula; } TEST(GmmxxDtmcPrctlModelCheckerTest, Crowds) { @@ -73,40 +61,31 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, Crowds) { std::shared_ptr<storm::models::Dtmc<double>> dtmc = abstractModel->as<storm::models::Dtmc<double>>(); - ASSERT_EQ(dtmc->getNumberOfStates(), 8607ull); - ASSERT_EQ(dtmc->getNumberOfTransitions(), 15113ull); + ASSERT_EQ(8607ull, dtmc->getNumberOfStates()); + ASSERT_EQ(15113ull, dtmc->getNumberOfTransitions()); storm::modelchecker::prctl::SparseDtmcPrctlModelChecker<double> mc(*dtmc, new storm::solver::GmmxxLinearEquationSolver<double>()); - storm::property::prctl::Ap<double>* apFormula = new storm::property::prctl::Ap<double>("observe0Greater1"); - storm::property::prctl::Eventually<double>* eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); - storm::property::prctl::ProbabilisticNoBoundOperator<double>* probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula); + auto apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("observe0Greater1"); + auto eventuallyFormula = std::make_shared<storm::properties::prctl::Eventually<double>>(apFormula); - std::vector<double> result = probFormula->check(mc); + std::vector<double> result = eventuallyFormula->check(mc, false); ASSERT_LT(std::abs(result[0] - 0.3328800375801578281), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; - - apFormula = new storm::property::prctl::Ap<double>("observeIGreater1"); - eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); - probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula); + apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("observeIGreater1"); + eventuallyFormula = std::make_shared<storm::properties::prctl::Eventually<double>>(apFormula); - result = probFormula->check(mc); + result = eventuallyFormula->check(mc, false); ASSERT_LT(std::abs(result[0] - 0.1522194965), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; + apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("observeOnlyTrueSender"); + eventuallyFormula = std::make_shared<storm::properties::prctl::Eventually<double>>(apFormula); - apFormula = new storm::property::prctl::Ap<double>("observeOnlyTrueSender"); - eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); - probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula); - - result = probFormula->check(mc); + result = eventuallyFormula->check(mc, false); ASSERT_LT(std::abs(result[0] - 0.32153724292835045), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - - delete probFormula; } TEST(GmmxxDtmcPrctlModelCheckerTest, SynchronousLeader) { @@ -118,38 +97,29 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, SynchronousLeader) { ASSERT_EQ(abstractModel->getType(), storm::models::DTMC); std::shared_ptr<storm::models::Dtmc<double>> dtmc = abstractModel->as<storm::models::Dtmc<double>>(); - ASSERT_EQ(dtmc->getNumberOfStates(), 12400ull); - ASSERT_EQ(dtmc->getNumberOfTransitions(), 16495ull); + ASSERT_EQ(12400ull, dtmc->getNumberOfStates()); + ASSERT_EQ(16495ull, dtmc->getNumberOfTransitions()); storm::modelchecker::prctl::SparseDtmcPrctlModelChecker<double> mc(*dtmc, new storm::solver::GmmxxLinearEquationSolver<double>()); - storm::property::prctl::Ap<double>* apFormula = new storm::property::prctl::Ap<double>("elected"); - storm::property::prctl::Eventually<double>* eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); - storm::property::prctl::ProbabilisticNoBoundOperator<double>* probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula); + auto apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("elected"); + auto eventuallyFormula = std::make_shared<storm::properties::prctl::Eventually<double>>(apFormula); - std::vector<double> result = probFormula->check(mc); + std::vector<double> result = eventuallyFormula->check(mc, false); ASSERT_LT(std::abs(result[0] - 1.0), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; - - apFormula = new storm::property::prctl::Ap<double>("elected"); - storm::property::prctl::BoundedUntil<double>* boundedUntilFormula = new storm::property::prctl::BoundedUntil<double>(new storm::property::prctl::Ap<double>("true"), apFormula, 20); - probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(boundedUntilFormula); + apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("elected"); + auto boundedUntilFormula = std::make_shared<storm::properties::prctl::BoundedUntil<double>>(std::make_shared<storm::properties::prctl::Ap<double>>("true"), apFormula, 20); - result = probFormula->check(mc); + result = boundedUntilFormula->check(mc, false); ASSERT_LT(std::abs(result[0] - 0.9999965911265462636), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; + apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("elected"); + auto reachabilityRewardFormula = std::make_shared<storm::properties::prctl::ReachabilityReward<double>>(apFormula); - apFormula = new storm::property::prctl::Ap<double>("elected"); - storm::property::prctl::ReachabilityReward<double>* reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward<double>(apFormula); - storm::property::prctl::RewardNoBoundOperator<double>* rewardFormula = new storm::property::prctl::RewardNoBoundOperator<double>(reachabilityRewardFormula); - - result = rewardFormula->check(mc); + result = reachabilityRewardFormula->check(mc, false); ASSERT_LT(std::abs(result[0] - 1.044879046), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - - delete rewardFormula; } diff --git a/test/functional/modelchecker/SparseMdpPrctlModelCheckerTest.cpp b/test/functional/modelchecker/SparseMdpPrctlModelCheckerTest.cpp index 67fe2d63a..0cb31fcec 100644 --- a/test/functional/modelchecker/SparseMdpPrctlModelCheckerTest.cpp +++ b/test/functional/modelchecker/SparseMdpPrctlModelCheckerTest.cpp @@ -19,83 +19,49 @@ TEST(SparseMdpPrctlModelCheckerTest, Dice) { storm::modelchecker::prctl::SparseMdpPrctlModelChecker<double> mc(*mdp, std::shared_ptr<storm::solver::NativeNondeterministicLinearEquationSolver<double>>(new storm::solver::NativeNondeterministicLinearEquationSolver<double>())); - storm::property::prctl::Ap<double>* apFormula = new storm::property::prctl::Ap<double>("two"); - storm::property::prctl::Eventually<double>* eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); - storm::property::prctl::ProbabilisticNoBoundOperator<double>* probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula, true); + auto apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("two"); + auto eventuallyFormula = std::make_shared<storm::properties::prctl::Eventually<double>>(apFormula); - std::vector<double> result = mc.checkNoBoundOperator(*probFormula); + std::vector<double> result = mc.checkOptimizingOperator(*eventuallyFormula, true); ASSERT_LT(std::abs(result[0] - 0.0277777612209320068), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; - - apFormula = new storm::property::prctl::Ap<double>("two"); - eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); - probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula, false); - - result = mc.checkNoBoundOperator(*probFormula); - + result = mc.checkOptimizingOperator(*eventuallyFormula, false); + ASSERT_LT(std::abs(result[0] - 0.0277777612209320068), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; - - apFormula = new storm::property::prctl::Ap<double>("three"); - eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); - probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula, true); + apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("three"); + eventuallyFormula = std::make_shared<storm::properties::prctl::Eventually<double>>(apFormula); - result = mc.checkNoBoundOperator(*probFormula); + result = mc.checkOptimizingOperator(*eventuallyFormula, true); ASSERT_LT(std::abs(result[0] - 0.0555555224418640136), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; - - apFormula = new storm::property::prctl::Ap<double>("three"); - eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); - probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula, false); - - result = mc.checkNoBoundOperator(*probFormula); - + result = mc.checkOptimizingOperator(*eventuallyFormula, false); + ASSERT_LT(std::abs(result[0] - 0.0555555224418640136), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; + apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("four"); + eventuallyFormula = std::make_shared<storm::properties::prctl::Eventually<double>>(apFormula); - apFormula = new storm::property::prctl::Ap<double>("four"); - eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); - probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula, true); - - result = mc.checkNoBoundOperator(*probFormula); + result = mc.checkOptimizingOperator(*eventuallyFormula, true); ASSERT_LT(std::abs(result[0] - 0.083333283662796020508), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - - delete probFormula; - - apFormula = new storm::property::prctl::Ap<double>("four"); - eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); - probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula, false); - - result = mc.checkNoBoundOperator(*probFormula); + + result = mc.checkOptimizingOperator(*eventuallyFormula, false); ASSERT_LT(std::abs(result[0] - 0.083333283662796020508), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - - delete probFormula; - - apFormula = new storm::property::prctl::Ap<double>("done"); - storm::property::prctl::ReachabilityReward<double>* reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward<double>(apFormula); - storm::property::prctl::RewardNoBoundOperator<double>* rewardFormula = new storm::property::prctl::RewardNoBoundOperator<double>(reachabilityRewardFormula, true); - - result = mc.checkNoBoundOperator(*rewardFormula); - + + apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("done"); + auto reachabilityRewardFormula = std::make_shared<storm::properties::prctl::ReachabilityReward<double>>(apFormula); + + result = mc.checkOptimizingOperator(*reachabilityRewardFormula, true); + ASSERT_LT(std::abs(result[0] - 7.333329499), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete rewardFormula; - - apFormula = new storm::property::prctl::Ap<double>("done"); - reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward<double>(apFormula); - rewardFormula = new storm::property::prctl::RewardNoBoundOperator<double>(reachabilityRewardFormula, false); - - result = mc.checkNoBoundOperator(*rewardFormula);; - + + result = mc.checkOptimizingOperator(*reachabilityRewardFormula, false); + ASSERT_LT(std::abs(result[0] - 7.333329499), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete rewardFormula; abstractModel = storm::parser::AutoParser::parseModel(STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.tra", STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.lab", STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.flip.state.rew", ""); @@ -105,23 +71,16 @@ TEST(SparseMdpPrctlModelCheckerTest, Dice) { storm::modelchecker::prctl::SparseMdpPrctlModelChecker<double> stateRewardModelChecker(*stateRewardMdp, std::shared_ptr<storm::solver::NativeNondeterministicLinearEquationSolver<double>>(new storm::solver::NativeNondeterministicLinearEquationSolver<double>())); - apFormula = new storm::property::prctl::Ap<double>("done"); - reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward<double>(apFormula); - rewardFormula = new storm::property::prctl::RewardNoBoundOperator<double>(reachabilityRewardFormula, true); - - result = stateRewardModelChecker.checkNoBoundOperator(*rewardFormula); + apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("done"); + reachabilityRewardFormula = std::make_shared<storm::properties::prctl::ReachabilityReward<double>>(apFormula); + + result = stateRewardModelChecker.checkOptimizingOperator(*reachabilityRewardFormula, true); ASSERT_LT(std::abs(result[0] - 7.333329499), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete rewardFormula; - - apFormula = new storm::property::prctl::Ap<double>("done"); - reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward<double>(apFormula); - rewardFormula = new storm::property::prctl::RewardNoBoundOperator<double>(reachabilityRewardFormula, false); - - result = stateRewardModelChecker.checkNoBoundOperator(*rewardFormula); - + + result = stateRewardModelChecker.checkOptimizingOperator(*reachabilityRewardFormula, false); + ASSERT_LT(std::abs(result[0] - 7.333329499), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete rewardFormula; abstractModel = storm::parser::AutoParser::parseModel(STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.tra", STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.lab", STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.flip.state.rew", STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.flip.trans.rew"); @@ -131,93 +90,61 @@ TEST(SparseMdpPrctlModelCheckerTest, Dice) { storm::modelchecker::prctl::SparseMdpPrctlModelChecker<double> stateAndTransitionRewardModelChecker(*stateAndTransitionRewardMdp, std::shared_ptr<storm::solver::NativeNondeterministicLinearEquationSolver<double>>(new storm::solver::NativeNondeterministicLinearEquationSolver<double>())); - apFormula = new storm::property::prctl::Ap<double>("done"); - reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward<double>(apFormula); - rewardFormula = new storm::property::prctl::RewardNoBoundOperator<double>(reachabilityRewardFormula, true); + apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("done"); + reachabilityRewardFormula = std::make_shared<storm::properties::prctl::ReachabilityReward<double>>(apFormula); - result = stateAndTransitionRewardModelChecker.checkNoBoundOperator(*rewardFormula); + result = stateAndTransitionRewardModelChecker.checkOptimizingOperator(*reachabilityRewardFormula, true); ASSERT_LT(std::abs(result[0] - 14.666658998), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete rewardFormula; - - apFormula = new storm::property::prctl::Ap<double>("done"); - reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward<double>(apFormula); - rewardFormula = new storm::property::prctl::RewardNoBoundOperator<double>(reachabilityRewardFormula, false); - - result = stateAndTransitionRewardModelChecker.checkNoBoundOperator(*rewardFormula); - + + result = stateAndTransitionRewardModelChecker.checkOptimizingOperator(*reachabilityRewardFormula, false); + ASSERT_LT(std::abs(result[0] - 14.666658998), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete rewardFormula; } TEST(SparseMdpPrctlModelCheckerTest, AsynchronousLeader) { storm::settings::Settings* s = storm::settings::Settings::getInstance(); std::shared_ptr<storm::models::AbstractModel<double>> abstractModel = storm::parser::AutoParser::parseModel(STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader4.tra", STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader4.lab", "", STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader4.trans.rew"); - ASSERT_EQ(abstractModel->getType(), storm::models::MDP); + ASSERT_EQ(storm::models::MDP, abstractModel->getType()); std::shared_ptr<storm::models::Mdp<double>> mdp = abstractModel->as<storm::models::Mdp<double>>(); - ASSERT_EQ(mdp->getNumberOfStates(), 3172ull); - ASSERT_EQ(mdp->getNumberOfTransitions(), 7144ull); + ASSERT_EQ(3172ull, mdp->getNumberOfStates()); + ASSERT_EQ(7144ull, mdp->getNumberOfTransitions()); storm::modelchecker::prctl::SparseMdpPrctlModelChecker<double> mc(*mdp, std::shared_ptr<storm::solver::NativeNondeterministicLinearEquationSolver<double>>(new storm::solver::NativeNondeterministicLinearEquationSolver<double>())); - storm::property::prctl::Ap<double>* apFormula = new storm::property::prctl::Ap<double>("elected"); - storm::property::prctl::Eventually<double>* eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); - storm::property::prctl::ProbabilisticNoBoundOperator<double>* probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula, true); + auto apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("elected"); + auto eventuallyFormula = std::make_shared<storm::properties::prctl::Eventually<double>>(apFormula); - std::vector<double> result = mc.checkNoBoundOperator(*probFormula); + std::vector<double> result = mc.checkOptimizingOperator(*eventuallyFormula, true); ASSERT_LT(std::abs(result[0] - 1), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; - - apFormula = new storm::property::prctl::Ap<double>("elected"); - eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); - probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula, false); - - result = mc.checkNoBoundOperator(*probFormula); + result = mc.checkOptimizingOperator(*eventuallyFormula, false); ASSERT_LT(std::abs(result[0] - 1), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; + apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("elected"); + auto boundedEventuallyFormula = std::make_shared<storm::properties::prctl::BoundedEventually<double>>(apFormula, 25); - apFormula = new storm::property::prctl::Ap<double>("elected"); - storm::property::prctl::BoundedEventually<double>* boundedEventuallyFormula = new storm::property::prctl::BoundedEventually<double>(apFormula, 25); - probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(boundedEventuallyFormula, false); - - result = mc.checkNoBoundOperator(*probFormula); + result = mc.checkOptimizingOperator(*boundedEventuallyFormula, true); ASSERT_LT(std::abs(result[0] - 0.0625), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; - - apFormula = new storm::property::prctl::Ap<double>("elected"); - boundedEventuallyFormula = new storm::property::prctl::BoundedEventually<double>(apFormula, 25); - probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(boundedEventuallyFormula, true); - - result = mc.checkNoBoundOperator(*probFormula); + result = mc.checkOptimizingOperator(*boundedEventuallyFormula, false); ASSERT_LT(std::abs(result[0] - 0.0625), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; + apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("elected"); + auto reachabilityRewardFormula = std::make_shared<storm::properties::prctl::ReachabilityReward<double>>(apFormula); - apFormula = new storm::property::prctl::Ap<double>("elected"); - storm::property::prctl::ReachabilityReward<double>* reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward<double>(apFormula); - storm::property::prctl::RewardNoBoundOperator<double>* rewardFormula = new storm::property::prctl::RewardNoBoundOperator<double>(reachabilityRewardFormula, true); - - result = mc.checkNoBoundOperator(*rewardFormula);; + result = mc.checkOptimizingOperator(*reachabilityRewardFormula, true); ASSERT_LT(std::abs(result[0] - 4.285689611), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete rewardFormula; - - apFormula = new storm::property::prctl::Ap<double>("elected"); - reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward<double>(apFormula); - rewardFormula = new storm::property::prctl::RewardNoBoundOperator<double>(reachabilityRewardFormula, false); - result = mc.checkNoBoundOperator(*rewardFormula);; + result = mc.checkOptimizingOperator(*reachabilityRewardFormula, false); ASSERT_LT(std::abs(result[0] - 4.285689611), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete rewardFormula; } diff --git a/test/functional/parser/CslParserTest.cpp b/test/functional/parser/CslParserTest.cpp index 4e4a67af9..42b805ac4 100644 --- a/test/functional/parser/CslParserTest.cpp +++ b/test/functional/parser/CslParserTest.cpp @@ -9,132 +9,251 @@ #include "storm-config.h" #include "src/parser/CslParser.h" #include "src/exceptions/WrongFormatException.h" +#include "src/properties/actions/FormulaAction.h" +#include "src/properties/actions/InvertAction.h" +#include "src/properties/actions/SortAction.h" +#include "src/properties/actions/RangeAction.h" +#include "src/properties/actions/BoundAction.h" + +namespace csl = storm::properties::csl; TEST(CslParserTest, parseApOnlyTest) { - std::string formula = "ap"; - storm::property::csl::AbstractCslFormula<double>* cslFormula = nullptr; + std::string input = "ap"; + std::shared_ptr<csl::CslFilter<double>> formula(nullptr); ASSERT_NO_THROW( - cslFormula = storm::parser::CslParser(formula); + formula = storm::parser::CslParser::parseCslFormula(input); ); - ASSERT_NE(cslFormula, nullptr); - ASSERT_EQ(cslFormula->toString(), formula); + // The parser did not falsely recognize the input as a comment. + ASSERT_NE(formula.get(), nullptr); + + ASSERT_TRUE(formula->getChild()->isPropositional()); + ASSERT_FALSE(formula->getChild()->isProbEventuallyAP()); - delete cslFormula; + // The input was parsed correctly. + ASSERT_EQ(input, formula->toString()); } TEST(CslParserTest, parsePropositionalFormulaTest) { - std::string formula = "!(a & b) | a & ! c"; - storm::property::csl::AbstractCslFormula<double>* cslFormula = nullptr; + std::string input = "!(a & b) | a & ! c"; + std::shared_ptr<csl::CslFilter<double>> formula(nullptr); ASSERT_NO_THROW( - cslFormula = storm::parser::CslParser(formula); + formula = storm::parser::CslParser::parseCslFormula(input); ); - ASSERT_NE(cslFormula, nullptr); - ASSERT_EQ(cslFormula->toString(), "(!(a & b) | (a & !c))"); + // The parser did not falsely recognize the input as a comment. + ASSERT_NE(formula.get(), nullptr); + + ASSERT_TRUE(formula->getChild()->isPropositional()); + ASSERT_FALSE(formula->getChild()->isProbEventuallyAP()); - delete cslFormula; + // The input was parsed correctly. + ASSERT_EQ("(!(a & b) | (a & !c))", formula->toString()); +} + +TEST(CslParserTest, parsePathFormulaTest) { + std::string input = "X( P<0.9 (a U b))"; + std::shared_ptr<csl::CslFilter<double>> formula(nullptr); + ASSERT_NO_THROW( + formula = storm::parser::CslParser::parseCslFormula(input) + ); + + // The parser did not falsely recognize the input as a comment. + ASSERT_NE(formula, nullptr); + + // The input was parsed correctly. + ASSERT_NE(std::dynamic_pointer_cast<csl::Next<double>>(formula->getChild()).get(), nullptr); + auto nextFormula = std::dynamic_pointer_cast<csl::Next<double>>(formula->getChild()); + ASSERT_FALSE(nextFormula->isPropositional()); + ASSERT_FALSE(nextFormula->isProbEventuallyAP()); + + ASSERT_NE(std::dynamic_pointer_cast<csl::ProbabilisticBoundOperator<double>>(nextFormula->getChild()).get(), nullptr); + auto probBoundFormula = std::dynamic_pointer_cast<csl::ProbabilisticBoundOperator<double>>(nextFormula->getChild()); + ASSERT_EQ(0.9, probBoundFormula->getBound()); + ASSERT_EQ(storm::properties::LESS, probBoundFormula->getComparisonOperator()); + ASSERT_FALSE(probBoundFormula->isPropositional()); + ASSERT_TRUE(probBoundFormula->isProbEventuallyAP()); + + ASSERT_NE(std::dynamic_pointer_cast<csl::Until<double>>(probBoundFormula->getChild()).get(), nullptr); + auto untilFormula = std::dynamic_pointer_cast<csl::Until<double>>(probBoundFormula->getChild()); + ASSERT_FALSE(untilFormula->isPropositional()); + ASSERT_FALSE(untilFormula->isProbEventuallyAP()); + + ASSERT_NE(std::dynamic_pointer_cast<csl::Ap<double>>(untilFormula->getLeft()).get(), nullptr); + ASSERT_NE(std::dynamic_pointer_cast<csl::Ap<double>>(untilFormula->getRight()).get(), nullptr); + ASSERT_EQ("a", std::dynamic_pointer_cast<csl::Ap<double>>(untilFormula->getLeft())->getAp()); + ASSERT_EQ("b", std::dynamic_pointer_cast<csl::Ap<double>>(untilFormula->getRight())->getAp()); + + + // The string representation is also correct. + ASSERT_EQ("P = ? (X P < 0.900000 (a U b))", formula->toString()); } TEST(CslParserTest, parseProbabilisticFormulaTest) { - std::string formula = "P > 0.5 [ F a ]"; - storm::property::csl::AbstractCslFormula<double>* cslFormula = nullptr; + std::string input = "P > 0.5 [ F a ]"; + std::shared_ptr<csl::CslFilter<double>> formula(nullptr); ASSERT_NO_THROW( - cslFormula = storm::parser::CslParser(formula); + formula = storm::parser::CslParser::parseCslFormula(input); ); - ASSERT_NE(cslFormula, nullptr); + // The parser did not falsely recognize the input as a comment. + ASSERT_NE(formula.get(), nullptr); - storm::property::csl::ProbabilisticBoundOperator<double>* op = static_cast<storm::property::csl::ProbabilisticBoundOperator<double>*>(cslFormula); - ASSERT_EQ(storm::property::GREATER, op->getComparisonOperator()); + auto op = std::dynamic_pointer_cast<storm::properties::csl::ProbabilisticBoundOperator<double>>(formula->getChild()); + ASSERT_NE(op.get(), nullptr); + ASSERT_EQ(storm::properties::GREATER, op->getComparisonOperator()); ASSERT_EQ(0.5, op->getBound()); + ASSERT_FALSE(op->isPropositional()); + ASSERT_TRUE(op->isProbEventuallyAP()); - ASSERT_EQ(cslFormula->toString(), "P > 0.500000 [F a]"); - - delete cslFormula; + // Test the string representation for the parsed formula. + ASSERT_EQ("P > 0.500000 (F a)", formula->toString()); } TEST(CslParserTest, parseSteadyStateBoundFormulaTest) { - std::string formula = "S >= 15 [ P < 0.2 [ a U<=3 b ] ]"; - storm::property::csl::AbstractCslFormula<double>* cslFormula = nullptr; + std::string input = "S >= 15 [ P < 0.2 [ a U<=3 b ] ]"; + std::shared_ptr<csl::CslFilter<double>> formula(nullptr); ASSERT_NO_THROW( - cslFormula = storm::parser::CslParser(formula); + formula = storm::parser::CslParser::parseCslFormula(input); ); - ASSERT_NE(cslFormula, nullptr); + // The parser did not falsely recognize the input as a comment. + ASSERT_NE(formula.get(), nullptr); - storm::property::csl::SteadyStateBoundOperator<double>* op = static_cast<storm::property::csl::SteadyStateBoundOperator<double>*>(cslFormula); - ASSERT_EQ(storm::property::GREATER_EQUAL, op->getComparisonOperator()); + auto op = std::dynamic_pointer_cast<storm::properties::csl::SteadyStateBoundOperator<double>>(formula->getChild()); + ASSERT_NE(op.get(), nullptr); + ASSERT_EQ(storm::properties::GREATER_EQUAL, op->getComparisonOperator()); ASSERT_EQ(15.0, op->getBound()); + ASSERT_FALSE(op->isPropositional()); + ASSERT_FALSE(op->isProbEventuallyAP()); - ASSERT_EQ(cslFormula->toString(), "S >= 15.000000 [P < 0.200000 [a U[0.000000,3.000000] b]]"); - - delete cslFormula; + // Test the string representation for the parsed formula. + ASSERT_EQ("S >= 15.000000 (P < 0.200000 (a U[0.000000,3.000000] b))", formula->toString()); } TEST(CslParserTest, parseSteadyStateNoBoundFormulaTest) { - std::string formula = "S = ? [ P <= 0.5 [ F<=3 a ] ]"; - storm::property::csl::AbstractCslFormula<double>* cslFormula = nullptr; + std::string input = "S = ? [ P <= 0.5 [ F<=3 a ] ]"; + std::shared_ptr<csl::CslFilter<double>> formula(nullptr); ASSERT_NO_THROW( - cslFormula = storm::parser::CslParser(formula); + formula = storm::parser::CslParser::parseCslFormula(input); ); - ASSERT_NE(cslFormula, nullptr); - ASSERT_EQ(cslFormula->toString(), "S = ? [P <= 0.500000 [F[0.000000,3.000000] a]]"); + // The parser did not falsely recognize the input as a comment. + ASSERT_NE(formula.get(), nullptr); + + ASSERT_FALSE(formula->getChild()->isPropositional()); + ASSERT_FALSE(formula->getChild()->isProbEventuallyAP()); - delete cslFormula; + // The input was parsed correctly. + ASSERT_EQ("S = ? (P <= 0.500000 (F[0.000000,3.000000] a))", formula->toString()); } TEST(CslParserTest, parseProbabilisticNoBoundFormulaTest) { - std::string formula = "P = ? [ a U [3,4] b & (!c) ]"; - storm::property::csl::AbstractCslFormula<double>* cslFormula = nullptr; + std::string input = "P = ? [ a U [3,4] b & (!c) ]"; + std::shared_ptr<csl::CslFilter<double>> formula(nullptr); ASSERT_NO_THROW( - cslFormula = storm::parser::CslParser(formula); + formula = storm::parser::CslParser::parseCslFormula(input); ); - ASSERT_NE(cslFormula, nullptr); - ASSERT_EQ(cslFormula->toString(), "P = ? [a U[3.000000,4.000000] (b & !c)]"); + // The parser did not falsely recognize the input as a comment. + ASSERT_NE(formula.get(), nullptr); - delete cslFormula; + ASSERT_FALSE(formula->getChild()->isPropositional()); + ASSERT_FALSE(formula->getChild()->isProbEventuallyAP()); + + // The input was parsed correctly. + ASSERT_EQ("P = ? (a U[3.000000,4.000000] (b & !c))", formula->toString()); } TEST(CslParserTest, parseComplexFormulaTest) { - std::string formula = "S<=0.5 [ P <= 0.5 [ a U c ] ] & (P > 0.5 [ G b] | !P < 0.4 [ G P>0.9 [F >=7 a & b] ]) //and a comment"; - storm::property::csl::AbstractCslFormula<double>* cslFormula = nullptr; + std::string input = "S<=0.5 [ P <= 0.5 [ a U c ] ] & (P > 0.5 [ G b] | !P < 0.4 [ G P>0.9 [F >=7 a & b] ]) //and a comment"; + std::shared_ptr<csl::CslFilter<double>> formula(nullptr); + ASSERT_NO_THROW( + formula = storm::parser::CslParser::parseCslFormula(input); + ); + + // The parser did not falsely recognize the input as a comment. + ASSERT_NE(formula.get(), nullptr); + + ASSERT_FALSE(formula->getChild()->isPropositional()); + ASSERT_FALSE(formula->getChild()->isProbEventuallyAP()); + + // The input was parsed correctly. + ASSERT_EQ("S <= 0.500000 ((P <= 0.500000 (a U c) & (P > 0.500000 (G b) | !P < 0.400000 (G P > 0.900000 (F>=7.000000 (a & b))))))", formula->toString()); +} + +TEST(CslParserTest, parseCslFilterTest) { + std::string input = "filter[max; formula(b); invert; bound(<, 0.5); sort(value); range(0,3)](F a)"; + std::shared_ptr<csl::CslFilter<double>> formula(nullptr); + ASSERT_NO_THROW( + formula = storm::parser::CslParser::parseCslFormula(input) + ); + + // The parser did not falsely recognize the input as a comment. + ASSERT_NE(formula, nullptr); + + ASSERT_EQ(storm::properties::MAXIMIZE, formula->getOptimizingOperator()); + + ASSERT_EQ(5, formula->getActionCount()); + ASSERT_NE(std::dynamic_pointer_cast<storm::properties::action::FormulaAction<double>>(formula->getAction(0)).get(), nullptr); + ASSERT_NE(std::dynamic_pointer_cast<storm::properties::action::InvertAction<double>>(formula->getAction(1)).get(), nullptr); + ASSERT_NE(std::dynamic_pointer_cast<storm::properties::action::BoundAction<double>>(formula->getAction(2)).get(), nullptr); + ASSERT_NE(std::dynamic_pointer_cast<storm::properties::action::SortAction<double>>(formula->getAction(3)).get(), nullptr); + ASSERT_NE(std::dynamic_pointer_cast<storm::properties::action::RangeAction<double>>(formula->getAction(4)).get(), nullptr); + + ASSERT_FALSE(formula->getChild()->isPropositional()); + ASSERT_FALSE(formula->getChild()->isProbEventuallyAP()); + + // The input was parsed correctly. + ASSERT_EQ("filter[max; formula(b); invert; bound(<, 0.500000); sort(value, ascending); range(0, 3)](F a)", formula->toString()); +} + +TEST(CslParserTest, commentTest) { + std::string input = "// This is a comment. And this is a commented out formula: P<=0.5 [ X a ]"; + std::shared_ptr<csl::CslFilter<double>> formula(nullptr); + ASSERT_NO_THROW( + formula = storm::parser::CslParser::parseCslFormula(input) + ); + + // The parser recognized the input as a comment. + ASSERT_NE(nullptr, formula.get()); + + // Test if the parser recognizes the comment at the end of a line. + input = "P<=0.5 [ X a ] // This is a comment."; ASSERT_NO_THROW( - cslFormula = storm::parser::CslParser(formula); + formula = storm::parser::CslParser::parseCslFormula(input) ); - ASSERT_NE(cslFormula, nullptr); - ASSERT_EQ(cslFormula->toString(), "(S <= 0.500000 [P <= 0.500000 [a U c]] & (P > 0.500000 [G b] | !P < 0.400000 [G P > 0.900000 [F>=7.000000 (a & b)]]))"); + ASSERT_FALSE(formula->getChild()->isPropositional()); + ASSERT_FALSE(formula->getChild()->isProbEventuallyAP()); - delete cslFormula; + ASSERT_EQ("P <= 0.500000 (X a)", formula->toString()); } TEST(CslParserTest, wrongProbabilisticFormulaTest) { - std::string formula = "P > 0.5 [ a ]"; - storm::property::csl::AbstractCslFormula<double>* cslFormula = nullptr; + std::string input = "P > 0.5 [ a ]"; + std::shared_ptr<csl::CslFilter<double>> formula(nullptr); ASSERT_THROW( - cslFormula = storm::parser::CslParser(formula), + formula = storm::parser::CslParser::parseCslFormula(input), storm::exceptions::WrongFormatException ); } TEST(CslParserTest, wrongFormulaTest) { - std::string formula = "(a | b) & +"; - storm::property::csl::AbstractCslFormula<double>* cslFormula = nullptr; + std::string input = "(a | b) & +"; + std::shared_ptr<csl::CslFilter<double>> formula(nullptr); ASSERT_THROW( - cslFormula = storm::parser::CslParser(formula), + formula = storm::parser::CslParser::parseCslFormula(input), storm::exceptions::WrongFormatException ); } TEST(CslParserTest, wrongFormulaTest2) { - std::string formula = "P>0 [ F & a ]"; - storm::property::csl::AbstractCslFormula<double>* cslFormula = nullptr; + std::string input = "P>0 [ F & a ]"; + std::shared_ptr<csl::CslFilter<double>> formula(nullptr); ASSERT_THROW( - cslFormula = storm::parser::CslParser(formula), + formula = storm::parser::CslParser::parseCslFormula(input), storm::exceptions::WrongFormatException ); } diff --git a/test/functional/parser/LtlParserTest.cpp b/test/functional/parser/LtlParserTest.cpp index 1da53769d..d13c48688 100644 --- a/test/functional/parser/LtlParserTest.cpp +++ b/test/functional/parser/LtlParserTest.cpp @@ -9,31 +9,37 @@ #include "storm-config.h" #include "src/parser/LtlParser.h" #include "src/exceptions/WrongFormatException.h" +#include "src/properties/actions/InvertAction.h" +#include "src/properties/actions/SortAction.h" +#include "src/properties/actions/RangeAction.h" +#include "src/properties/actions/BoundAction.h" + +namespace ltl = storm::properties::ltl; TEST(LtlParserTest, parseApOnlyTest) { - std::string formula = "ap"; - storm::property::ltl::AbstractLtlFormula<double>* ltlFormula = nullptr; + std::string input = "ap"; + std::shared_ptr<storm::properties::ltl::LtlFilter<double>> formula(nullptr); ASSERT_NO_THROW( - ltlFormula = storm::parser::LtlParser(formula); + formula = storm::parser::LtlParser::parseLtlFormula(input); ); - ASSERT_NE(ltlFormula, nullptr); - ASSERT_EQ(ltlFormula->toString(), formula); + ASSERT_TRUE(formula->getChild()->isPropositional()); - delete ltlFormula; + ASSERT_NE(formula.get(), nullptr); + ASSERT_EQ(input, formula->toString()); } TEST(LtlParserTest, parsePropositionalFormulaTest) { - std::string formula = "!(a & b) | a & ! c"; - storm::property::ltl::AbstractLtlFormula<double>* ltlFormula = nullptr; + std::string input = "!(a & b) | a & ! c"; + std::shared_ptr<ltl::LtlFilter<double>> formula(nullptr); ASSERT_NO_THROW( - ltlFormula = storm::parser::LtlParser(formula); + formula = storm::parser::LtlParser::parseLtlFormula(input); ); - ASSERT_NE(ltlFormula, nullptr); - ASSERT_EQ(ltlFormula->toString(), "(!(a & b) | (a & !c))"); + ASSERT_TRUE(formula->getChild()->isPropositional()); - delete ltlFormula; + ASSERT_NE(formula.get(), nullptr); + ASSERT_EQ("(!(a & b) | (a & !c))", formula->toString()); } /*! @@ -41,16 +47,16 @@ TEST(LtlParserTest, parsePropositionalFormulaTest) { * "Eventually" operator. */ TEST(LtlParserTest, parseAmbiguousFormulaTest) { - std::string formula = "F & b"; - storm::property::ltl::AbstractLtlFormula<double>* ltlFormula = nullptr; + std::string input = "F & b"; + std::shared_ptr<ltl::LtlFilter<double>> formula(nullptr); ASSERT_NO_THROW( - ltlFormula = storm::parser::LtlParser(formula); + formula = storm::parser::LtlParser::parseLtlFormula(input); ); - ASSERT_NE(ltlFormula, nullptr); - ASSERT_EQ(ltlFormula->toString(), "(F & b)"); + ASSERT_TRUE(formula->getChild()->isPropositional()); - delete ltlFormula; + ASSERT_NE(formula.get(), nullptr); + ASSERT_EQ("(F & b)", formula->toString()); } /*! @@ -58,85 +64,128 @@ TEST(LtlParserTest, parseAmbiguousFormulaTest) { * depending where it occurs. */ TEST(LtlParserTest, parseAmbiguousFormulaTest2) { - std::string formula = "F F"; - storm::property::ltl::AbstractLtlFormula<double>* ltlFormula = nullptr; + std::string input = "F F"; + std::shared_ptr<ltl::LtlFilter<double>> formula(nullptr); ASSERT_NO_THROW( - ltlFormula = storm::parser::LtlParser(formula); + formula = storm::parser::LtlParser::parseLtlFormula(input); ); - ASSERT_NE(ltlFormula, nullptr); - ASSERT_EQ(ltlFormula->toString(), "F F"); + ASSERT_FALSE(formula->getChild()->isPropositional()); - delete ltlFormula; + ASSERT_NE(formula.get(), nullptr); + ASSERT_EQ("F F", formula->toString()); } TEST(LtlParserTest, parseBoundedEventuallyFormulaTest) { - std::string formula = "F<=5 a"; - storm::property::ltl::AbstractLtlFormula<double>* ltlFormula = nullptr; + std::string input = "F<=5 a"; + std::shared_ptr<ltl::LtlFilter<double>> formula(nullptr); ASSERT_NO_THROW( - ltlFormula = storm::parser::LtlParser(formula); + formula = storm::parser::LtlParser::parseLtlFormula(input); ); - ASSERT_NE(ltlFormula, nullptr); + ASSERT_NE(formula.get(), nullptr); - storm::property::ltl::BoundedEventually<double>* op = static_cast<storm::property::ltl::BoundedEventually<double>*>(ltlFormula); - ASSERT_EQ(static_cast<uint_fast64_t>(5), op->getBound()); + ASSERT_FALSE(formula->getChild()->isPropositional()); + std::shared_ptr<storm::properties::ltl::BoundedEventually<double>> op = std::dynamic_pointer_cast<storm::properties::ltl::BoundedEventually<double>>(formula->getChild()); + ASSERT_NE(op.get(), nullptr); + ASSERT_EQ(static_cast<uint_fast64_t>(5), op->getBound()); - ASSERT_EQ(ltlFormula->toString(), "F<=5 a"); - delete ltlFormula; + ASSERT_EQ("F<=5 a", formula->toString()); } TEST(LtlParserTest, parseBoundedUntilFormulaTest) { - std::string formula = "a U<=3 b"; - storm::property::ltl::AbstractLtlFormula<double>* ltlFormula = nullptr; + std::string input = "a U<=3 b"; + std::shared_ptr<ltl::LtlFilter<double>> formula(nullptr); ASSERT_NO_THROW( - ltlFormula = storm::parser::LtlParser(formula); + formula = storm::parser::LtlParser::parseLtlFormula(input); ); - ASSERT_NE(ltlFormula, nullptr); + ASSERT_NE(formula.get(), nullptr); - storm::property::ltl::BoundedUntil<double>* op = static_cast<storm::property::ltl::BoundedUntil<double>*>(ltlFormula); + ASSERT_FALSE(formula->getChild()->isPropositional()); + + std::shared_ptr<storm::properties::ltl::BoundedUntil<double>> op = std::dynamic_pointer_cast<storm::properties::ltl::BoundedUntil<double>>(formula->getChild()); + ASSERT_NE(op.get(), nullptr); ASSERT_EQ(static_cast<uint_fast64_t>(3), op->getBound()); - ASSERT_EQ(ltlFormula->toString(), "(a U<=3 b)"); + ASSERT_EQ("(a U<=3 b)", formula->toString()); +} + +TEST(LtlParserTest, parseLtlFilterTest) { + std::string input = "filter[max; invert; bound(<, 0.5); sort(value); range(0,3)](X a)"; + std::shared_ptr<ltl::LtlFilter<double>> formula(nullptr); + ASSERT_NO_THROW( + formula = storm::parser::LtlParser::parseLtlFormula(input) + ); + + // The parser did not falsely recognize the input as a comment. + ASSERT_NE(formula, nullptr); + + ASSERT_FALSE(formula->getChild()->isPropositional()); + + ASSERT_EQ(storm::properties::MAXIMIZE, formula->getOptimizingOperator()); + + ASSERT_EQ(4, formula->getActionCount()); + ASSERT_NE(std::dynamic_pointer_cast<storm::properties::action::InvertAction<double>>(formula->getAction(0)).get(), nullptr); + ASSERT_NE(std::dynamic_pointer_cast<storm::properties::action::BoundAction<double>>(formula->getAction(1)).get(), nullptr); + ASSERT_NE(std::dynamic_pointer_cast<storm::properties::action::SortAction<double>>(formula->getAction(2)).get(), nullptr); + ASSERT_NE(std::dynamic_pointer_cast<storm::properties::action::RangeAction<double>>(formula->getAction(3)).get(), nullptr); - delete ltlFormula; + // The input was parsed correctly. + ASSERT_EQ("filter[max; invert; bound(<, 0.500000); sort(value, ascending); range(0, 3)](X a)", formula->toString()); } -TEST(LtlParserTest, parseComplexUntilTest) { - std::string formula = "a U b U<=3 c"; - storm::property::ltl::AbstractLtlFormula<double>* ltlFormula = nullptr; +TEST(LtlParserTest, commentTest) { + std::string input = "// This is a comment. And this is a commented out formula: F X a"; + std::shared_ptr<ltl::LtlFilter<double>> formula(nullptr); + ASSERT_NO_THROW( + formula = storm::parser::LtlParser::parseLtlFormula(input) + ); + + // The parser recognized the input as a comment. + ASSERT_NE(nullptr, formula.get()); + ASSERT_EQ(nullptr, formula->getChild().get()); + + // Test if the parser recognizes the comment at the end of a line. + input = "F X a // This is a comment."; ASSERT_NO_THROW( - ltlFormula = storm::parser::LtlParser(formula); + formula = storm::parser::LtlParser::parseLtlFormula(input) ); - ASSERT_NE(ltlFormula, nullptr); - ASSERT_EQ(ltlFormula->toString(), "((a U b) U<=3 c)"); + ASSERT_FALSE(formula->getChild()->isPropositional()); - delete ltlFormula; + ASSERT_EQ("F X a", formula->toString()); } -TEST(LtlParserTest, parseComplexFormulaTest) { - std::string formula = "a U F b | G a & F<=3 a U<=7 b // and a comment"; - storm::property::ltl::AbstractLtlFormula<double>* ltlFormula = nullptr; +TEST(LtlParserTest, parseComplexUntilTest) { + std::string input = "a U b U<=3 c"; + std::shared_ptr<ltl::LtlFilter<double>> formula(nullptr); ASSERT_NO_THROW( - ltlFormula = storm::parser::LtlParser(formula); + formula = storm::parser::LtlParser::parseLtlFormula(input); ); - ASSERT_NE(ltlFormula, nullptr); - ASSERT_EQ(ltlFormula->toString(), "(a U F (b | G (a & F<=3 (a U<=7 b))))"); + ASSERT_NE(formula.get(), nullptr); + ASSERT_EQ("((a U b) U<=3 c)", formula->toString()); +} + +TEST(LtlParserTest, parseComplexFormulaTest) { + std::string input = "a U F b | G a & F<=3 a U<=7 b // and a comment"; + std::shared_ptr<ltl::LtlFilter<double>> formula(nullptr); + ASSERT_NO_THROW( + formula = storm::parser::LtlParser::parseLtlFormula(input); + ); - delete ltlFormula; + ASSERT_NE(formula.get(), nullptr); + ASSERT_EQ("(a U F (b | G (a & F<=3 (a U<=7 b))))", formula->toString()); } TEST(LtlParserTest, wrongFormulaTest) { - std::string formula = "(a | c) & +"; - storm::property::ltl::AbstractLtlFormula<double>* ltlFormula = nullptr; + std::string input = "(a | c) & +"; ASSERT_THROW( - ltlFormula = storm::parser::LtlParser(formula), + storm::parser::LtlParser::parseLtlFormula(input), storm::exceptions::WrongFormatException ); } diff --git a/test/functional/parser/PrctlParserTest.cpp b/test/functional/parser/PrctlParserTest.cpp index c51cf3164..22e52e7d1 100644 --- a/test/functional/parser/PrctlParserTest.cpp +++ b/test/functional/parser/PrctlParserTest.cpp @@ -10,151 +10,250 @@ #include "storm-config.h" #include "src/parser/PrctlParser.h" #include "src/exceptions/WrongFormatException.h" +#include "src/properties/actions/FormulaAction.h" +#include "src/properties/actions/InvertAction.h" +#include "src/properties/actions/SortAction.h" +#include "src/properties/actions/RangeAction.h" +#include "src/properties/actions/BoundAction.h" + +namespace prctl = storm::properties::prctl; TEST(PrctlParserTest, parseApOnlyTest) { - std::string ap = "ap"; - storm::parser::PrctlParser* prctlParser = nullptr; + std::string input = "ap"; + std::shared_ptr<prctl::PrctlFilter<double>> formula(nullptr); ASSERT_NO_THROW( - prctlParser = new storm::parser::PrctlParser(ap); + formula = storm::parser::PrctlParser::parsePrctlFormula(input) ); - ASSERT_NE(prctlParser->getFormula(), nullptr); - + // The parser did not falsely recognize the input as a comment. + ASSERT_NE(formula.get(), nullptr); - ASSERT_EQ(ap, prctlParser->getFormula()->toString()); - - delete prctlParser->getFormula(); - delete prctlParser; + ASSERT_TRUE(formula->getChild()->isPropositional()); + ASSERT_FALSE(formula->getChild()->isProbEventuallyAP()); + // The input was parsed correctly. + ASSERT_EQ(input, formula->toString()); } TEST(PrctlParserTest, parsePropositionalFormulaTest) { - storm::parser::PrctlParser* prctlParser = nullptr; + std::string input = "!(a & b) | a & ! c"; + std::shared_ptr<prctl::PrctlFilter<double>> formula(nullptr); ASSERT_NO_THROW( - prctlParser = new storm::parser::PrctlParser("!(a & b) | a & ! c") + formula = storm::parser::PrctlParser::parsePrctlFormula(input) ); - ASSERT_NE(prctlParser->getFormula(), nullptr); + // The parser did not falsely recognize the input as a comment. + ASSERT_NE(formula.get(), nullptr); + ASSERT_TRUE(formula->getChild()->isPropositional()); + ASSERT_FALSE(formula->getChild()->isProbEventuallyAP()); - ASSERT_EQ(prctlParser->getFormula()->toString(), "(!(a & b) | (a & !c))"); + // The input was parsed correctly. + ASSERT_EQ("(!(a & b) | (a & !c))", formula->toString()); +} - delete prctlParser->getFormula(); - delete prctlParser; +TEST(PrctlParserTest, parsePathFormulaTest) { + std::string input = "X( P<0.9 (a U b))"; + std::shared_ptr<prctl::PrctlFilter<double>> formula(nullptr); + ASSERT_NO_THROW( + formula = storm::parser::PrctlParser::parsePrctlFormula(input) + ); + // The parser did not falsely recognize the input as a comment. + ASSERT_NE(formula.get(), nullptr); + + // The input was parsed correctly. + ASSERT_NE(std::dynamic_pointer_cast<prctl::Next<double>>(formula->getChild()).get(), nullptr); + auto nextFormula = std::dynamic_pointer_cast<prctl::Next<double>>(formula->getChild()); + ASSERT_FALSE(nextFormula->isPropositional()); + ASSERT_FALSE(nextFormula->isProbEventuallyAP()); + + ASSERT_NE(std::dynamic_pointer_cast<prctl::ProbabilisticBoundOperator<double>>(nextFormula->getChild()).get(), nullptr); + auto probBoundFormula = std::dynamic_pointer_cast<prctl::ProbabilisticBoundOperator<double>>(nextFormula->getChild()); + ASSERT_EQ(0.9, probBoundFormula->getBound()); + ASSERT_EQ(storm::properties::LESS, probBoundFormula->getComparisonOperator()); + ASSERT_FALSE(probBoundFormula->isPropositional()); + ASSERT_TRUE(probBoundFormula->isProbEventuallyAP()); + + ASSERT_NE(std::dynamic_pointer_cast<prctl::Until<double>>(probBoundFormula->getChild()).get(), nullptr); + auto untilFormula = std::dynamic_pointer_cast<prctl::Until<double>>(probBoundFormula->getChild()); + ASSERT_FALSE(untilFormula->isPropositional()); + ASSERT_FALSE(untilFormula->isProbEventuallyAP()); + + ASSERT_NE(std::dynamic_pointer_cast<prctl::Ap<double>>(untilFormula->getLeft()).get(), nullptr); + ASSERT_NE(std::dynamic_pointer_cast<prctl::Ap<double>>(untilFormula->getRight()).get(), nullptr); + ASSERT_EQ("a", std::dynamic_pointer_cast<prctl::Ap<double>>(untilFormula->getLeft())->getAp()); + ASSERT_EQ("b", std::dynamic_pointer_cast<prctl::Ap<double>>(untilFormula->getRight())->getAp()); + + // The string representation is also correct. + ASSERT_EQ("P = ? (X P < 0.900000 (a U b))", formula->toString()); } TEST(PrctlParserTest, parseProbabilisticFormulaTest) { - storm::parser::PrctlParser* prctlParser = nullptr; + std::string input = "P > 0.5 [ F a ]"; + std::shared_ptr<prctl::PrctlFilter<double>> formula(nullptr); ASSERT_NO_THROW( - prctlParser = new storm::parser::PrctlParser("P > 0.5 [ F a ]") + formula = storm::parser::PrctlParser::parsePrctlFormula(input) ); - ASSERT_NE(prctlParser->getFormula(), nullptr); + // The parser did not falsely recognize the input as a comment. + ASSERT_NE(formula.get(), nullptr); - storm::property::prctl::ProbabilisticBoundOperator<double>* op = static_cast<storm::property::prctl::ProbabilisticBoundOperator<double>*>(prctlParser->getFormula()); - - ASSERT_EQ(storm::property::GREATER, op->getComparisonOperator()); - ASSERT_EQ(0.5, op->getBound()); - ASSERT_EQ(prctlParser->getFormula()->toString(), "P > 0.500000 [F a]"); + ASSERT_NE(std::dynamic_pointer_cast<prctl::ProbabilisticBoundOperator<double>>(formula->getChild()).get(), nullptr); + std::shared_ptr<prctl::ProbabilisticBoundOperator<double>> op = std::static_pointer_cast<prctl::ProbabilisticBoundOperator<double>>(formula->getChild()); - delete prctlParser->getFormula(); - delete prctlParser; + ASSERT_EQ(storm::properties::GREATER, op->getComparisonOperator()); + ASSERT_EQ(0.5, op->getBound()); + ASSERT_FALSE(op->isPropositional()); + ASSERT_TRUE(op->isProbEventuallyAP()); + // Test the string representation for the parsed formula. + ASSERT_EQ("P > 0.500000 (F a)", formula->toString()); } TEST(PrctlParserTest, parseRewardFormulaTest) { - storm::parser::PrctlParser* prctlParser = nullptr; + std::string input = "R >= 15 [ I=5 ]"; + std::shared_ptr<prctl::PrctlFilter<double>>formula(nullptr); ASSERT_NO_THROW( - prctlParser = new storm::parser::PrctlParser("R >= 15 [ I=5 ]") + formula = storm::parser::PrctlParser::parsePrctlFormula(input); ); - ASSERT_NE(prctlParser->getFormula(), nullptr); + // The parser did not falsely recognize the input as a comment. + ASSERT_NE(formula.get(), nullptr); - storm::property::prctl::RewardBoundOperator<double>* op = static_cast<storm::property::prctl::RewardBoundOperator<double>*>(prctlParser->getFormula()); + ASSERT_NE(std::dynamic_pointer_cast<prctl::RewardBoundOperator<double>>(formula->getChild()).get(), nullptr); + std::shared_ptr<prctl::RewardBoundOperator<double>> op = std::static_pointer_cast<prctl::RewardBoundOperator<double>>(formula->getChild()); - ASSERT_EQ(storm::property::GREATER_EQUAL, op->getComparisonOperator()); + ASSERT_EQ(storm::properties::GREATER_EQUAL, op->getComparisonOperator()); ASSERT_EQ(15.0, op->getBound()); + ASSERT_FALSE(op->isPropositional()); + ASSERT_FALSE(op->isProbEventuallyAP()); - ASSERT_EQ("R >= 15.000000 [I=5]", prctlParser->getFormula()->toString()); - - delete prctlParser->getFormula(); - delete prctlParser; + // Test the string representation for the parsed formula. + ASSERT_EQ("R >= 15.000000 (I=5)", formula->toString()); } TEST(PrctlParserTest, parseRewardNoBoundFormulaTest) { - storm::parser::PrctlParser* prctlParser = nullptr; + std::string input = "R = ? [ F a ]"; + std::shared_ptr<prctl::PrctlFilter<double>> formula(nullptr); ASSERT_NO_THROW( - prctlParser = new storm::parser::PrctlParser("R = ? [ F a ]") + formula = storm::parser::PrctlParser::parsePrctlFormula(input) ); - ASSERT_NE(prctlParser->getFormula(), nullptr); + // The parser did not falsely recognize the input as a comment. + ASSERT_NE(formula.get(), nullptr); + ASSERT_FALSE(formula->getChild()->isPropositional()); + ASSERT_FALSE(formula->getChild()->isProbEventuallyAP()); + + // The input was parsed correctly. + ASSERT_EQ("R = ? (F a)", formula->toString()); +} - ASSERT_EQ(prctlParser->getFormula()->toString(), "R = ? [F a]"); +TEST(PrctlParserTest, parseProbabilisticNoBoundFormulaTest) { + std::string input = "P = ? [ a U <= 4 b & (!c) ]"; + std::shared_ptr<prctl::PrctlFilter<double>> formula(nullptr); + ASSERT_NO_THROW( + formula = storm::parser::PrctlParser::parsePrctlFormula(input) + ); - delete prctlParser->getFormula(); - delete prctlParser; + // The parser did not falsely recognize the input as a comment. + ASSERT_NE(formula.get(), nullptr); + ASSERT_FALSE(formula->getChild()->isPropositional()); + ASSERT_FALSE(formula->getChild()->isProbEventuallyAP()); + + // The input was parsed correctly. + ASSERT_EQ("P = ? (a U<=4 (b & !c))", formula->toString()); } -TEST(PrctlParserTest, parseProbabilisticNoBoundFormulaTest) { - storm::parser::PrctlParser* prctlParser = nullptr; +TEST(PrctlParserTest, parseComplexFormulaTest) { + std::string input = "R<=0.5 [ S ] & (R > 15 [ C<=0.5 ] | !P < 0.4 [ G P>0.9 [F<=7 a & b] ])"; + std::shared_ptr<prctl::PrctlFilter<double>> formula(nullptr); + ASSERT_NO_THROW( + formula = storm::parser::PrctlParser::parsePrctlFormula(input) + ); + + // The parser did not falsely recognize the input as a comment. + ASSERT_NE(formula.get(), nullptr); + + ASSERT_FALSE(formula->getChild()->isPropositional()); + ASSERT_FALSE(formula->getChild()->isProbEventuallyAP()); + + // The input was parsed correctly. + ASSERT_EQ("(R <= 0.500000 (S) & (R > 15.000000 (C <= 0.500000) | !P < 0.400000 (G P > 0.900000 (F<=7 (a & b)))))", formula->toString()); +} + +TEST(PrctlParserTest, parsePrctlFilterTest) { + std::string input = "filter[max; formula(b); invert; bound(<, 0.5); sort(value); range(0,3)](F a)"; + std::shared_ptr<prctl::PrctlFilter<double>> formula(nullptr); ASSERT_NO_THROW( - prctlParser = new storm::parser::PrctlParser("P = ? [ a U <= 4 b & (!c) ]") + formula = storm::parser::PrctlParser::parsePrctlFormula(input) ); - ASSERT_NE(prctlParser->getFormula(), nullptr); + // The parser did not falsely recognize the input as a comment. + ASSERT_NE(formula.get(), nullptr); + ASSERT_EQ(storm::properties::MAXIMIZE, formula->getOptimizingOperator()); - ASSERT_EQ(prctlParser->getFormula()->toString(), "P = ? [a U<=4 (b & !c)]"); + ASSERT_EQ(5, formula->getActionCount()); + ASSERT_NE(std::dynamic_pointer_cast<storm::properties::action::FormulaAction<double>>(formula->getAction(0)).get(), nullptr); + ASSERT_NE(std::dynamic_pointer_cast<storm::properties::action::InvertAction<double>>(formula->getAction(1)).get(), nullptr); + ASSERT_NE(std::dynamic_pointer_cast<storm::properties::action::BoundAction<double>>(formula->getAction(2)).get(), nullptr); + ASSERT_NE(std::dynamic_pointer_cast<storm::properties::action::SortAction<double>>(formula->getAction(3)).get(), nullptr); + ASSERT_NE(std::dynamic_pointer_cast<storm::properties::action::RangeAction<double>>(formula->getAction(4)).get(), nullptr); - delete prctlParser->getFormula(); - delete prctlParser; + ASSERT_FALSE(formula->getChild()->isPropositional()); + ASSERT_FALSE(formula->getChild()->isProbEventuallyAP()); + // The input was parsed correctly. + ASSERT_EQ("filter[max; formula(b); invert; bound(<, 0.500000); sort(value, ascending); range(0, 3)](F a)", formula->toString()); } -TEST(PrctlParserTest, parseComplexFormulaTest) { - storm::parser::PrctlParser* prctlParser = nullptr; +TEST(PrctlParserTest, commentTest) { + std::string input = "// This is a comment. And this is a commented out formula: P<=0.5 [ X a ]"; + std::shared_ptr<prctl::PrctlFilter<double>> formula(nullptr); ASSERT_NO_THROW( - prctlParser = new storm::parser::PrctlParser("R<=0.5 [ S ] & (R > 15 [ C<=0.5 ] | !P < 0.4 [ G P>0.9 [F<=7 a & b] ])") + formula = storm::parser::PrctlParser::parsePrctlFormula(input) ); - ASSERT_NE(prctlParser->getFormula(), nullptr); + // The parser recognized the input as a comment. + ASSERT_NE(nullptr, formula.get()); + // Test if the parser recognizes the comment at the end of a line. + input = "P<=0.5 [ X a ] // This is a comment."; + ASSERT_NO_THROW( + formula = storm::parser::PrctlParser::parsePrctlFormula(input) + ); - ASSERT_EQ("(R <= 0.500000 [S] & (R > 15.000000 [C <= 0.500000] | !P < 0.400000 [G P > 0.900000 [F<=7 (a & b)]]))", prctlParser->getFormula()->toString()); - delete prctlParser->getFormula(); - delete prctlParser; + ASSERT_FALSE(formula->getChild()->isPropositional()); + ASSERT_FALSE(formula->getChild()->isProbEventuallyAP()); + ASSERT_EQ("P <= 0.500000 (X a)", formula->toString()); } TEST(PrctlParserTest, wrongProbabilisticFormulaTest) { - storm::parser::PrctlParser* prctlParser = nullptr; + std::shared_ptr<prctl::PrctlFilter<double>> formula(nullptr); ASSERT_THROW( - prctlParser = new storm::parser::PrctlParser("P > 0.5 [ a ]"), + formula = storm::parser::PrctlParser::parsePrctlFormula("P > 0.5 [ a ]"), storm::exceptions::WrongFormatException ); - - delete prctlParser; } TEST(PrctlParserTest, wrongFormulaTest) { - storm::parser::PrctlParser* prctlParser = nullptr; + std::shared_ptr<prctl::PrctlFilter<double>> formula(nullptr); ASSERT_THROW( - prctlParser = new storm::parser::PrctlParser("(a | b) & +"), + formula = storm::parser::PrctlParser::parsePrctlFormula("(a | b) & +"), storm::exceptions::WrongFormatException ); - delete prctlParser; } TEST(PrctlParserTest, wrongFormulaTest2) { - storm::parser::PrctlParser* prctlParser = nullptr; + std::shared_ptr<prctl::PrctlFilter<double>> formula(nullptr); ASSERT_THROW( - prctlParser = new storm::parser::PrctlParser("P>0 [ F & a ]"), + formula = storm::parser::PrctlParser::parsePrctlFormula("P>0 [ F & a ]"), storm::exceptions::WrongFormatException ); - delete prctlParser; } diff --git a/test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp b/test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp index 2fddf8702..e705bb393 100644 --- a/test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp +++ b/test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp @@ -16,46 +16,37 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, Crowds) { std::shared_ptr<storm::models::Dtmc<double>> dtmc = abstractModel->as<storm::models::Dtmc<double>>(); - ASSERT_EQ(dtmc->getNumberOfStates(), 2036647ull); - ASSERT_EQ(dtmc->getNumberOfTransitions(), 7362293ull); + ASSERT_EQ(2036647ull, dtmc->getNumberOfStates()); + ASSERT_EQ(7362293ull, dtmc->getNumberOfTransitions()); storm::modelchecker::prctl::SparseDtmcPrctlModelChecker<double> mc(*dtmc, new storm::solver::GmmxxLinearEquationSolver<double>()); - storm::property::prctl::Ap<double>* apFormula = new storm::property::prctl::Ap<double>("observe0Greater1"); - storm::property::prctl::Eventually<double>* eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); - storm::property::prctl::ProbabilisticNoBoundOperator<double>* probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula); + auto apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("observe0Greater1"); + auto eventuallyFormula = std::make_shared<storm::properties::prctl::Eventually<double>>(apFormula); LOG4CPLUS_WARN(logger, "Model Checking P=? [F observe0Greater1] on crowds/crowds20_5..."); - std::vector<double> result = probFormula->check(mc); + std::vector<double> result = eventuallyFormula->check(mc, false); LOG4CPLUS_WARN(logger, "Done."); ASSERT_LT(std::abs(result[0] - 0.2296800237), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; - - apFormula = new storm::property::prctl::Ap<double>("observeIGreater1"); - eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); - probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula); + apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("observeIGreater1"); + eventuallyFormula = std::make_shared<storm::properties::prctl::Eventually<double>>(apFormula); LOG4CPLUS_WARN(logger, "Model Checking P=? [F observeIGreater1] on crowds/crowds20_5..."); - result = probFormula->check(mc); + result = eventuallyFormula->check(mc, false); LOG4CPLUS_WARN(logger, "Done."); ASSERT_LT(std::abs(result[0] - 0.05073232193), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; - - apFormula = new storm::property::prctl::Ap<double>("observeOnlyTrueSender"); - eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); - probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula); + apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("observeOnlyTrueSender"); + eventuallyFormula = std::make_shared<storm::properties::prctl::Eventually<double>>(apFormula); LOG4CPLUS_WARN(logger, "Model Checking P=? [F observeOnlyTrueSender] on crowds/crowds20_5..."); - result = probFormula->check(mc); + result = eventuallyFormula->check(mc, false); LOG4CPLUS_WARN(logger, "Done."); ASSERT_LT(std::abs(result[0] - 0.22742171078), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - - delete probFormula; } @@ -67,47 +58,37 @@ TEST(GmmxxDtmcPrctlModelCheckerTest, SynchronousLeader) { ASSERT_EQ(abstractModel->getType(), storm::models::DTMC); - std::shared_ptr<storm::models::Dtmc<double>> dtmc = abstractModel->as<storm::models::Dtmc<double>>(); - ASSERT_EQ(dtmc->getNumberOfStates(), 1312334ull); - ASSERT_EQ(dtmc->getNumberOfTransitions(), 1574477ull); + ASSERT_EQ(1312334ull, dtmc->getNumberOfStates()); + ASSERT_EQ(1574477ull, dtmc->getNumberOfTransitions()); storm::modelchecker::prctl::SparseDtmcPrctlModelChecker<double> mc(*dtmc, new storm::solver::GmmxxLinearEquationSolver<double>()); - storm::property::prctl::Ap<double>* apFormula = new storm::property::prctl::Ap<double>("elected"); - storm::property::prctl::Eventually<double>* eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); - storm::property::prctl::ProbabilisticNoBoundOperator<double>* probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula); + auto apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("elected"); + auto eventuallyFormula = std::make_shared<storm::properties::prctl::Eventually<double>>(apFormula); LOG4CPLUS_WARN(logger, "Model Checking P=? [F elected] on synchronous_leader/leader6_8..."); - std::vector<double> result = probFormula->check(mc); + std::vector<double> result = eventuallyFormula->check(mc, false); LOG4CPLUS_WARN(logger, "Done."); ASSERT_LT(std::abs(result[0] - 1.0), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; - - apFormula = new storm::property::prctl::Ap<double>("elected"); - storm::property::prctl::BoundedUntil<double>* boundedUntilFormula = new storm::property::prctl::BoundedUntil<double>(new storm::property::prctl::Ap<double>("true"), apFormula, 20); - probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(boundedUntilFormula); + apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("elected"); + auto boundedUntilFormula = std::make_shared<storm::properties::prctl::BoundedUntil<double>>(std::make_shared<storm::properties::prctl::Ap<double>>("true"), apFormula, 20); LOG4CPLUS_WARN(logger, "Model Checking P=? [F<=20 elected] on synchronous_leader/leader6_8..."); - result = probFormula->check(mc); + result = boundedUntilFormula->check(mc, false); LOG4CPLUS_WARN(logger, "Done."); ASSERT_LT(std::abs(result[0] - 0.9993949793), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; - - apFormula = new storm::property::prctl::Ap<double>("elected"); - storm::property::prctl::ReachabilityReward<double>* reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward<double>(apFormula); - storm::property::prctl::RewardNoBoundOperator<double>* rewardFormula = new storm::property::prctl::RewardNoBoundOperator<double>(reachabilityRewardFormula); + apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("elected"); + auto reachabilityRewardFormula = std::make_shared<storm::properties::prctl::ReachabilityReward<double>>(apFormula); LOG4CPLUS_WARN(logger, "Model Checking R=? [F elected] on synchronous_leader/leader6_8..."); - result = rewardFormula->check(mc); + result = reachabilityRewardFormula->check(mc, false); LOG4CPLUS_WARN(logger, "Done."); ASSERT_LT(std::abs(result[0] - 1.025106273), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - - delete rewardFormula; } diff --git a/test/performance/modelchecker/SparseMdpPrctlModelCheckerTest.cpp b/test/performance/modelchecker/SparseMdpPrctlModelCheckerTest.cpp index 8f083f89f..0a177b588 100644 --- a/test/performance/modelchecker/SparseMdpPrctlModelCheckerTest.cpp +++ b/test/performance/modelchecker/SparseMdpPrctlModelCheckerTest.cpp @@ -14,64 +14,43 @@ TEST(SparseMdpPrctlModelCheckerTest, AsynchronousLeader) { std::shared_ptr<storm::models::Mdp<double>> mdp = abstractModel->as<storm::models::Mdp<double>>(); - ASSERT_EQ(mdp->getNumberOfStates(), 2095783ull); - ASSERT_EQ(mdp->getNumberOfTransitions(), 7714385ull); + ASSERT_EQ(2095783ull, mdp->getNumberOfStates()); + ASSERT_EQ(7714385ull, mdp->getNumberOfTransitions()); storm::modelchecker::prctl::SparseMdpPrctlModelChecker<double> mc(*mdp, std::shared_ptr<storm::solver::NativeNondeterministicLinearEquationSolver<double>>(new storm::solver::NativeNondeterministicLinearEquationSolver<double>())); - storm::property::prctl::Ap<double>* apFormula = new storm::property::prctl::Ap<double>("elected"); - storm::property::prctl::Eventually<double>* eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); - storm::property::prctl::ProbabilisticNoBoundOperator<double>* probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula, true); + auto apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("elected"); + auto eventuallyFormula = std::make_shared<storm::properties::prctl::Eventually<double>>(apFormula); - std::vector<double> result = mc.checkNoBoundOperator(*probFormula); + std::vector<double> result = mc.checkOptimizingOperator(*eventuallyFormula, true); ASSERT_LT(std::abs(result[0] - 1.0), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; - apFormula = new storm::property::prctl::Ap<double>("elected"); - eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); - probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula, false); - - result = mc.checkNoBoundOperator(*probFormula); + result = mc.checkOptimizingOperator(*eventuallyFormula, false); ASSERT_LT(std::abs(result[0] - 1.0), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; - apFormula = new storm::property::prctl::Ap<double>("elected"); - storm::property::prctl::BoundedEventually<double>* boundedEventuallyFormula = new storm::property::prctl::BoundedEventually<double>(apFormula, 25); - probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(boundedEventuallyFormula, true); + apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("elected"); + auto boundedEventuallyFormula = std::make_shared<storm::properties::prctl::BoundedEventually<double>>(apFormula, 25); - result = mc.checkNoBoundOperator(*probFormula); + result = mc.checkOptimizingOperator(*boundedEventuallyFormula, true); ASSERT_LT(std::abs(result[0] - 0.0), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; - - apFormula = new storm::property::prctl::Ap<double>("elected"); - boundedEventuallyFormula = new storm::property::prctl::BoundedEventually<double>(apFormula, 25); - probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(boundedEventuallyFormula, false); - result = mc.checkNoBoundOperator(*probFormula); + result = mc.checkOptimizingOperator(*boundedEventuallyFormula, false); ASSERT_LT(std::abs(result[0] - 0.0), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; - apFormula = new storm::property::prctl::Ap<double>("elected"); - storm::property::prctl::ReachabilityReward<double>* reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward<double>(apFormula); - storm::property::prctl::RewardNoBoundOperator<double>* rewardFormula = new storm::property::prctl::RewardNoBoundOperator<double>(reachabilityRewardFormula, true); + apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("elected"); + auto reachabilityRewardFormula = std::make_shared<storm::properties::prctl::ReachabilityReward<double>>(apFormula); - result = mc.checkNoBoundOperator(*rewardFormula); + result = mc.checkOptimizingOperator(*reachabilityRewardFormula, true); ASSERT_LT(std::abs(result[0] - 6.172433512), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete rewardFormula; - - apFormula = new storm::property::prctl::Ap<double>("elected"); - reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward<double>(apFormula); - rewardFormula = new storm::property::prctl::RewardNoBoundOperator<double>(reachabilityRewardFormula, false); - result = mc.checkNoBoundOperator(*rewardFormula); + result = mc.checkOptimizingOperator(*reachabilityRewardFormula, false); ASSERT_LT(std::abs(result[0] - 6.1724344), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete rewardFormula; } TEST(SparseMdpPrctlModelCheckerTest, Consensus) { @@ -85,87 +64,65 @@ TEST(SparseMdpPrctlModelCheckerTest, Consensus) { std::shared_ptr<storm::models::Mdp<double>> mdp = abstractModel->as<storm::models::Mdp<double>>(); - ASSERT_EQ(mdp->getNumberOfStates(), 63616ull); - ASSERT_EQ(mdp->getNumberOfTransitions(), 213472ull); + ASSERT_EQ(63616ull, mdp->getNumberOfStates()); + ASSERT_EQ(213472ull, mdp->getNumberOfTransitions()); storm::modelchecker::prctl::SparseMdpPrctlModelChecker<double> mc(*mdp, std::shared_ptr<storm::solver::NativeNondeterministicLinearEquationSolver<double>>(new storm::solver::NativeNondeterministicLinearEquationSolver<double>())); - storm::property::prctl::Ap<double>* apFormula = new storm::property::prctl::Ap<double>("finished"); - storm::property::prctl::Eventually<double>* eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula); - storm::property::prctl::ProbabilisticNoBoundOperator<double>* probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula, true); + auto apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("finished"); + auto eventuallyFormula = std::make_shared<storm::properties::prctl::Eventually<double>>(apFormula); - std::vector<double> result = mc.checkNoBoundOperator(*probFormula); + std::vector<double> result = mc.checkOptimizingOperator(*eventuallyFormula, true); ASSERT_LT(std::abs(result[31168] - 1.0), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; - - apFormula = new storm::property::prctl::Ap<double>("finished"); - storm::property::prctl::Ap<double>* apFormula2 = new storm::property::prctl::Ap<double>("all_coins_equal_0"); - storm::property::prctl::And<double>* andFormula = new storm::property::prctl::And<double>(apFormula, apFormula2); - eventuallyFormula = new storm::property::prctl::Eventually<double>(andFormula); - probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula, true); + + apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("finished"); + auto apFormula2 = std::make_shared<storm::properties::prctl::Ap<double>>("all_coins_equal_0"); + auto andFormula = std::make_shared<storm::properties::prctl::And<double>>(apFormula, apFormula2); + eventuallyFormula = std::make_shared<storm::properties::prctl::Eventually<double>>(andFormula); - result = mc.checkNoBoundOperator(*probFormula); + result = mc.checkOptimizingOperator(*eventuallyFormula, true); ASSERT_LT(std::abs(result[31168] - 0.4374282832), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; - apFormula = new storm::property::prctl::Ap<double>("finished"); - apFormula2 = new storm::property::prctl::Ap<double>("all_coins_equal_1"); - andFormula = new storm::property::prctl::And<double>(apFormula, apFormula2); - eventuallyFormula = new storm::property::prctl::Eventually<double>(andFormula); - probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula, false); + apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("finished"); + apFormula2 = std::make_shared<storm::properties::prctl::Ap<double>>("all_coins_equal_1"); + andFormula = std::make_shared<storm::properties::prctl::And<double>>(apFormula, apFormula2); + eventuallyFormula = std::make_shared<storm::properties::prctl::Eventually<double>>(andFormula); - result = mc.checkNoBoundOperator(*probFormula); + result = mc.checkOptimizingOperator(*eventuallyFormula, false); ASSERT_LT(std::abs(result[31168] - 0.5293286369), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; - - apFormula = new storm::property::prctl::Ap<double>("finished"); - apFormula2 = new storm::property::prctl::Ap<double>("agree"); - storm::property::prctl::Not<double>* notFormula = new storm::property::prctl::Not<double>(apFormula2); - andFormula = new storm::property::prctl::And<double>(apFormula, notFormula); - eventuallyFormula = new storm::property::prctl::Eventually<double>(andFormula); - probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula, false); + + apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("finished"); + apFormula2 = std::make_shared<storm::properties::prctl::Ap<double>>("agree"); + auto notFormula = std::make_shared<storm::properties::prctl::Not<double>>(apFormula2); + andFormula = std::make_shared<storm::properties::prctl::And<double>>(apFormula, notFormula); + eventuallyFormula = std::make_shared<storm::properties::prctl::Eventually<double>>(andFormula); - result = mc.checkNoBoundOperator(*probFormula); + result = mc.checkOptimizingOperator(*eventuallyFormula, false); ASSERT_LT(std::abs(result[31168] - 0.10414097), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; - - apFormula = new storm::property::prctl::Ap<double>("finished"); - storm::property::prctl::BoundedEventually<double>* boundedEventuallyFormula = new storm::property::prctl::BoundedEventually<double>(apFormula, 50ull); - probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(boundedEventuallyFormula, true); + + apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("finished"); + auto boundedEventuallyFormula = std::make_shared<storm::properties::prctl::BoundedEventually<double>>(apFormula, 50ull); - result = mc.checkNoBoundOperator(*probFormula); + result = mc.checkOptimizingOperator(*boundedEventuallyFormula, true); ASSERT_LT(std::abs(result[31168] - 0.0), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; - - apFormula = new storm::property::prctl::Ap<double>("finished"); - boundedEventuallyFormula = new storm::property::prctl::BoundedEventually<double>(apFormula, 50ull); - probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(boundedEventuallyFormula, false); - - result = mc.checkNoBoundOperator(*probFormula); + result = mc.checkOptimizingOperator(*boundedEventuallyFormula, false); + ASSERT_LT(std::abs(result[31168] - 0.0), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete probFormula; - apFormula = new storm::property::prctl::Ap<double>("finished"); - storm::property::prctl::ReachabilityReward<double>* reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward<double>(apFormula); - storm::property::prctl::RewardNoBoundOperator<double>* rewardFormula = new storm::property::prctl::RewardNoBoundOperator<double>(reachabilityRewardFormula, true); + apFormula = std::make_shared<storm::properties::prctl::Ap<double>>("finished"); + auto reachabilityRewardFormula = std::make_shared<storm::properties::prctl::ReachabilityReward<double>>(apFormula); - result = mc.checkNoBoundOperator(*rewardFormula); + result = mc.checkOptimizingOperator(*reachabilityRewardFormula, true); ASSERT_LT(std::abs(result[31168] - 1725.593313), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete rewardFormula; - - apFormula = new storm::property::prctl::Ap<double>("finished"); - reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward<double>(apFormula); - rewardFormula = new storm::property::prctl::RewardNoBoundOperator<double>(reachabilityRewardFormula, false); - - result = mc.checkNoBoundOperator(*rewardFormula); - + + result = mc.checkOptimizingOperator(*reachabilityRewardFormula, false); + ASSERT_LT(std::abs(result[31168] - 2183.142422), s->getOptionByLongName("precision").getArgument(0).getValueAsDouble()); - delete rewardFormula; }