Browse Source
First version of minimum expected time for Markov automata.
First version of minimum expected time for Markov automata.
Former-commit-id: 6053be896e
tempestpy_adaptions
dehnert
11 years ago
8 changed files with 184 additions and 8 deletions
-
4src/formula/Csl/AbstractNoBoundOperator.h
-
2src/formula/abstract/StateNoBoundOperator.h
-
2src/modelchecker/csl/AbstractModelChecker.h
-
153src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h
-
2src/modelchecker/prctl/AbstractModelChecker.h
-
13src/models/MarkovAutomaton.h
-
7src/parser/MarkovAutomatonSparseTransitionParser.cpp
-
7src/storm.cpp
@ -0,0 +1,153 @@ |
|||
#ifndef STORM_MODELCHECKER_CSL_SPARSEMARKOVAUTOMATONCSLMODELCHECKER_H_ |
|||
#define STORM_MODELCHECKER_CSL_SPARSEMARKOVAUTOMATONCSLMODELCHECKER_H_ |
|||
|
|||
#include <stack> |
|||
|
|||
#include "src/modelchecker/csl/AbstractModelChecker.h" |
|||
#include "src/models/MarkovAutomaton.h" |
|||
#include "src/storage/BitVector.h" |
|||
#include "src/solver/AbstractNondeterministicLinearEquationSolver.h" |
|||
#include "src/exceptions/NotImplementedException.h" |
|||
|
|||
namespace storm { |
|||
namespace modelchecker { |
|||
namespace csl { |
|||
|
|||
template<typename ValueType> |
|||
class SparseMarkovAutomatonCslModelChecker : public AbstractModelChecker<ValueType> { |
|||
public: |
|||
|
|||
explicit SparseMarkovAutomatonCslModelChecker(storm::models::MarkovAutomaton<ValueType> const& model, storm::solver::AbstractNondeterministicLinearEquationSolver<ValueType>* linearEquationSolver) : AbstractModelChecker<ValueType>(model), minimumOperatorStack(), linearEquationSolver(linearEquationSolver) { |
|||
// Intentionally left empty. |
|||
} |
|||
|
|||
/*! |
|||
* Returns a constant reference to the MDP associated with this model checker. |
|||
* @returns A constant reference to the MDP associated with this model checker. |
|||
*/ |
|||
storm::models::MarkovAutomaton<ValueType> const& getModel() const { |
|||
return AbstractModelChecker<ValueType>::template getModel<storm::models::MarkovAutomaton<ValueType>>(); |
|||
} |
|||
|
|||
std::vector<ValueType> checkUntil(storm::property::csl::Until<ValueType> const& formula, bool qualitative) const { |
|||
throw storm::exceptions::NotImplementedException() << "Model checking Until formulas on Markov automata is not yet implemented."; |
|||
} |
|||
|
|||
std::vector<ValueType> checkTimeBoundedUntil(storm::property::csl::TimeBoundedUntil<ValueType> const& formula, bool qualitative) const { |
|||
throw storm::exceptions::NotImplementedException() << "Model checking Until formulas on Markov automata is not yet implemented."; |
|||
} |
|||
|
|||
std::vector<ValueType> checkTimeBoundedEventually(storm::property::csl::TimeBoundedEventually<ValueType> const& formula, bool qualitative) const { |
|||
throw storm::exceptions::NotImplementedException() << "Model checking time-bounded Until formulas on Markov automata is not yet implemented."; |
|||
} |
|||
|
|||
std::vector<ValueType> checkGlobally(storm::property::csl::Globally<ValueType> const& formula, bool qualitative) const { |
|||
throw storm::exceptions::NotImplementedException() << "Model checking Globally formulas on Markov automata is not yet implemented."; |
|||
} |
|||
|
|||
std::vector<ValueType> checkEventually(storm::property::csl::Eventually<ValueType> const& formula, bool qualitative) const { |
|||
throw storm::exceptions::NotImplementedException() << "Model checking Eventually formulas on Markov automata is not yet implemented."; |
|||
} |
|||
|
|||
std::vector<ValueType> checkNext(storm::property::csl::Next<ValueType> const& formula, bool qualitative) const { |
|||
throw storm::exceptions::NotImplementedException() << "Model checking Next formulas on Markov automata is not yet implemented."; |
|||
} |
|||
|
|||
std::vector<ValueType> checkNoBoundOperator(storm::property::csl::AbstractNoBoundOperator<ValueType> const& formula) const { |
|||
// Check if the operator was an non-optimality operator and report an error in that case. |
|||
if (!formula.isOptimalityOperator()) { |
|||
LOG4CPLUS_ERROR(logger, "Formula does not specify neither min nor max optimality, which is not meaningful for nondeterministic models."); |
|||
throw storm::exceptions::InvalidArgumentException() << "Formula does not specify neither min nor max optimality, which is not meaningful for nondeterministic models."; |
|||
} |
|||
minimumOperatorStack.push(formula.isMinimumOperator()); |
|||
std::vector<ValueType> result = formula.check(*this, false); |
|||
minimumOperatorStack.pop(); |
|||
return result; |
|||
} |
|||
|
|||
std::vector<ValueType> checkExpectedTime(bool min, storm::storage::BitVector const& goalStates) const { |
|||
// TODO: check whether the Markov automaton is closed once again? Or should that rather be done when constructing the model checker? |
|||
// For now we just assume that it is closed already. |
|||
|
|||
// Start by identifying the states for which values need to be computed. |
|||
storm::storage::BitVector maybeStates = ~goalStates; |
|||
|
|||
// Then, we can eliminate the rows and columns for all states whose values are already known to be 0. |
|||
std::vector<ValueType> x(maybeStates.getNumberOfSetBits()); |
|||
std::vector<uint_fast64_t> subNondeterministicChoiceIndices = this->computeNondeterministicChoiceIndicesForConstraint(maybeStates); |
|||
storm::storage::SparseMatrix<ValueType> submatrix = this->getModel().getTransitionMatrix().getSubmatrix(maybeStates, this->getModel().getNondeterministicChoiceIndices()); |
|||
|
|||
// Now prepare the mean sojourn times for all states so they can be used as the right-hand side of the equation system. |
|||
std::vector<ValueType> meanSojournTimes(this->getModel().getExitRates()); |
|||
for (auto state : this->getModel().getMarkovianStates()) { |
|||
meanSojournTimes[state] = storm::utility::constGetOne<ValueType>() / meanSojournTimes[state]; |
|||
} |
|||
|
|||
// Finally, prepare the actual right-hand side. |
|||
std::vector<ValueType> b(submatrix.getRowCount()); |
|||
storm::utility::vector::selectVectorValuesRepeatedly(b, maybeStates, this->getModel().getNondeterministicChoiceIndices(), meanSojournTimes); |
|||
|
|||
// Solve the corresponding system of equations. |
|||
if (linearEquationSolver != nullptr) { |
|||
this->linearEquationSolver->solveEquationSystem(min, submatrix, x, b, subNondeterministicChoiceIndices); |
|||
} else { |
|||
throw storm::exceptions::InvalidStateException() << "No valid linear equation solver available."; |
|||
} |
|||
|
|||
// Create resulting vector. |
|||
std::vector<ValueType> result(this->getModel().getNumberOfStates()); |
|||
|
|||
// Set values of resulting vector according to previous result (goal states will have a value of 0) and return the result. |
|||
storm::utility::vector::setVectorValues<ValueType>(result, maybeStates, x); |
|||
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: |
|||
/*! |
|||
* Computes the nondeterministic choice indices vector resulting from reducing the full system to the states given |
|||
* by the parameter constraint. |
|||
* |
|||
* @param constraint A bit vector specifying which states are kept. |
|||
* @returns A vector of the nondeterministic choice indices of the subsystem induced by the given constraint. |
|||
*/ |
|||
std::vector<uint_fast64_t> computeNondeterministicChoiceIndicesForConstraint(storm::storage::BitVector const& constraint) const { |
|||
// First, get a reference to the full nondeterministic choice indices. |
|||
std::vector<uint_fast64_t> const& nondeterministicChoiceIndices = this->getModel().getNondeterministicChoiceIndices(); |
|||
|
|||
// Reserve the known amount of slots for the resulting vector. |
|||
std::vector<uint_fast64_t> subNondeterministicChoiceIndices(constraint.getNumberOfSetBits() + 1); |
|||
uint_fast64_t currentRowCount = 0; |
|||
uint_fast64_t currentIndexCount = 1; |
|||
|
|||
// Set the first element as this will clearly begin at offset 0. |
|||
subNondeterministicChoiceIndices[0] = 0; |
|||
|
|||
// Loop over all states that need to be kept and copy the relative indices of the nondeterministic choices over |
|||
// to the resulting vector. |
|||
for (auto index : constraint) { |
|||
subNondeterministicChoiceIndices[currentIndexCount] = currentRowCount + nondeterministicChoiceIndices[index + 1] - nondeterministicChoiceIndices[index]; |
|||
currentRowCount += nondeterministicChoiceIndices[index + 1] - nondeterministicChoiceIndices[index]; |
|||
++currentIndexCount; |
|||
} |
|||
|
|||
// Put a sentinel element at the end. |
|||
subNondeterministicChoiceIndices[constraint.getNumberOfSetBits()] = currentRowCount; |
|||
|
|||
return subNondeterministicChoiceIndices; |
|||
} |
|||
|
|||
// An object that is used for solving linear equations and performing matrix-vector multiplication. |
|||
std::unique_ptr<storm::solver::AbstractNondeterministicLinearEquationSolver<ValueType>> linearEquationSolver; |
|||
}; |
|||
} |
|||
} |
|||
} |
|||
|
|||
#endif /* STORM_MODELCHECKER_CSL_SPARSEMARKOVAUTOMATONCSLMODELCHECKER_H_ */ |
Write
Preview
Loading…
Cancel
Save
Reference in new issue