50 lines
2.4 KiB

#include "src/storage/BisimulationDecomposition.h"
#include <queue>
namespace storm {
namespace storage {
template<typename ValueType>
BisimulationDecomposition<ValueType>::BisimulationDecomposition(storm::models::Dtmc<ValueType> const& model, bool weak) {
computeBisimulationEquivalenceClasses(model, weak);
}
template<typename ValueType>
void BisimulationDecomposition<ValueType>::computeBisimulationEquivalenceClasses(storm::models::Dtmc<ValueType> const& model, bool weak) {
// We start by computing the initial partition. In particular, we also keep a mapping of states to their blocks.
std::vector<std::size_t> stateToBlockMapping(model.getNumberOfStates());
storm::storage::BitVector labeledStates = model.getLabeledStates("one");
this->blocks.emplace_back(labeledStates.begin(), labeledStates.end());
std::for_each(labeledStates.begin(), labeledStates.end(), [&] (storm::storage::sparse::state_type const& state) { stateToBlockMapping[state] = 0; } );
labeledStates.complement();
this->blocks.emplace_back(labeledStates.begin(), labeledStates.end());
std::for_each(labeledStates.begin(), labeledStates.end(), [&] (storm::storage::sparse::state_type const& state) { stateToBlockMapping[state] = 1; } );
// Retrieve the backward transitions to allow for better checking of states that need to be re-examined.
storm::storage::SparseMatrix<ValueType> const& backwardTransitions = model.getBackwardTransitions();
// Initially, both blocks are potential splitters.
std::queue<std::size_t> splitterQueue;
splitterQueue.push(0);
splitterQueue.push(1);
// As long as there is a splitter, we keep refining the current partition.
while (!splitterQueue.empty()) {
}
// While there is a splitter...
//
// check the predecessors of the splitter:
// * if they still have the same signature as before, then they remain unsplit
// * otherwise, split off the states that now behave differently
// and mark the smaller block as a splitter
//
}
template class BisimulationDecomposition<double>;
}
}