Browse Source
started working on more flexible model generation using next-state-generators
started working on more flexible model generation using next-state-generators
Former-commit-id: 805940f179
main
12 changed files with 504 additions and 124 deletions
-
4src/CMakeLists.txt
-
39src/builder/ExplicitPrismModelBuilder.cpp
-
54src/builder/ExplicitPrismModelBuilder.h
-
111src/generator/Choice.cpp
-
158src/generator/Choice.h
-
27src/generator/NextStateGenerator.h
-
22src/generator/PrismNextStateGenerator.cpp
-
32src/generator/PrismNextStateGenerator.h
-
44src/generator/prism/VariableInformation.cpp
-
73src/generator/prism/VariableInformation.h
-
52src/storage/Distribution.cpp
-
12src/storage/Distribution.h
@ -0,0 +1,111 @@ |
|||
#include "src/generator/Choice.h"
|
|||
|
|||
#include "src/utility/constants.h"
|
|||
|
|||
namespace storm { |
|||
namespace generator { |
|||
|
|||
template<typename ValueType, typename StateType> |
|||
Choice<ValueType, StateType>::Choice(uint_fast64_t actionIndex, bool markovian) : markovian(markovian), actionIndex(actionIndex), distribution(), totalMass(storm::utility::zero<ValueType>()), choiceReward(storm::utility::zero<ValueType>()) { |
|||
// Intentionally left empty.
|
|||
} |
|||
|
|||
template<typename ValueType, typename StateType> |
|||
typename storm::storage::Distribution<ValueType, StateType>::iterator Choice<ValueType, StateType>::begin() { |
|||
return distribution.begin(); |
|||
} |
|||
|
|||
template<typename ValueType, typename StateType> |
|||
typename storm::storage::Distribution<ValueType, StateType>::const_iterator Choice<ValueType, StateType>::begin() const { |
|||
return distribution.cbegin(); |
|||
} |
|||
|
|||
template<typename ValueType, typename StateType> |
|||
typename storm::storage::Distribution<ValueType, StateType>::iterator Choice<ValueType, StateType>::end() { |
|||
return distribution.end(); |
|||
} |
|||
|
|||
template<typename ValueType, typename StateType> |
|||
typename storm::storage::Distribution<ValueType, StateType>::const_iterator Choice<ValueType, StateType>::end() const { |
|||
return distribution.cend(); |
|||
} |
|||
|
|||
template<typename ValueType, typename StateType> |
|||
void Choice<ValueType, StateType>::addChoiceLabel(uint_fast64_t label) { |
|||
if (!choiceLabels) { |
|||
choiceLabels = LabelSet(); |
|||
} |
|||
choiceLabels->insert(label); |
|||
} |
|||
|
|||
template<typename ValueType, typename StateType> |
|||
void Choice<ValueType, StateType>::addChoiceLabels(LabelSet const& labelSet) { |
|||
if (!choiceLabels) { |
|||
choiceLabels = LabelSet(); |
|||
} |
|||
choiceLabels->insert(labelSet.begin(), labelSet.end()); |
|||
} |
|||
|
|||
template<typename ValueType, typename StateType> |
|||
boost::container::flat_set<uint_fast64_t> const& Choice<ValueType, StateType>::getChoiceLabels() const { |
|||
return *choiceLabels; |
|||
} |
|||
|
|||
template<typename ValueType, typename StateType> |
|||
uint_fast64_t Choice<ValueType, StateType>::getActionIndex() const { |
|||
return actionIndex; |
|||
} |
|||
|
|||
template<typename ValueType, typename StateType> |
|||
ValueType Choice<ValueType, StateType>::getTotalMass() const { |
|||
return totalMass; |
|||
} |
|||
|
|||
template<typename ValueType, typename StateType> |
|||
ValueType& Choice<ValueType, StateType>::getOrAddEntry(StateType const& state) { |
|||
auto stateProbabilityPair = distribution.find(state); |
|||
|
|||
if (stateProbabilityPair == distribution.end()) { |
|||
distribution[state] = ValueType(); |
|||
} |
|||
return distribution.at(state); |
|||
} |
|||
|
|||
template<typename ValueType, typename StateType> |
|||
ValueType const& Choice<ValueType, StateType>::getOrAddEntry(StateType const& state) const { |
|||
auto stateProbabilityPair = distribution.find(state); |
|||
|
|||
if (stateProbabilityPair == distribution.end()) { |
|||
distribution[state] = ValueType(); |
|||
} |
|||
return distribution.at(state); |
|||
} |
|||
|
|||
template<typename ValueType, typename StateType> |
|||
void Choice<ValueType, StateType>::addProbability(StateType const& state, ValueType const& value) { |
|||
totalMass += value; |
|||
distribution[state] += value; |
|||
} |
|||
|
|||
template<typename ValueType, typename StateType> |
|||
void Choice<ValueType, StateType>::addChoiceReward(ValueType const& value) { |
|||
choiceReward += value; |
|||
} |
|||
|
|||
template<typename ValueType, typename StateType> |
|||
std::size_t Choice<ValueType, StateType>::size() const { |
|||
return distribution.size(); |
|||
} |
|||
|
|||
template<typename ValueType, typename StateType> |
|||
std::ostream& operator<<(std::ostream& out, Choice<ValueType, StateType> const& choice) { |
|||
out << "<"; |
|||
for (auto const& stateProbabilityPair : choice) { |
|||
out << stateProbabilityPair.first << " : " << stateProbabilityPair.second << ", "; |
|||
} |
|||
out << ">"; |
|||
return out; |
|||
} |
|||
|
|||
} |
|||
} |
@ -0,0 +1,158 @@ |
|||
#ifndef STORM_GENERATOR_CHOICE_H_ |
|||
#define STORM_GENERATOR_CHOICE_H_ |
|||
|
|||
#include <cstdint> |
|||
#include <functional> |
|||
|
|||
#include <boost/optional.hpp> |
|||
#include <boost/container/flat_set.hpp> |
|||
|
|||
#include "src/storage/Distribution.h" |
|||
|
|||
namespace storm { |
|||
namespace generator { |
|||
|
|||
// A structure holding information about a particular choice. |
|||
template<typename ValueType, typename StateType=uint32_t> |
|||
struct Choice { |
|||
public: |
|||
typedef boost::container::flat_set<uint_fast64_t> LabelSet; |
|||
|
|||
Choice(uint_fast64_t actionIndex = 0, bool markovian = false); |
|||
|
|||
Choice(Choice const& other) = default; |
|||
Choice& operator=(Choice const& other) = default; |
|||
Choice(Choice&& other) = default; |
|||
Choice& operator=(Choice&& other) = default; |
|||
|
|||
/*! |
|||
* Returns an iterator to the distribution associated with this choice. |
|||
* |
|||
* @return An iterator to the first element of the distribution. |
|||
*/ |
|||
typename storm::storage::Distribution<ValueType, StateType>::iterator begin(); |
|||
|
|||
/*! |
|||
* Returns an iterator to the distribution associated with this choice. |
|||
* |
|||
* @return An iterator to the first element of the distribution. |
|||
*/ |
|||
typename storm::storage::Distribution<ValueType, StateType>::const_iterator begin() const; |
|||
|
|||
/*! |
|||
* Returns an iterator past the end of the distribution associated with this choice. |
|||
* |
|||
* @return An iterator past the end of the distribution. |
|||
*/ |
|||
typename storm::storage::Distribution<ValueType, StateType>::iterator end(); |
|||
|
|||
/*! |
|||
* Returns an iterator past the end of the distribution associated with this choice. |
|||
* |
|||
* @return An iterator past the end of the distribution. |
|||
*/ |
|||
typename storm::storage::Distribution<ValueType, StateType>::const_iterator end() const; |
|||
|
|||
/*! |
|||
* Inserts the contents of this object to the given output stream. |
|||
* |
|||
* @param out The stream in which to insert the contents. |
|||
*/ |
|||
template<typename ValueTypePrime, typename StateTypePrime> |
|||
friend std::ostream& operator<<(std::ostream& out, Choice<ValueTypePrime, StateTypePrime> const& choice); |
|||
|
|||
/*! |
|||
* Adds the given label to the labels associated with this choice. |
|||
* |
|||
* @param label The label to associate with this choice. |
|||
*/ |
|||
void addChoiceLabel(uint_fast64_t label); |
|||
|
|||
/*! |
|||
* Adds the given label set to the labels associated with this choice. |
|||
* |
|||
* @param labelSet The label set to associate with this choice. |
|||
*/ |
|||
void addChoiceLabels(LabelSet const& labelSet); |
|||
|
|||
/*! |
|||
* Retrieves the set of labels associated with this choice. |
|||
* |
|||
* @return The set of labels associated with this choice. |
|||
*/ |
|||
LabelSet const& getChoiceLabels() const; |
|||
|
|||
/*! |
|||
* Retrieves the index of the action of this choice. |
|||
* |
|||
* @return The index of the action of this choice. |
|||
*/ |
|||
uint_fast64_t getActionIndex() const; |
|||
|
|||
/*! |
|||
* Retrieves the total mass of this choice. |
|||
* |
|||
* @return The total mass. |
|||
*/ |
|||
ValueType getTotalMass() const; |
|||
|
|||
/*! |
|||
* Retrieves the entry in the choice that is associated with the given state and creates one if none exists, |
|||
* yet. |
|||
* |
|||
* @param state The state for which to add the entry. |
|||
* @return A reference to the entry that is associated with the given state. |
|||
*/ |
|||
ValueType& getOrAddEntry(StateType const& state); |
|||
|
|||
/*! |
|||
* Retrieves the entry in the choice that is associated with the given state and creates one if none exists, |
|||
* yet. |
|||
* |
|||
* @param state The state for which to add the entry. |
|||
* @return A reference to the entry that is associated with the given state. |
|||
*/ |
|||
ValueType const& getOrAddEntry(StateType const& state) const; |
|||
|
|||
/*! |
|||
* Adds the given probability value to the given state in the underlying distribution. |
|||
*/ |
|||
void addProbability(StateType const& state, ValueType const& value); |
|||
|
|||
/*! |
|||
* Adds the given value to the reward associated with this choice. |
|||
*/ |
|||
void addChoiceReward(ValueType const& value); |
|||
|
|||
/*! |
|||
* Retrieves the size of the distribution associated with this choice. |
|||
*/ |
|||
std::size_t size() const; |
|||
|
|||
private: |
|||
// A flag indicating whether this choice is Markovian or not. |
|||
bool markovian; |
|||
|
|||
// The action index associated with this choice. |
|||
uint_fast64_t actionIndex; |
|||
|
|||
// The distribution that is associated with the choice. |
|||
storm::storage::Distribution<ValueType, StateType> distribution; |
|||
|
|||
// The total probability mass (or rates) of this choice. |
|||
ValueType totalMass; |
|||
|
|||
// The reward value associated with this choice. |
|||
ValueType choiceReward; |
|||
|
|||
// The labels that are associated with this choice. |
|||
boost::optional<LabelSet> choiceLabels; |
|||
}; |
|||
|
|||
template<typename ValueType, typename StateType> |
|||
std::ostream& operator<<(std::ostream& out, Choice<ValueType, StateType> const& choice); |
|||
|
|||
} |
|||
} |
|||
|
|||
#endif /* STORM_GENERATOR_CHOICE_H_ */ |
@ -0,0 +1,27 @@ |
|||
#ifndef STORM_GENERATOR_NEXTSTATEGENERATOR_H_ |
|||
#define STORM_GENERATOR_NEXTSTATEGENERATOR_H_ |
|||
|
|||
#include <vector> |
|||
#include <cstdint> |
|||
|
|||
#include "src/storage/sparse/StateType.h" |
|||
#include "src/storage/BitVector.h" |
|||
|
|||
#include "src/generator/Choice.h" |
|||
|
|||
namespace storm { |
|||
namespace generator { |
|||
template<typename ValueType, typename StateType = uint32_t> |
|||
class NextStateGenerator { |
|||
public: |
|||
typedef storm::storage::BitVector InternalStateType; |
|||
typedef StateType (*StateToIdCallback)(InternalStateType const&); |
|||
|
|||
virtual std::vector<StateType> getInitialStates(StateToIdCallback stateToIdCallback) = 0; |
|||
virtual std::vector<Choice<ValueType>> expand(StateType const& state, StateToIdCallback stateToIdCallback) = 0; |
|||
virtual ValueType getStateReward(StateType const& state) = 0; |
|||
}; |
|||
} |
|||
} |
|||
|
|||
#endif |
@ -0,0 +1,22 @@ |
|||
#include "src/generator/PrismNextStateGenerator.h"
|
|||
|
|||
namespace storm { |
|||
namespace generator { |
|||
|
|||
template<typename ValueType, typename StateType> |
|||
PrismNextStateGenerator<ValueType, StateType>::PrismNextStateGenerator(storm::prism::Program const& program) : program(program) { |
|||
// Intentionally left empty.
|
|||
} |
|||
|
|||
template<typename ValueType, typename StateType> |
|||
std::vector<Choice<ValueType>> PrismNextStateGenerator<ValueType, StateType>::expand(StateType const& state, typename NextStateGenerator<ValueType, StateType>::StateToIdCallback stateToIdCallback) { |
|||
// TODO
|
|||
} |
|||
|
|||
template<typename ValueType, typename StateType> |
|||
ValueType PrismNextStateGenerator<ValueType, StateType>::getStateReward(StateType const& state) { |
|||
// TODO
|
|||
} |
|||
|
|||
} |
|||
} |
@ -0,0 +1,32 @@ |
|||
#ifndef STORM_GENERATOR_PRISMNEXTSTATEGENERATOR_H_ |
|||
#define STORM_GENERATOR_PRISMNEXTSTATEGENERATOR_H_ |
|||
|
|||
#include "src/generator/NextStateGenerator.h" |
|||
|
|||
#include "src/storage/prism/Program.h" |
|||
|
|||
namespace storm { |
|||
namespace generator { |
|||
|
|||
template<typename ValueType, typename StateType = uint32_t> |
|||
class PrismNextStateGenerator : public NextStateGenerator<ValueType, StateType> { |
|||
public: |
|||
typedef typename NextStateGenerator<ValueType, StateType>::StateToIdCallback StateToIdCallback; |
|||
|
|||
PrismNextStateGenerator(storm::prism::Program const& program); |
|||
|
|||
virtual std::vector<StateType> getInitialStates(StateToIdCallback stateToIdCallback) = 0; |
|||
virtual std::vector<Choice<ValueType>> expand(StateType const& state, StateToIdCallback stateToIdCallback) override; |
|||
virtual ValueType getStateReward(StateType const& state) override; |
|||
|
|||
private: |
|||
// The program used for the generation of next states. |
|||
storm::prism::Program program; |
|||
|
|||
|
|||
}; |
|||
|
|||
} |
|||
} |
|||
|
|||
#endif /* STORM_GENERATOR_PRISMNEXTSTATEGENERATOR_H_ */ |
@ -0,0 +1,44 @@ |
|||
#include "src/generator/prism/VariableInformation.h"
|
|||
|
|||
#include "src/utility/macros.h"
|
|||
#include "src/exceptions/InvalidArgumentException.h"
|
|||
|
|||
namespace storm { |
|||
namespace generator { |
|||
namespace prism { |
|||
|
|||
BooleanVariableInformation::BooleanVariableInformation(storm::expressions::Variable const& variable, bool initialValue, uint_fast64_t bitOffset) : variable(variable), initialValue(initialValue), bitOffset(bitOffset) { |
|||
// Intentionally left empty.
|
|||
} |
|||
|
|||
IntegerVariableInformation::IntegerVariableInformation(storm::expressions::Variable const& variable, int_fast64_t initialValue, int_fast64_t lowerBound, int_fast64_t upperBound, uint_fast64_t bitOffset, uint_fast64_t bitWidth) : variable(variable), initialValue(initialValue), lowerBound(lowerBound), upperBound(upperBound), bitOffset(bitOffset), bitWidth(bitWidth) { |
|||
// Intentionally left empty.
|
|||
} |
|||
|
|||
VariableInformation::VariableInformation(storm::expressions::ExpressionManager const& manager) : manager(manager) { |
|||
// Intentionally left empty.
|
|||
} |
|||
|
|||
uint_fast64_t VariableInformation::getBitOffset(storm::expressions::Variable const& variable) const { |
|||
auto const& booleanIndex = booleanVariableToIndexMap.find(variable); |
|||
if (booleanIndex != booleanVariableToIndexMap.end()) { |
|||
return booleanVariables[booleanIndex->second].bitOffset; |
|||
} |
|||
auto const& integerIndex = integerVariableToIndexMap.find(variable); |
|||
if (integerIndex != integerVariableToIndexMap.end()) { |
|||
return integerVariables[integerIndex->second].bitOffset; |
|||
} |
|||
STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Cannot look-up bit index of unknown variable."); |
|||
} |
|||
|
|||
uint_fast64_t VariableInformation::getBitWidth(storm::expressions::Variable const& variable) const { |
|||
auto const& integerIndex = integerVariableToIndexMap.find(variable); |
|||
if (integerIndex != integerVariableToIndexMap.end()) { |
|||
return integerVariables[integerIndex->second].bitWidth; |
|||
} |
|||
STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Cannot look-up bit width of unknown variable."); |
|||
} |
|||
|
|||
} |
|||
} |
|||
} |
@ -0,0 +1,73 @@ |
|||
#ifndef STORM_GENERATOR_PRISM_VARIABLEINFORMATION_H_ |
|||
#define STORM_GENERATOR_PRISM_VARIABLEINFORMATION_H_ |
|||
|
|||
#include <vector> |
|||
#include <boost/container/flat_map.hpp> |
|||
|
|||
#include "src/storage/expressions/Variable.h" |
|||
|
|||
namespace storm { |
|||
namespace generator { |
|||
namespace prism { |
|||
|
|||
// A structure storing information about the boolean variables of the program. |
|||
struct BooleanVariableInformation { |
|||
BooleanVariableInformation(storm::expressions::Variable const& variable, bool initialValue, uint_fast64_t bitOffset); |
|||
|
|||
// The boolean variable. |
|||
storm::expressions::Variable variable; |
|||
|
|||
// Its initial value. |
|||
bool initialValue; |
|||
|
|||
// Its bit offset in the compressed state. |
|||
uint_fast64_t bitOffset; |
|||
}; |
|||
|
|||
// A structure storing information about the integer variables of the program. |
|||
struct IntegerVariableInformation { |
|||
IntegerVariableInformation(storm::expressions::Variable const& variable, int_fast64_t initialValue, int_fast64_t lowerBound, int_fast64_t upperBound, uint_fast64_t bitOffset, uint_fast64_t bitWidth); |
|||
|
|||
// The integer variable. |
|||
storm::expressions::Variable variable; |
|||
|
|||
// Its initial value. |
|||
int_fast64_t initialValue; |
|||
|
|||
// The lower bound of its range. |
|||
int_fast64_t lowerBound; |
|||
|
|||
// The upper bound of its range. |
|||
int_fast64_t upperBound; |
|||
|
|||
// Its bit offset in the compressed state. |
|||
uint_fast64_t bitOffset; |
|||
|
|||
// Its bit width in the compressed state. |
|||
uint_fast64_t bitWidth; |
|||
}; |
|||
|
|||
// A structure storing information about the used variables of the program. |
|||
struct VariableInformation { |
|||
VariableInformation(storm::expressions::ExpressionManager const& manager); |
|||
|
|||
// Provide methods to access the bit offset and width of variables in the compressed state. |
|||
uint_fast64_t getBitOffset(storm::expressions::Variable const& variable) const; |
|||
uint_fast64_t getBitWidth(storm::expressions::Variable const& variable) const; |
|||
|
|||
// The known boolean variables. |
|||
boost::container::flat_map<storm::expressions::Variable, uint_fast64_t> booleanVariableToIndexMap; |
|||
std::vector<BooleanVariableInformation> booleanVariables; |
|||
|
|||
// The known integer variables. |
|||
boost::container::flat_map<storm::expressions::Variable, uint_fast64_t> integerVariableToIndexMap; |
|||
std::vector<IntegerVariableInformation> integerVariables; |
|||
|
|||
storm::expressions::ExpressionManager const& manager; |
|||
}; |
|||
|
|||
} |
|||
} |
|||
} |
|||
|
|||
#endif /* STORM_GENERATOR_PRISM_VARIABLEINFORMATION_H_ */ |
Write
Preview
Loading…
Cancel
Save
Reference in new issue