|
@ -43,6 +43,10 @@ namespace storm { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Finally eliminate initial state.
|
|
|
|
|
|
STORM_PRINT_AND_LOG("Eliminating initial state " << *initialStates.begin() << std::endl); |
|
|
|
|
|
eliminateState(flexibleMatrix, oneStepProbabilities, *initialStates.begin(), flexibleBackwardTransitions); |
|
|
|
|
|
|
|
|
// Make sure that we have eliminated all transitions from the initial state.
|
|
|
// Make sure that we have eliminated all transitions from the initial state.
|
|
|
STORM_LOG_ASSERT(flexibleMatrix.getRow(*initialStates.begin()).empty(), "The transitions of the initial states are non-empty."); |
|
|
STORM_LOG_ASSERT(flexibleMatrix.getRow(*initialStates.begin()).empty(), "The transitions of the initial states are non-empty."); |
|
|
|
|
|
|
|
@ -119,6 +123,7 @@ namespace storm { |
|
|
|
|
|
|
|
|
// Subtract from the maybe states the set of states that is not reachable (on a path from the initial to a target state).
|
|
|
// Subtract from the maybe states the set of states that is not reachable (on a path from the initial to a target state).
|
|
|
maybeStates &= reachableStates; |
|
|
maybeStates &= reachableStates; |
|
|
|
|
|
STORM_PRINT_AND_LOG("Found " << maybeStates.getNumberOfSetBits() << " maybe states." << std::endl); |
|
|
|
|
|
|
|
|
// Create a vector for the probabilities to go to a state with probability 1 in one step.
|
|
|
// Create a vector for the probabilities to go to a state with probability 1 in one step.
|
|
|
std::vector<ValueType> oneStepProbabilities = dtmc.getTransitionMatrix().getConstrainedRowSumVector(maybeStates, statesWithProbability1); |
|
|
std::vector<ValueType> oneStepProbabilities = dtmc.getTransitionMatrix().getConstrainedRowSumVector(maybeStates, statesWithProbability1); |
|
@ -292,6 +297,14 @@ namespace storm { |
|
|
template<typename ValueType> |
|
|
template<typename ValueType> |
|
|
void SparseSccModelChecker<ValueType>::eliminateState(FlexibleSparseMatrix<ValueType>& matrix, std::vector<ValueType>& oneStepProbabilities, uint_fast64_t state, FlexibleSparseMatrix<ValueType>& backwardTransitions) { |
|
|
void SparseSccModelChecker<ValueType>::eliminateState(FlexibleSparseMatrix<ValueType>& matrix, std::vector<ValueType>& oneStepProbabilities, uint_fast64_t state, FlexibleSparseMatrix<ValueType>& backwardTransitions) { |
|
|
|
|
|
|
|
|
|
|
|
// std::cout << "before eliminating state " << state << std::endl;
|
|
|
|
|
|
// matrix.print();
|
|
|
|
|
|
// std::cout << "one step probs" << std::endl;
|
|
|
|
|
|
// for (uint_fast64_t index = 0; index < oneStepProbabilities.size(); ++index) {
|
|
|
|
|
|
// std::cout << "(" << index << ", " << oneStepProbabilities[index] << ") ";
|
|
|
|
|
|
// }
|
|
|
|
|
|
// std::cout << std::endl;
|
|
|
|
|
|
|
|
|
auto eliminationStart = std::chrono::high_resolution_clock::now(); |
|
|
auto eliminationStart = std::chrono::high_resolution_clock::now(); |
|
|
|
|
|
|
|
|
++counter; |
|
|
++counter; |
|
@ -329,14 +342,21 @@ namespace storm { |
|
|
// Scale all entries in this row with (1 / (1 - loopProbability)) only in case there was a self-loop.
|
|
|
// Scale all entries in this row with (1 / (1 - loopProbability)) only in case there was a self-loop.
|
|
|
std::size_t scaledSuccessors = 0; |
|
|
std::size_t scaledSuccessors = 0; |
|
|
if (hasSelfLoop) { |
|
|
if (hasSelfLoop) { |
|
|
|
|
|
// std::cout << "loop: " << loopProbability << std::endl;
|
|
|
|
|
|
// ValueType oneMinusLoop = (storm::utility::constantOne<ValueType>() - loopProbability);
|
|
|
|
|
|
// std::cout << "1-loop: " << oneMinusLoop << std::endl;
|
|
|
|
|
|
// std::cout << "1/(1-loop): " << (storm::utility::constantOne<ValueType>() / oneMinusLoop) << std::endl;
|
|
|
loopProbability = storm::utility::constantOne<ValueType>() / (storm::utility::constantOne<ValueType>() - loopProbability); |
|
|
loopProbability = storm::utility::constantOne<ValueType>() / (storm::utility::constantOne<ValueType>() - loopProbability); |
|
|
storm::utility::simplify(loopProbability); |
|
|
storm::utility::simplify(loopProbability); |
|
|
|
|
|
// std::cout << "state has self-loop with probability " << loopProbability << std::endl;
|
|
|
for (auto& entry : matrix.getRow(state)) { |
|
|
for (auto& entry : matrix.getRow(state)) { |
|
|
// Only scale the non-diagonal entries.
|
|
|
// Only scale the non-diagonal entries.
|
|
|
if (entry.getColumn() != state) { |
|
|
if (entry.getColumn() != state) { |
|
|
++scaledSuccessors; |
|
|
++scaledSuccessors; |
|
|
multiplicationClock = std::chrono::high_resolution_clock::now(); |
|
|
multiplicationClock = std::chrono::high_resolution_clock::now(); |
|
|
auto result = entry.getValue() * loopProbability; |
|
|
|
|
|
|
|
|
// std::cout << "scaling " << entry.getValue() << " with " << loopProbability << std::endl;
|
|
|
|
|
|
auto result = storm::utility::simplify(entry.getValue() * loopProbability); |
|
|
|
|
|
// std::cout << "got " << result << " for state " << entry.getColumn() << std::endl;
|
|
|
multiplicationTime += std::chrono::high_resolution_clock::now() - multiplicationClock; |
|
|
multiplicationTime += std::chrono::high_resolution_clock::now() - multiplicationClock; |
|
|
entry.setValue(result); |
|
|
entry.setValue(result); |
|
|
} |
|
|
} |
|
@ -355,6 +375,7 @@ namespace storm { |
|
|
std::size_t predecessorForwardTransitionCount = 0; |
|
|
std::size_t predecessorForwardTransitionCount = 0; |
|
|
for (auto const& predecessorEntry : currentStatePredecessors) { |
|
|
for (auto const& predecessorEntry : currentStatePredecessors) { |
|
|
uint_fast64_t predecessor = predecessorEntry.getColumn(); |
|
|
uint_fast64_t predecessor = predecessorEntry.getColumn(); |
|
|
|
|
|
// std::cout << "treating predecessor " << predecessor << std::endl;
|
|
|
|
|
|
|
|
|
// Skip the state itself as one of its predecessors.
|
|
|
// Skip the state itself as one of its predecessors.
|
|
|
if (predecessor == state) { |
|
|
if (predecessor == state) { |
|
@ -413,14 +434,18 @@ namespace storm { |
|
|
++first1; |
|
|
++first1; |
|
|
} else { |
|
|
} else { |
|
|
multiplicationClock = std::chrono::high_resolution_clock::now(); |
|
|
multiplicationClock = std::chrono::high_resolution_clock::now(); |
|
|
|
|
|
// std::cout << "multiplying " << multiplyFactor << " with " << first2->getValue() << std::endl;
|
|
|
auto tmp1 = multiplyFactor * first2->getValue(); |
|
|
auto tmp1 = multiplyFactor * first2->getValue(); |
|
|
|
|
|
// std::cout << "result: " << tmp1 << std::endl;
|
|
|
multiplicationTime += std::chrono::high_resolution_clock::now() - multiplicationClock; |
|
|
multiplicationTime += std::chrono::high_resolution_clock::now() - multiplicationClock; |
|
|
simplifyClock = std::chrono::high_resolution_clock::now(); |
|
|
simplifyClock = std::chrono::high_resolution_clock::now(); |
|
|
tmp1 = storm::utility::simplify(tmp1); |
|
|
tmp1 = storm::utility::simplify(tmp1); |
|
|
multiplicationClock = std::chrono::high_resolution_clock::now(); |
|
|
multiplicationClock = std::chrono::high_resolution_clock::now(); |
|
|
simplifyTime += std::chrono::high_resolution_clock::now() - simplifyClock; |
|
|
simplifyTime += std::chrono::high_resolution_clock::now() - simplifyClock; |
|
|
additionClock = std::chrono::high_resolution_clock::now(); |
|
|
additionClock = std::chrono::high_resolution_clock::now(); |
|
|
|
|
|
// std::cout << "adding " << first1->getValue() << " and " << tmp1 << std::endl;
|
|
|
auto tmp2 = first1->getValue() + tmp1; |
|
|
auto tmp2 = first1->getValue() + tmp1; |
|
|
|
|
|
// std::cout << "result: " << tmp2 << std::endl;
|
|
|
additionTime += std::chrono::high_resolution_clock::now() - additionClock; |
|
|
additionTime += std::chrono::high_resolution_clock::now() - additionClock; |
|
|
simplifyClock = std::chrono::high_resolution_clock::now(); |
|
|
simplifyClock = std::chrono::high_resolution_clock::now(); |
|
|
tmp2 = storm::utility::simplify(tmp2); |
|
|
tmp2 = storm::utility::simplify(tmp2); |
|
@ -530,6 +555,14 @@ namespace storm { |
|
|
STORM_PRINT("Number of predecessors: " << numberOfPredecessors << "." << std::endl); |
|
|
STORM_PRINT("Number of predecessors: " << numberOfPredecessors << "." << std::endl); |
|
|
STORM_PRINT("Number of predecessor forward transitions " << predecessorForwardTransitionCount << "." << std::endl); |
|
|
STORM_PRINT("Number of predecessor forward transitions " << predecessorForwardTransitionCount << "." << std::endl); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// std::cout << "after eliminating state " << state << std::endl;
|
|
|
|
|
|
// matrix.print();
|
|
|
|
|
|
// std::cout << "one step probs" << std::endl;
|
|
|
|
|
|
// for (uint_fast64_t index = 0; index < oneStepProbabilities.size(); ++index) {
|
|
|
|
|
|
// std::cout << "(" << index << ", " << oneStepProbabilities[index] << ") ";
|
|
|
|
|
|
// }
|
|
|
|
|
|
// std::cout << std::endl;
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
template <typename ValueType> |
|
|
template <typename ValueType> |
|
@ -637,6 +670,17 @@ namespace storm { |
|
|
return this->data.size(); |
|
|
return this->data.size(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
template<typename ValueType> |
|
|
|
|
|
void FlexibleSparseMatrix<ValueType>::print() const { |
|
|
|
|
|
for (uint_fast64_t index = 0; index < this->data.size(); ++index) { |
|
|
|
|
|
std::cout << index << " - "; |
|
|
|
|
|
for (auto const& element : this->getRow(index)) { |
|
|
|
|
|
std::cout << "(" << element.getColumn() << ", " << element.getValue() << ") "; |
|
|
|
|
|
} |
|
|
|
|
|
std::cout << std::endl; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
template<typename ValueType> |
|
|
template<typename ValueType> |
|
|
FlexibleSparseMatrix<ValueType> SparseSccModelChecker<ValueType>::getFlexibleSparseMatrix(storm::storage::SparseMatrix<ValueType> const& matrix, bool setAllValuesToOne) { |
|
|
FlexibleSparseMatrix<ValueType> SparseSccModelChecker<ValueType>::getFlexibleSparseMatrix(storm::storage::SparseMatrix<ValueType> const& matrix, bool setAllValuesToOne) { |
|
|
FlexibleSparseMatrix<ValueType> flexibleMatrix(matrix.getRowCount()); |
|
|
FlexibleSparseMatrix<ValueType> flexibleMatrix(matrix.getRowCount()); |
|
|