@ -6,9 +6,10 @@
# include "src/utility/vector.h"
# include "src/utility/graph.h"
# include "src/solver/LinearEquationSolver.h"
# include "src/modelchecker/results/ExplicitQuantitativeCheckResult.h"
# include "src/exceptions/InvalidStateException.h"
# include "src/exceptions/InvalidPropertyException.h"
@ -217,6 +218,91 @@ namespace storm {
std : : vector < ValueType > SparseDtmcPrctlHelper < ValueType , RewardModelType > : : computeLongRunAverageProbabilities ( storm : : storage : : SparseMatrix < ValueType > const & transitionMatrix , storm : : storage : : BitVector const & psiStates , bool qualitative , storm : : utility : : solver : : LinearEquationSolverFactory < ValueType > const & linearEquationSolverFactory ) {
return SparseCtmcCslHelper < ValueType > : : computeLongRunAverageProbabilities ( transitionMatrix , psiStates , nullptr , qualitative , linearEquationSolverFactory ) ;
}
template < typename ValueType , typename RewardModelType >
std : : vector < ValueType > SparseDtmcPrctlHelper < ValueType , RewardModelType > : : computeConditionalProbabilities ( storm : : storage : : SparseMatrix < ValueType > const & transitionMatrix , storm : : storage : : SparseMatrix < ValueType > const & backwardTransitions , storm : : storage : : BitVector const & targetStates , storm : : storage : : BitVector const & conditionStates , bool qualitative , storm : : utility : : solver : : LinearEquationSolverFactory < ValueType > const & linearEquationSolverFactory ) {
std : : vector < ValueType > probabilitiesToReachConditionStates = computeUntilProbabilities ( transitionMatrix , backwardTransitions , storm : : storage : : BitVector ( transitionMatrix . getRowCount ( ) , true ) , conditionStates , false , linearEquationSolverFactory ) ;
// Start by computing all 'before' states, i.e. the states for which the conditional probability is defined.
storm : : storage : : BitVector beforeStates ( targetStates . size ( ) , true ) ;
uint_fast64_t state = 0 ;
uint_fast64_t beforeStateIndex = 0 ;
for ( auto const & value : probabilitiesToReachConditionStates ) {
if ( value = = storm : : utility : : zero < ValueType > ( ) ) {
beforeStates . set ( state , false ) ;
} else {
probabilitiesToReachConditionStates [ beforeStateIndex ] = value ;
+ + beforeStateIndex ;
}
+ + state ;
}
probabilitiesToReachConditionStates . resize ( beforeStateIndex ) ;
uint_fast64_t normalStatesOffset = beforeStates . getNumberOfSetBits ( ) ;
storm : : storage : : BitVector allStates ( targetStates . size ( ) , true ) ;
storm : : storage : : BitVector statesWithProbabilityGreater0 = storm : : utility : : graph : : performProbGreater0 ( backwardTransitions , allStates , targetStates ) ;
statesWithProbabilityGreater0 & = storm : : utility : : graph : : getReachableStates ( transitionMatrix , conditionStates , allStates , targetStates ) ;
std : : vector < uint_fast64_t > numberOfNormalStatesUpToState = statesWithProbabilityGreater0 . getNumberOfSetBitsBeforeIndices ( ) ;
// Now, we create the matrix of 'before' and 'normal' states.
std : : vector < uint_fast64_t > numberOfBeforeStatesUpToState = beforeStates . getNumberOfSetBitsBeforeIndices ( ) ;
storm : : storage : : SparseMatrixBuilder < ValueType > builder ;
uint_fast64_t currentRow = 0 ;
// Start by creating the transitions of the 'before' states.
for ( auto beforeState : beforeStates ) {
if ( conditionStates . get ( beforeState ) ) {
// For condition states, we move to the 'normal' states.
for ( auto const & successorEntry : transitionMatrix . getRow ( beforeState ) ) {
if ( statesWithProbabilityGreater0 . get ( successorEntry . getColumn ( ) ) ) {
builder . addNextValue ( currentRow , normalStatesOffset + numberOfNormalStatesUpToState [ successorEntry . getColumn ( ) ] , successorEntry . getValue ( ) ) ;
}
}
} else {
// For non-condition states, we scale the probabilities going to other before states.
for ( auto const & successorEntry : transitionMatrix . getRow ( beforeState ) ) {
if ( beforeStates . get ( successorEntry . getColumn ( ) ) ) {
builder . addNextValue ( currentRow , numberOfBeforeStatesUpToState [ successorEntry . getColumn ( ) ] , successorEntry . getValue ( ) * probabilitiesToReachConditionStates [ numberOfBeforeStatesUpToState [ successorEntry . getColumn ( ) ] ] / probabilitiesToReachConditionStates [ currentRow ] ) ;
}
}
}
+ + currentRow ;
}
// Then, create the transitions of the 'normal' states.
uint_fast64_t deadlockState = normalStatesOffset + statesWithProbabilityGreater0 . getNumberOfSetBits ( ) ;
for ( auto state : statesWithProbabilityGreater0 ) {
ValueType zeroProbability = storm : : utility : : zero < ValueType > ( ) ;
for ( auto const & successorEntry : transitionMatrix . getRow ( state ) ) {
if ( statesWithProbabilityGreater0 . get ( successorEntry . getColumn ( ) ) ) {
builder . addNextValue ( currentRow , normalStatesOffset + numberOfNormalStatesUpToState [ successorEntry . getColumn ( ) ] , successorEntry . getValue ( ) ) ;
} else {
zeroProbability + = successorEntry . getValue ( ) ;
}
}
if ( ! storm : : utility : : isZero ( zeroProbability ) ) {
builder . addNextValue ( currentRow , deadlockState , zeroProbability ) ;
}
+ + currentRow ;
}
builder . addNextValue ( deadlockState , deadlockState , storm : : utility : : one < ValueType > ( ) ) ;
// Build the new transition matrix and the new targets.
storm : : storage : : SparseMatrix < ValueType > newTransitionMatrix = builder . build ( ) ;
storm : : storage : : BitVector newTargetStates = targetStates % beforeStates ;
newTargetStates . resize ( newTransitionMatrix . getRowCount ( ) ) ;
for ( auto state : targetStates % statesWithProbabilityGreater0 ) {
newTargetStates . set ( normalStatesOffset + state , true ) ;
}
// Finally, compute the conditional probabiltities by a reachability query.
std : : vector < ValueType > conditionalProbabilities = computeUntilProbabilities ( newTransitionMatrix , newTransitionMatrix . transpose ( ) , storm : : storage : : BitVector ( newTransitionMatrix . getRowCount ( ) , true ) , newTargetStates , qualitative , linearEquationSolverFactory ) ;
// Unpack and return result.
std : : vector < ValueType > result ( transitionMatrix . getRowCount ( ) , storm : : utility : : infinity < ValueType > ( ) ) ;
storm : : utility : : vector : : setVectorValues ( result , beforeStates , conditionalProbabilities ) ;
return result ;
}
template class SparseDtmcPrctlHelper < double > ;
}