|  |  | @ -17,6 +17,8 @@ | 
			
		
	
		
			
				
					|  |  |  | #include "storm/exceptions/NotSupportedException.h"
 | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | #include <set>
 | 
			
		
	
		
			
				
					|  |  |  | #include <storm/storage/StronglyConnectedComponentDecomposition.h>
 | 
			
		
	
		
			
				
					|  |  |  | #include <storm/storage/StronglyConnectedComponent.h>
 | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | #include "storm/storage/BitVector.h"
 | 
			
		
	
		
			
				
					|  |  |  | #include "storm/utility/macros.h"
 | 
			
		
	
	
		
			
				
					|  |  | @ -25,8 +27,35 @@ namespace storm { | 
			
		
	
		
			
				
					|  |  |  |     namespace analysis { | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         template<typename ValueType> | 
			
		
	
		
			
				
					|  |  |  |         LatticeExtender<ValueType>::LatticeExtender(std::shared_ptr<storm::models::sparse::Model<ValueType>> model) : model(model) { | 
			
		
	
		
			
				
					|  |  |  |             // intentionally left empty
 | 
			
		
	
		
			
				
					|  |  |  |         LatticeExtender<ValueType>::LatticeExtender(std::shared_ptr<storm::models::sparse::Model<ValueType>> model) { | 
			
		
	
		
			
				
					|  |  |  |             this->model = model; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |             initialMiddleStates = storm::storage::BitVector(model->getNumberOfStates()); | 
			
		
	
		
			
				
					|  |  |  |             // Check if MC is acyclic
 | 
			
		
	
		
			
				
					|  |  |  |             auto decomposition = storm::storage::StronglyConnectedComponentDecomposition<ValueType>(model->getTransitionMatrix(), false, false); | 
			
		
	
		
			
				
					|  |  |  |             for (auto i = 0; i < decomposition.size(); ++i) { | 
			
		
	
		
			
				
					|  |  |  |                 auto scc = decomposition.getBlock(i); | 
			
		
	
		
			
				
					|  |  |  |                 if (scc.size() > 1) { | 
			
		
	
		
			
				
					|  |  |  |                     auto states = scc.getStates(); | 
			
		
	
		
			
				
					|  |  |  |                     bool added = false; | 
			
		
	
		
			
				
					|  |  |  |                     for (auto itr = states.begin(); !added && itr != states.end(); ++itr) { | 
			
		
	
		
			
				
					|  |  |  |                         auto state = *itr; | 
			
		
	
		
			
				
					|  |  |  |                         storm::storage::BitVector subSystem = storm::storage::BitVector(model->getNumberOfStates()); | 
			
		
	
		
			
				
					|  |  |  |                         subSystem.set(states.begin(), states.end(), true); | 
			
		
	
		
			
				
					|  |  |  |                         subSystem.set(state, false); | 
			
		
	
		
			
				
					|  |  |  |                         auto subDecomposition = storm::storage::StronglyConnectedComponentDecomposition<ValueType>(model->getTransitionMatrix(), subSystem, false, false); | 
			
		
	
		
			
				
					|  |  |  |                         bool acyclic = true; | 
			
		
	
		
			
				
					|  |  |  |                         for (auto i = 0; acyclic && i < subDecomposition.size(); ++i) { | 
			
		
	
		
			
				
					|  |  |  |                             auto subScc = subDecomposition.getBlock(i); | 
			
		
	
		
			
				
					|  |  |  |                             acyclic = subScc.size() <= 1; | 
			
		
	
		
			
				
					|  |  |  |                         } | 
			
		
	
		
			
				
					|  |  |  |                         if (acyclic) { | 
			
		
	
		
			
				
					|  |  |  |                             initialMiddleStates.set(state); | 
			
		
	
		
			
				
					|  |  |  |                             added = true; | 
			
		
	
		
			
				
					|  |  |  |                         } | 
			
		
	
		
			
				
					|  |  |  |                     } | 
			
		
	
		
			
				
					|  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         template <typename ValueType> | 
			
		
	
	
		
			
				
					|  |  | @ -71,6 +100,9 @@ namespace storm { | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |             // Create the Lattice
 | 
			
		
	
		
			
				
					|  |  |  |             storm::analysis::Lattice *lattice = new storm::analysis::Lattice(topStates, bottomStates, numberOfStates); | 
			
		
	
		
			
				
					|  |  |  |             for (auto state = initialMiddleStates.getNextSetIndex(0); state != numberOfStates; state = initialMiddleStates.getNextSetIndex(state + 1)) { | 
			
		
	
		
			
				
					|  |  |  |                 lattice->add(state); | 
			
		
	
		
			
				
					|  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |             return this->extendLattice(lattice); | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  | @ -110,8 +142,9 @@ namespace storm { | 
			
		
	
		
			
				
					|  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |             auto oldNumberSet = lattice->getAddedStates().getNumberOfSetBits(); | 
			
		
	
		
			
				
					|  |  |  |             while (lattice->getAddedStates().getNumberOfSetBits() != numberOfStates) { | 
			
		
	
		
			
				
					|  |  |  |             auto oldNumberSet = numberOfStates; | 
			
		
	
		
			
				
					|  |  |  |             while (oldNumberSet != lattice->getAddedStates().getNumberOfSetBits()) { | 
			
		
	
		
			
				
					|  |  |  |                 oldNumberSet = lattice->getAddedStates().getNumberOfSetBits(); | 
			
		
	
		
			
				
					|  |  |  |                 for (auto stateItr = stateMap.begin(); stateItr != stateMap.end(); ++stateItr) { | 
			
		
	
		
			
				
					|  |  |  |                     storm::storage::BitVector seenStates = (lattice->getAddedStates()); | 
			
		
	
		
			
				
					|  |  |  |                     // Iterate over all states
 | 
			
		
	
	
		
			
				
					|  |  | @ -169,12 +202,6 @@ namespace storm { | 
			
		
	
		
			
				
					|  |  |  |                         lattice->addBetween(stateNumber, lattice->getNode(highest), lattice->getNode(lowest)); | 
			
		
	
		
			
				
					|  |  |  |                     } | 
			
		
	
		
			
				
					|  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |                 // Nothing changed and not done yet
 | 
			
		
	
		
			
				
					|  |  |  |                 if (oldNumberSet == lattice->getAddedStates().getNumberOfSetBits()) { | 
			
		
	
		
			
				
					|  |  |  |                     // add the first unset state to the lattice between top and bottom
 | 
			
		
	
		
			
				
					|  |  |  |                     lattice->add(lattice->getAddedStates().getNextUnsetIndex(0)); | 
			
		
	
		
			
				
					|  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |                 oldNumberSet = lattice->getAddedStates().getNumberOfSetBits(); | 
			
		
	
		
			
				
					|  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |             return std::make_tuple(lattice, numberOfStates, numberOfStates); | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
	
		
			
				
					|  |  | 
 |