59 typedef std::pair<state_type, state_type> product_state_type;
61 STORM_LOG_THROW(monitor.hasChoiceLabeling(), storm::exceptions::InvalidArgumentException,
"The monitor should contain choice labeling.");
63 const std::set<std::string>& actions = monitor.getChoiceLabeling().getLabels();
66 std::vector<std::string> monitorChoiceLabels;
68 auto const& monitorLabels = monitor.getChoiceLabeling().getLabelsOfChoice(i);
69 STORM_LOG_THROW(monitorLabels.size() == 1, storm::exceptions::InvalidArgumentException,
"Monitor choice has not exactly one choice label.");
70 monitorChoiceLabels.push_back(*monitorLabels.begin());
73 uint32_t nextObservation = 0;
74 std::map<std::pair<uint32_t, bool>, uint32_t> observationMap;
75 std::vector<uint32_t> observations;
77 std::map<std::pair<const std::string, uint32_t>,
storage::BitVector> rowActionObservationMap;
78 std::vector<std::set<std::string>> observationUsedActions;
81 std::size_t currentRow = 0;
82 state_type nextStateId = 0;
84 state_type goalIndex = nextStateId++;
85 builder.newRowGroup(currentRow);
86 rowActionObservationMap[std::make_pair(
"end", nextObservation)].grow(currentRow + 1);
87 rowActionObservationMap[std::make_pair(
"end", nextObservation)].set(currentRow);
88 observationUsedActions.push_back({
"end"});
90 observations.push_back(nextObservation++);
92 state_type stopIndex = nextStateId++;
93 builder.newRowGroup(currentRow);
94 rowActionObservationMap[std::make_pair(
"end", nextObservation)].grow(currentRow + 1);
95 rowActionObservationMap[std::make_pair(
"end", nextObservation)].set(currentRow);
96 observationUsedActions.push_back({
"end"});
98 observations.push_back(nextObservation++);
100 std::map<product_state_type, state_type> prodToIndexMap;
101 std::vector<state_type> rejectToStates;
103 state_type rejectionIndex;
104 if (!options.useRestartSemantics) {
106 rejectionIndex = nextStateId++;
107 builder.newRowGroup(currentRow);
108 rowActionObservationMap[std::make_pair(
"end", nextObservation)].grow(currentRow + 1);
109 rowActionObservationMap[std::make_pair(
"end", nextObservation)].set(currentRow);
110 observationUsedActions.push_back({
"end"});
112 observations.push_back(nextObservation++);
113 rejectToStates.push_back(rejectionIndex);
116 std::vector<state_type> initialStates;
118 std::deque<product_state_type> todo;
119 for (state_type mc_s_0 : mc.getInitialStates()) {
120 for (state_type mon_s_0 : monitor.getInitialStates()) {
121 product_state_type prod_s(mc_s_0, mon_s_0);
122 state_type index = nextStateId++;
123 prodToIndexMap[prod_s] = index;
124 initialStates.push_back(index);
125 if (options.useRestartSemantics) {
126 rejectToStates.push_back(index);
128 todo.push_back(prod_s);
132 while (!todo.empty()) {
133 auto const [mc_from, mon_from] = std::move(todo.front());
137 bool accepting = monitor.getStateLabeling().getStateHasLabel(options.acceptingLabel, mon_from);
139 for (
auto& label : monitor.getStateLabeling().getLabelsOfState(mon_from)) {
140 if (label.starts_with(options.stepPrefix)) {
141 step = std::stoi(label.substr(options.stepPrefix.length()));
144 std::pair obsPair(step, accepting);
145 if (!observationMap.contains(obsPair)) {
146 observationMap[obsPair] = nextObservation++;
147 observationUsedActions.push_back(std::set<std::string>());
149 uint32_t currentObservation = observationMap.at(obsPair);
150 observations.push_back(currentObservation);
153 builder.newRowGroup(currentRow);
154 if (monitor.getStateLabeling().getLabelsOfState(mon_from).contains(options.horizonLabel)) {
155 const auto& action = *actions.begin();
156 for (state_type initState : rejectToStates) {
159 rowActionObservationMap[std::make_pair(action, currentObservation)].grow(currentRow + 1);
160 rowActionObservationMap[std::make_pair(action, currentObservation)].set(currentRow);
161 observationUsedActions[currentObservation].emplace(action);
164 std::size_t numMonRows = monitor.getTransitionMatrix().getRowGroupSize(mon_from);
165 std::size_t monGroupStart = monitor.getTransitionMatrix().getRowGroupIndices()[mon_from];
166 std::set<std::string> actionsNotTaken(actions);
167 for (std::size_t i = 0; i < numMonRows; i++) {
170 const auto action = monitorChoiceLabels[monGroupStart + i];
171 actionsNotTaken.erase(action);
173 const auto& monitorRow = monitor.getTransitionMatrix().getRow(mon_from, i);
174 STORM_LOG_ASSERT(monitorRow.getNumberOfEntries() == 1,
"Monitor is not fully deterministic.");
175 const auto& monitorEntry = monitorRow.begin();
177 const auto& mcRow = mc.getTransitionMatrix().getRow(mc_from);
181 for (
const auto& mcEntry : mcRow) {
182 if (mc.getStateLabeling().getStateHasLabel(action, mcEntry.getColumn())) {
183 totalProbability += mcEntry.getValue();
188 std::map<state_type, ValueType> newRow;
192 for (state_type initState : rejectToStates) {
193 if (newRow.contains(initState)) {
194 newRow[initState] = newRow[initState] + (1 - totalProbability) / rejectToStates.size();
196 newRow[initState] = (1 - totalProbability) / rejectToStates.size();
203 for (
const auto& mcEntry : mcRow) {
204 if (mc.getStateLabeling().getStateHasLabel(action, mcEntry.getColumn())) {
205 const product_state_type to_pair(mcEntry.getColumn(), monitorEntry->getColumn());
207 if (
auto it = prodToIndexMap.find(to_pair); it != prodToIndexMap.end()) {
208 indexTo = it->second;
210 indexTo = nextStateId++;
211 todo.push_back(to_pair);
212 prodToIndexMap[to_pair] = indexTo;
214 if (newRow.contains(indexTo)) {
215 newRow[indexTo] = newRow[indexTo] + mcEntry.getValue();
217 newRow[indexTo] = mcEntry.getValue();
223 observationUsedActions[currentObservation].emplace(action);
227 for (
const auto& entry : newRow) {
228 builder.addNextValue(currentRow, entry.first, entry.second);
230 auto& rowBitVec = rowActionObservationMap[std::make_pair(action, currentObservation)];
231 rowBitVec.grow(currentRow + 1);
232 rowBitVec.set(currentRow);
236 for (
const auto& action : actionsNotTaken) {
237 for (state_type initState : rejectToStates) {
240 auto& rowBitVec = rowActionObservationMap[std::make_pair(action, currentObservation)];
241 rowBitVec.grow(currentRow + 1);
242 rowBitVec.set(currentRow);
247 if (monitor.getStateLabeling().getStateHasLabel(options.acceptingLabel, mon_from)) {
249 exceptions::IllegalArgumentException,
"Risk for state " + std::to_string(mc_from) +
" is not in [0, 1].");
255 builder.addNextValue(currentRow, goalIndex, risk[mc_from]);
258 observationUsedActions[currentObservation].emplace(
"end");
259 auto& rowBitVec = rowActionObservationMap[std::make_pair(
"end", currentObservation)];
260 rowBitVec.grow(currentRow + 1);
261 rowBitVec.set(currentRow);
266 size_t numberOfRows = currentRow;
269 for (
auto& [labelObsPair, vec] : rowActionObservationMap) {
270 vec.resize(numberOfRows);
276 std::map<uint32_t, std::string> observationDefaultAction;
277 u_int32_t currentObservation = 0;
278 for (
auto const& actionsInObs : observationUsedActions) {
279 if (actionsInObs.size() == 1) {
280 observationDefaultAction[currentObservation] = *actionsInObs.begin();
283 for (
auto const& action : actionsInObs) {
284 rowsToKeep |= rowActionObservationMap[std::make_pair(action, currentObservation)];
286 currentObservation++;
293 const state_type numberOfStates = nextStateId;
307 if (!options.useRestartSemantics) {
318 for (
const auto& [labelObsPair, bitvec] : rowActionObservationMap) {
321 for (uint64_t setbit : bitvec) {
322 if (rowsToKeep[setbit]) {
323 newBitVec.
set(rowMapping[setbit]);
329 choiceLabeling.
setChoices(labelObsPair.first, newBitVec | choiceLabeling.
getChoices(labelObsPair.first));
331 choiceLabeling.
addLabel(labelObsPair.first, newBitVec);
337 if (mc.hasStateValuations()) {
339 auto const& oldValuations = mc.getStateValuations().getStorage();
344 STORM_LOG_ASSERT(oldValuations.numClasses() == 1,
"Only one class of valuations supported.");
345 svBuilder.
addVariables(oldValuations.getClassDescription());
348 stateValuations.
resize(numberOfStates);
350 for (uint64_t i = 0; i < mc.getNumberOfStates(); i++) {
351 for (uint64_t j = 0; j < monitor.getNumberOfStates(); j++) {
352 product_state_type
const s(i, j);
353 if (!prodToIndexMap.contains(s)) {
356 auto const productStateIndex = prodToIndexMap[s];
359 stateValuations.
writeCallback(productStateIndex, [
this, &oldValuations, i, j](
auto,
auto const& var,
auto& value) {
360 using VT = std::remove_cvref_t<
decltype(value)>;
361 if (var == monvar || var == mcvar) {
362 if constexpr (std::is_same_v<VT, int64_t>) {
363 value = var == monvar ? j : i;
369 value = oldValuations.template readValue<VT>(i, var);
375 stateValuations.
writeValue<int64_t>(goalIndex, monvar, -1);
376 stateValuations.
writeValue<int64_t>(goalIndex, mcvar, -1);
377 stateValuations.
writeValue<int64_t>(stopIndex, monvar, -1);
378 stateValuations.
writeValue<int64_t>(stopIndex, mcvar, -1);
384 auto mv = std::make_shared<MonitorVerifier<ValueType>>(std::move(product), std::move(observationMap), std::move(observationDefaultAction));