Storm 1.14.0.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
FirstStateNextStateGenerator.h
Go to the documentation of this file.
1#pragma once
2
3#include <set>
4#include <string>
5#include <unordered_map>
6#include <utility>
7#include <vector>
8
10
13
15
16namespace storm::pomdp::beliefs {
17
18// Forward declare handle
19namespace detail {
20template<typename PomdpType, typename BeliefType, typename PreAbstractionType, typename PostAbstractionType, typename DiscoverCallback>
22}
23
68template<typename PomdpType, typename BeliefType>
70 public:
71 template<typename PreAbstractionType, typename PostAbstractionType, typename DiscoverCallbackType>
73
75 FirstStateNextStateGenerator(PomdpType const& pomdp);
76
78 void setRewardModel(std::string const& rewardModelName = "");
80 bool hasRewardModel() const;
81 void unsetRewardModel();
82
87 BeliefType computeInitialBelief() const;
88
90 uint64_t getBeliefNumberOfActions(BeliefType const& belief) const;
91
93 typename PomdpType::ValueType getBeliefActionReward(BeliefType const& belief, uint64_t const& localActionIndex) const;
94
96 std::set<std::string> getBeliefActionChoiceLabels(BeliefType const& belief, uint64_t const& localActionIndex) const;
97
99 template<typename DiscoverCallbackType>
100 auto getHandle(DiscoverCallbackType& discoverCallback) {
102 }
103
105 template<typename PreAbstractionType, typename DiscoverCallbackType>
106 auto getPreAbstractionHandle(PreAbstractionType& preAbstraction, DiscoverCallbackType& discoverCallback) {
107 return Handle<PreAbstractionType, NoAbstractionType const, DiscoverCallbackType>{this->pomdp, preAbstraction, NoAbstraction, discoverCallback};
108 }
109
111 template<typename PostAbstractionType, typename DiscoverCallbackType>
112 auto getPostAbstractionHandle(PostAbstractionType& postAbstraction, DiscoverCallbackType& discoverCallback) {
113 return Handle<NoAbstractionType const, PostAbstractionType, DiscoverCallbackType>{this->pomdp, NoAbstraction, postAbstraction, discoverCallback};
114 }
115
117 template<typename PreAbstractionType, typename PostAbstractionType, typename DiscoverCallbackType>
118 auto getPrePostAbstractionHandle(PreAbstractionType& preAbstraction, PostAbstractionType& postAbstraction, DiscoverCallbackType& discoverCallback) {
119 return Handle<PreAbstractionType, PostAbstractionType, DiscoverCallbackType>{this->pomdp, preAbstraction, postAbstraction, discoverCallback};
120 }
121
122 private:
123 PomdpType const& pomdp;
124 std::vector<typename PomdpType::ValueType> actionRewards;
125};
126
127namespace detail {
128
133template<typename PomdpType, typename BeliefType, typename PreAbstractionType, typename PostAbstractionType, typename DiscoverCallback>
135 using BeliefValueType = typename BeliefType::ValueType;
136
137 template<typename... CallBackArgs>
139 void operator()(BeliefType const& belief, uint64_t localActionIndex, CallBackArgs const&... additionalCallbackArgs) {
140 applyPreAbstraction(belief, localActionIndex, std::forward<CallBackArgs const>(additionalCallbackArgs)...);
141 }
142
143 PomdpType const& pomdp;
144 PreAbstractionType& preAbstraction;
145 PostAbstractionType& postAbstraction;
146 DiscoverCallback& discoverCallback;
147
148 private:
149 template<typename... CallBackArgs>
150 void applyPreAbstraction(BeliefType const& belief, uint64_t localActionIndex, CallBackArgs const&... additionalCallbackArgs) {
152 computeSuccessorBeliefs(belief, localActionIndex, storm::utility::one<BeliefValueType>(), DefaultActionObservation, additionalCallbackArgs...);
153 } else {
154 preAbstraction.abstract(
155 belief, localActionIndex,
156 [this, &localActionIndex, &additionalCallbackArgs...](
157 BeliefType&& preBel, BeliefValueType&& preVal, BeliefActionObservationType actionObservation, auto const&... additionalPreAbstractionArgs) {
158 this->computeSuccessorBeliefs(preBel, localActionIndex, std::move(preVal), actionObservation,
159 std::forward<CallBackArgs const>(additionalCallbackArgs)...,
160 std::forward<decltype(additionalPreAbstractionArgs)>(additionalPreAbstractionArgs)...);
161 });
162 }
163 }
164
168 std::unordered_map<BeliefObservationType, BeliefValueType> computeSuccessorObservations(BeliefType const& belief, uint64_t localActionIndex,
169 BeliefActionObservationType actionObservation) {
170 std::unordered_map<BeliefObservationType, BeliefValueType> successorObservations;
171 belief.forEach([&localActionIndex, &successorObservations, &actionObservation, this](BeliefStateType const& state, BeliefValueType const& beliefValue) {
172 for (auto const& pomdpTransition : pomdp.getTransitionMatrix().getRow(state, localActionIndex)) {
173 if (!storm::utility::isZero(pomdpTransition.getValue())) {
174 auto const obs = (pomdp.getNrObservations() * actionObservation) + pomdp.getObservation(pomdpTransition.getColumn());
175 STORM_LOG_ASSERT(obs < InvalidObservation, "Encoded belief observation " << obs << " exceeds the valid observation range.");
176 BeliefValueType const val = beliefValue * storm::utility::convertNumber<BeliefValueType>(pomdpTransition.getValue());
177 if (auto [insertionIt, inserted] = successorObservations.emplace(static_cast<BeliefObservationType>(obs), val); !inserted) {
178 insertionIt->second += val;
179 }
180 }
181 }
182 });
183
184 // Adjust the distribution to diminish numerical inaccuracies a bit
186 if (successorObservations.size() == 1) {
187 successorObservations.begin()->second = storm::utility::one<BeliefValueType>();
188 }
189 }
190 return successorObservations;
191 }
192
193 template<typename... CallBackArgs>
194 void computeSuccessorBeliefs(BeliefType const& belief, uint64_t localActionIndex, BeliefValueType const& transitionProbability,
195 BeliefActionObservationType actionObservation, CallBackArgs const&... additionalCallbackArgs) {
196 // For each successor observation we build the successor belief
197 auto const successorObservations = computeSuccessorObservations(belief, localActionIndex, actionObservation);
198 for (auto const& successorObsValue : successorObservations) {
199 BeliefBuilder<BeliefType> builder;
200 builder.setObservation(successorObsValue.first);
201 belief.forEach([&builder, &localActionIndex, &successorObsValue, this](BeliefStateType const& state, BeliefValueType const& beliefValue) {
202 for (auto const& pomdpTransition : pomdp.getTransitionMatrix().getRow(state, localActionIndex)) {
203 if (!storm::utility::isZero(pomdpTransition.getValue()) &&
204 pomdp.getObservation(pomdpTransition.getColumn()) == (successorObsValue.first % pomdp.getNrObservations())) {
205 BeliefValueType const prob =
206 beliefValue * storm::utility::convertNumber<BeliefValueType>(pomdpTransition.getValue()) / successorObsValue.second;
207 STORM_LOG_ASSERT(prob > storm::utility::zero<BeliefValueType>(), "Invalid belief probability " << prob << ".");
208 builder.addValue(pomdpTransition.getColumn(), prob);
209 }
210 }
211 });
213 if (successorObservations.size() == 1) {
214 // The observation probability was forced to one, so normalize the successor belief separately.
215 builder.normalize();
216 }
217 }
218 applyPostAbstraction(builder.build(), static_cast<BeliefValueType>(successorObsValue.second * transitionProbability),
219 std::forward<CallBackArgs const>(additionalCallbackArgs)...);
220 }
221 }
222
223 template<typename... CallBackArgs>
224 void applyPostAbstraction(BeliefType&& belief, BeliefValueType&& transitionProbability, CallBackArgs const&... additionalCallbackArgs) {
226 discoverCallback(std::move(belief), std::move(transitionProbability), additionalCallbackArgs...);
227 } else {
228 postAbstraction.abstract(
229 std::move(belief), std::move(transitionProbability),
230 [this, &additionalCallbackArgs...](BeliefType&& postBel, BeliefValueType&& postVal, auto&&... additionalPostAbstractionArgs) {
231 discoverCallback(std::move(postBel), std::move(postVal), std::forward<CallBackArgs const>(additionalCallbackArgs)...,
232 std::forward<decltype(additionalPostAbstractionArgs)>(additionalPostAbstractionArgs)...);
233 });
234 }
235 }
236};
237
238} // namespace detail
239} // namespace storm::pomdp::beliefs
auto getHandle(DiscoverCallbackType &discoverCallback)
Returns a handle that generates unabstracted successor beliefs.
FirstStateNextStateGenerator(PomdpType const &pomdp)
Creates a successor generator for pomdp.
PomdpType::ValueType getBeliefActionReward(BeliefType const &belief, uint64_t const &localActionIndex) const
void setRewardModel(std::string const &rewardModelName="")
Selects the reward model whose expected action rewards are queried; an empty name selects the default...
std::set< std::string > getBeliefActionChoiceLabels(BeliefType const &belief, uint64_t const &localActionIndex) const
auto getPreAbstractionHandle(PreAbstractionType &preAbstraction, DiscoverCallbackType &discoverCallback)
Returns a handle that applies preAbstraction before successor generation.
auto getPrePostAbstractionHandle(PreAbstractionType &preAbstraction, PostAbstractionType &postAbstraction, DiscoverCallbackType &discoverCallback)
Returns a handle that applies both abstractions around successor generation.
auto getPostAbstractionHandle(PostAbstractionType &postAbstraction, DiscoverCallbackType &discoverCallback)
Returns a handle that applies postAbstraction to each successor belief.
uint64_t getBeliefNumberOfActions(BeliefType const &belief) const
detail::NextStateGeneratorHandle< PomdpType, BeliefType, PreAbstractionType, PostAbstractionType, DiscoverCallbackType > Handle
#define STORM_LOG_ASSERT(cond, message)
Definition macros.h:9
constexpr BeliefObservationType InvalidObservation
Required e.g. for comparing two beliefs.
Definition types.h:20
constexpr NoAbstractionType NoAbstraction
constexpr BeliefActionObservationType DefaultActionObservation
Definition types.h:14
uint64_t BeliefStateType
Shared identifiers and sparse-container types used by the belief subsystem.
Definition types.h:10
uint32_t BeliefObservationType
Definition types.h:11
constexpr bool isNoAbstraction
uint32_t BeliefActionObservationType
Definition types.h:13
bool isZero(ValueType const &a)
Definition constants.cpp:44
ValueType zero()
Definition constants.cpp:26
ValueType one()
Definition constants.cpp:21
TargetType convertNumber(SourceType const &number)
static const bool IsExact
void operator()(BeliefType const &belief, uint64_t localActionIndex, CallBackArgs const &... additionalCallbackArgs)
Generates all observation-distinguished successors for one belief/action pair.