Browse Source

Removed GraphTransition class, which is now replaced by SparseMatrix in the instances where it was used before. Changed GraphAnalyzer accordingly and adapted tests.

main
dehnert 12 years ago
parent
commit
fbe1f41213
  1. 2
      src/modelchecker/GmmxxMdpPrctlModelChecker.h
  2. 6
      src/modelchecker/TopologicalValueIterationMdpPrctlModelChecker.h
  3. 5
      src/models/AbstractDeterministicModel.h
  4. 73
      src/models/AbstractModel.h
  5. 7
      src/models/AbstractNondeterministicModel.h
  6. 258
      src/models/GraphTransitions.h
  7. 24
      src/storage/SparseMatrix.h
  8. 41
      src/utility/GraphAnalyzer.h
  9. 9
      test/functional/storm-functional-tests.cpp
  10. 98
      test/performance/graph/GraphTest.cpp
  11. 14
      test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp
  12. 40
      test/performance/modelchecker/GmmxxMdpPrctModelCheckerTest.cpp
  13. 12
      test/performance/storm-performance-tests.cpp

2
src/modelchecker/GmmxxMdpPrctlModelChecker.h

@ -151,7 +151,7 @@ private:
if (converged) {
LOG4CPLUS_INFO(logger, "Iterative solver converged after " << iterations << " iterations.");
} else {
LOG4CPLUS_WARN(logger, "Iterative solver did not converge.");
LOG4CPLUS_WARN(logger, "Iterative solver did not converge after " << iterations << " iterations.");
}
}
};

6
src/modelchecker/TopologicalValueIterationMdpPrctlModelChecker.h

@ -67,10 +67,8 @@ private:
bool relative = s->get<bool>("relative");
// Now, we need to determine the SCCs of the MDP and a topological sort.
std::pair<std::vector<std::vector<uint_fast64_t>>, storm::models::GraphTransitions<Type>> sccDecomposition = storm::utility::GraphAnalyzer::performSccDecomposition(this->getModel(), stronglyConnectedComponents, stronglyConnectedComponentsDependencyGraph);
std::vector<std::vector<uint_fast64_t>> stronglyConnectedComponents = std::move(sccDecomposition.first);
storm::models::GraphTransitions<Type> stronglyConnectedComponentsDependencyGraph = std::move(sccDecomposition.second);
std::vector<std::vector<uint_fast64_t>> stronglyConnectedComponents = storm::utility::GraphAnalyzer::performSccDecomposition(this->getModel(), stronglyConnectedComponents, stronglyConnectedComponentsDependencyGraph);
storm::storage::SparseMatrix<bool> stronglyConnectedComponentsDependencyGraph = this->getModel().extractSccDependencyGraph(stronglyConnectedComponents);
std::vector<uint_fast64_t> topologicalSort = storm::utility::GraphAnalyzer::getTopologicalSort(stronglyConnectedComponentsDependencyGraph);
// Set up the environment for the power method.

5
src/models/AbstractDeterministicModel.h

@ -2,7 +2,6 @@
#define STORM_MODELS_ABSTRACTDETERMINISTICMODEL_H_
#include "AbstractModel.h"
#include "GraphTransitions.h"
#include <memory>
@ -53,7 +52,7 @@ class AbstractDeterministicModel: public AbstractModel<T> {
* @return An iterator to the successors of the given state.
*/
virtual typename storm::storage::SparseMatrix<T>::ConstIndexIterator constStateSuccessorIteratorBegin(uint_fast64_t state) const {
return this->getTransitionMatrix()->constColumnIteratorBegin(state);
return this->transitionMatrix->constColumnIteratorBegin(state);
}
/*!
@ -63,7 +62,7 @@ class AbstractDeterministicModel: public AbstractModel<T> {
* @return An iterator pointing to the element past the successors of the given state.
*/
virtual typename storm::storage::SparseMatrix<T>::ConstIndexIterator constStateSuccessorIteratorEnd(uint_fast64_t state) const {
return this->getTransitionMatrix()->constColumnIteratorEnd(state);
return this->transitionMatrix->constColumnIteratorEnd(state);
}
};

73
src/models/AbstractModel.h

