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 trivialMecs = 0;
83 uint64_t smallestSize = std::numeric_limits<uint64_t>::max();
84 uint64_t largestSize = 0;
85 for (
auto const& mec : this->blocks) {
86 statesInMec += mec.size();
87 if (mec.size() == 1u) {
90 smallestSize = std::min<uint64_t>(smallestSize, mec.size());
91 largestSize = std::max<uint64_t>(largestSize, mec.size());
94 uint64_t
const statesInNonTrivialMec = statesInMec - trivialMecs;
95 auto getPercentage = [&totalNumberOfStates](uint64_t states) ->
double {
96 return (totalNumberOfStates == 0) ? 0.0 : (100.0 * states / totalNumberOfStates);
99 ss <<
"MEC decomposition statistics: ";
100 ss <<
"There are " << this->size() <<
" MECs out of which " << trivialMecs <<
" are trivial, i.e., consist of a single state.";
101 ss <<
" " << statesInMec <<
" out of " << totalNumberOfStates <<
" states (" << getPercentage(statesInMec) <<
"%) are on some MEC. "
102 << statesInNonTrivialMec <<
" states (" << getPercentage(statesInNonTrivialMec) <<
"%) are on a non-trivial mec. ";
103 if (largestSize > 0) {
104 ss <<
"The smallest non-trivial MEC has " << smallestSize <<
" states and the largest non-trivial MEC has " << largestSize <<
" states.";
118 sccIndications.assign(sccDecRes.
sccCount + 1, 0ull);
122 std::span<uint64_t> sccCounts(sccIndications.begin() + 1, sccIndications.end());
130 for (
auto& count : sccCounts) {
131 auto const oldSum = sum;
139 sccStates[sccCounts[sccIndex]] = state;
140 ++sccCounts[sccIndex];
147template<
typename ValueType>
156 SccDecompositionResult sccDecRes;
157 SccDecompositionMemoryCache sccDecCache;
158 StronglyConnectedComponentDecompositionOptions sccDecOptions;
159 sccDecOptions.dropNaiveSccs();
161 sccDecOptions.subsystem(*states);
164 ecChoices = *choices;
165 sccDecOptions.choices(ecChoices);
171 std::vector<uint64_t> ecSccStates, ecSccIndications;
172 auto getSccStates = [&ecSccStates, &ecSccIndications](uint64_t
const sccIndex) {
173 return std::span(ecSccStates).subspan(ecSccIndications[sccIndex], ecSccIndications[sccIndex + 1] - ecSccIndications[sccIndex]);
179 remainingEcCandidates = sccDecRes.nonTrivialStates;
183 for (
auto state : remainingEcCandidates) {
184 auto const sccIndex = sccDecRes.stateToSccMapping[state];
185 nonTrivSccIndices.set(sccIndex,
true);
186 bool stateCanStayInScc =
false;
187 for (
auto const choice : transitionMatrix.getRowGroupIndices(state)) {
188 if (!ecChoices.
get(choice)) {
191 auto row = transitionMatrix.
getRow(choice);
192 if (std::any_of(row.begin(), row.end(), [&sccIndex, &sccDecRes](
auto const& entry) {
193 return sccIndex != sccDecRes.stateToSccMapping[entry.getColumn()] && !storm::utility::isZero(entry.getValue());
195 ecChoices.
set(choice,
false);
196 ecSccIndices.set(sccIndex,
false);
198 stateCanStayInScc =
true;
201 if (!stateCanStayInScc) {
202 remainingEcCandidates.
set(state,
false);
207 ecSccIndices &= nonTrivSccIndices;
208 for (
auto sccIndex : ecSccIndices) {
209 MaximalEndComponent newMec;
210 for (
auto const state : getSccStates(sccIndex)) {
212 remainingEcCandidates.
set(state,
false);
215 for (
auto ecChoiceIt = ecChoices.
begin(nondeterministicChoiceIndices[state]); *ecChoiceIt < nondeterministicChoiceIndices[state + 1];
217 containedChoices.insert(*ecChoiceIt);
219 STORM_LOG_ASSERT(!containedChoices.empty(),
"The contained choices of any state in an MEC must be non-empty.");
220 newMec.addState(state, std::move(containedChoices));
222 this->blocks.emplace_back(std::move(newMec));
225 if (nonTrivSccIndices == ecSccIndices) {
233 remainingEcCandidates, ~remainingEcCandidates,
false, 0, ecChoices);
235 sccDecOptions.subsystem(remainingEcCandidates);
236 sccDecOptions.choices(ecChoices);
239 STORM_LOG_DEBUG(
"MEC decomposition found " << this->size() <<
" MEC(s).");
243template class MaximalEndComponentDecomposition<double>;
246template class MaximalEndComponentDecomposition<storm::RationalNumber>;
250template class MaximalEndComponentDecomposition<storm::Interval>;
254template 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.
uint64_t getNumberOfSetBits() const
Returns the number of bits that are set to true in this bit vector.
void set(uint64_t index, bool value=true)
Sets the given truth value at the given index.
const_iterator begin() const
Returns an iterator to the indices of the set bits in the bit vector.
void resize(uint64_t newLength, bool init=false)
Resizes the bit vector to hold the given new number of bits.
bool get(uint64_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.