16template<
typename ValueType>
21template<
typename ValueType>
22template<
typename RewardModelType>
28template<
typename ValueType>
31 performMaximalEndComponentDecomposition(transitionMatrix, backwardTransitions);
34template<
typename ValueType>
38 performMaximalEndComponentDecomposition(transitionMatrix, backwardTransitions, states);
41template<
typename ValueType>
46 performMaximalEndComponentDecomposition(transitionMatrix, backwardTransitions, states, choices);
49template<
typename ValueType>
55template<
typename ValueType>
60template<
typename ValueType>
66template<
typename ValueType>
71template<
typename ValueType>
77template<
typename ValueType>
80 return "Empty MEC decomposition.";
82 uint64_t statesInMec = 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>
159 SccDecompositionResult sccDecRes;
160 SccDecompositionMemoryCache sccDecCache;
161 StronglyConnectedComponentDecompositionOptions sccDecOptions;
162 sccDecOptions.dropNaiveSccs();
164 sccDecOptions.subsystem(*states);
167 ecChoices = *choices;
168 sccDecOptions.choices(ecChoices);
174 std::vector<uint64_t> ecSccStates, ecSccIndications;
175 auto getSccStates = [&ecSccStates, &ecSccIndications](uint64_t
const sccIndex) {
176 return std::span(ecSccStates).subspan(ecSccIndications[sccIndex], ecSccIndications[sccIndex + 1] - ecSccIndications[sccIndex]);
182 remainingEcCandidates = sccDecRes.nonTrivialStates;
183 storm::storage::BitVector ecSccIndices(sccDecRes.sccCount,
true);
184 storm::storage::BitVector nonTrivSccIndices(sccDecRes.sccCount,
false);
186 for (
auto state : remainingEcCandidates) {
187 auto const sccIndex = sccDecRes.stateToSccMapping[state];
188 nonTrivSccIndices.set(sccIndex,
true);
189 bool stateCanStayInScc =
false;
191 if (!ecChoices.
get(choice)) {
194 auto row = transitionMatrix.
getRow(choice);
195 if (std::any_of(row.begin(), row.end(), [&sccIndex, &sccDecRes](
auto const& entry) {
196 return sccIndex != sccDecRes.stateToSccMapping[entry.getColumn()] && !storm::utility::isZero(entry.getValue());
198 ecChoices.
set(choice,
false);
199 ecSccIndices.set(sccIndex,
false);
201 stateCanStayInScc =
true;
204 if (!stateCanStayInScc) {
205 remainingEcCandidates.set(state,
false);
210 ecSccIndices &= nonTrivSccIndices;
211 for (
auto sccIndex : ecSccIndices) {
213 for (
auto const state : getSccStates(sccIndex)) {
215 remainingEcCandidates.set(state,
false);
218 for (
auto ecChoiceIt = ecChoices.
begin(nondeterministicChoiceIndices[state]); *ecChoiceIt < nondeterministicChoiceIndices[state + 1];
220 containedChoices.insert(*ecChoiceIt);
222 STORM_LOG_ASSERT(!containedChoices.empty(),
"The contained choices of any state in an MEC must be non-empty.");
223 newMec.addState(state, std::move(containedChoices));
225 this->blocks.emplace_back(std::move(newMec));
228 if (nonTrivSccIndices == ecSccIndices) {
236 remainingEcCandidates, ~remainingEcCandidates,
false, 0, ecChoices);
237 remainingEcCandidates.complement();
238 sccDecOptions.subsystem(remainingEcCandidates);
239 sccDecOptions.choices(ecChoices);
242 STORM_LOG_DEBUG(
"MEC decomposition found " << this->size() <<
" MEC(s).");
251 storm::models::sparse::NondeterministicModel<storm::RationalNumber>
const& model);
255 storm::models::sparse::NondeterministicModel<storm::Interval>
const& model);
259 storm::models::sparse::NondeterministicModel<storm::RationalInterval>
const& model);
263 storm::models::sparse::NondeterministicModel<storm::RationalFunction>
const& model);
Helper class that optionally holds a reference to an object of type T.
bool has_value() const
Yields true iff this contains a reference.
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.
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.
Decomposition & operator=(Decomposition const &other)
Assigns the contents of the given decomposition to the current one by copying the contents.
std::vector< block_type > blocks
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-...
This class represents a maximal end-component of a nondeterministic model.
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.
index_type getRowGroupCount() const
Returns the number of row groups in the matrix.
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.