56 typedef std::pair<state_type, state_type> product_state_type;
58 STORM_LOG_THROW(monitor.hasChoiceLabeling(), storm::exceptions::InvalidArgumentException,
"The monitor should contain choice labeling");
60 const std::set<std::string>& actions = monitor.getChoiceLabeling().getLabels();
63 std::vector<std::string> monitorChoiceLabels;
65 auto const& monitorLabels = monitor.getChoiceLabeling().getLabelsOfChoice(i);
66 STORM_LOG_THROW(monitorLabels.size() == 1, storm::exceptions::InvalidArgumentException,
"Monitor choice has not exactly one choice label");
67 monitorChoiceLabels.push_back(*monitorLabels.begin());
70 uint32_t nextObservation = 0;
71 std::map<std::pair<uint32_t, bool>, uint32_t> observationMap;
72 std::vector<uint32_t> observations;
74 std::map<std::pair<const std::string, uint32_t>,
storage::BitVector> rowActionObservationMap;
75 std::vector<std::set<std::string>> observationUsedActions;
78 std::size_t currentRow = 0;
79 state_type nextStateId = 0;
81 state_type goalIndex = nextStateId++;
82 builder.newRowGroup(currentRow);
83 rowActionObservationMap[std::make_pair(
"end", nextObservation)].grow(currentRow + 1);
84 rowActionObservationMap[std::make_pair(
"end", nextObservation)].set(currentRow);
85 observationUsedActions.push_back({
"end"});
87 observations.push_back(nextObservation++);
89 state_type stopIndex = nextStateId++;
90 builder.newRowGroup(currentRow);
91 rowActionObservationMap[std::make_pair(
"end", nextObservation)].grow(currentRow + 1);
92 rowActionObservationMap[std::make_pair(
"end", nextObservation)].set(currentRow);
93 observationUsedActions.push_back({
"end"});
95 observations.push_back(nextObservation++);
97 std::map<product_state_type, state_type> prodToIndexMap;
98 std::vector<state_type> rejectToStates;
100 state_type rejectionIndex;
101 if (!options.useRestartSemantics) {
103 rejectionIndex = nextStateId++;
104 builder.newRowGroup(currentRow);
105 rowActionObservationMap[std::make_pair(
"end", nextObservation)].grow(currentRow + 1);
106 rowActionObservationMap[std::make_pair(
"end", nextObservation)].set(currentRow);
107 observationUsedActions.push_back({
"end"});
109 observations.push_back(nextObservation++);
110 rejectToStates.push_back(rejectionIndex);
113 std::vector<state_type> initialStates;
115 std::deque<product_state_type> todo;
116 for (state_type mc_s_0 : mc.getInitialStates()) {
117 for (state_type mon_s_0 : monitor.getInitialStates()) {
118 product_state_type prod_s(mc_s_0, mon_s_0);
119 state_type index = nextStateId++;
120 prodToIndexMap[prod_s] = index;
121 initialStates.push_back(index);
122 if (options.useRestartSemantics)
123 rejectToStates.push_back(index);
124 todo.push_back(prod_s);
128 while (!todo.empty()) {
129 auto const [mc_from, mon_from] = std::move(todo.front());
133 bool accepting = monitor.getStateLabeling().getStateHasLabel(options.acceptingLabel, mon_from);
135 for (
auto& label : monitor.getStateLabeling().getLabelsOfState(mon_from)) {
136 if (label.starts_with(options.stepPrefix)) {
137 step = std::stoi(label.substr(options.stepPrefix.length()));
140 std::pair obsPair(step, accepting);
141 if (!observationMap.contains(obsPair)) {
142 observationMap[obsPair] = nextObservation++;
143 observationUsedActions.push_back(std::set<std::string>());
145 uint32_t currentObservation = observationMap.at(obsPair);
146 observations.push_back(currentObservation);
149 builder.newRowGroup(currentRow);
150 if (monitor.getStateLabeling().getLabelsOfState(mon_from).contains(options.horizonLabel)) {
151 const auto& action = *actions.begin();
152 for (state_type initState : rejectToStates) {
155 rowActionObservationMap[std::make_pair(action, currentObservation)].grow(currentRow + 1);
156 rowActionObservationMap[std::make_pair(action, currentObservation)].set(currentRow);
157 observationUsedActions[currentObservation].emplace(action);
160 std::size_t numMonRows = monitor.getTransitionMatrix().getRowGroupSize(mon_from);
161 std::size_t monGroupStart = monitor.getTransitionMatrix().getRowGroupIndices()[mon_from];
162 std::set<std::string> actionsNotTaken(actions);
163 for (std::size_t i = 0; i < numMonRows; i++) {
166 const auto action = monitorChoiceLabels[monGroupStart + i];
167 actionsNotTaken.erase(action);
169 const auto& monitorRow = monitor.getTransitionMatrix().getRow(mon_from, i);
170 STORM_LOG_ASSERT(monitorRow.getNumberOfEntries() == 1,
"Monitor is not fully deterministic");
171 const auto& monitorEntry = monitorRow.begin();
173 const auto& mcRow = mc.getTransitionMatrix().getRow(mc_from);
177 for (
const auto& mcEntry : mcRow) {
178 if (mc.getStateLabeling().getStateHasLabel(action, mcEntry.getColumn())) {
179 totalProbability += mcEntry.getValue();
184 std::map<state_type, ValueType> newRow;
188 for (state_type initState : rejectToStates) {
189 if (newRow.contains(initState))
190 newRow[initState] = newRow[initState] + (1 - totalProbability) / rejectToStates.size();
192 newRow[initState] = (1 - totalProbability) / rejectToStates.size();
198 for (
const auto& mcEntry : mcRow) {
199 if (mc.getStateLabeling().getStateHasLabel(action, mcEntry.getColumn())) {
200 const product_state_type to_pair(mcEntry.getColumn(), monitorEntry->getColumn());
202 if (
auto it = prodToIndexMap.find(to_pair); it != prodToIndexMap.end()) {
203 indexTo = it->second;
205 indexTo = nextStateId++;
206 todo.push_back(to_pair);
207 prodToIndexMap[to_pair] = indexTo;
209 if (newRow.contains(indexTo))
210 newRow[indexTo] = newRow[indexTo] + mcEntry.getValue();
212 newRow[indexTo] = mcEntry.getValue();
217 observationUsedActions[currentObservation].emplace(action);
221 for (
const auto& entry : newRow) {
222 builder.addNextValue(currentRow, entry.first, entry.second);
224 auto& rowBitVec = rowActionObservationMap[std::make_pair(action, currentObservation)];
225 rowBitVec.grow(currentRow + 1);
226 rowBitVec.set(currentRow);
230 for (
const auto& action : actionsNotTaken) {
231 for (state_type initState : rejectToStates) {
234 auto& rowBitVec = rowActionObservationMap[std::make_pair(action, currentObservation)];
235 rowBitVec.grow(currentRow + 1);
236 rowBitVec.set(currentRow);
241 if (monitor.getStateLabeling().getStateHasLabel(options.acceptingLabel, mon_from)) {
243 exceptions::IllegalArgumentException,
"Risk for state " + std::to_string(mc_from) +
" is not in [0, 1]");
249 builder.addNextValue(currentRow, goalIndex, risk[mc_from]);
252 observationUsedActions[currentObservation].emplace(
"end");
253 auto& rowBitVec = rowActionObservationMap[std::make_pair(
"end", currentObservation)];
254 rowBitVec.grow(currentRow + 1);
255 rowBitVec.set(currentRow);
260 size_t numberOfRows = currentRow;
263 for (
auto& [labelObsPair, vec] : rowActionObservationMap) {
264 vec.resize(numberOfRows);
270 std::map<uint32_t, std::string> observationDefaultAction;
271 u_int32_t currentObservation = 0;
272 for (
auto const& actionsInObs : observationUsedActions) {
273 if (actionsInObs.size() == 1) {
274 observationDefaultAction[currentObservation] = *actionsInObs.begin();
277 for (
auto const& action : actionsInObs) {
279 rowsToKeep |= rowActionObservationMap[std::make_pair(action, currentObservation)];
281 currentObservation++;
289 const state_type numberOfStates = nextStateId;
303 if (!options.useRestartSemantics) {
314 for (
const auto& [labelObsPair, bitvec] : rowActionObservationMap) {
317 for (
const auto& setbit : bitvec) {
318 if (rowsToKeep[setbit])
319 newBitVec.
set(rowMapping[setbit]);
324 choiceLabeling.
setChoices(labelObsPair.first, newBitVec | choiceLabeling.
getChoices(labelObsPair.first));
326 choiceLabeling.
addLabel(labelObsPair.first, newBitVec);
332 if (mc.hasStateValuations()) {
337 std::set<expressions::Variable> variables;
338 for (uint64_t i = 0; i < mc.getNumberOfStates(); i++) {
339 const auto& valAssignment = mc.getStateValuations().at(i);
340 for (
auto val = valAssignment.begin(); val != valAssignment.end(); ++val) {
341 if (val.isVariableAssignment() && !variables.contains(val.getVariable())) {
342 variables.emplace(val.getVariable());
348 for (uint64_t i = 0; i < mc.getNumberOfStates(); i++) {
349 for (uint64_t j = 0; j < monitor.getNumberOfStates(); j++) {
350 product_state_type s(i, j);
351 if (!prodToIndexMap.contains(s))
354 std::vector<bool> booleanValues;
355 std::vector<int64_t> integerValues;
356 std::vector<storm::RationalNumber> rationalValues;
358 integerValues.push_back(j);
359 integerValues.push_back(i);
361 const auto& valAssignment = mc.getStateValuations().at(i);
363 for (
auto& var : variables) {
364 for (
auto val = valAssignment.begin(); val != valAssignment.end(); ++val) {
365 if (var == val.getVariable()) {
366 if (val.isBoolean()) {
367 booleanValues.push_back(val.getBooleanValue());
368 }
else if (val.isInteger()) {
369 integerValues.push_back(val.getIntegerValue());
370 }
else if (val.isRational()) {
371 rationalValues.push_back(val.getRationalValue());
377 svBuilder.
addState(prodToIndexMap[std::make_pair(i, j)], std::move(booleanValues), std::move(integerValues), std::move(rationalValues));
381 std::vector<bool> goalBooleanValues;
382 std::vector<int64_t> goalIntegerValues(2, -1);
383 std::vector<storm::RationalNumber> goalRationalValues;
384 for (
auto& var : variables) {
385 if (var.hasBooleanType()) {
386 goalBooleanValues.push_back(
false);
387 }
else if (var.hasIntegerType()) {
388 goalIntegerValues.push_back(-1);
389 }
else if (var.hasRationalType()) {
390 goalRationalValues.emplace_back(-1);
393 svBuilder.
addState(goalIndex, std::move(goalBooleanValues), std::move(goalIntegerValues), std::move(goalRationalValues));
395 std::vector<bool> stopBooleanValues;
396 std::vector<int64_t> stopIntegerValues(2, -1);
397 std::vector<storm::RationalNumber> stopRationalValues;
398 for (
auto& var : variables) {
399 if (var.hasBooleanType()) {
400 stopBooleanValues.push_back(
false);
401 }
else if (var.hasIntegerType()) {
402 stopIntegerValues.push_back(-1);
403 }
else if (var.hasRationalType()) {
404 stopRationalValues.emplace_back(-1);
407 svBuilder.
addState(stopIndex, std::move(stopBooleanValues), std::move(stopIntegerValues), std::move(stopRationalValues));
414 auto mv = std::make_shared<MonitorVerifier<ValueType>>(std::move(product), std::move(observationMap), std::move(observationDefaultAction));