| 
					
					
						
							
						
					
					
				 | 
				@ -8,7 +8,10 @@ | 
			
		
		
	
		
			
				 | 
				 | 
				#include <iostream> | 
				 | 
				 | 
				#include <iostream> | 
			
		
		
	
		
			
				 | 
				 | 
				#include <vector> | 
				 | 
				 | 
				#include <vector> | 
			
		
		
	
		
			
				 | 
				 | 
				
 | 
				 | 
				 | 
				
 | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				#include "storm/models/sparse/Model.h" | 
			
		
		
	
		
			
				 | 
				 | 
				#include "storm/storage/BitVector.h" | 
				 | 
				 | 
				#include "storm/storage/BitVector.h" | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				#include "storm/storage/SparseMatrix.h" | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				
 | 
			
		
		
	
		
			
				 | 
				 | 
				
 | 
				 | 
				 | 
				
 | 
			
		
		
	
		
			
				 | 
				 | 
				namespace storm { | 
				 | 
				 | 
				namespace storm { | 
			
		
		
	
		
			
				 | 
				 | 
				            namespace analysis { | 
				 | 
				 | 
				            namespace analysis { | 
			
		
		
	
	
		
			
				| 
					
					
					
						
							
						
					
				 | 
				@ -33,18 +36,24 @@ namespace storm { | 
			
		
		
	
		
			
				 | 
				 | 
				                    /*! | 
				 | 
				 | 
				                    /*! | 
			
		
		
	
		
			
				 | 
				 | 
				                     * Adds a node with the given state below node1 and above node2. | 
				 | 
				 | 
				                     * Adds a node with the given state below node1 and above node2. | 
			
		
		
	
		
			
				 | 
				 | 
				                     * @param state The given state. | 
				 | 
				 | 
				                     * @param state The given state. | 
			
		
		
	
		
			
				 | 
				 | 
				                     * @param node1 The pointer to the node below which a new node is added. | 
				 | 
				 | 
				 | 
			
		
		
	
		
			
				 | 
				 | 
				                     * @param node2 The pointer to the node above which a new node is added. | 
				 | 
				 | 
				 | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                     * @param node1 The pointer to the node below which a new node (with state) is added | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                     * @param node2 The pointer to the node above which a new node (with state) is added | 
			
		
		
	
		
			
				 | 
				 | 
				                     */ | 
				 | 
				 | 
				                     */ | 
			
		
		
	
		
			
				 | 
				 | 
				                    void addBetween(uint_fast64_t state, Node *node1, Node *node2); | 
				 | 
				 | 
				                    void addBetween(uint_fast64_t state, Node *node1, Node *node2); | 
			
		
		
	
		
			
				 | 
				 | 
				
 | 
				 | 
				 | 
				
 | 
			
		
		
	
		
			
				 | 
				 | 
				                    /*! | 
				 | 
				 | 
				                    /*! | 
			
		
		
	
		
			
				 | 
				 | 
				                     * Adds state to the states of the given node. | 
				 | 
				 | 
				                     * Adds state to the states of the given node. | 
			
		
		
	
		
			
				 | 
				 | 
				                     * @param state The state which is added. | 
				 | 
				 | 
				                     * @param state The state which is added. | 
			
		
		
	
		
			
				 | 
				 | 
				                     * @param node The pointer to the node to which state is added. | 
				 | 
				 | 
				 | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                     * @param node The pointer to the node to which state is added, should not be nullptr. | 
			
		
		
	
		
			
				 | 
				 | 
				                     */ | 
				 | 
				 | 
				                     */ | 
			
		
		
	
		
			
				 | 
				 | 
				                    void addToNode(uint_fast64_t state, Node *node); | 
				 | 
				 | 
				                    void addToNode(uint_fast64_t state, Node *node); | 
			
		
		
	
		
			
				 | 
				 | 
				
 | 
				 | 
				 | 
				
 | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                    /*! | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                     * Adds state between the top and bottom node of the lattice | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                     * @param state The given state | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                     */ | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                    void add(uint_fast64_t state); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				
 | 
			
		
		
	
		
			
				 | 
				 | 
				                    /*! | 
				 | 
				 | 
				                    /*! | 
			
		
		
	
		
			
				 | 
				 | 
				                     * Compares the level of the nodes of the states. | 
				 | 
				 | 
				                     * Compares the level of the nodes of the states. | 
			
		
		
	
		
			
				 | 
				 | 
				                     * Behaviour unknown when one or more of the states doesnot occur at any Node in the Lattice. | 
				 | 
				 | 
				                     * Behaviour unknown when one or more of the states doesnot occur at any Node in the Lattice. | 
			
		
		
	
	
		
			
				| 
					
						
							
						
					
					
						
							
						
					
					
				 | 
				@ -74,11 +83,103 @@ namespace storm { | 
			
		
		
	
		
			
				 | 
				 | 
				                     */ | 
				 | 
				 | 
				                     */ | 
			
		
		
	
		
			
				 | 
				 | 
				                    void toString(std::ostream &out); | 
				 | 
				 | 
				                    void toString(std::ostream &out); | 
			
		
		
	
		
			
				 | 
				 | 
				
 | 
				 | 
				 | 
				
 | 
			
		
		
	
		
			
				 | 
				 | 
				//                    std::vector<uint_fast64_t> addedStates; | 
				 | 
				 | 
				 | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                    /*! | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                     * Creates a Lattice based on the transition matrix, topStates of the Lattice and bottomStates of the Lattice | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                     * @tparam ValueType Type of the probabilities | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                     * @param matrix The transition matrix. | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                     * @param topStates Set of topStates of the Lattice. | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                     * @param bottomStates Set of bottomStates of the Lattice. | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                     * @return pointer to the created Lattice. | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                     */ | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                    template <typename ValueType> | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                    static Lattice* toLattice(storm::storage::SparseMatrix<ValueType> matrix, | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                                                 storm::storage::BitVector topStates, | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                                                 storm::storage::BitVector bottomStates) { | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                        uint_fast64_t numberOfStates = matrix.getColumnCount(); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				
 | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                        // Transform the transition matrix into a vector containing the states with the state to which the transition goes. | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                        std::vector <State*> stateVector = std::vector<State *>({}); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                        for (uint_fast64_t i = 0; i < numberOfStates; ++i) { | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                            State* state = new State(); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                            state->stateNumber = i; | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				
 | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                            auto row = matrix.getRow(i); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                            //TODO assert that there are at most two successors | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                            if ((*(row.begin())).getValue() != ValueType(1)) { | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                                state->successor1 = (*(row.begin())).getColumn(); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                                state->successor2 = (*(++row.begin())).getColumn(); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                            } else { | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                                state-> successor1 = (*(row.begin())).getColumn(); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                                state-> successor2 = (*(row.begin())).getColumn(); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                            } | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				
 | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                            stateVector.push_back(state); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                        } | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                        // Start creating the Lattice | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                        storm::analysis::Lattice *lattice = new storm::analysis::Lattice(topStates, bottomStates, numberOfStates); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                        storm::storage::BitVector oldStates(numberOfStates); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                        // Create a copy of the states already present in the lattice. | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                        storm::storage::BitVector seenStates = topStates|= bottomStates; | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				
 | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                        while (oldStates != seenStates) { | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                            // As long as new states are added to the lattice, continue. | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                            oldStates = storm::storage::BitVector(seenStates); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				
 | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                            for (auto itr = stateVector.begin(); itr != stateVector.end(); ++itr) { | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                                // Iterate over all states | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                                State *currentState = *itr; | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				
 | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                                if (!seenStates[currentState->stateNumber] | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                                    && seenStates[currentState->successor1] | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                                    && seenStates[currentState->successor2]) { | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				
 | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				
 | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                                    // Otherwise, check how the two states compare, and add if the comparison is possible. | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                                    uint_fast64_t successor1 = currentState->successor1; | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                                    uint_fast64_t successor2 = currentState->successor2; | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                                    int compareResult = lattice->compare(successor1, successor2); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                                    if (compareResult == 1) { | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                                        // successor 1 is closer to top than successor 2 | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                                        lattice->addBetween(currentState->stateNumber, lattice->getNode(successor1), | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                                                            lattice->getNode(successor2)); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                                        // Add stateNumber to the set with seen states. | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                                        seenStates.set(currentState->stateNumber); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                                    } else if (compareResult == 2) { | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                                        // successor 2 is closer to top than successor 1 | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                                        lattice->addBetween(currentState->stateNumber, lattice->getNode(successor2), | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                                                            lattice->getNode(successor1)); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                                        // Add stateNumber to the set with seen states. | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                                        seenStates.set(currentState->stateNumber); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                                    } else if (compareResult == 0) { | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                                        // the successors are at the same level | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                                        lattice->addToNode(currentState->stateNumber, lattice->getNode(successor1)); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                                        // Add stateNumber to the set with seen states. | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                                        seenStates.set(currentState->stateNumber); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                                    } else { | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                                        // TODO: is this what we want? | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                                        lattice->add(currentState->stateNumber); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                                    } | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				
 | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                                } | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                            } | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                        } | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				
 | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                        return lattice; | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                    } | 
			
		
		
	
		
			
				 | 
				 | 
				
 | 
				 | 
				 | 
				
 | 
			
		
		
	
		
			
				 | 
				 | 
				                private: | 
				 | 
				 | 
				                private: | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                    struct State { | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                        uint_fast64_t stateNumber; | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                        uint_fast64_t successor1; | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                        uint_fast64_t successor2; | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                    }; | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				
 | 
			
		
		
	
		
			
				 | 
				 | 
				                    std::vector<Node *> nodes; | 
				 | 
				 | 
				                    std::vector<Node *> nodes; | 
			
		
		
	
		
			
				 | 
				 | 
				
 | 
				 | 
				 | 
				
 | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                    Node * top; | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				
 | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                    Node * bottom; | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				
 | 
			
		
		
	
		
			
				 | 
				 | 
				                    uint_fast64_t numberOfStates; | 
				 | 
				 | 
				                    uint_fast64_t numberOfStates; | 
			
		
		
	
		
			
				 | 
				 | 
				
 | 
				 | 
				 | 
				
 | 
			
		
		
	
		
			
				 | 
				 | 
				                    bool above(Node *, Node *); | 
				 | 
				 | 
				                    bool above(Node *, Node *); | 
			
		
		
	
	
		
			
				| 
					
						
							
						
					
					
					
				 | 
				
  |