7 changed files with 343 additions and 55 deletions
			
			
		- 
					25src/storm-pomdp-cli/settings/modules/POMDPSettings.cpp
- 
					3src/storm-pomdp-cli/settings/modules/POMDPSettings.h
- 
					7src/storm-pomdp-cli/storm-pomdp.cpp
- 
					168src/storm-pomdp/storage/PomdpMemory.cpp
- 
					60src/storm-pomdp/storage/PomdpMemory.h
- 
					112src/storm-pomdp/transformer/PomdpMemoryUnfolder.cpp
- 
					17src/storm-pomdp/transformer/PomdpMemoryUnfolder.h
| @ -0,0 +1,168 @@ | |||||
|  | #include "storm-pomdp/storage/PomdpMemory.h"
 | ||||
|  | 
 | ||||
|  | #include "storm/utility/macros.h"
 | ||||
|  | #include "storm/exceptions/InvalidArgumentException.h"
 | ||||
|  | 
 | ||||
|  | namespace storm { | ||||
|  |     namespace storage { | ||||
|  |          | ||||
|  |         PomdpMemory::PomdpMemory(std::vector<storm::storage::BitVector> const& transitions, uint64_t initialState) : transitions(transitions), initialState(initialState) { | ||||
|  |             STORM_LOG_THROW(this->initialState < this->transitions.size(), storm::exceptions::InvalidArgumentException, "Initial state " << this->initialState << " of pomdp memory is invalid."); | ||||
|  |             for (auto const& t : this->transitions) { | ||||
|  |                 STORM_LOG_THROW(t.size() == this->transitions.size(), storm::exceptions::InvalidArgumentException, "Invalid dimension of transition matrix of pomdp memory."); | ||||
|  |                 STORM_LOG_THROW(!t.empty(), storm::exceptions::InvalidArgumentException, "Invalid transition matrix of pomdp memory: No deadlock states allowed."); | ||||
|  |             } | ||||
|  |         } | ||||
|  |      | ||||
|  |         uint64_t PomdpMemory::getNumberOfStates() const { | ||||
|  |             return transitions.size(); | ||||
|  |         } | ||||
|  |      | ||||
|  |         uint64_t PomdpMemory::getInitialState() const { | ||||
|  |             return initialState; | ||||
|  |         } | ||||
|  |      | ||||
|  |         storm::storage::BitVector const& PomdpMemory::getTransitions(uint64_t state) const { | ||||
|  |             return transitions.at(state); | ||||
|  |         } | ||||
|  |      | ||||
|  |         uint64_t PomdpMemory::getNumberOfOutgoingTransitions(uint64_t state) const { | ||||
|  |             return getTransitions(state).getNumberOfSetBits(); | ||||
|  |         } | ||||
|  |      | ||||
|  |         std::vector<storm::storage::BitVector> const& PomdpMemory::getTransitions() const { | ||||
|  |             return transitions; | ||||
|  |         } | ||||
|  |          | ||||
|  |         std::string PomdpMemory::toString() const { | ||||
|  |             std::string result = "PomdpMemory with " + std::to_string(getNumberOfStates()) + " states.\n"; | ||||
|  |             result += "Initial state is " + std::to_string(getInitialState()) + ". Transitions are \n"; | ||||
|  |              | ||||
|  |             // header
 | ||||
|  |             result += "  |"; | ||||
|  |             for (uint64_t state = 0; state < getNumberOfStates(); ++state) { | ||||
|  |                 if (state < 10) { | ||||
|  |                     result += " "; | ||||
|  |                 } | ||||
|  |                 result += std::to_string(state); | ||||
|  |             } | ||||
|  |             result += "\n"; | ||||
|  |             result += "--|"; | ||||
|  |             for (uint64_t state = 0; state < getNumberOfStates(); ++state) { | ||||
|  |                 result += "--"; | ||||
|  |             } | ||||
|  |             result += "\n"; | ||||
|  |              | ||||
|  |             // transition matrix entries
 | ||||
|  |             for (uint64_t state = 0; state < getNumberOfStates(); ++state) { | ||||
|  |                 if (state < 10) { | ||||
|  |                     result += " "; | ||||
|  |                 } | ||||
|  |                 result += std::to_string(state) + "|"; | ||||
|  |                 for (uint64_t statePrime = 0; statePrime < getNumberOfStates(); ++statePrime) { | ||||
|  |                     result += " "; | ||||
|  |                     if (getTransitions(state).get(statePrime)) { | ||||
|  |                         result += "1"; | ||||
|  |                     } else { | ||||
|  |                         result += "0"; | ||||
|  |                     } | ||||
|  |                 } | ||||
|  |                 result += "\n"; | ||||
|  |             } | ||||
|  |             return result; | ||||
|  |         } | ||||
|  |          | ||||
|  |         std::string toString(PomdpMemoryPattern const& pattern) { | ||||
|  |             switch (pattern) { | ||||
|  |                 case PomdpMemoryPattern::Trivial: | ||||
|  |                     return "trivial"; | ||||
|  |                 case PomdpMemoryPattern::FixedCounter: | ||||
|  |                     return "fixedcounter"; | ||||
|  |                 case PomdpMemoryPattern::SelectiveCounter: | ||||
|  |                     return "selectivecounter"; | ||||
|  |                 case PomdpMemoryPattern::Ring: | ||||
|  |                     return "ring"; | ||||
|  |                 case PomdpMemoryPattern::SettableBits: | ||||
|  |                     return "settablebits"; | ||||
|  |                 case PomdpMemoryPattern::Full: | ||||
|  |                     return "full"; | ||||
|  |             } | ||||
|  |             return "unknown"; | ||||
|  |         } | ||||
|  | 
 | ||||
|  |         PomdpMemory PomdpMemoryBuilder::build(PomdpMemoryPattern pattern, uint64_t numStates) const { | ||||
|  |             switch (pattern) { | ||||
|  |                 case PomdpMemoryPattern::Trivial: | ||||
|  |                     STORM_LOG_ERROR_COND(numStates == 1, "Invoked building trivial POMDP memory with " << numStates << " states. However, trivial POMDP memory always has one state."); | ||||
|  |                     return buildTrivialMemory(); | ||||
|  |                 case PomdpMemoryPattern::FixedCounter: | ||||
|  |                     return buildFixedCountingMemory(numStates); | ||||
|  |                 case PomdpMemoryPattern::SelectiveCounter: | ||||
|  |                     return buildSelectiveCountingMemory(numStates); | ||||
|  |                 case PomdpMemoryPattern::Ring: | ||||
|  |                     return buildRingMemory(numStates); | ||||
|  |                 case PomdpMemoryPattern::SettableBits: | ||||
|  |                     return buildSettableBitsMemory(numStates); | ||||
|  |                 case PomdpMemoryPattern::Full: | ||||
|  |                     return buildFullyConnectedMemory(numStates); | ||||
|  |             } | ||||
|  |         } | ||||
|  |          | ||||
|  |         PomdpMemory PomdpMemoryBuilder::buildTrivialMemory() const { | ||||
|  |             return buildFullyConnectedMemory(1); | ||||
|  |         } | ||||
|  |          | ||||
|  |         PomdpMemory PomdpMemoryBuilder::buildFixedCountingMemory(uint64_t numStates) const { | ||||
|  |             std::vector<storm::storage::BitVector> transitions(numStates, storm::storage::BitVector(numStates, false)); | ||||
|  |             for (uint64_t state = 0; state < numStates; ++state) { | ||||
|  |                 transitions[state].set(std::min(state + 1, numStates - 1)); | ||||
|  |             } | ||||
|  |             return PomdpMemory(transitions, 0); | ||||
|  |         } | ||||
|  |          | ||||
|  |         PomdpMemory PomdpMemoryBuilder::buildSelectiveCountingMemory(uint64_t numStates) const { | ||||
|  |             std::vector<storm::storage::BitVector> transitions(numStates, storm::storage::BitVector(numStates, false)); | ||||
|  |             for (uint64_t state = 0; state < numStates; ++state) { | ||||
|  |                 transitions[state].set(state); | ||||
|  |                 transitions[state].set(std::min(state + 1, numStates - 1)); | ||||
|  |             } | ||||
|  |             return PomdpMemory(transitions, 0); | ||||
|  |         } | ||||
|  |          | ||||
|  |         PomdpMemory PomdpMemoryBuilder::buildRingMemory(uint64_t numStates) const { | ||||
|  |             std::vector<storm::storage::BitVector> transitions(numStates, storm::storage::BitVector(numStates, false)); | ||||
|  |             for (uint64_t state = 0; state < numStates; ++state) { | ||||
|  |                 transitions[state].set(state); | ||||
|  |                 transitions[state].set((state + 1) % numStates); | ||||
|  |             } | ||||
|  |             return PomdpMemory(transitions, 0); | ||||
|  |         } | ||||
|  |          | ||||
|  |         PomdpMemory PomdpMemoryBuilder::buildSettableBitsMemory(uint64_t numStates) const { | ||||
|  |             // compute the number of bits, i.e., floor(log(numStates))
 | ||||
|  |             uint64_t numBits = 0; | ||||
|  |             uint64_t actualNumStates = 1; | ||||
|  |             while (actualNumStates * 2 <= numStates) { | ||||
|  |                 actualNumStates *= 2; | ||||
|  |                 ++numBits; | ||||
|  |             } | ||||
|  |              | ||||
|  |             STORM_LOG_WARN_COND(actualNumStates == numStates, "The number of memory states for the settable bits pattern has to be a power of 2. Shrinking the number of memory states to " << actualNumStates << "."); | ||||
|  |              | ||||
|  |             std::vector<storm::storage::BitVector> transitions(actualNumStates, storm::storage::BitVector(actualNumStates, false)); | ||||
|  |             for (uint64_t state = 0; state < actualNumStates; ++state) { | ||||
|  |                 transitions[state].set(state); | ||||
|  |                 for (uint64_t bit = 0; bit < numBits; ++bit) { | ||||
|  |                     uint64_t bitMask = 1u << bit; | ||||
|  |                     transitions[state].set(state | bitMask); | ||||
|  |                 } | ||||
|  |             } | ||||
|  |             return PomdpMemory(transitions, 0); | ||||
|  |         } | ||||
|  |          | ||||
|  |         PomdpMemory PomdpMemoryBuilder::buildFullyConnectedMemory(uint64_t numStates) const { | ||||
|  |             std::vector<storm::storage::BitVector> transitions(numStates, storm::storage::BitVector(numStates, true)); | ||||
|  |             return PomdpMemory(transitions, 0); | ||||
|  |         } | ||||
|  |     } | ||||
|  | } | ||||
| @ -0,0 +1,60 @@ | |||||
|  | #pragma once | ||||
|  | 
 | ||||