@ -91,9 +91,20 @@ class AbstractModel: public std::enable_shared_from_this<AbstractModel<T>> {
* @param stronglyConnectedComponents A vector containing the SCCs of the system.
* @param stateToSccMap A mapping from state indices to
*/
storm::storage::SparseMatrix<bool> extractSccDependencyGraph(std::vector<std::vector<uint_fast64_t>> const& stronglyConnectedComponents, std::map<uint_fast64_t, uint_fast64_t> const& stateToSccMap) const {
// The resulting sparse matrix will have as many rows/columns as there are SCCs.
storm::storage::SparseMatrix<bool> extractSccDependencyGraph(std::vector<std::vector<uint_fast64_t>> const& stronglyConnectedComponents) const {
uint_fast64_t numberOfStates = stronglyConnectedComponents.size();
// First, we need to create a mapping of states to their SCC index, to ease the computation
// of dependency transitions later.
std::vector<uint_fast64_t> stateToSccMap(this->getNumberOfStates());
for (uint_fast64_t i = 0; i < numberOfStates; ++i) {
for (uint_fast64_t j = 0; j < stronglyConnectedComponents[i].size(); ++j) {
stateToSccMap[stronglyConnectedComponents[i][j]] = i;
}
}
// The resulting sparse matrix will have as many rows/columns as there are SCCs.
storm::storage::SparseMatrix<bool> sccDependencyGraph(numberOfStates);
sccDependencyGraph.initialize();
@ -105,7 +116,7 @@ class AbstractModel: public std::enable_shared_from_this<AbstractModel<T>> {
std::set<uint_fast64_t> allTargetSccs;
for (auto state : scc) {
for (typename storm::storage::SparseMatrix<T>::ConstIndexIterator succIt = this->constStateSuccessorIteratorBegin(state), succIte = this->constStateSuccessorIteratorEnd(state); succIt != succIte; ++succIt) {
uint_fast64_t targetScc = stateToSccMap.find(*succIt)->second;
uint_fast64_t targetScc = stateToSccMap[*succIt];
// We only need to consider transitions that are actually leaving the SCC.
if (targetScc != currentSccIndex) {
@ -125,6 +136,59 @@ class AbstractModel: public std::enable_shared_from_this<AbstractModel<T>> {
return sccDependencyGraph;
}
/*!
* Retrieves the backward transition relation of the model, i.e. a set of transitions
* between states that correspond to the reversed transition relation of this model.
*
* @return A sparse matrix that represents the backward transitions of this model.
*/
virtual storm::storage::SparseMatrix<bool> getBackwardTransitions() const {
uint_fast64_t numberOfStates = this->getNumberOfStates();
uint_fast64_t numberOfTransitions = this->getNumberOfTransitions();
std::vector<uint_fast64_t> rowIndications(numberOfStates + 1);
std::vector<uint_fast64_t> columnIndications(numberOfTransitions);
std::vector<bool> values(numberOfTransitions, true);
// First, we need to count how many backward transitions each state has.
for (uint_fast64_t i = 0; i < numberOfStates; ++i) {
for (auto rowIt = this->constStateSuccessorIteratorBegin(i), rowIte = this->constStateSuccessorIteratorEnd(i); rowIt != rowIte; ++rowIt) {
rowIndications[*rowIt + 1]++;
}
}
// Now compute the accumulated offsets.
for (uint_fast64_t i = 1; i < numberOfStates; ++i) {
rowIndications[i] = rowIndications[i - 1] + rowIndications[i];
}
// Put a sentinel element at the end of the indices list. This way,
// for each state i the range of indices can be read off between
// state_indices_list[i] and state_indices_list[i + 1].
// FIXME: This should not be necessary and already be implied by the first steps.
rowIndications[numberOfStates] = numberOfTransitions;
// Create an array that stores the next index for each state. Initially
// this corresponds to the previously computed accumulated offsets.
std::vector<uint_fast64_t> nextIndices = rowIndications;
// Now we are ready to actually fill in the list of predecessors for
// every state. Again, we start by considering all but the last row.
for (uint_fast64_t i = 0; i < numberOfStates; ++i) {
for (auto rowIt = this->constStateSuccessorIteratorBegin(i), rowIte = this->constStateSuccessorIteratorEnd(i); rowIt != rowIte; ++rowIt) {
columnIndications[nextIndices[*rowIt]++] = i;
}
}
storm::storage::SparseMatrix<bool> backwardTransitionMatrix(numberOfStates, numberOfStates,
numberOfTransitions,
std::move(rowIndications),
std::move(columnIndications),
std::move(values));
return backwardTransitionMatrix;
}
/*!
* Returns an iterator to the successors of the given state.
@ -269,10 +333,11 @@ class AbstractModel: public std::enable_shared_from_this<AbstractModel<T>> {
<< std::endl;
}
private:
protected:
/*! A matrix representing the likelihoods of moving between states. */
std::shared_ptr<storm::storage::SparseMatrix<T>> transitionMatrix;
private:
/*! The labeling of the states of the model. */
std::shared_ptr<storm::models::AtomicPropositionsLabeling> stateLabeling;

7
src/models/AbstractNondeterministicModel.h

@ -2,7 +2,6 @@
#define STORM_MODELS_ABSTRACTNONDETERMINISTICMODEL_H_
#include "AbstractModel.h"
#include "GraphTransitions.h"
#include <memory>
@ -56,7 +55,7 @@ class AbstractNondeterministicModel: public AbstractModel<T> {
* @return The number of choices for all states of the MDP.
*/
uint_fast64_t getNumberOfChoices() const {
return this->getTransitionMatrix()->getRowCount();
return this->transitionMatrix->getRowCount();
}
/*!
@ -85,7 +84,7 @@ class AbstractNondeterministicModel: public AbstractModel<T> {
* @return An iterator to the successors of the given state.
*/
virtual typename storm::storage::SparseMatrix<T>::ConstIndexIterator constStateSuccessorIteratorBegin(uint_fast64_t state) const {
return this->getTransitionMatrix()->constColumnIteratorBegin((*nondeterministicChoiceIndices)[state]);
return this->transitionMatrix->constColumnIteratorBegin((*nondeterministicChoiceIndices)[state]);
}
/*!
@ -95,7 +94,7 @@ class AbstractNondeterministicModel: public AbstractModel<T> {
* @return An iterator pointing to the element past the successors of the given state.
*/
virtual typename storm::storage::SparseMatrix<T>::ConstIndexIterator constStateSuccessorIteratorEnd(uint_fast64_t state) const {
return this->getTransitionMatrix()->constColumnIteratorEnd((*nondeterministicChoiceIndices)[state + 1] - 1);
return this->transitionMatrix->constColumnIteratorEnd((*nondeterministicChoiceIndices)[state + 1] - 1);
}
private:

258
src/models/GraphTransitions.h

@ -1,258 +0,0 @@
/*
* GraphTransitions.h
*
* Created on: 17.11.2012
* Author: Christian Dehnert
*/
#ifndef STORM_MODELS_GRAPHTRANSITIONS_H_
#define STORM_MODELS_GRAPHTRANSITIONS_H_
#include "src/storage/SparseMatrix.h"
#include <algorithm>
#include <memory>
namespace storm {
namespace models {
/*!
* This class stores the successors of all states in a state space of the
* given size.
*/
template <class T>
class GraphTransitions {
public:
/*!
* Just typedef the iterator as a pointer to the index type.
*/
typedef const uint_fast64_t * stateSuccessorIterator;
//! Constructor
/*!
* Constructs an object representing the graph structure of the given
* transition relation, which is given by a sparse matrix.
* @param transitionMatrix The (0-based) matrix representing the transition
* relation.
* @param forward If set to true, this objects will store the graph structure
* of the backwards transition relation.
*/
GraphTransitions(storm::storage::SparseMatrix<T> const& transitionMatrix, bool forward)
: numberOfStates(transitionMatrix.getColumnCount()), numberOfTransitions(transitionMatrix.getNonZeroEntryCount()), successorList(numberOfTransitions), stateIndications(numberOfStates + 1) {
if (forward) {
this->initializeForward(transitionMatrix);
} else {
this->initializeBackward(transitionMatrix);
}
}
GraphTransitions(storm::storage::SparseMatrix<T> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, bool forward)
: numberOfStates(transitionMatrix.getColumnCount()), numberOfTransitions(transitionMatrix.getNonZeroEntryCount()), successorList(numberOfTransitions), stateIndications(numberOfStates + 1) {
if (forward) {
this->initializeForward(transitionMatrix, nondeterministicChoiceIndices);
} else {
this->initializeBackward(transitionMatrix, nondeterministicChoiceIndices);
}
}
GraphTransitions(GraphTransitions<T> const& transitions, std::vector<std::vector<std::uint_fast64_t>> const& stronglyConnectedComponents, std::map<uint_fast64_t, uint_fast64_t> const& stateToSccMap)
: numberOfStates(stronglyConnectedComponents.size()), numberOfTransitions(0), successorList(), stateIndications(numberOfStates + 1) {
this->initializeFromSccDecomposition(transitions, stronglyConnectedComponents, stateToSccMap);
}
GraphTransitions() : numberOfStates(0), numberOfTransitions(0), successorList(), stateIndications() {
// Intentionally left empty.
}
/*!
* Retrieves the size of the internal representation of the graph transitions in memory.
* @return the size of the internal representation of the graph transitions in memory
* measured in bytes.
*/
virtual uint_fast64_t getSizeInMemory() const {
uint_fast64_t result = sizeof(this) + (numberOfStates + numberOfTransitions + 1) * sizeof(uint_fast64_t);
return result;
}
uint_fast64_t getNumberOfStates() const {
return numberOfStates;
}
uint_fast64_t getNumberOfTransitions() const {
return numberOfTransitions;
}
/*!
* Returns an iterator to the successors of the given state.
* @param state The state for which to get the successor iterator.
* @return An iterator to the predecessors of the given states.
*/
stateSuccessorIterator beginStateSuccessorsIterator(uint_fast64_t state) const {
return &(this->successorList[0]) + this->stateIndications[state];
}
/*!
* Returns an iterator referring to the element after the successors of
* the given state.
* @param state The state for which to get the iterator.
* @return An iterator referring to the element after the successors of
* the given state.
*/
stateSuccessorIterator endStateSuccessorsIterator(uint_fast64_t state) const {
return &(this->successorList[0]) + this->stateIndications[state + 1];
}
/*!
* Returns a (naive) string representation of the transitions in this object.
* @returns a (naive) string representation of the transitions in this object.
*/
std::string toString() const {
std::stringstream stream;
for (uint_fast64_t state = 0; state < numberOfStates; ++state) {
for (auto succIt = this->beginStateSuccessorsIterator(state), succIte = this->endStateSuccessorsIterator(state); succIt != succIte; ++succIt) {
stream << state << " -> " << *succIt << std::endl;
}
}
return stream.str();
}
private:
/*!
* Initializes this graph transitions object using the forward transition
* relation given by means of a sparse matrix.
*/
void initializeForward(storm::storage::SparseMatrix<T> const& transitionMatrix) {
// First, we copy the index list from the sparse matrix as this will
// stay the same.
std::copy(transitionMatrix.constColumnIteratorBegin(), transitionMatrix.constColumnIteratorEnd(), this->stateIndications.begin());
// Now we can iterate over all rows of the transition matrix and record the target state.
for (uint_fast64_t i = 0, currentNonZeroElement = 0; i < numberOfStates; i++) {
for (auto rowIt = transitionMatrix.constColumnIteratorBegin(i); rowIt != transitionMatrix.constColumnIteratorEnd(i); ++rowIt) {
this->successorList[currentNonZeroElement++] = *rowIt;
}
}
}
void initializeForward(storm::storage::SparseMatrix<T> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices) {
// We can directly copy the starting indices from the transition matrix as we do not
// eliminate duplicate transitions and therefore will have as many non-zero entries as this
// matrix.
typename storm::storage::SparseMatrix<T>::ConstRowsIterator rowsIt(transitionMatrix);
for (uint_fast64_t i = 0; i < numberOfStates; ++i) {
rowsIt.moveToRow(nondeterministicChoiceIndices[i]);
this->stateIndications[i] = rowsIt.index();
}
this->stateIndications[numberOfStates] = numberOfTransitions;
// Now we can iterate over all rows of the transition matrix and record
// the target state.
for (uint_fast64_t i = 0, currentNonZeroElement = 0; i < numberOfStates; i++) {
for (uint_fast64_t j = nondeterministicChoiceIndices[i]; j < nondeterministicChoiceIndices[i + 1]; ++j) {
for (auto rowIt = transitionMatrix.constColumnIteratorBegin(j); rowIt != transitionMatrix.constColumnIteratorEnd(j); ++rowIt) {
this->successorList[currentNonZeroElement++] = *rowIt;
}
}
}
}
/*!
* Initializes this graph transitions object using the backwards transition
* relation, whose forward transition relation is given by means of a sparse
* matrix.
*/
void initializeBackward(storm::storage::SparseMatrix<T> const& transitionMatrix) {
// First, we need to count how many backward transitions each state has.
for (uint_fast64_t i = 0; i < numberOfStates; ++i) {
for (auto rowIt = transitionMatrix.constColumnIteratorBegin(i); rowIt != transitionMatrix.constColumnIteratorEnd(i); ++rowIt) {
this->stateIndications[*rowIt + 1]++;
}
}
// Now compute the accumulated offsets.
for (uint_fast64_t i = 1; i < numberOfStates; ++i) {
this->stateIndications[i] = this->stateIndications[i - 1] + this->stateIndications[i];
}
// Put a sentinel element at the end of the indices list. This way,
// for each state i the range of indices can be read off between
// state_indices_list[i] and state_indices_list[i + 1].
this->stateIndications[numberOfStates] = numberOfTransitions;
// Create an array that stores the next index for each state. Initially
// this corresponds to the previously computed accumulated offsets.
std::vector<uint_fast64_t> nextIndices = stateIndications;
// Now we are ready to actually fill in the list of predecessors for
// every state. Again, we start by considering all but the last row.
for (uint_fast64_t i = 0; i < numberOfStates; ++i) {
for (auto rowIt = transitionMatrix.constColumnIteratorBegin(i); rowIt != transitionMatrix.constColumnIteratorEnd(i); ++rowIt) {
this->successorList[nextIndices[*rowIt]++] = i;
}
}
}
void initializeBackward(storm::storage::SparseMatrix<T> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices) {
// First, we need to count how many backward transitions each state has.
for (uint_fast64_t i = 0; i < numberOfStates; ++i) {
for (uint_fast64_t j = nondeterministicChoiceIndices[i]; j < nondeterministicChoiceIndices[i + 1]; ++j) {
for (auto rowIt = transitionMatrix.constColumnIteratorBegin(j); rowIt != transitionMatrix.constColumnIteratorEnd(j); ++rowIt) {
this->stateIndications[*rowIt + 1]++;
}
}
}
// Now compute the accumulated offsets.
for (uint_fast64_t i = 1; i < numberOfStates; i++) {
this->stateIndications[i] = this->stateIndications[i - 1] + this->stateIndications[i];
}
// Put a sentinel element at the end of the indices list. This way,
// for each state i the range of indices can be read off between
// state_indices_list[i] and state_indices_list[i + 1].
this->stateIndications[numberOfStates] = numberOfTransitions;
// Create an array that stores the next index for each state. Initially
// this corresponds to the previously computed accumulated offsets.
std::vector<uint_fast64_t> nextIndices = stateIndications;
// Now we are ready to actually fill in the list of predecessors for
// every state. Again, we start by considering all but the last row.
for (uint_fast64_t i = 0; i < numberOfStates; i++) {
for (uint_fast64_t j = nondeterministicChoiceIndices[i]; j < nondeterministicChoiceIndices[i + 1]; ++j) {
for (auto rowIt = transitionMatrix.constColumnIteratorBegin(j); rowIt != transitionMatrix.constColumnIteratorEnd(j); ++rowIt) {
this->successorList[nextIndices[*rowIt]++] = i;
}
}
}
}
/*!
* Store the number of states to determine the highest index at which the
* state_indices_list may be accessed.
*/
uint_fast64_t numberOfStates;
/*!
* Store the number of non-zero transition entries to determine the highest
* index at which the predecessor_list may be accessed.
*/
uint_fast64_t numberOfTransitions;
/*! A list of successors for *all* states. */
std::vector<uint_fast64_t> successorList;
/*!
* A list of indices indicating at which position in the global array the
* successors of a state can be found.
*/
std::vector<uint_fast64_t> stateIndications;
};
} // namespace models
} // namespace storm
#endif /* STORM_MODELS_GRAPHTRANSITIONS_H_ */

24
src/storage/SparseMatrix.h

@ -211,7 +211,7 @@ public:
*/
SparseMatrix(uint_fast64_t rows, uint_fast64_t cols) : rowCount(rows), colCount(cols),
nonZeroEntryCount(0), internalStatus(MatrixStatus::UnInitialized), currentSize(0), lastRow(0) {
// Intentionally left empty.
}
/*!
@ -222,8 +222,28 @@ public:
SparseMatrix(uint_fast64_t size = 0)
: rowCount(size), colCount(size), nonZeroEntryCount(0),
internalStatus(MatrixStatus::UnInitialized), currentSize(0), lastRow(0) {
// Intentionally left empty.
}
/*!
* Constructs a sparse matrix object with the given (moved) contents.
*
* @param rowCount The number of rows.
* @param colCount The number of columns.
* @param nonZeroEntryCount The number of non-zero entries.
* @param rowIndications The vector indicating where the rows start.
* @param columnIndications The vector indicating the column for each non-zero element.
* @param values The vector containing the non-zero values.
*/
SparseMatrix(uint_fast64_t rowCount, uint_fast64_t colCount, uint_fast64_t nonZeroEntryCount,
std::vector<uint_fast64_t>&& rowIndications,
std::vector<uint_fast64_t>&& columnIndications, std::vector<T>&& values)
: rowCount(rowCount), colCount(colCount), nonZeroEntryCount(nonZeroEntryCount),
valueStorage(values), columnIndications(columnIndications),
rowIndications(rowIndications), internalStatus(MatrixStatus::Initialized),
currentSize(0), lastRow(0) {
// Intentionally left empty.
}
/*!
* Initializes the sparse matrix with the given number of non-zero entries

41
src/utility/GraphAnalyzer.h

@ -58,7 +58,7 @@ public:
storm::storage::BitVector statesWithProbabilityGreater0(model.getNumberOfStates());
// Get the backwards transition relation from the model to ease the search.
storm::models::GraphTransitions<T> backwardTransitions(*model.getTransitionMatrix(), false);
storm::storage::SparseMatrix<bool> backwardTransitions = model.getBackwardTransitions();
// Add all psi states as the already satisfy the condition.
statesWithProbabilityGreater0 |= psiStates;
@ -73,7 +73,7 @@ public:
uint_fast64_t currentState = stack.back();
stack.pop_back();
for(auto it = backwardTransitions.beginStateSuccessorsIterator(currentState); it != backwardTransitions.endStateSuccessorsIterator(currentState); ++it) {
for(auto it = backwardTransitions.constColumnIteratorBegin(currentState); it != backwardTransitions.constColumnIteratorEnd(currentState); ++it) {
if (phiStates.get(*it) && !statesWithProbabilityGreater0.get(*it)) {
statesWithProbabilityGreater0.set(*it, true);
stack.push_back(*it);
@ -161,7 +161,7 @@ public:
storm::storage::BitVector statesWithProbability0(model.getNumberOfStates());
// Get the backwards transition relation from the model to ease the search.
storm::models::GraphTransitions<T> backwardTransitions(*model.getTransitionMatrix(), *model.getNondeterministicChoiceIndices(), false);
storm::storage::SparseMatrix<bool> backwardTransitions = model.getBackwardTransitions();
// Add all psi states as the already satisfy the condition.
statesWithProbability0 |= psiStates;
@ -176,7 +176,7 @@ public:
uint_fast64_t currentState = stack.back();
stack.pop_back();
for(auto it = backwardTransitions.beginStateSuccessorsIterator(currentState); it != backwardTransitions.endStateSuccessorsIterator(currentState); ++it) {
for(auto it = backwardTransitions.constColumnIteratorBegin(currentState), ite = backwardTransitions.constColumnIteratorEnd(currentState); it != ite; ++it) {
if (phiStates.get(*it) && !statesWithProbability0.get(*it)) {
statesWithProbability0.set(*it, true);
stack.push_back(*it);
@ -207,7 +207,7 @@ public:
std::shared_ptr<std::vector<uint_fast64_t>> nondeterministicChoiceIndices = model.getNondeterministicChoiceIndices();
// Get the backwards transition relation from the model to ease the search.
storm::models::GraphTransitions<T> backwardTransitions(*model.getTransitionMatrix(), *model.getNondeterministicChoiceIndices(), false);
storm::storage::SparseMatrix<bool> backwardTransitions = model.getBackwardTransitions();
storm::storage::BitVector currentStates(model.getNumberOfStates(), true);
@ -225,7 +225,7 @@ public:
uint_fast64_t currentState = stack.back();
stack.pop_back();
for(auto it = backwardTransitions.beginStateSuccessorsIterator(currentState); it != backwardTransitions.endStateSuccessorsIterator(currentState); ++it) {
for(auto it = backwardTransitions.constColumnIteratorBegin(currentState), ite = backwardTransitions.constColumnIteratorEnd(currentState); it != ite; ++it) {
if (phiStates.get(*it) && !nextStates.get(*it)) {
// Check whether the predecessor has only successors in the current state set for one of the
// nondeterminstic choices.
@ -300,7 +300,7 @@ public:
std::shared_ptr<std::vector<uint_fast64_t>> nondeterministicChoiceIndices = model.getNondeterministicChoiceIndices();
// Get the backwards transition relation from the model to ease the search.
storm::models::GraphTransitions<T> backwardTransitions(*transitionMatrix, *nondeterministicChoiceIndices, false);
storm::storage::SparseMatrix<bool> backwardTransitions = model.getBackwardTransitions();
// Add all psi states as the already satisfy the condition.
statesWithProbability0 |= psiStates;
@ -315,7 +315,7 @@ public:
uint_fast64_t currentState = stack.back();
stack.pop_back();
for(auto it = backwardTransitions.beginStateSuccessorsIterator(currentState); it != backwardTransitions.endStateSuccessorsIterator(currentState); ++it) {
for(auto it = backwardTransitions.constColumnIteratorBegin(currentState), ite = backwardTransitions.constColumnIteratorEnd(currentState); it != ite; ++it) {
if (phiStates.get(*it) && !statesWithProbability0.get(*it)) {
// Check whether the predecessor has at least one successor in the current state
// set for every nondeterministic choice.
@ -366,7 +366,7 @@ public:
std::shared_ptr<std::vector<uint_fast64_t>> nondeterministicChoiceIndices = model.getNondeterministicChoiceIndices();
// Get the backwards transition relation from the model to ease the search.
storm::models::GraphTransitions<T> backwardTransitions(*model.getTransitionMatrix(), *model.getNondeterministicChoiceIndices(), false);
storm::storage::SparseMatrix<bool> backwardTransitions = model.getBackwardTransitions();
storm::storage::BitVector currentStates(model.getNumberOfStates(), true);
@ -384,7 +384,7 @@ public:
uint_fast64_t currentState = stack.back();
stack.pop_back();
for(auto it = backwardTransitions.beginStateSuccessorsIterator(currentState); it != backwardTransitions.endStateSuccessorsIterator(currentState); ++it) {
for(auto it = backwardTransitions.constColumnIteratorBegin(currentState), ite = backwardTransitions.constColumnIteratorEnd(currentState); it != ite; ++it) {
if (phiStates.get(*it) && !nextStates.get(*it)) {
// Check whether the predecessor has only successors in the current state set for all of the
// nondeterminstic choices.
@ -421,17 +421,16 @@ public:
}
/*!
* Performs a decomposition of the given nondeterministic model into its SCCs.
* Performs a decomposition of the given model into its SCCs.
*
* @param model The nondeterminstic model to decompose.
* @return A pair whose first component represents the SCCs and whose second component represents the dependency
* graph of the SCCs.
* @return A vector of SCCs of the model.
*/
template <typename T>
static std::pair<std::vector<std::vector<uint_fast64_t>>, storm::storage::SparseMatrix<bool>> performSccDecomposition(storm::models::AbstractModel<T> const& model) {
static std::vector<std::vector<uint_fast64_t>> performSccDecomposition(storm::models::AbstractModel<T> const& model) {
LOG4CPLUS_INFO(logger, "Computing SCC decomposition.");
std::pair<std::vector<std::vector<uint_fast64_t>>, storm::storage::SparseMatrix<bool>> sccDecomposition;
std::vector<std::vector<uint_fast64_t>> scc;
uint_fast64_t numberOfStates = model.getNumberOfStates();
// Set up the environment of Tarjan's algorithm.
@ -441,21 +440,17 @@ public:
std::vector<uint_fast64_t> stateIndices(numberOfStates);
std::vector<uint_fast64_t> lowlinks(numberOfStates);
storm::storage::BitVector visitedStates(numberOfStates);
std::map<uint_fast64_t, uint_fast64_t> stateToSccMap;
// Start the search for SCCs from every vertex in the graph structure, because there is.
uint_fast64_t currentIndex = 0;
for (uint_fast64_t state = 0; state < numberOfStates; ++state) {
if (!visitedStates.get(state)) {
performSccDecompositionHelper(state, currentIndex, stateIndices, lowlinks, tarjanStack, tarjanStackStates, visitedStates, *model.getTransitionMatrix(), sccDecomposition.first, stateToSccMap);
performSccDecompositionHelper(state, currentIndex, stateIndices, lowlinks, tarjanStack, tarjanStackStates, visitedStates, *model.getTransitionMatrix(), scc);
}
}
// Finally, determine the dependency graph over the SCCs and return result.
sccDecomposition.second = model.extractSccDependencyGraph(sccDecomposition.first, stateToSccMap);
LOG4CPLUS_INFO(logger, "Done computing SCC decomposition.");
return sccDecomposition;
return scc;
}
/*!
@ -551,10 +546,9 @@ private:
* @param visitedStates A bit vector that stores all states that have already been visited.
* @param matrix The transition matrix representing the graph structure.
* @param stronglyConnectedComponents A vector of strongly connected components to which newly found SCCs are added.
* @param stateToSccMap A mapping from state indices to SCC indices that maps each state to its SCC.
*/
template <typename T>
static void performSccDecompositionHelper(uint_fast64_t startState, uint_fast64_t& currentIndex, std::vector<uint_fast64_t>& stateIndices, std::vector<uint_fast64_t>& lowlinks, std::vector<uint_fast64_t>& tarjanStack, storm::storage::BitVector& tarjanStackStates, storm::storage::BitVector& visitedStates, storm::storage::SparseMatrix<T> const& matrix, std::vector<std::vector<uint_fast64_t>>& stronglyConnectedComponents, std::map<uint_fast64_t, uint_fast64_t>& stateToSccMap) {
static void performSccDecompositionHelper(uint_fast64_t startState, uint_fast64_t& currentIndex, std::vector<uint_fast64_t>& stateIndices, std::vector<uint_fast64_t>& lowlinks, std::vector<uint_fast64_t>& tarjanStack, storm::storage::BitVector& tarjanStackStates, storm::storage::BitVector& visitedStates, storm::storage::SparseMatrix<T> const& matrix, std::vector<std::vector<uint_fast64_t>>& stronglyConnectedComponents) {
// Create the stacks needed for turning the recursive formulation of Tarjan's algorithm
// into an iterative version. In particular, we keep one stack for states and one stack
// for the iterators. The last one is not strictly needed, but reduces iteration work when
@ -623,7 +617,6 @@ private:
// Add the state to the current SCC.
stronglyConnectedComponents.back().push_back(lastState);
stateToSccMap[lastState] = stronglyConnectedComponents.size() - 1;
} while (lastState != currentState);
}

9
test/functional/storm-functional-tests.cpp

@ -15,10 +15,12 @@ log4cplus::Logger logger;
* Initializes the logging framework.
*/
void setUpLogging() {
logger = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("main"));
logger.setLogLevel(log4cplus::ERROR_LOG_LEVEL);
log4cplus::SharedAppenderPtr fileLogAppender(new log4cplus::FileAppender("storm-functional-tests.log"));
fileLogAppender->setName("mainFileAppender");
fileLogAppender->setThreshold(log4cplus::FATAL_LOG_LEVEL);
fileLogAppender->setLayout(std::auto_ptr<log4cplus::Layout>(new log4cplus::PatternLayout("%-5p - %D{%H:%M} (%r ms) - %F:%L : %m%n")));
logger = log4cplus::Logger::getInstance("mainLogger");
logger.addAppender(fileLogAppender);
// Uncomment these lines to enable console logging output
@ -62,5 +64,8 @@ int main(int argc, char* argv[]) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
int result = RUN_ALL_TESTS();
logger.closeNestedAppenders();
return result;
}

98
test/performance/graph/GraphTest.cpp

@ -9,7 +9,7 @@ TEST(GraphAnalyzerTest, PerformProb01) {
std::shared_ptr<storm::models::Dtmc<double>> dtmc = parser.getModel<storm::models::Dtmc<double>>();
LOG4CPLUS_INFO(logger, "Computing prob01 (3 times) for crowds/crowds20_5.");
LOG4CPLUS_WARN(logger, "Computing prob01 (3 times) for crowds/crowds20_5...");
std::pair<storm::storage::BitVector, storm::storage::BitVector> prob01 = storm::utility::GraphAnalyzer::performProb01(*dtmc, storm::storage::BitVector(dtmc->getNumberOfStates(), true), storm::storage::BitVector(dtmc->getLabeledStates("observe0Greater1")));
ASSERT_EQ(prob01.first.getNumberOfSetBits(), 1724414u);
@ -24,94 +24,132 @@ TEST(GraphAnalyzerTest, PerformProb01) {
ASSERT_EQ(prob01.first.getNumberOfSetBits(), 1785309u);
ASSERT_EQ(prob01.second.getNumberOfSetBits(), 40992u);
LOG4CPLUS_INFO(logger, "Done computing prob01 (3 times) for crowds/crowds20_5.");
LOG4CPLUS_WARN(logger, "Done.");
dtmc = nullptr;
storm::parser::AutoParser<double> parser2(STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader6_8.tra", STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader6_8.lab", "", STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader6_8.pick.trans.rew");
std::shared_ptr<storm::models::Dtmc<double>> dtmc2 = parser2.getModel<storm::models::Dtmc<double>>();
LOG4CPLUS_INFO(logger, "Computing prob01 for synchronous_leader/leader6_8");
LOG4CPLUS_WARN(logger, "Computing prob01 for synchronous_leader/leader6_8...");
prob01 = storm::utility::GraphAnalyzer::performProb01(*dtmc2, storm::storage::BitVector(dtmc2->getNumberOfStates(), true), storm::storage::BitVector(dtmc2->getLabeledStates("elected")));
LOG4CPLUS_INFO(logger, "Done computing prob01 for synchronous_leader/leader6_8");
LOG4CPLUS_WARN(logger, "Done.");
ASSERT_EQ(prob01.first.getNumberOfSetBits(), 0u);
ASSERT_EQ(prob01.second.getNumberOfSetBits(), 1312334u);
dtmc2 = nullptr;
}
TEST(GraphAnalyzerTest, PerformProb01MinMax) {
storm::parser::AutoParser<double> parser(STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader7.tra", STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader7.lab", "", STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader7.trans.rew");
std::shared_ptr<storm::models::Mdp<double>> mdp = parser.getModel<storm::models::Mdp<double>>();
LOG4CPLUS_INFO(logger, "Computing prob01min for asynchronous_leader/leader7");
LOG4CPLUS_WARN(logger, "Computing prob01min for asynchronous_leader/leader7...");
std::pair<storm::storage::BitVector, storm::storage::BitVector> prob01 = storm::utility::GraphAnalyzer::performProb01Min(*mdp, storm::storage::BitVector(mdp->getNumberOfStates(), true), mdp->getLabeledStates("elected"));
LOG4CPLUS_INFO(logger, "Done computing prob01min for asynchronous_leader/leader7");
LOG4CPLUS_WARN(logger, "Done.");
ASSERT_EQ(prob01.first.getNumberOfSetBits(), 0u);
ASSERT_EQ(prob01.second.getNumberOfSetBits(), 2095783u);
LOG4CPLUS_INFO(logger, "Computing prob01max for asynchronous_leader/leader7");
LOG4CPLUS_WARN(logger, "Computing prob01max for asynchronous_leader/leader7...");
prob01 = storm::utility::GraphAnalyzer::performProb01Max(*mdp, storm::storage::BitVector(mdp->getNumberOfStates(), true), mdp->getLabeledStates("elected"));
LOG4CPLUS_INFO(logger, "Done computing prob01max for asynchronous_leader/leader7");
LOG4CPLUS_WARN(logger, "Done.");
ASSERT_EQ(prob01.first.getNumberOfSetBits(), 0u);
ASSERT_EQ(prob01.second.getNumberOfSetBits(), 2095783u);
mdp = nullptr;
storm::parser::AutoParser<double> parser2(STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin4_6.tra", STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin4_6.lab", STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin4_6.steps.state.rew", "");
std::shared_ptr<storm::models::Mdp<double>> mdp2 = parser2.getModel<storm::models::Mdp<double>>();
LOG4CPLUS_INFO(logger, "Computing prob01min for consensus/coin4_6");
LOG4CPLUS_WARN(logger, "Computing prob01min for consensus/coin4_6...");
prob01 = storm::utility::GraphAnalyzer::performProb01Min(*mdp2, storm::storage::BitVector(mdp2->getNumberOfStates(), true), mdp2->getLabeledStates("finished"));
LOG4CPLUS_INFO(logger, "Done computing prob01min for consensus/coin4_6");
LOG4CPLUS_WARN(logger, "Done.");
ASSERT_EQ(prob01.first.getNumberOfSetBits(), 0u);
ASSERT_EQ(prob01.second.getNumberOfSetBits(), 63616u);
LOG4CPLUS_INFO(logger, "Computing prob01max for consensus/coin4_6");
LOG4CPLUS_WARN(logger, "Computing prob01max for consensus/coin4_6...");
prob01 = storm::utility::GraphAnalyzer::performProb01Max(*mdp2, storm::storage::BitVector(mdp2->getNumberOfStates(), true), mdp2->getLabeledStates("finished"));
LOG4CPLUS_INFO(logger, "Done computing prob01max for consensus/coin4_6");
LOG4CPLUS_WARN(logger, "Done.");
ASSERT_EQ(prob01.first.getNumberOfSetBits(), 0u);
ASSERT_EQ(prob01.second.getNumberOfSetBits(), 63616u);
mdp2 = nullptr;
}
TEST(GraphAnalyzerTest, PerformSCCDecomposition) {
TEST(GraphAnalyzerTest, PerformSCCDecompositionAndGetDependencyGraph) {
storm::parser::AutoParser<double> parser(STORM_CPP_BASE_PATH "/examples/dtmc/crowds/crowds20_5.tra", STORM_CPP_BASE_PATH "/examples/dtmc/crowds/crowds20_5.lab", "", "");
std::shared_ptr<storm::models::Dtmc<double>> dtmc = parser.getModel<storm::models::Dtmc<double>>();
LOG4CPLUS_INFO(logger, "Computing SCC decomposition of crowds/crowds20_5.");
std::pair<std::vector<std::vector<uint_fast64_t>>, storm::storage::SparseMatrix<bool>> sccDecomposition = storm::utility::GraphAnalyzer::performSccDecomposition(*dtmc);
LOG4CPLUS_INFO(logger, "Done computing SCC decomposition of crowds/crowds20_5.");
LOG4CPLUS_WARN(logger, "Computing SCC decomposition of crowds/crowds20_5...");
std::vector<std::vector<uint_fast64_t>> sccDecomposition = storm::utility::GraphAnalyzer::performSccDecomposition(*dtmc);
LOG4CPLUS_WARN(logger, "Done.");
ASSERT_EQ(sccDecomposition.first.size(), 1290297u);
ASSERT_EQ(sccDecomposition.second.getNonZeroEntryCount(), 1371253u);
ASSERT_EQ(sccDecomposition.size(), 1290297u);
LOG4CPLUS_WARN(logger, "Extracting SCC dependency graph of crowds/crowds20_5...");
storm::storage::SparseMatrix<bool> sccDependencyGraph = dtmc->extractSccDependencyGraph(sccDecomposition);
LOG4CPLUS_WARN(logger, "Done.");
ASSERT_EQ(sccDependencyGraph.getNonZeroEntryCount(), 1371253u);
dtmc = nullptr;
storm::parser::AutoParser<double> parser2(STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader6_8.tra", STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader6_8.lab", "", STORM_CPP_BASE_PATH "/examples/dtmc/synchronous_leader/leader6_8.pick.trans.rew");
std::shared_ptr<storm::models::Dtmc<double>> dtmc2 = parser2.getModel<storm::models::Dtmc<double>>();
LOG4CPLUS_INFO(logger, "Computing SCC decomposition of synchronous_leader/leader6_8");
LOG4CPLUS_WARN(logger, "Computing SCC decomposition of synchronous_leader/leader6_8...");
sccDecomposition = storm::utility::GraphAnalyzer::performSccDecomposition(*dtmc2);
LOG4CPLUS_INFO(logger, "Computing SCC decomposition of synchronous_leader/leader6_8.");
LOG4CPLUS_WARN(logger, "Done.");
ASSERT_EQ(sccDecomposition.first.size(), 1279673u);
ASSERT_EQ(sccDecomposition.second.getNonZeroEntryCount(), 1535367u);
ASSERT_EQ(sccDecomposition.size(), 1279673u);
LOG4CPLUS_WARN(logger, "Extracting SCC dependency graph of synchronous_leader/leader6_8...");
sccDependencyGraph = dtmc2->extractSccDependencyGraph(sccDecomposition);
LOG4CPLUS_WARN(logger, "Done.");
ASSERT_EQ(sccDependencyGraph.getNonZeroEntryCount(), 1535367u);
dtmc2 = nullptr;
/*
storm::parser::AutoParser<double> parser3(STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader7.tra", STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader7.lab", "", STORM_CPP_BASE_PATH "/examples/mdp/asynchronous_leader/leader7.trans.rew");
std::shared_ptr<storm::models::Mdp<double>> mdp = parser3.getModel<storm::models::Mdp<double>>();
LOG4CPLUS_INFO(logger, "Computing SCC decomposition of asynchronous_leader/leader7");
LOG4CPLUS_WARN(logger, "Computing SCC decomposition of asynchronous_leader/leader7...");
sccDecomposition = storm::utility::GraphAnalyzer::performSccDecomposition(*mdp);
LOG4CPLUS_INFO(logger, "Done computing SCC decomposition of asynchronous_leader/leader7");
LOG4CPLUS_WARN(logger, "Done.");
ASSERT_EQ(sccDecomposition.first.size(), 1914691u);
ASSERT_EQ(sccDecomposition.second.getNonZeroEntryCount(), 7023587u);
ASSERT_EQ(sccDecomposition.size(), 1914691u);
LOG4CPLUS_WARN(logger, "Extracting SCC dependency graph of asynchronous_leader/leader7...");
sccDependencyGraph = mdp->extractSccDependencyGraph(sccDecomposition);
LOG4CPLUS_WARN(logger, "Done.");
ASSERT_EQ(sccDependencyGraph.getNonZeroEntryCount(), 7023587u);
mdp = nullptr;
*/
storm::parser::AutoParser<double> parser4(STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin4_6.tra", STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin4_6.lab", STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin4_6.steps.state.rew", "");
std::shared_ptr<storm::models::Mdp<double>> mdp2 = parser4.getModel<storm::models::Mdp<double>>();
LOG4CPLUS_INFO(logger, "Computing SCC decomposition of consensus/coin4_6");
LOG4CPLUS_WARN(logger, "Computing SCC decomposition of consensus/coin4_6...");
sccDecomposition = storm::utility::GraphAnalyzer::performSccDecomposition(*mdp2);
LOG4CPLUS_INFO(logger, "Computing SCC decomposition of consensus/coin4_6");
LOG4CPLUS_WARN(logger, "Done.");
ASSERT_EQ(sccDecomposition.size(), 63611u);
LOG4CPLUS_WARN(logger, "Extracting SCC dependency graph of consensus/coin4_6...");
sccDependencyGraph = mdp2->extractSccDependencyGraph(sccDecomposition);
LOG4CPLUS_WARN(logger, "Done.");
ASSERT_EQ(sccDependencyGraph.getNonZeroEntryCount(), 213400u);
ASSERT_EQ(sccDecomposition.first.size(), 63611u);
ASSERT_EQ(sccDecomposition.second.getNonZeroEntryCount(), 213400u);
mdp2 = nullptr;
}

14
test/performance/modelchecker/GmmxxDtmcPrctModelCheckerTest.cpp

@ -22,7 +22,9 @@ TEST(GmmxxDtmcPrctModelCheckerTest, Crowds) {
storm::property::prctl::Eventually<double>* eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula);
storm::property::prctl::ProbabilisticNoBoundOperator<double>* probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula);
LOG4CPLUS_WARN(logger, "Model Checking P=? [F observe0Greater1] on crowds/crowds20_5...");
std::vector<double>* result = probFormula->check(mc);
LOG4CPLUS_WARN(logger, "Done.");
ASSERT_NE(nullptr, result);
@ -35,8 +37,10 @@ TEST(GmmxxDtmcPrctModelCheckerTest, Crowds) {
eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula);
probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula);
LOG4CPLUS_WARN(logger, "Model Checking P=? [F observeIGreater1] on crowds/crowds20_5...");
result = probFormula->check(mc);
LOG4CPLUS_WARN(logger, "Done.");
ASSERT_NE(nullptr, result);
ASSERT_LT(std::abs((*result)[0] - 0.05072232915), s->get<double>("precision"));
@ -48,7 +52,9 @@ TEST(GmmxxDtmcPrctModelCheckerTest, Crowds) {
eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula);
probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula);
LOG4CPLUS_WARN(logger, "Model Checking P=? [F observeOnlyTrueSender] on crowds/crowds20_5...");
result = probFormula->check(mc);
LOG4CPLUS_WARN(logger, "Done.");
ASSERT_NE(nullptr, result);
@ -77,7 +83,9 @@ TEST(GmmxxDtmcPrctModelCheckerTest, SynchronousLeader) {
storm::property::prctl::Eventually<double>* eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula);
storm::property::prctl::ProbabilisticNoBoundOperator<double>* probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula);
LOG4CPLUS_WARN(logger, "Model Checking P=? [F elected] on synchronous_leader/leader6_8...");
std::vector<double>* result = probFormula->check(mc);
LOG4CPLUS_WARN(logger, "Done.");
ASSERT_NE(nullptr, result);
@ -90,7 +98,9 @@ TEST(GmmxxDtmcPrctModelCheckerTest, SynchronousLeader) {
storm::property::prctl::BoundedUntil<double>* boundedUntilFormula = new storm::property::prctl::BoundedUntil<double>(new storm::property::prctl::Ap<double>("true"), apFormula, 20);
probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(boundedUntilFormula);
LOG4CPLUS_WARN(logger, "Model Checking P=? [F<=20 elected] on synchronous_leader/leader6_8...");
result = probFormula->check(mc);
LOG4CPLUS_WARN(logger, "Done.");
ASSERT_NE(nullptr, result);
@ -103,7 +113,9 @@ TEST(GmmxxDtmcPrctModelCheckerTest, SynchronousLeader) {
storm::property::prctl::ReachabilityReward<double>* reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward<double>(apFormula);
storm::property::prctl::RewardNoBoundOperator<double>* rewardFormula = new storm::property::prctl::RewardNoBoundOperator<double>(reachabilityRewardFormula);
LOG4CPLUS_WARN(logger, "Model Checking R=? [F elected] on synchronous_leader/leader6_8...");
result = rewardFormula->check(mc);
LOG4CPLUS_WARN(logger, "Done.");
ASSERT_NE(nullptr, result);

40
test/performance/modelchecker/GmmxxMdpPrctModelCheckerTest.cpp

@ -22,7 +22,9 @@ TEST(GmmxxMdpPrctModelCheckerTest, AsynchronousLeader) {
storm::property::prctl::Eventually<double>* eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula);
storm::property::prctl::ProbabilisticNoBoundOperator<double>* probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula, true);
LOG4CPLUS_WARN(logger, "Model Checking Pmin=? [F elected] on asynchronous_leader/leader7...");
std::vector<double>* result = mc.checkNoBoundOperator(*probFormula);
LOG4CPLUS_WARN(logger, "Done.");
ASSERT_NE(nullptr, result);
@ -35,7 +37,9 @@ TEST(GmmxxMdpPrctModelCheckerTest, AsynchronousLeader) {
eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula);
probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula, false);
LOG4CPLUS_WARN(logger, "Model Checking Pmax=? [F elected] on asynchronous_leader/leader7...");
result = mc.checkNoBoundOperator(*probFormula);
LOG4CPLUS_WARN(logger, "Done.");
ASSERT_NE(nullptr, result);
@ -48,7 +52,9 @@ TEST(GmmxxMdpPrctModelCheckerTest, AsynchronousLeader) {
storm::property::prctl::BoundedEventually<double>* boundedEventuallyFormula = new storm::property::prctl::BoundedEventually<double>(apFormula, 25);
probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(boundedEventuallyFormula, true);
LOG4CPLUS_WARN(logger, "Model Checking Pmin=? [F<=25 elected] on asynchronous_leader/leader7...");
result = mc.checkNoBoundOperator(*probFormula);
LOG4CPLUS_WARN(logger, "Done.");
ASSERT_NE(nullptr, result);
@ -61,7 +67,9 @@ TEST(GmmxxMdpPrctModelCheckerTest, AsynchronousLeader) {
boundedEventuallyFormula = new storm::property::prctl::BoundedEventually<double>(apFormula, 25);
probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(boundedEventuallyFormula, false);
LOG4CPLUS_WARN(logger, "Model Checking Pmax=? [F<=25 elected] on asynchronous_leader/leader7...");
result = mc.checkNoBoundOperator(*probFormula);
LOG4CPLUS_WARN(logger, "Done.");
ASSERT_NE(nullptr, result);
@ -74,7 +82,9 @@ TEST(GmmxxMdpPrctModelCheckerTest, AsynchronousLeader) {
storm::property::prctl::ReachabilityReward<double>* reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward<double>(apFormula);
storm::property::prctl::RewardNoBoundOperator<double>* rewardFormula = new storm::property::prctl::RewardNoBoundOperator<double>(reachabilityRewardFormula, true);
LOG4CPLUS_WARN(logger, "Model Checking Rmin=? [F elected] on asynchronous_leader/leader7...");
result = mc.checkNoBoundOperator(*rewardFormula);
LOG4CPLUS_WARN(logger, "Done.");
ASSERT_LT(std::abs((*result)[0] - 6.172433512), s->get<double>("precision"));
@ -85,7 +95,9 @@ TEST(GmmxxMdpPrctModelCheckerTest, AsynchronousLeader) {
reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward<double>(apFormula);
rewardFormula = new storm::property::prctl::RewardNoBoundOperator<double>(reachabilityRewardFormula, false);
result = mc.checkNoBoundOperator(*rewardFormula);;
LOG4CPLUS_WARN(logger, "Model Checking Rmax=? [F elected] on asynchronous_leader/leader7...");
result = mc.checkNoBoundOperator(*rewardFormula);
LOG4CPLUS_WARN(logger, "Done");
ASSERT_NE(nullptr, result);
@ -97,6 +109,8 @@ TEST(GmmxxMdpPrctModelCheckerTest, AsynchronousLeader) {
TEST(GmmxxMdpPrctModelCheckerTest, Consensus) {
storm::settings::Settings* s = storm::settings::instance();
s->set<unsigned>("maxiter", 20000);
std::cout << s->get<unsigned>("maxiter") << std::endl;
storm::parser::AutoParser<double> parser(STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin4_6.tra", STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin4_6.lab", STORM_CPP_BASE_PATH "/examples/mdp/consensus/coin4_6.steps.state.rew", "");
ASSERT_EQ(parser.getType(), storm::models::MDP);
@ -112,7 +126,9 @@ TEST(GmmxxMdpPrctModelCheckerTest, Consensus) {
storm::property::prctl::Eventually<double>* eventuallyFormula = new storm::property::prctl::Eventually<double>(apFormula);
storm::property::prctl::ProbabilisticNoBoundOperator<double>* probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula, true);
LOG4CPLUS_WARN(logger, "Model Checking Pmin=? [F finished] on consensus/coin4_6...");
std::vector<double>* result = mc.checkNoBoundOperator(*probFormula);
LOG4CPLUS_WARN(logger, "Done.");
ASSERT_NE(nullptr, result);
@ -127,7 +143,9 @@ TEST(GmmxxMdpPrctModelCheckerTest, Consensus) {
eventuallyFormula = new storm::property::prctl::Eventually<double>(andFormula);
probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula, true);
LOG4CPLUS_WARN(logger, "Model Checking Pmin=? [F finished & all_coins_equal_0] on consensus/coin4_6...");
result = mc.checkNoBoundOperator(*probFormula);
LOG4CPLUS_WARN(logger, "Done.");
ASSERT_NE(nullptr, result);
@ -142,10 +160,11 @@ TEST(GmmxxMdpPrctModelCheckerTest, Consensus) {
eventuallyFormula = new storm::property::prctl::Eventually<double>(andFormula);
probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula, false);
LOG4CPLUS_WARN(logger, "Model Checking Pmax=? [F finished & all_coins_equal_1] on consensus/coin4_6...");
result = mc.checkNoBoundOperator(*probFormula);
LOG4CPLUS_WARN(logger, "Done.");
ASSERT_NE(nullptr, result);
ASSERT_LT(std::abs((*result)[31168] - 0.5282872761373342829216), s->get<double>("precision"));
delete probFormula;
@ -158,10 +177,11 @@ TEST(GmmxxMdpPrctModelCheckerTest, Consensus) {
eventuallyFormula = new storm::property::prctl::Eventually<double>(andFormula);
probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(eventuallyFormula, false);
LOG4CPLUS_WARN(logger, "Model Checking Pmax=? [F finished & !agree] on consensus/coin4_6...");
result = mc.checkNoBoundOperator(*probFormula);
LOG4CPLUS_WARN(logger, "Done.");
ASSERT_NE(nullptr, result);
ASSERT_LT(std::abs((*result)[31168] - 0.10343451035775527713), s->get<double>("precision"));
delete probFormula;
@ -171,10 +191,11 @@ TEST(GmmxxMdpPrctModelCheckerTest, Consensus) {
storm::property::prctl::BoundedEventually<double>* boundedEventuallyFormula = new storm::property::prctl::BoundedEventually<double>(apFormula, 50);
probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(boundedEventuallyFormula, true);
LOG4CPLUS_WARN(logger, "Model Checking Pmin=? [F<=50 finished] on consensus/coin4_6...");
result = mc.checkNoBoundOperator(*probFormula);
LOG4CPLUS_WARN(logger, "Done.");
ASSERT_NE(nullptr, result);
ASSERT_LT(std::abs((*result)[31168] - 0), s->get<double>("precision"));
delete probFormula;
@ -184,10 +205,11 @@ TEST(GmmxxMdpPrctModelCheckerTest, Consensus) {
boundedEventuallyFormula = new storm::property::prctl::BoundedEventually<double>(apFormula, 50);
probFormula = new storm::property::prctl::ProbabilisticNoBoundOperator<double>(boundedEventuallyFormula, false);
LOG4CPLUS_WARN(logger, "Model Checking Pmax=? [F<=50 finished] on consensus/coin4_6...");
result = mc.checkNoBoundOperator(*probFormula);
LOG4CPLUS_WARN(logger, "Done.");
ASSERT_NE(nullptr, result);
ASSERT_LT(std::abs((*result)[31168] - 0), s->get<double>("precision"));
delete probFormula;
@ -197,8 +219,11 @@ TEST(GmmxxMdpPrctModelCheckerTest, Consensus) {
storm::property::prctl::ReachabilityReward<double>* reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward<double>(apFormula);
storm::property::prctl::RewardNoBoundOperator<double>* rewardFormula = new storm::property::prctl::RewardNoBoundOperator<double>(reachabilityRewardFormula, true);
LOG4CPLUS_WARN(logger, "Model Checking Rmin=? [F finished] on consensus/coin4_6...");
result = mc.checkNoBoundOperator(*rewardFormula);
LOG4CPLUS_WARN(logger, "Done.");
ASSERT_NE(nullptr, result);
ASSERT_LT(std::abs((*result)[31168] - 1725.5933133943854045), s->get<double>("precision"));
delete rewardFormula;
@ -208,10 +233,11 @@ TEST(GmmxxMdpPrctModelCheckerTest, Consensus) {
reachabilityRewardFormula = new storm::property::prctl::ReachabilityReward<double>(apFormula);
rewardFormula = new storm::property::prctl::RewardNoBoundOperator<double>(reachabilityRewardFormula, false);
result = mc.checkNoBoundOperator(*rewardFormula);;
LOG4CPLUS_WARN(logger, "Model Checking Rmax=? [F finished] on consensus/coin4_6...");
result = mc.checkNoBoundOperator(*rewardFormula);
LOG4CPLUS_WARN(logger, "Done.");
ASSERT_NE(nullptr, result);
ASSERT_LT(std::abs((*result)[31168] - 2179.014847073392047605011), s->get<double>("precision"));
delete rewardFormula;

12
test/performance/storm-performance-tests.cpp

@ -16,7 +16,7 @@ log4cplus::Logger logger;
*/
void setUpLogging() {
logger = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("main"));
logger.setLogLevel(log4cplus::INFO_LOG_LEVEL);
logger.setLogLevel(log4cplus::WARN_LOG_LEVEL);
log4cplus::SharedAppenderPtr fileLogAppender(new log4cplus::FileAppender("storm-performance-tests.log"));
fileLogAppender->setName("mainFileAppender");
fileLogAppender->setThreshold(log4cplus::WARN_LOG_LEVEL);
@ -42,9 +42,8 @@ bool parseOptions(int const argc, char const * const argv[]) {
storm::settings::Settings::registerModule<storm::modelchecker::GmmxxDtmcPrctlModelChecker<double>>();
s = storm::settings::newInstance(argc, argv, nullptr, true);
} catch (storm::exceptions::InvalidSettingsException& e) {
std::cout << "Could not recover from settings error: " << e.what() << "." << std::endl;
std::cout << std::endl << storm::settings::help;
return false;
// Ignore this case.
return true;
}
if (s->isSet("help")) {
@ -64,5 +63,8 @@ int main(int argc, char* argv[]) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
int result = RUN_ALL_TESTS();
logger.closeNestedAppenders();
return result;
}
Loading…
Cancel
Save