Storm 1.14.0.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
BeliefExploration.h
Go to the documentation of this file.
1#pragma once
2
3#include <functional>
4#include <optional>
5#include <vector>
6
11
12namespace storm::pomdp::beliefs {
13
14template<typename BeliefType>
16
17template<typename BeliefMdpValueType, typename PomdpType, typename BeliefType>
19
20template<typename BeliefMdpValueType, typename PomdpType, typename BeliefType>
24
28 void operator()(BeliefType&& bel, typename BeliefType::ValueType&& val) {
29 auto const belId = info.discoveredBeliefs.getIdOrAddBelief(std::move(bel));
30 if (info.exploredBeliefs.count(belId) == 0u && info.terminalBeliefValues.count(belId) == 0u) {
31 info.queue.push(belId);
32 }
33 info.matrix.transitions.push_back({storm::utility::convertNumber<BeliefMdpValueType>(val), belId});
34 }
35};
36
37template<typename BeliefMdpValueType, typename PomdpType, typename BeliefType>
41
45 void operator()(BeliefType&& bel, typename BeliefType::ValueType&& val, std::optional<typename BeliefType::ValueType> optionalWeightedClippingValue,
46 std::optional<typename BeliefType::ValueType> optionalRewardAdjustment) {
47 auto const belId = info.discoveredBeliefs.getIdOrAddBelief(std::move(bel));
48 if (info.exploredBeliefs.count(belId) == 0u && info.terminalBeliefValues.count(belId) == 0u) {
49 info.queue.push(belId);
50 }
51 if (optionalWeightedClippingValue) {
52 if (optionalRewardAdjustment) {
53 STORM_LOG_TRACE("Add transition to belief " << belId << " with val " << val << ", weighted clipping value " << *optionalWeightedClippingValue
54 << " and reward adjustment " << *optionalRewardAdjustment << ".");
55 info.matrix.transitions.push_back({storm::utility::convertNumber<BeliefMdpValueType>(val),
56 belId,
57 {storm::utility::convertNumber<BeliefMdpValueType>(*optionalWeightedClippingValue),
58 storm::utility::convertNumber<BeliefMdpValueType>(*optionalRewardAdjustment)}});
59 } else {
60 info.matrix.transitions.push_back({storm::utility::convertNumber<BeliefMdpValueType>(val),
61 belId,
62 {storm::utility::convertNumber<BeliefMdpValueType>(*optionalWeightedClippingValue), std::nullopt}});
63 }
64 } else {
65 info.matrix.transitions.push_back({storm::utility::convertNumber<BeliefMdpValueType>(val), belId, {std::nullopt, std::nullopt}});
66 }
67 }
68 void operator()(BeliefType&& bel, typename BeliefType::ValueType&& val) {
69 auto const belId = info.discoveredBeliefs.getIdOrAddBelief(std::move(bel));
70 if (info.exploredBeliefs.count(belId) == 0u && info.terminalBeliefValues.count(belId) == 0u) {
71 info.queue.push(belId);
72 }
73 info.matrix.transitions.push_back({storm::utility::convertNumber<BeliefMdpValueType>(val), belId, {std::nullopt, std::nullopt}});
74 }
75};
76
77template<typename BeliefMdpValueType, typename PomdpType, typename BeliefType>
81
85 void operator()(BeliefType&& bel, typename BeliefType::ValueType&& val, std::vector<BeliefMdpValueType> const& rewards) {
86 auto const belId = info.discoveredBeliefs.getIdOrAddBelief(std::move(bel));
87 if (info.exploredBeliefs.count(belId) == 0u && info.terminalBeliefValues.count(belId) == 0u) {
88 info.queue.push(belId);
89 }
90 info.matrix.transitions.push_back({storm::utility::convertNumber<BeliefMdpValueType>(val), belId, rewards});
91 }
92};
93
101template<typename BeliefMdpValueType, typename PomdpType, typename BeliefType>
103 public:
104 using TerminationCallback = std::function<bool()>;
105 using TerminalBeliefCallback = std::function<std::optional<BeliefMdpValueType>(BeliefType const&)>;
106
108 explicit BeliefExploration(PomdpType const& pomdp);
109
115 template<typename InfoType>
116 InfoType initializeExploration(uint64_t nrObservationsInPomdp, ExplorationQueueOrder const explorationQueueOrder = ExplorationQueueOrder::Unordered) {
117 InfoType info;
118 info.queue.changeOrder(explorationQueueOrder);
119 info.initialBeliefId = info.discoveredBeliefs.addBelief(firstStateNextStateGenerator.computeInitialBelief());
120 info.queue.push(info.initialBeliefId);
121 info.nrObservationsInPomdp = nrObservationsInPomdp;
122 return info;
123 }
124
130 template<typename AbstractionType>
132 TerminationCallback const& terminationCallback, storm::OptionalRef<std::string const> rewardModelName,
134 if (rewardModelName.has_value()) {
135 firstStateNextStateGenerator.setRewardModel(rewardModelName.value());
136 } else {
137 firstStateNextStateGenerator.unsetRewardModel();
138 }
140 if (abstraction) {
141 performExploration(info, firstStateNextStateGenerator.getPostAbstractionHandle(abstraction.value(), discoverCallback), terminalBeliefCallback,
142 terminationCallback);
143 } else {
144 performExploration(info, firstStateNextStateGenerator.getHandle(discoverCallback), terminalBeliefCallback, terminationCallback);
145 }
146 }
147
152 template<typename AbstractionType>
154 TerminalBeliefCallback const& terminalBeliefCallback, TerminationCallback const& terminationCallback,
157 firstStateNextStateGenerator.unsetRewardModel();
159 if (abstraction) {
160 performExploration(info, firstStateNextStateGenerator.getPrePostAbstractionHandle(rewardSplitter, abstraction.value(), discoverCallback),
161 terminalBeliefCallback, terminationCallback);
162 } else {
163 performExploration(info, firstStateNextStateGenerator.getPreAbstractionHandle(rewardSplitter, discoverCallback), terminalBeliefCallback,
164 terminationCallback);
165 }
166 }
167
171 template<typename AbstractionType>
173 TerminationCallback const& terminationCallback, storm::OptionalRef<std::string const> rewardModelName,
175 if (rewardModelName.has_value()) {
176 firstStateNextStateGenerator.setRewardModel(rewardModelName.value());
177 } else {
178 firstStateNextStateGenerator.unsetRewardModel();
179 }
181 if (abstraction) {
182 performExploration(info, firstStateNextStateGenerator.getPostAbstractionHandle(abstraction.value(), discoverCallback), terminalBeliefCallback,
183 terminationCallback);
184 } else {
185 performExploration(info, firstStateNextStateGenerator.getHandle(discoverCallback), terminalBeliefCallback, terminationCallback);
186 }
187 }
188
189 private:
190 template<typename InfoType, typename NextStateHandleType>
191 bool performExploration(InfoType& info, NextStateHandleType&& exploreNextStates, TerminalBeliefCallback const& terminalBeliefCallback,
192 TerminationCallback const& terminationCallback) {
193 while (info.queue.hasNext()) {
194 // Check if we terminate prematurely
195 if ((terminationCallback && terminationCallback()) || storm::utility::resources::isTerminate()) {
196 STORM_LOG_ASSERT(storm::utility::resources::isTerminate() || info.queue.getContents() == info.getFrontierBeliefs(),
197 "Frontier beliefs inconsistent.");
198 return false; // Terminate prematurely
199 }
200
201 // Get the next belief to explore and perform some checks
202 auto const currentBeliefId = info.queue.popNext();
203 STORM_LOG_ASSERT(info.discoveredBeliefs.containsId(currentBeliefId), "Unknown belief id");
204 STORM_LOG_ASSERT(info.exploredBeliefs.count(currentBeliefId) == 0, "Belief #" << currentBeliefId << " already explored.");
205 STORM_LOG_ASSERT(info.terminalBeliefValues.count(currentBeliefId) == 0, "Belief #" << currentBeliefId << " already found to be terminal.");
206 // do not take the current belief as reference since it will be invalidated when collecting more beliefs
207 auto const currentBelief = info.discoveredBeliefs.getBeliefFromId(currentBeliefId);
208 STORM_LOG_TRACE("Explore belief " << currentBeliefId << " : " << currentBelief.toString());
209 // Check if the current belief is terminal
210 if (terminalBeliefCallback) {
211 if (auto terminal = terminalBeliefCallback(currentBelief); terminal.has_value()) {
212 info.terminalBeliefValues.emplace(currentBeliefId, std::move(terminal.value()));
213 continue;
214 }
215 }
216
217 // Explore for each action the successors of the current belief with that action. Potentially also add rewards.
218 info.exploredBeliefs.emplace(currentBeliefId, info.matrix.groups());
219 auto const numActions = firstStateNextStateGenerator.getBeliefNumberOfActions(currentBelief);
220 for (uint64_t localActionIndex = 0; localActionIndex < numActions; ++localActionIndex) {
221 exploreNextStates(currentBelief, localActionIndex);
222 info.matrix.endCurrentRow();
223 if (firstStateNextStateGenerator.hasRewardModel()) {
224 info.actionRewards.emplace_back(
225 storm::utility::convertNumber<BeliefMdpValueType>(firstStateNextStateGenerator.getBeliefActionReward(currentBelief, localActionIndex)));
226 }
227 if (info.generateChoiceLabeling) {
228 info.matrix.choiceLabels.push_back(firstStateNextStateGenerator.getBeliefActionChoiceLabels(currentBelief, localActionIndex));
229 }
230 }
231 info.matrix.endCurrentRowGroup();
232 }
233 return true;
234 }
235
236 FirstStateNextStateGenerator<PomdpType, BeliefType> firstStateNextStateGenerator;
237};
238} // namespace storm::pomdp::beliefs
Helper class that optionally holds a reference to an object of type T.
Definition OptionalRef.h:48
T & value()
Accesses the contained reference (if any).
bool has_value() const
Yields true iff this contains a reference.
BeliefExploration(PomdpType const &pomdp)
Creates an explorer for pomdp.
InfoType initializeExploration(uint64_t nrObservationsInPomdp, ExplorationQueueOrder const explorationQueueOrder=ExplorationQueueOrder::Unordered)
Initializes an exploration with the initial belief as its only queued frontier belief.
void resumeRewardAwareExploration(RewardAwareExplorationInformation< BeliefMdpValueType, BeliefType > &info, TerminalBeliefCallback const &terminalBeliefCallback, TerminationCallback const &terminationCallback, RewardBoundedBeliefSplitter< BeliefMdpValueType, PomdpType, BeliefType > &rewardSplitter, storm::OptionalRef< AbstractionType > abstraction)
Continues reward-aware exploration, splitting a belief by reward vector before generating successors.
void resumeClippingExploration(ClippingExplorationInformation< BeliefMdpValueType, BeliefType > &info, TerminalBeliefCallback const &terminalBeliefCallback, TerminationCallback const &terminationCallback, storm::OptionalRef< std::string const > rewardModelName, storm::OptionalRef< AbstractionType > abstraction)
Continues exploration with clipping metadata on the generated transitions.
void resumeExploration(StandardExplorationInformation< BeliefMdpValueType, BeliefType > &info, TerminalBeliefCallback const &terminalBeliefCallback, TerminationCallback const &terminationCallback, storm::OptionalRef< std::string const > rewardModelName, storm::OptionalRef< AbstractionType > abstraction)
Continues an ordinary exploration until the queue is empty, a terminal callback applies,...
std::function< std::optional< BeliefMdpValueType >(BeliefType const &)> TerminalBeliefCallback
Abstracts a belief by triangulating it using the Freudenthal triangulation.
Abstracts a given belief by splitting it into sub-beliefs based on the (state-action) reward of the P...
#define STORM_LOG_TRACE(message)
Definition logging.h:22
#define STORM_LOG_ASSERT(cond, message)
Definition macros.h:9
ExplorationInformation< BeliefMdpValueType, BeliefType, std::optional< BeliefMdpValueType >, std::optional< BeliefMdpValueType > > ClippingExplorationInformation
Exploration information that stores optional clipping probability and reward-adjustment metadata.
ExplorationInformation< BeliefMdpValueType, BeliefType > StandardExplorationInformation
Exploration information without transition metadata.
ExplorationQueueOrder
Order used to select the next discovered belief for exploration.
ExplorationInformation< BeliefMdpValueType, BeliefType, std::vector< BeliefMdpValueType > > RewardAwareExplorationInformation
Exploration information that stores a reward vector on each transition.
bool isTerminate()
Check whether the program should terminate (due to some abort signal).
TargetType convertNumber(SourceType const &number)
Stores successor transitions together with clipping metadata.
void operator()(BeliefType &&bel, typename BeliefType::ValueType &&val)
ClippingDiscoverCallback(ClippingExplorationInformation< BeliefMdpValueType, BeliefType > &info)
void operator()(BeliefType &&bel, typename BeliefType::ValueType &&val, std::optional< typename BeliefType::ValueType > optionalWeightedClippingValue, std::optional< typename BeliefType::ValueType > optionalRewardAdjustment)
ClippingExplorationInformation< BeliefMdpValueType, BeliefType > & info
Stores reward-aware successor transitions and their reward vectors.
RewardAwareExplorationInformation< BeliefMdpValueType, BeliefType > & info
RewardAwareDiscoverCallback(RewardAwareExplorationInformation< BeliefMdpValueType, BeliefType > &info)
void operator()(BeliefType &&bel, typename BeliefType::ValueType &&val, std::vector< BeliefMdpValueType > const &rewards)
Stores ordinary successor transitions in exploration information.
void operator()(BeliefType &&bel, typename BeliefType::ValueType &&val)
StandardDiscoverCallback(StandardExplorationInformation< BeliefMdpValueType, BeliefType > &info)
StandardExplorationInformation< BeliefMdpValueType, BeliefType > & info