|  | #include <vector> | ||||
|  | #include "storm/storage/BitVector.h" | ||||
|  | #include "storm/exceptions/InvalidArgumentException.h" | ||||
|  | 
 | ||||
|  | namespace storm { | ||||
|  |     namespace storage { | ||||
|  |          | ||||
|  |         class PomdpMemory { | ||||
|  |          | ||||
|  |             public: | ||||
|  |                 PomdpMemory(std::vector<storm::storage::BitVector> const& transitions, uint64_t initialState); | ||||
|  |                 uint64_t getNumberOfStates() const; | ||||
|  |                 uint64_t getInitialState() const; | ||||
|  |                 storm::storage::BitVector const& getTransitions(uint64_t state) const; | ||||
|  |                 uint64_t getNumberOfOutgoingTransitions(uint64_t state) const; | ||||
|  |                 std::vector<storm::storage::BitVector> const& getTransitions() const; | ||||
|  |                 std::string toString() const; | ||||
|  |             private: | ||||
|  |                 std::vector<storm::storage::BitVector> transitions; | ||||
|  |                 uint64_t initialState; | ||||
|  |         }; | ||||
|  |          | ||||
|  |         enum class PomdpMemoryPattern { | ||||
|  |             Trivial, FixedCounter, SelectiveCounter, Ring, SettableBits, Full | ||||
|  |         }; | ||||
|  |          | ||||
|  |         std::string toString(PomdpMemoryPattern const& pattern); | ||||
|  |          | ||||
|  |         class PomdpMemoryBuilder { | ||||
|  |         public: | ||||
|  |             // Builds a memory structure with the given pattern and the given number of states. | ||||
|  |             PomdpMemory build(PomdpMemoryPattern pattern, uint64_t numStates) const; | ||||
|  |              | ||||
|  |             // Builds a memory structure that consists of just a single memory state | ||||
|  |             PomdpMemory buildTrivialMemory() const; | ||||
|  |              | ||||
|  |             // Builds a memory structure that consists of a chain of the given number of states. | ||||
|  |             // Every state has exactly one transition to the next state. The last state has just a selfloop. | ||||
|  |             PomdpMemory buildFixedCountingMemory(uint64_t numStates) const; | ||||
|  |              | ||||
|  |             // Builds a memory structure that consists of a chain of the given number of states. | ||||
|  |             // Every state has a selfloop and a transition to the next state. The last state just has a selfloop. | ||||
|  |             PomdpMemory buildSelectiveCountingMemory(uint64_t numStates) const; | ||||
|  |              | ||||
|  |             // Builds a memory structure that consists of a ring of the given number of states. | ||||
|  |             // Every state has a transition to the successor state and a selfloop | ||||
|  |             PomdpMemory buildRingMemory(uint64_t numStates) const; | ||||
|  |              | ||||
|  |             // Builds a memory structure that represents floor(log(numStates)) bits that can only be set from zero to one or from zero to zero. | ||||
|  |             PomdpMemory buildSettableBitsMemory(uint64_t numStates) const; | ||||
|  |              | ||||
|  |             // Builds a memory structure that consists of the given number of states which are fully connected. | ||||
|  |             PomdpMemory buildFullyConnectedMemory(uint64_t numStates) const; | ||||
|  |              | ||||
|  |         }; | ||||
|  |          | ||||
|  |     } | ||||
|  | } | ||||
						Write
						Preview
					
					
					Loading…
					
					Cancel
						Save
					
		Reference in new issue