Browse Source

Merge branch 'master' into imca

Conflicts:
	src/models/AbstractModel.h

Former-commit-id: f94c912331
tempestpy_adaptions
dehnert 11 years ago
parent
commit
c5ff387b98
  1. 11
      CMakeLists.txt
  2. 2
      examples/mdp/tiny/tiny.pctl
  3. 4
      src/counterexamples/MILPMinimalLabelSetGenerator.h
  4. 6
      src/counterexamples/SMTMinimalCommandSetGenerator.h
  5. 1
      src/ir/expressions/BinaryNumericalFunctionExpression.cpp
  6. 38
      src/modelchecker/prctl/SparseMdpPrctlModelChecker.h
  7. 13
      src/models/AbstractModel.h
  8. 7
      src/models/AbstractNondeterministicModel.h
  9. 11
      src/models/Ctmc.h
  10. 12
      src/models/Ctmdp.h
  11. 14
      src/models/Dtmc.h
  12. 15
      src/models/Mdp.h
  13. 40
      src/storage/PartialScheduler.cpp
  14. 29
      src/storage/PartialScheduler.h
  15. 39
      src/storage/Scheduler.h
  16. 37
      src/storage/TotalScheduler.cpp
  17. 33
      src/storage/TotalScheduler.h
  18. 1
      src/storage/VectorSet.h
  19. 52
      src/utility/matrix.h

11
CMakeLists.txt

@ -90,6 +90,7 @@ if ("${Z3_ROOT}" STREQUAL "")
set(ENABLE_Z3 OFF)
else()
set(ENABLE_Z3 ON)
set(Z3_LIB_NAME "z3")
endif()
message(STATUS "StoRM - CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}")
@ -132,6 +133,10 @@ elseif(MSVC)
# Windows.h breaks GMM in gmm_except.h because of its macro definition for min and max
add_definitions(/DNOMINMAX)
if(ENABLE_Z3)
set(Z3_LIB_NAME "libz3")
endif()
# MSVC does not do strict-aliasing, so no option needed
else(CLANG)
message(STATUS "StoRM - Using Compiler Configuration: Clang (LLVM)")
@ -362,9 +367,9 @@ endif(ENABLE_GUROBI)
if (ENABLE_Z3)
message (STATUS "StoRM - Linking with Z3")
include_directories("${Z3_ROOT}/include")
target_link_libraries(storm "z3")
target_link_libraries(storm-functional-tests "z3")
target_link_libraries(storm-performance-tests "z3")
target_link_libraries(storm ${Z3_LIB_NAME})
target_link_libraries(storm-functional-tests ${Z3_LIB_NAME})
target_link_libraries(storm-performance-tests ${Z3_LIB_NAME})
endif(ENABLE_Z3)
#############################################################

2
examples/mdp/tiny/tiny.pctl

@ -0,0 +1,2 @@
Pmin=? [ F a ]
Pmax=? [ F a ]

4
src/counterexamples/MILPMinimalLabelSetGenerator.h

