15template<
typename ValueType>
20template<
typename ValueType>
21template<
typename RewardModelType>
27template<
typename ValueType>
30 performMaximalEndComponentDecomposition(transitionMatrix, backwardTransitions);
33template<
typename ValueType>
37 performMaximalEndComponentDecomposition(transitionMatrix, backwardTransitions, states);
40template<
typename ValueType>
45 performMaximalEndComponentDecomposition(transitionMatrix, backwardTransitions, states, choices);
48template<
typename ValueType>
54template<
typename ValueType>
59template<
typename ValueType>
65template<
typename ValueType>
70template<
typename ValueType>
76template<
typename ValueType>
79 return "Empty MEC decomposition.";
81 uint64_t statesInMec = 0;
82 uint64_t choicesInMec = 0;
83 uint64_t trivialMecs = 0;
84 uint64_t smallestSize = std::numeric_limits<uint64_t>::max();
85 uint64_t largestSize = 0;
86 for (
auto const& mec : this->blocks) {
87 statesInMec += mec.size();
88 if (mec.size() == 1u) {
91 smallestSize = std::min<uint64_t>(smallestSize, mec.size());
92 largestSize = std::max<uint64_t>(largestSize, mec.size());
95 uint64_t
const statesInNonTrivialMec = statesInMec - trivialMecs;
96 auto getPercentage = [&totalNumberOfStates](uint64_t states) ->
double {
97 return (totalNumberOfStates == 0) ? 0.0 : (100.0 * states / totalNumberOfStates);
100 ss <<
"MEC decomposition statistics: ";
101 ss <<
"There are " << this->size() <<
" MECs out of which " << trivialMecs <<
" are trivial, i.e., consist of a single state.";
102 ss <<
" " << statesInMec <<
" out of " << totalNumberOfStates <<
" states (" << getPercentage(statesInMec) <<
"%) are on some MEC. "
103 << statesInNonTrivialMec <<
" states (" << getPercentage(statesInNonTrivialMec) <<
"%) are on a non-trivial mec. ";
104 if (largestSize > 0) {
105 ss <<
"The smallest non-trivial MEC has " << smallestSize <<
" states and the largest non-trivial MEC has " << largestSize <<
" states.";
119 sccIndications.assign(sccDecRes.
sccCount + 1, 0ull);
123 std::span<uint64_t> sccCounts(sccIndications.begin() + 1, sccIndications.end());
131 for (
auto& count : sccCounts) {
132 auto const oldSum = sum;
140 sccStates[sccCounts[sccIndex]] = state;
141 ++sccCounts[sccIndex];
148template<
typename ValueType>
157 SccDecompositionResult sccDecRes;
158 SccDecompositionMemoryCache sccDecCache;
159 StronglyConnectedComponentDecompositionOptions sccDecOptions;
160 sccDecOptions.dropNaiveSccs();
162 sccDecOptions.subsystem(*states);
165 ecChoices = *choices;
166 sccDecOptions.choices(ecChoices);
172 std::vector<uint64_t> ecSccStates, ecSccIndications;
173 auto getSccStates = [&ecSccStates, &ecSccIndications](uint64_t
const sccIndex) {
174 return std::span(ecSccStates).subspan(ecSccIndications[sccIndex], ecSccIndications[sccIndex + 1] - ecSccIndications[sccIndex]);
180 remainingEcCandidates = sccDecRes.nonTrivialStates;
184 for (
auto state : remainingEcCandidates) {
185 auto const sccIndex = sccDecRes.stateToSccMapping[state];
186 nonTrivSccIndices.set(sccIndex,
true);
187 bool stateCanStayInScc =
false;
188 for (
auto const choice : transitionMatrix.getRowGroupIndices(state)) {
189 if (!ecChoices.
get(choice)) {
192 auto row = transitionMatrix.
getRow(choice);
193 if (std::any_of(row.begin(), row.end(), [&sccIndex, &sccDecRes](
auto const& entry) {
194 return sccIndex != sccDecRes.stateToSccMapping[entry.getColumn()] && !storm::utility::isZero(entry.getValue());
196 ecChoices.
set(choice,
false);
197 ecSccIndices.set(sccIndex,
false);
199 stateCanStayInScc =
true;
202 if (!stateCanStayInScc) {
203 remainingEcCandidates.
set(state,
false);
208 ecSccIndices &= nonTrivSccIndices;
209 for (
auto sccIndex : ecSccIndices) {
210 MaximalEndComponent newMec;
211 for (
auto const state : getSccStates(sccIndex)) {
213 remainingEcCandidates.
set(state,
false);
216 for (
auto ecChoiceIt = ecChoices.
begin(nondeterministicChoiceIndices[state]); *ecChoiceIt < nondeterministicChoiceIndices[state + 1];
218 containedChoices.insert(*ecChoiceIt);
220 STORM_LOG_ASSERT(!containedChoices.empty(),
"The contained choices of any state in an MEC must be non-empty.");
221 newMec.addState(state, std::move(containedChoices));
223 this->blocks.emplace_back(std::move(newMec));
226 if (nonTrivSccIndices == ecSccIndices) {
234 remainingEcCandidates, ~remainingEcCandidates,
false, 0, ecChoices);
236 sccDecOptions.subsystem(remainingEcCandidates);
237 sccDecOptions.choices(ecChoices);
240 STORM_LOG_DEBUG(
"MEC decomposition found " << this->size() <<
" MEC(s).");
244template class MaximalEndComponentDecomposition<double>;
247template class MaximalEndComponentDecomposition<storm::RationalNumber>;
251template class MaximalEndComponentDecomposition<storm::Interval>;
255template class MaximalEndComponentDecomposition<storm::RationalFunction>;
Helper class that optionally holds a reference to an object of type T.
storm::storage::SparseMatrix< ValueType > const & getTransitionMatrix() const
Retrieves the matrix representing the transitions of the model.
storm::storage::SparseMatrix< ValueType > getBackwardTransitions() const
Retrieves the backward transition relation of the model, i.e.
The base class of sparse nondeterministic models.
A bit vector that is internally represented as a vector of 64-bit values.
void complement()
Negates all bits in the bit vector.
void resize(uint_fast64_t newLength, bool init=false)
Resizes the bit vector to hold the given new number of bits.
const_iterator begin() const
Returns an iterator to the indices of the set bits in the bit vector.
void set(uint_fast64_t index, bool value=true)
Sets the given truth value at the given index.
uint_fast64_t getNumberOfSetBits() const
Returns the number of bits that are set to true in this bit vector.
bool get(uint_fast64_t index) const
Retrieves the truth value of the bit at the given index and performs a bound check.
This class represents the decomposition of a model into blocks which are of the template type.
Decomposition & operator=(Decomposition const &other)
Assigns the contents of the given decomposition to the current one by copying the contents.
This class represents the decomposition of a nondeterministic model into its maximal end components.
MaximalEndComponentDecomposition & operator=(MaximalEndComponentDecomposition const &other)
Assigns the contents of the given MEC decomposition to the current one by copying its contents.
MaximalEndComponentDecomposition()
std::string statistics(uint64_t totalNumberOfStates) const
Returns a string containing statistics about the MEC decomposition, e.g., the number of (trivial/non-...
storm::storage::FlatSet< sparse::state_type > set_type
A class that holds a possibly non-square matrix in the compressed row storage format.
const_rows getRow(index_type row) const
Returns an object representing the given row.
std::vector< index_type > const & getRowGroupIndices() const
Returns the grouping of rows of this matrix.
index_type getRowCount() const
Returns the number of rows of the matrix.
#define STORM_LOG_DEBUG(message)
#define STORM_LOG_ASSERT(cond, message)
void getFlatSccDecomposition(SccDecompositionResult const &sccDecRes, std::vector< uint64_t > &sccStates, std::vector< uint64_t > &sccIndications)
Compute a mapping from SCC index to the set of states in that SCC.
void performSccDecomposition(storm::storage::SparseMatrix< ValueType > const &transitionMatrix, StronglyConnectedComponentDecompositionOptions const &options, SccDecompositionResult &result)
Computes an SCC decomposition for the given matrix and options.
storm::storage::BitVector performProbGreater0A(storm::storage::SparseMatrix< T > const &transitionMatrix, std::vector< uint_fast64_t > const &nondeterministicChoiceIndices, storm::storage::SparseMatrix< T > const &backwardTransitions, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates, bool useStepBound, uint_fast64_t maximalSteps, boost::optional< storm::storage::BitVector > const &choiceConstraint)
Computes the sets of states that have probability greater 0 of satisfying phi until psi under any pos...
Holds the result data of the implemented SCC decomposition algorithm.
std::vector< uint64_t > stateToSccMapping
Number of found SCCs.
storm::storage::BitVector nonTrivialStates
Mapping from states to the SCC it belongs to.
uint64_t sccCount
True if an SCC is associated to the given state.