@ -1268,14 +1268,14 @@ namespace storm {
static storm::storage::VectorSet<uint_fast64_t> getMinimalLabelSet(storm::models::Mdp<T> const& labeledMdp, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, double probabilityThreshold, bool strictBound, bool checkThresholdFeasible = false, bool includeSchedulerCuts = false) {
#ifdef STORM_HAVE_GUROBI
// (0) Check whether the MDP is indeed labeled.
if (!labeledMdp.hasChoiceLabels()) {
if (!labeledMdp.hasChoiceLabeling()) {
throw storm::exceptions::InvalidArgumentException() << "Minimal label set generation is impossible for unlabeled model.";
}
// (1) Check whether its possible to exceed the threshold if checkThresholdFeasible is set.
double maximalReachabilityProbability = 0;
storm::modelchecker::prctl::SparseMdpPrctlModelChecker<T> modelchecker(labeledMdp, new storm::solver::GmmxxNondeterministicLinearEquationSolver<T>());
std::vector<T> result = modelchecker.checkUntil(false, phiStates, psiStates, false, nullptr);
std::vector<T> result = modelchecker.checkUntil(false, phiStates, psiStates, false).first;
for (auto state : labeledMdp.getInitialStates()) {
maximalReachabilityProbability = std::max(maximalReachabilityProbability, result[state]);
}

6
src/counterexamples/SMTMinimalCommandSetGenerator.h

@ -1447,14 +1447,14 @@ namespace storm {
storm::utility::ir::defineUndefinedConstants(program, constantDefinitionString);
// (0) Check whether the MDP is indeed labeled.
if (!labeledMdp.hasChoiceLabels()) {
if (!labeledMdp.hasChoiceLabeling()) {
throw storm::exceptions::InvalidArgumentException() << "Minimal command set generation is impossible for unlabeled model.";
}
// (1) Check whether its possible to exceed the threshold if checkThresholdFeasible is set.
double maximalReachabilityProbability = 0;
storm::modelchecker::prctl::SparseMdpPrctlModelChecker<T> modelchecker(labeledMdp, new storm::solver::GmmxxNondeterministicLinearEquationSolver<T>());
std::vector<T> result = modelchecker.checkUntil(false, phiStates, psiStates, false, nullptr);
std::vector<T> result = modelchecker.checkUntil(false, phiStates, psiStates, false).first;
for (auto state : labeledMdp.getInitialStates()) {
maximalReachabilityProbability = std::max(maximalReachabilityProbability, result[state]);
}
@ -1517,7 +1517,7 @@ namespace storm {
storm::models::Mdp<T> subMdp = labeledMdp.restrictChoiceLabels(commandSet);
storm::modelchecker::prctl::SparseMdpPrctlModelChecker<T> modelchecker(subMdp, new storm::solver::GmmxxNondeterministicLinearEquationSolver<T>());
LOG4CPLUS_DEBUG(logger, "Invoking model checker.");
std::vector<T> result = modelchecker.checkUntil(false, phiStates, psiStates, false, nullptr);
std::vector<T> result = modelchecker.checkUntil(false, phiStates, psiStates, false).first;
LOG4CPLUS_DEBUG(logger, "Computed model checking results.");
totalModelCheckingTime += std::chrono::high_resolution_clock::now() - modelCheckingClock;

1
src/ir/expressions/BinaryNumericalFunctionExpression.cpp

@ -6,6 +6,7 @@
*/
#include <sstream>
#include <algorithm>
#include "BinaryNumericalFunctionExpression.h"

38
src/modelchecker/prctl/SparseMdpPrctlModelChecker.h

@ -19,6 +19,7 @@
#include "src/utility/vector.h"
#include "src/utility/graph.h"
#include "src/settings/Settings.h"
#include "src/storage/TotalScheduler.h"
namespace storm {
namespace modelchecker {
@ -265,7 +266,7 @@ namespace storm {
* checker. If the qualitative flag is set, exact probabilities might not be computed.
*/
virtual std::vector<Type> checkUntil(const storm::property::prctl::Until<Type>& formula, bool qualitative) const {
return this->checkUntil(this->minimumOperatorStack.top(), formula.getLeft().check(*this), formula.getRight().check(*this), qualitative, nullptr);
return this->checkUntil(this->minimumOperatorStack.top(), formula.getLeft().check(*this), formula.getRight().check(*this), qualitative).first;
}
/*!
@ -284,7 +285,7 @@ namespace storm {
* @return The probabilities for the satisfying phi until psi for each state of the model. If the
* qualitative flag is set, exact probabilities might not be computed.
*/
std::vector<Type> checkUntil(bool minimize, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative, std::vector<uint_fast64_t>* scheduler) const {
std::pair<std::vector<Type>, storm::storage::TotalScheduler> checkUntil(bool minimize, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative) const {
// We need to identify the states which have to be taken out of the matrix, i.e.
// all states that have probability 0 and 1 of satisfying the until-formula.
std::pair<storm::storage::BitVector, storm::storage::BitVector> statesWithProbability01;
@ -347,12 +348,10 @@ namespace storm {
storm::utility::vector::setVectorValues<Type>(result, statesWithProbability0, storm::utility::constGetZero<Type>());
storm::utility::vector::setVectorValues<Type>(result, statesWithProbability1, storm::utility::constGetOne<Type>());
// If we were required to generate a scheduler, do so now.
if (scheduler != nullptr) {
this->computeTakenChoices(this->minimumOperatorStack.top(), false, result, *scheduler, this->getModel().getNondeterministicChoiceIndices());
}
// Finally, compute a scheduler that achieves the extramal value.
storm::storage::TotalScheduler scheduler = this->computeExtremalScheduler(this->minimumOperatorStack.top(), false, result);
return result;
return std::make_pair(result, scheduler);
}
/*!
@ -443,7 +442,7 @@ namespace storm {
* checker. If the qualitative flag is set, exact values might not be computed.
*/
virtual std::vector<Type> checkReachabilityReward(const storm::property::prctl::ReachabilityReward<Type>& formula, bool qualitative) const {
return this->checkReachabilityReward(this->minimumOperatorStack.top(), formula.getChild().check(*this), qualitative, nullptr);
return this->checkReachabilityReward(this->minimumOperatorStack.top(), formula.getChild().check(*this), qualitative).first;
}
/*!
@ -461,7 +460,7 @@ namespace storm {
* @return The expected reward values gained before a target state is reached for each state. If the
* qualitative flag is set, exact values might not be computed.
*/
virtual std::vector<Type> checkReachabilityReward(bool minimize, storm::storage::BitVector const& targetStates, bool qualitative, std::vector<uint_fast64_t>* scheduler) const {
virtual std::pair<std::vector<Type>, storm::storage::TotalScheduler> checkReachabilityReward(bool minimize, storm::storage::BitVector const& targetStates, 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.");
@ -548,12 +547,10 @@ namespace storm {
storm::utility::vector::setVectorValues(result, targetStates, storm::utility::constGetZero<Type>());
storm::utility::vector::setVectorValues(result, infinityStates, storm::utility::constGetInfinity<Type>());
// If we were required to generate a scheduler, do so now.
if (scheduler != nullptr) {
this->computeTakenChoices(this->minimumOperatorStack.top(), true, result, *scheduler, this->getModel().getNondeterministicChoiceIndices());
}
// Finally, compute a scheduler that achieves the extramal value.
storm::storage::TotalScheduler scheduler = this->computeExtremalScheduler(this->minimumOperatorStack.top(), false, result);
return result;
return std::make_pair(result, scheduler);
}
protected:
@ -565,8 +562,8 @@ namespace storm {
* @param takenChoices The output vector that is to store the taken choices.
* @param nondeterministicChoiceIndices The assignment of states to their nondeterministic choices in the matrix.
*/
void computeTakenChoices(bool minimize, bool addRewards, std::vector<Type> const& result, std::vector<uint_fast64_t>& takenChoices, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices) const {
std::vector<Type> temporaryResult(nondeterministicChoiceIndices.size() - 1);
storm::storage::TotalScheduler computeExtremalScheduler(bool minimize, bool addRewards, std::vector<Type> const& result) const {
std::vector<Type> temporaryResult(this->getModel().getNondeterministicChoiceIndices().size() - 1);
std::vector<Type> nondeterministicResult(result);
storm::solver::GmmxxLinearEquationSolver<Type> solver;
solver.performMatrixVectorMultiplication(this->getModel().getTransitionMatrix(), nondeterministicResult, nullptr, 1);
@ -585,11 +582,16 @@ namespace storm {
}
storm::utility::vector::addVectorsInPlace(nondeterministicResult, totalRewardVector);
}
std::vector<uint_fast64_t> choices(this->getModel().getNumberOfStates());
if (minimize) {
storm::utility::vector::reduceVectorMin(nondeterministicResult, temporaryResult, nondeterministicChoiceIndices, &takenChoices);
storm::utility::vector::reduceVectorMin(nondeterministicResult, temporaryResult, this->getModel().getNondeterministicChoiceIndices(), &choices);
} else {
storm::utility::vector::reduceVectorMax(nondeterministicResult, temporaryResult, nondeterministicChoiceIndices, &takenChoices);
storm::utility::vector::reduceVectorMax(nondeterministicResult, temporaryResult, this->getModel().getNondeterministicChoiceIndices(), &choices);
}
return storm::storage::TotalScheduler(choices);
}
/*!

13
src/models/AbstractModel.h

@ -9,6 +9,7 @@
#include "src/models/AtomicPropositionsLabeling.h"
#include "src/storage/BitVector.h"
#include "src/storage/SparseMatrix.h"
#include "src/storage/Scheduler.h"
#include "src/storage/VectorSet.h"
#include "src/storage/StronglyConnectedComponentDecomposition.h"
#include "src/utility/Hash.h"
@ -403,7 +404,7 @@ class AbstractModel: public std::enable_shared_from_this<AbstractModel<T>> {
* Retrieves whether this model has a labeling for the choices.
* @return True if this model has a labeling.
*/
bool hasChoiceLabels() const {
bool hasChoiceLabeling() const {
return choiceLabeling;
}
@ -459,7 +460,15 @@ class AbstractModel: public std::enable_shared_from_this<AbstractModel<T>> {
* @return void
*/
virtual void setStateIdBasedChoiceLabeling() = 0;
/*
* Applies the given scheduler to the model.
*
* @param scheduler The scheduler to apply.
* @return The model resulting from applying the scheduler to the model.
*/
virtual std::shared_ptr<AbstractModel<T>> applyScheduler(storm::storage::Scheduler const& scheduler) const = 0;
/*!
* Exports the model to the dot-format and prints the result to the given stream.
*

7
src/models/AbstractNondeterministicModel.h

@ -1,10 +1,11 @@
#ifndef STORM_MODELS_ABSTRACTNONDETERMINISTICMODEL_H_
#define STORM_MODELS_ABSTRACTNONDETERMINISTICMODEL_H_
#include "AbstractModel.h"
#include <memory>
#include "AbstractModel.h"
#include "src/storage/Scheduler.h"
namespace storm {
namespace models {
@ -235,7 +236,7 @@ namespace storm {
this->choiceLabeling.reset(newChoiceLabeling);
}
private:
/*! A vector of indices mapping states to the choices (rows) in the transition matrix. */
std::vector<uint_fast64_t> nondeterministicChoiceIndices;

11
src/models/Ctmc.h

@ -86,6 +86,17 @@ public:
virtual std::size_t getHash() const override {
return AbstractDeterministicModel<T>::getHash();
}
virtual std::shared_ptr<AbstractModel<T>> applyScheduler(storm::storage::Scheduler const& scheduler) const override {
std::vector<uint_fast64_t> nondeterministicChoiceIndices(this->getNumberOfStates() + 1);
for (uint_fast64_t state = 0; state < this->getNumberOfStates(); ++state) {
nondeterministicChoiceIndices[state] = state;
}
nondeterministicChoiceIndices[this->getNumberOfStates()] = this->getNumberOfStates();
storm::storage::SparseMatrix<T> newTransitionMatrix = storm::utility::matrix::applyScheduler(this->getTransitionMatrix(), nondeterministicChoiceIndices, scheduler);
return std::shared_ptr<AbstractModel<T>>(new Ctmc(newTransitionMatrix, this->getStateLabeling(), this->hasStateRewards() ? this->getStateRewardVector() : boost::optional<std::vector<T>>(), this->hasTransitionRewards() ? this->getTransitionRewardMatrix() : boost::optional<storm::storage::SparseMatrix<T>>(), this->hasChoiceLabeling() ? this->getChoiceLabeling() : boost::optional<std::vector<storm::storage::VectorSet<uint_fast64_t>>>()));
}
};
} // namespace models

12
src/models/Ctmdp.h

@ -115,6 +115,18 @@ public:
return AbstractNondeterministicModel<T>::getHash();
}
virtual std::shared_ptr<AbstractModel<T>> applyScheduler(storm::storage::Scheduler const& scheduler) const override {
storm::storage::SparseMatrix<T> newTransitionMatrix = storm::utility::matrix::applyScheduler(this->getTransitionMatrix(), this->getNondeterministicChoiceIndices(), scheduler);
// Construct the new nondeterministic choice indices for the resulting matrix.
std::vector<uint_fast64_t> nondeterministicChoiceIndices(this->getNumberOfStates() + 1);
for (uint_fast64_t state = 0; state < this->getNumberOfStates(); ++state) {
nondeterministicChoiceIndices[state] = state;
}
nondeterministicChoiceIndices[this->getNumberOfStates()] = this->getNumberOfStates();
return std::shared_ptr<AbstractModel<T>>(new Ctmdp(newTransitionMatrix, this->getStateLabeling(), nondeterministicChoiceIndices, this->hasStateRewards() ? this->getStateRewardVector() : boost::optional<std::vector<T>>(), this->hasTransitionRewards() ? this->getTransitionRewardMatrix() : boost::optional<storm::storage::SparseMatrix<T>>(), this->hasChoiceLabeling() ? this->getChoiceLabeling() : boost::optional<std::vector<storm::storage::VectorSet<uint_fast64_t>>>()));
}
private:
/*!

14
src/models/Dtmc.h

@ -19,6 +19,7 @@
#include "src/exceptions/InvalidArgumentException.h"
#include "src/settings/Settings.h"
#include "src/utility/vector.h"
#include "src/utility/matrix.h"
namespace storm {
@ -276,7 +277,7 @@ public:
}
boost::optional<std::vector<storm::storage::VectorSet<uint_fast64_t>>> newChoiceLabels;
if(this->hasChoiceLabels()) {
if(this->hasChoiceLabeling()) {
// Get the choice label sets and move the needed values to the front.
std::vector<storm::storage::VectorSet<uint_fast64_t>> newChoice(this->getChoiceLabeling());
@ -299,6 +300,17 @@ public:
}
virtual std::shared_ptr<AbstractModel<T>> applyScheduler(storm::storage::Scheduler const& scheduler) const override {
std::vector<uint_fast64_t> nondeterministicChoiceIndices(this->getNumberOfStates() + 1);
for (uint_fast64_t state = 0; state < this->getNumberOfStates(); ++state) {
nondeterministicChoiceIndices[state] = state;
}
nondeterministicChoiceIndices[this->getNumberOfStates()] = this->getNumberOfStates();
storm::storage::SparseMatrix<T> newTransitionMatrix = storm::utility::matrix::applyScheduler(this->getTransitionMatrix(), nondeterministicChoiceIndices, scheduler);
return std::shared_ptr<AbstractModel<T>>(new Dtmc(newTransitionMatrix, this->getStateLabeling(), this->hasStateRewards() ? this->getStateRewardVector() : boost::optional<std::vector<T>>(), this->hasTransitionRewards() ? this->getTransitionRewardMatrix() : boost::optional<storm::storage::SparseMatrix<T>>(), this->hasChoiceLabeling() ? this->getChoiceLabeling() : boost::optional<std::vector<storm::storage::VectorSet<uint_fast64_t>>>()));
}
private:
/*!
* @brief Perform some sanity checks.

15
src/models/Mdp.h

@ -18,6 +18,7 @@
#include "src/settings/Settings.h"
#include "src/models/AbstractNondeterministicModel.h"
#include "src/utility/set.h"
#include "src/utility/matrix.h"
namespace storm {
@ -136,7 +137,7 @@ public:
*/
Mdp<T> restrictChoiceLabels(storm::storage::VectorSet<uint_fast64_t> const& enabledChoiceLabels) const {
// Only perform this operation if the given model has choice labels.
if (!this->hasChoiceLabels()) {
if (!this->hasChoiceLabeling()) {
throw storm::exceptions::InvalidArgumentException() << "Restriction to label set is impossible for unlabeled model.";
}
@ -192,6 +193,18 @@ public:
return AbstractNondeterministicModel<T>::getHash();
}
virtual std::shared_ptr<AbstractModel<T>> applyScheduler(storm::storage::Scheduler const& scheduler) const override {
storm::storage::SparseMatrix<T> newTransitionMatrix = storm::utility::matrix::applyScheduler(this->getTransitionMatrix(), this->getNondeterministicChoiceIndices(), scheduler);
// Construct the new nondeterministic choice indices for the resulting matrix.
std::vector<uint_fast64_t> nondeterministicChoiceIndices(this->getNumberOfStates() + 1);
for (uint_fast64_t state = 0; state < this->getNumberOfStates(); ++state) {
nondeterministicChoiceIndices[state] = state;
}
nondeterministicChoiceIndices[this->getNumberOfStates()] = this->getNumberOfStates();
return std::shared_ptr<AbstractModel<T>>(new Mdp(newTransitionMatrix, this->getStateLabeling(), nondeterministicChoiceIndices, this->hasStateRewards() ? this->getStateRewardVector() : boost::optional<std::vector<T>>(), this->hasTransitionRewards() ? this->getTransitionRewardMatrix() : boost::optional<storm::storage::SparseMatrix<T>>(), this->hasChoiceLabeling() ? this->getChoiceLabeling() : boost::optional<std::vector<storm::storage::VectorSet<uint_fast64_t>>>()));
}
private:
/*!

40
src/storage/PartialScheduler.cpp

@ -0,0 +1,40 @@
#include "src/storage/PartialScheduler.h"
#include "src/exceptions/InvalidArgumentException.h"
namespace storm {
namespace storage {
void PartialScheduler::setChoice(uint_fast64_t state, uint_fast64_t choice) {
choices[state] = choice;
}
bool PartialScheduler::isChoiceDefined(uint_fast64_t state) const {
return choices.find(state) != choices.end();
}
uint_fast64_t PartialScheduler::getChoice(uint_fast64_t state) const {
auto stateChoicePair = choices.find(state);
if (stateChoicePair == choices.end()) {
throw storm::exceptions::InvalidArgumentException() << "Scheduler does not define a choice for state " << state;
}
return stateChoicePair->second;
}
std::ostream& operator<<(std::ostream& out, PartialScheduler const& scheduler) {
out << "partial scheduler (defined on " << scheduler.choices.size() << " states) [ ";
uint_fast64_t remainingEntries = scheduler.choices.size();
for (auto stateChoicePair : scheduler.choices) {
out << stateChoicePair.first << " -> " << stateChoicePair.second;
--remainingEntries;
if (remainingEntries > 0) {
out << ", ";
}
}
out << "]";
return out;
}
} // namespace storage
} // namespace storm

29
src/storage/PartialScheduler.h

@ -0,0 +1,29 @@
#ifndef STORM_STORAGE_PARTIALSCHEDULER_H_
#define STORM_STORAGE_PARTIALSCHEDULER_H_
#include <unordered_map>
#include <ostream>
#include "src/storage/Scheduler.h"
namespace storm {
namespace storage {
class PartialScheduler : public Scheduler {
public:
void setChoice(uint_fast64_t state, uint_fast64_t choice) override;
bool isChoiceDefined(uint_fast64_t state) const override;
uint_fast64_t getChoice(uint_fast64_t state) const override;
friend std::ostream& operator<<(std::ostream& out, PartialScheduler const& scheduler);
private:
// A mapping from all states that have defined choices to their respective choices.
std::unordered_map<uint_fast64_t, uint_fast64_t> choices;
};
}
}
#endif /* STORM_STORAGE_PARTIALSCHEDULER_H_ */

39
src/storage/Scheduler.h

@ -0,0 +1,39 @@
#ifndef STORM_STORAGE_SCHEDULER_H_
#define STORM_STORAGE_SCHEDULER_H_
#include <cstdint>
namespace storm {
namespace storage {
/*
* This class is the abstract base class of all scheduler classes. Scheduler classes define which action is chosen in a particular state of a non-deterministic model.
* More concretely, a scheduler maps a state s to i if the scheduler takes the i-th action available in s (i.e. the choices are relative to the states).
*/
class Scheduler {
public:
/*
* Sets the choice defined by the scheduler for the given state.
*
* @param state The state for which to set the choice.
* @param choice The choice to set for the given state.
*/
virtual void setChoice(uint_fast64_t state, uint_fast64_t choice) = 0;
/*
* Retrieves whether this scheduler defines a choice for the given state.
*
* @param state The state for which to check whether the scheduler defines a choice.
* @return True if the scheduler defines a choice for the given state.
*/
virtual bool isChoiceDefined(uint_fast64_t state) const = 0;
/*!
* Retrieves the choice for the given state under the assumption that the scheduler defines a proper choice for the state.
*/
virtual uint_fast64_t getChoice(uint_fast64_t state) const = 0;
};
}
}
#endif /* STORM_STORAGE_SCHEDULER_H_ */

37
src/storage/TotalScheduler.cpp

@ -0,0 +1,37 @@
#include "src/storage/TotalScheduler.h"
namespace storm {
namespace storage {
TotalScheduler::TotalScheduler(uint_fast64_t numberOfStates) : choices(numberOfStates) {
// Intentionally left empty.
}
TotalScheduler::TotalScheduler(std::vector<uint_fast64_t> const& choices) : choices(choices) {
// Intentionally left empty.
}
void TotalScheduler::setChoice(uint_fast64_t state, uint_fast64_t choice) {
choices[state] = choice;
}
bool TotalScheduler::isChoiceDefined(uint_fast64_t state) const {
return true;
}
uint_fast64_t TotalScheduler::getChoice(uint_fast64_t state) const {
return choices[state];
}
std::ostream& operator<<(std::ostream& out, TotalScheduler const& scheduler) {
out << "total scheduler (defined on " << scheduler.choices.size() << " states) [ ";
for (uint_fast64_t state = 0; state < scheduler.choices.size() - 1; ++state) {
out << state << " -> " << scheduler.choices[state] << ", ";
}
if (scheduler.choices.size() > 0) {
out << (scheduler.choices.size() - 1) << " -> " << scheduler.choices[scheduler.choices.size() - 1] << " ]";
}
return out;
}
}
}

33
src/storage/TotalScheduler.h

@ -0,0 +1,33 @@
#ifndef STORM_STORAGE_TOTALSCHEDULER_H_
#define STORM_STORAGE_TOTALSCHEDULER_H_
#include <vector>
#include <ostream>
#include "src/storage/Scheduler.h"
namespace storm {
namespace storage {
class TotalScheduler : public Scheduler {
public:
TotalScheduler(uint_fast64_t numberOfStates);
TotalScheduler(std::vector<uint_fast64_t> const& choices);
void setChoice(uint_fast64_t state, uint_fast64_t choice) override;
bool isChoiceDefined(uint_fast64_t state) const override;
uint_fast64_t getChoice(uint_fast64_t state) const override;
friend std::ostream& operator<<(std::ostream& out, TotalScheduler const& scheduler);
private:
// A vector that stores the choice for each state.
std::vector<uint_fast64_t> choices;
};
} // namespace storage
} // namespace storm
#endif /* STORM_STORAGE_TOTALSCHEDULER_H_ */

1
src/storage/VectorSet.h

@ -8,6 +8,7 @@
#ifndef STORM_STORAGE_VECTORSET_H
#define STORM_STORAGE_VECTORSET_H
#include <set>
#include <algorithm>
#include <iostream>
#include <vector>

52
src/utility/matrix.h

@ -0,0 +1,52 @@
#ifndef STORM_UTILITY_MATRIX_H_
#define STORM_UTILITY_MATRIX_H_
#include "src/storage/SparseMatrix.h"
#include "src/storage/Scheduler.h"
#include "src/exceptions/InvalidStateException.h"
namespace storm {
namespace utility {
namespace matrix {
/*!
* Applies the given scheduler to the given transition matrix. This means that all choices that are not taken by the scheduler are
* dropped from the transition matrix. If a state has no choice enabled, it is equipped with a self-loop instead.
*
* @param transitionMatrix The transition matrix of the original system.
* @param nondeterministicChoiceIndices A vector indicating at which rows the choices for the states begin.
* @param scheduler The scheduler to apply to the system.
* @return A transition matrix that corresponds to all transitions of the given system that are selected by the given scheduler.
*/
template <typename T>
storm::storage::SparseMatrix<T> applyScheduler(storm::storage::SparseMatrix<T> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, storm::storage::Scheduler const& scheduler) {
storm::storage::SparseMatrix<T> result(nondeterministicChoiceIndices.size() - 1, transitionMatrix.getColumnCount());
for (uint_fast64_t state = 0; state < nondeterministicChoiceIndices.size() - 1; ++state) {
if (scheduler.isChoiceDefined(state)) {
// Check whether the choice is valid for this state.
uint_fast64_t choice = nondeterministicChoiceIndices[state] + scheduler.getChoice(state);
if (choice >= nondeterministicChoiceIndices[state + 1]) {
throw storm::exceptions::InvalidStateException() << "Scheduler defines illegal choice " << choice << " for state " << state << ".";
}
// If a valid choice for this state is defined, we copy over the corresponding entries.
typename storm::storage::SparseMatrix<T>::Rows selectedRow = transitionMatrix.getRow(choice);
for (auto entry : selectedRow) {
result.insertNextValue(state, entry.column(), entry.value());
}
} else {
// If no valid choice for the state is defined, we insert a self-loop.
result.insertNextValue(state, state, storm::utility::constGetOne<T>());
}
}
// Finalize the matrix creation and return result.
result.finalize();
return result;
}
}
}
}
#endif /* STORM_UTILITY_MATRIX_H_ */
Loading…
Cancel
Save