23template<
typename ValueType,
typename ConstantType>
27 this->matrix = model->getTransitionMatrix();
28 this->numberOfStates = this->model->getNumberOfStates();
29 this->formula = formula;
33template<
typename ValueType,
typename ConstantType>
37 this->matrix = matrix;
38 this->model =
nullptr;
44 this->numberOfStates = matrix.getColumnCount();
45 std::vector<uint64_t> firstStates;
48 for (uint64_t state : topStates) {
49 firstStates.push_back(state);
50 subStates.
set(state,
false);
52 for (uint64_t state : bottomStates) {
53 firstStates.push_back(state);
54 subStates.
set(state,
false);
63 this->bottomTopOrder = std::make_shared<Order>(topStates, bottomStates, numberOfStates, std::move(decomposition), std::move(statesSorted));
66 for (uint_fast64_t state = 0; state < numberOfStates; ++state) {
67 auto const& row = matrix.getRow(state);
68 stateMap[state] = std::vector<uint_fast64_t>();
69 std::set<VariableType> occurringVariables;
71 for (
auto& entry : matrix.getRow(state)) {
73 if (state != entry.getColumn() || row.getNumberOfEntries() == 1) {
74 if (!subStates[entry.getColumn()] && !bottomTopOrder->contains(state)) {
75 bottomTopOrder->add(state);
77 stateMap[state].push_back(entry.getColumn());
81 if (occurringVariables.empty()) {
82 nonParametricStates.insert(state);
85 for (
auto& var : occurringVariables) {
86 occuringStatesAtVariable[var].push_back(state);
88 occuringVariablesAtState.push_back(std::move(occurringVariables));
94template<
typename ValueType,
typename ConstantType>
95std::shared_ptr<Order> OrderExtender<ValueType, ConstantType>::getBottomTopOrder() {
96 if (bottomTopOrder ==
nullptr) {
98 STORM_LOG_THROW(matrix.getRowCount() == matrix.getColumnCount(), exceptions::NotSupportedException,
99 "Creating order not supported for non-square matrix.");
103 STORM_LOG_ASSERT(formula->isProbabilityOperatorFormula(),
"Expected probability operator formula.");
104 if (formula->asProbabilityOperatorFormula().getSubformula().isUntilFormula()) {
105 phiStates = propositionalChecker.check(formula->asProbabilityOperatorFormula().getSubformula().asUntilFormula().getLeftSubformula())
106 ->template asExplicitQualitativeCheckResult<ValueType>()
107 .getTruthValuesVector();
108 psiStates = propositionalChecker.check(formula->asProbabilityOperatorFormula().getSubformula().asUntilFormula().getRightSubformula())
109 ->template asExplicitQualitativeCheckResult<ValueType>()
110 .getTruthValuesVector();
112 STORM_LOG_ASSERT(formula->asProbabilityOperatorFormula().getSubformula().isEventuallyFormula(),
"Expected eventually formula.");
114 psiStates = propositionalChecker.check(formula->asProbabilityOperatorFormula().getSubformula().asEventuallyFormula().getSubformula())
115 ->template asExplicitQualitativeCheckResult<ValueType>()
116 .getTruthValuesVector();
119 std::pair<storage::BitVector, storage::BitVector> statesWithProbability01 =
121 storage::BitVector topStates = statesWithProbability01.second;
122 storage::BitVector bottomStates = statesWithProbability01.first;
124 STORM_LOG_THROW(topStates.begin() != topStates.end(), exceptions::NotSupportedException,
"Formula yields to no 1 states.");
125 STORM_LOG_THROW(bottomStates.begin() != bottomStates.end(), exceptions::NotSupportedException,
"Formula yields to no zero states.");
126 auto& matrix = this->model->getTransitionMatrix();
127 std::vector<uint64_t> firstStates;
130 for (
auto state : topStates) {
131 firstStates.push_back(state);
132 subStates.set(state,
false);
134 for (
auto state : bottomStates) {
135 firstStates.push_back(state);
136 subStates.set(state,
false);
139 storm::storage::StronglyConnectedComponentDecomposition<ValueType> decomposition;
141 storm::storage::StronglyConnectedComponentDecompositionOptions options;
143 decomposition = storm::storage::StronglyConnectedComponentDecomposition<ValueType>(matrix, options);
146 bottomTopOrder = std::make_shared<Order>(topStates, bottomStates, numberOfStates, std::move(decomposition), std::move(statesSorted));
149 for (uint_fast64_t state = 0; state < numberOfStates; ++state) {
150 auto const& row = matrix.getRow(state);
151 stateMap[state] = std::vector<uint_fast64_t>();
152 std::set<VariableType> occurringVariables;
154 for (
auto& entry : matrix.getRow(state)) {
156 if (state != entry.getColumn() || row.getNumberOfEntries() == 1) {
160 stateMap[state].push_back(entry.getColumn());
164 if (occurringVariables.empty()) {
165 nonParametricStates.insert(state);
168 for (
auto& var : occurringVariables) {
169 occuringStatesAtVariable[var].push_back(state);
171 occuringVariablesAtState.push_back(std::move(occurringVariables));
175 if (minValuesInit && maxValuesInit) {
176 continueExtending[bottomTopOrder] =
true;
177 usePLA[bottomTopOrder] =
true;
178 minValues[bottomTopOrder] = std::move(minValuesInit.get());
179 maxValues[bottomTopOrder] = std::move(maxValuesInit.get());
181 usePLA[bottomTopOrder] =
false;
183 return bottomTopOrder;
186template<
typename ValueType,
typename ConstantType>
189 return this->
extendOrder(
nullptr, region, monRes,
nullptr);
192template<
typename ValueType,
typename ConstantType>
193void OrderExtender<ValueType, ConstantType>::handleAssumption(std::shared_ptr<Order> order,
194 std::shared_ptr<expressions::BinaryRelationExpression> assumption)
const {
196 STORM_LOG_ASSERT(assumption->getFirstOperand()->isVariable() && assumption->getSecondOperand()->isVariable(),
"Expected variable operands.");
200 auto const& val1 = std::stoul(var1.
getName(),
nullptr, 0);
201 auto const& val2 = std::stoul(var2.
getName(),
nullptr, 0);
209 if (n1 !=
nullptr && n2 !=
nullptr) {
210 order->mergeNodes(n1, n2);
211 }
else if (n1 !=
nullptr) {
212 order->addToNode(val2, n1);
213 }
else if (n2 !=
nullptr) {
214 order->addToNode(val1, n2);
217 order->addToNode(val2, order->getNode(val1));
221 if (n1 !=
nullptr && n2 !=
nullptr) {
222 order->addRelationNodes(n1, n2);
223 }
else if (n1 !=
nullptr) {
224 order->addBetween(val2, n1, order->getBottom());
225 }
else if (n2 !=
nullptr) {
226 order->addBetween(val1, order->getTop(), n2);
229 order->addBetween(val2, order->getNode(val1), order->getBottom());
234template<
typename ValueType,
typename ConstantType>
237 std::shared_ptr<expressions::BinaryRelationExpression> assumption) {
238 this->region = region;
239 if (order ==
nullptr) {
240 order = getBottomTopOrder();
242 auto& min = minValues[order];
243 auto& max = maxValues[order];
245 auto& statesSorted = order->getStatesSorted();
246 auto itr = statesSorted.begin();
247 while (itr != statesSorted.end()) {
249 auto& successors = stateMap[state];
251 for (uint_fast64_t i = 0; i < successors.size(); ++i) {
252 auto state1 = successors[i];
253 for (uint_fast64_t j = i + 1; j < successors.size(); ++j) {
254 auto state2 = successors[j];
255 if (min[state1] > max[state2]) {
256 if (!order->contains(state1)) {
259 if (!order->contains(state2)) {
262 order->addRelation(state1, state2,
false);
263 }
else if (min[state2] > max[state1]) {
264 if (!order->contains(state1)) {
267 if (!order->contains(state2)) {
270 order->addRelation(state2, state1,
false);
271 }
else if (min[state1] == max[state2] && max[state1] == min[state2]) {
272 if (!order->contains(state1) && !order->contains(state2)) {
274 order->addToNode(state2, order->getNode(state1));
275 }
else if (!order->contains(state1)) {
276 order->addToNode(state1, order->getNode(state2));
277 }
else if (!order->contains(state2)) {
278 order->addToNode(state2, order->getNode(state1));
280 order->merge(state1, state2);
289 STORM_LOG_INFO(
"All successors of state " << state <<
" sorted based on min max values");
294 continueExtending[order] =
true;
296 if (continueExtending[order] || assumption !=
nullptr) {
299 auto& res = unknownStatesMap[order];
300 continueExtending[order] =
false;
301 return {order, res.first, res.second};
305template<
typename ValueType,
typename ConstantType>
307 std::shared_ptr<Order> order, std::shared_ptr<
MonotonicityResult<VariableType>> monRes, std::shared_ptr<expressions::BinaryRelationExpression> assumption) {
308 if (assumption !=
nullptr) {
310 handleAssumption(order, assumption);
313 auto currentStateMode = getNextState(order, numberOfStates,
false);
314 while (currentStateMode.first != numberOfStates) {
315 STORM_LOG_ASSERT(currentStateMode.first < numberOfStates,
"State out of range.");
316 auto& currentState = currentStateMode.first;
317 auto& successors = stateMap[currentState];
318 std::pair<uint_fast64_t, uint_fast64_t> result = {numberOfStates, numberOfStates};
320 if (successors.size() == 1) {
321 STORM_LOG_ASSERT(order->contains(successors[0]),
"Order does not contain successor.");
322 handleOneSuccessor(order, currentState, successors[0]);
323 }
else if (!successors.empty()) {
324 if (order->isOnlyBottomTopOrder()) {
325 order->add(currentState);
326 if (!order->isTrivial(currentState)) {
328 result = extendByForwardReasoning(order, currentState, successors, assumption !=
nullptr);
330 result = {numberOfStates, numberOfStates};
333 result = extendNormal(order, currentState, successors, assumption !=
nullptr);
337 if (result.first == numberOfStates) {
339 STORM_LOG_ASSERT(result.second == numberOfStates,
"Result second mismatch.");
340 STORM_LOG_ASSERT(order->sortStates(&successors).size() == successors.size(),
"Sort states size mismatch.");
341 STORM_LOG_ASSERT(order->contains(currentState) && order->getNode(currentState) !=
nullptr,
"Current state not in order.");
343 if (monRes !=
nullptr) {
344 for (
auto& param : occuringVariablesAtState[currentState]) {
345 checkParOnStateMonRes(currentState, order, param, monRes);
349 currentStateMode = getNextState(order, currentState,
true);
351 STORM_LOG_ASSERT(result.first < numberOfStates,
"Result first out of range.");
352 STORM_LOG_ASSERT(result.second < numberOfStates,
"Result second out of range.");
356 if (currentStateMode.second && extendByAssumption(order, result.first, result.second)) {
360 if (nonParametricStates.find(currentState) != nonParametricStates.end()) {
361 if (!order->contains(currentState)) {
363 order->add(currentState);
365 currentStateMode = getNextState(order, currentState,
true);
368 if (!currentStateMode.second) {
370 currentStateMode = getNextState(order, currentState,
false);
375 order->addStateSorted(currentState);
376 continueExtending[order] =
false;
377 return {order, result.first, result.second};
381 STORM_LOG_ASSERT(order->sortStates(&successors).size() == successors.size(),
"Sort states size mismatch after extension.");
385 if (monRes !=
nullptr) {
389 return std::make_tuple(order, numberOfStates, numberOfStates);
392template<
typename ValueType,
typename ConstantType>
393std::pair<uint_fast64_t, uint_fast64_t> OrderExtender<ValueType, ConstantType>::extendNormal(std::shared_ptr<Order> order, uint_fast64_t currentState,
394 const std::vector<uint_fast64_t>& successors,
bool allowMerge) {
396 if (cyclic && !order->isTrivial(currentState) && order->contains(currentState)) {
398 return extendByForwardReasoning(order, currentState, successors, allowMerge);
400 STORM_LOG_ASSERT(order->isTrivial(currentState) || !order->contains(currentState),
"State is neither trivial nor missing.");
402 return extendByBackwardReasoning(order, currentState, successors, allowMerge);
406template<
typename ValueType,
typename ConstantType>
407void OrderExtender<ValueType, ConstantType>::handleOneSuccessor(std::shared_ptr<Order> order, uint_fast64_t currentState, uint_fast64_t successor) {
408 STORM_LOG_ASSERT(order->contains(successor),
"Order does not contain successor.");
409 if (currentState != successor) {
410 if (order->contains(currentState)) {
411 order->merge(currentState, successor);
413 order->addToNode(currentState, order->getNode(successor));
418template<
typename ValueType,
typename ConstantType>
419std::pair<uint_fast64_t, uint_fast64_t> OrderExtender<ValueType, ConstantType>::extendByBackwardReasoning(std::shared_ptr<Order> order,
420 uint_fast64_t currentState,
421 std::vector<uint_fast64_t>
const& successors,
423 STORM_LOG_ASSERT(!order->isOnlyBottomTopOrder(),
"Order is only bottom-top.");
426 bool pla = (usePLA.find(order) != usePLA.end() && usePLA.at(order));
427 std::vector<uint_fast64_t> sortedSuccs;
429 if (pla && (continueExtending.find(order) == continueExtending.end() || continueExtending.at(order))) {
430 for (
auto& state1 : successors) {
431 if (sortedSuccs.size() == 0) {
432 sortedSuccs.push_back(state1);
435 for (
auto itr = sortedSuccs.begin(); itr != sortedSuccs.end(); ++itr) {
437 auto compareRes = order->compareFast(state1, state2);
439 compareRes = addStatesBasedOnMinMax(order, state1, state2);
443 compareRes = order->compare(state1, state2);
447 sortedSuccs.insert(itr, state1);
451 continueExtending[order] =
false;
452 return {state1, state2};
456 sortedSuccs.push_back(state1);
461 auto temp = order->sortStatesUnorderedPair(&successors);
462 if (temp.first.first != numberOfStates) {
465 sortedSuccs = std::move(temp.second);
469 if (order->compare(sortedSuccs[0], sortedSuccs[sortedSuccs.size() - 1]) ==
Order::SAME) {
470 if (!order->contains(currentState)) {
471 order->addToNode(currentState, order->getNode(sortedSuccs[0]));
473 order->merge(currentState, sortedSuccs[0]);
476 if (!order->contains(sortedSuccs[0])) {
477 STORM_LOG_ASSERT(order->isBottomState(sortedSuccs[sortedSuccs.size() - 1]),
"Expected bottom state.");
479 order->addAbove(sortedSuccs[0], order->getBottom());
481 if (!order->contains(sortedSuccs[sortedSuccs.size() - 1])) {
484 order->addBelow(sortedSuccs[sortedSuccs.size() - 1], order->getTop());
487 if (!order->contains(currentState)) {
488 order->addBetween(currentState, sortedSuccs[0], sortedSuccs[sortedSuccs.size() - 1]);
490 order->addRelation(sortedSuccs[0], currentState, allowMerge);
491 order->addRelation(currentState, sortedSuccs[sortedSuccs.size() - 1], allowMerge);
495 order->compare(order->getNode(currentState), order->getTop()) ==
Order::BELOW,
496 "Order is not as expected.");
497 return {numberOfStates, numberOfStates};
500template<
typename ValueType,
typename ConstantType>
501std::pair<uint_fast64_t, uint_fast64_t> OrderExtender<ValueType, ConstantType>::extendByForwardReasoning(std::shared_ptr<Order> order,
502 uint_fast64_t currentState,
503 std::vector<uint_fast64_t>
const& successors,
506 STORM_LOG_ASSERT(order->contains(currentState),
"Current state not in order.");
509 std::vector<uint_fast64_t> statesSorted;
510 statesSorted.push_back(currentState);
511 bool pla = (usePLA.find(order) != usePLA.end() && usePLA.at(order));
513 bool oneUnknown =
false;
514 bool unknown =
false;
515 uint_fast64_t s1 = numberOfStates;
516 uint_fast64_t s2 = numberOfStates;
517 for (
auto& state : successors) {
520 for (
auto itr = statesSorted.begin(); itr != statesSorted.end(); ++itr) {
521 auto compareRes = order->compareFast(state, (*itr));
523 compareRes = addStatesBasedOnMinMax(order, state, (*itr));
526 compareRes = order->compare(state, *itr);
531 order->addStateToHandle(state);
535 statesSorted.insert(itr, state);
550 if (!(unknown && oneUnknown) && !added) {
552 statesSorted.push_back(state);
554 if (unknown && oneUnknown) {
558 if (!unknown && oneUnknown) {
559 STORM_LOG_ASSERT(statesSorted.size() == successors.size(),
"States sorted size mismatch.");
563 if (s1 == numberOfStates) {
564 STORM_LOG_ASSERT(statesSorted.size() == successors.size() + 1,
"States sorted size mismatch.");
566 }
else if (s2 == numberOfStates) {
567 if (!order->contains(s1)) {
571 if (statesSorted[0] == currentState) {
572 order->addRelation(s1, statesSorted[0], allowMerge);
574 (allowMerge && (order->compare(s1, statesSorted[statesSorted.size() - 1]) ==
Order::SAME)),
575 "Order is not as expected.");
576 order->addRelation(s1, statesSorted[statesSorted.size() - 1], allowMerge);
578 (allowMerge && (order->compare(s1, statesSorted[statesSorted.size() - 1]) ==
Order::SAME)),
579 "Order is not as expected.");
580 order->addStateToHandle(s1);
581 }
else if (statesSorted[statesSorted.size() - 1] == currentState) {
582 order->addRelation(statesSorted[0], s1, allowMerge);
584 (allowMerge && (order->compare(s1, statesSorted[statesSorted.size() - 1]) ==
Order::SAME)),
585 "Order is not as expected.");
586 order->addRelation(statesSorted[statesSorted.size() - 1], s1, allowMerge);
588 (allowMerge && (order->compare(s1, statesSorted[statesSorted.size() - 1]) ==
Order::SAME)),
589 "Order is not as expected.");
590 order->addStateToHandle(s1);
592 bool continueSearch =
true;
593 for (
auto& entry : matrix.getRow(currentState)) {
594 if (entry.getColumn() == s1) {
595 if (entry.getValue().isConstant()) {
596 continueSearch =
false;
600 if (continueSearch) {
601 for (
auto& i : statesSorted) {
612 order->compare(order->getNode(currentState), order->getTop()) ==
Order::BELOW,
613 "Order is not as expected.");
614 return {numberOfStates, numberOfStates};
617template<
typename ValueType,
typename ConstantType>
618bool OrderExtender<ValueType, ConstantType>::extendByAssumption(std::shared_ptr<Order> order, uint_fast64_t state1, uint_fast64_t state2) {
619 bool usePLANow = usePLA.find(order) != usePLA.end() && usePLA[order];
621 auto assumptions = usePLANow ? assumptionMaker->createAndCheckAssumptions(state1, state2, order, region, minValues[order], maxValues[order])
622 : assumptionMaker->createAndCheckAssumptions(state1, state2, order, region);
624 handleAssumption(order, assumptions.begin()->first);
631template<
typename ValueType,
typename ConstantType>
632Order::NodeComparison OrderExtender<ValueType, ConstantType>::addStatesBasedOnMinMax(std::shared_ptr<Order> order, uint_fast64_t state1,
633 uint_fast64_t state2)
const {
635 STORM_LOG_ASSERT(minValues.find(order) != minValues.end(),
"MinValues missing for order.");
636 std::vector<ConstantType>
const& mins = minValues.at(order);
637 std::vector<ConstantType>
const& maxs = maxValues.at(order);
638 if (mins[state1] == maxs[state1] && mins[state2] == maxs[state2] && mins[state1] == mins[state2]) {
639 if (order->contains(state1)) {
640 if (order->contains(state2)) {
641 order->merge(state1, state2);
644 order->addToNode(state2, order->getNode(state1));
648 }
else if (mins[state1] > maxs[state2]) {
650 if (!order->contains(state1)) {
653 if (!order->contains(state2)) {
658 order->addRelation(state1, state2);
661 }
else if (mins[state2] > maxs[state1]) {
663 if (!order->contains(state1)) {
666 if (!order->contains(state2)) {
671 order->addRelation(state2, state1);
679template<
typename ValueType,
typename ConstantType>
681 if (model !=
nullptr) {
684 std::unique_ptr<modelchecker::CheckResult> checkResult;
686 boost::optional<modelchecker::CheckTask<logic::Formula, ValueType>> checkTask;
687 if (this->formula->hasQuantitativeResult()) {
692 std::make_shared<storm::logic::ProbabilityOperatorFormula>(formula->asProbabilityOperatorFormula().getSubformula().asSharedPointer(), opInfo);
695 STORM_LOG_THROW(plaModelChecker.
canHandle(model, checkTask.get()), exceptions::NotSupportedException,
"Cannot handle this formula.");
696 bool const allowModelSimplification =
false;
697 plaModelChecker.
specify(env, model, checkTask.get(), std::nullopt,
nullptr, allowModelSimplification);
701 plaModelChecker.
check(env, annotatedRegion, solver::OptimizationDirection::Minimize)->template asExplicitQuantitativeCheckResult<ConstantType>();
703 plaModelChecker.
check(env, annotatedRegion, solver::OptimizationDirection::Maximize)->template asExplicitQuantitativeCheckResult<ConstantType>();
706 STORM_LOG_ASSERT(minValuesInit->size() == numberOfStates,
"MinValuesInit size mismatch.");
707 STORM_LOG_ASSERT(maxValuesInit->size() == numberOfStates,
"MaxValuesInit size mismatch.");
711template<
typename ValueType,
typename ConstantType>
713 std::vector<ConstantType>&& maxValues) {
714 STORM_LOG_ASSERT(minValues.size() == numberOfStates,
"MinValues size mismatch.");
715 STORM_LOG_ASSERT(maxValues.size() == numberOfStates,
"MaxValues size mismatch.");
716 usePLA[order] =
true;
717 if (unknownStatesMap.find(order) != unknownStatesMap.end()) {
718 auto& unknownStates = unknownStatesMap[order];
719 if (unknownStates.first != numberOfStates) {
720 continueExtending[order] =
721 minValues[unknownStates.first] >= maxValues[unknownStates.second] || minValues[unknownStates.second] >= maxValues[unknownStates.first];
723 continueExtending[order] =
true;
726 continueExtending[order] =
true;
728 this->minValues[order] = std::move(minValues);
729 this->maxValues[order] = std::move(maxValues);
732template<
typename ValueType,
typename ConstantType>
734 STORM_LOG_ASSERT(minValues.size() == numberOfStates,
"MinValues size mismatch.");
735 auto& maxValues = this->maxValues[order];
736 usePLA[order] = this->maxValues.find(order) != this->maxValues.end();
737 if (maxValues.size() == 0) {
738 continueExtending[order] =
false;
739 }
else if (unknownStatesMap.find(order) != unknownStatesMap.end()) {
740 auto& unknownStates = unknownStatesMap[order];
741 if (unknownStates.first != numberOfStates) {
742 continueExtending[order] =
743 minValues[unknownStates.first] >= maxValues[unknownStates.second] || minValues[unknownStates.second] >= maxValues[unknownStates.first];
745 continueExtending[order] =
true;
748 continueExtending[order] =
true;
750 this->minValues[order] = std::move(minValues);
753template<
typename ValueType,
typename ConstantType>
755 STORM_LOG_ASSERT(maxValues.size() == numberOfStates,
"MaxValues size mismatch.");
756 usePLA[order] = this->minValues.find(order) != this->minValues.end();
757 auto& minValues = this->minValues[order];
758 if (minValues.size() == 0) {
759 continueExtending[order] =
false;
760 }
else if (unknownStatesMap.find(order) != unknownStatesMap.end()) {
761 auto& unknownStates = unknownStatesMap[order];
762 if (unknownStates.first != numberOfStates) {
763 continueExtending[order] =
764 minValues[unknownStates.first] >= maxValues[unknownStates.second] || minValues[unknownStates.second] >= maxValues[unknownStates.first];
766 continueExtending[order] =
true;
769 continueExtending[order] =
true;
771 this->maxValues[order] = std::move(maxValues);
773template<
typename ValueType,
typename ConstantType>
775 STORM_LOG_ASSERT(minValues.size() == numberOfStates,
"MinValues size mismatch.");
776 this->minValuesInit = std::move(minValues);
779template<
typename ValueType,
typename ConstantType>
781 STORM_LOG_ASSERT(maxValues.size() == numberOfStates,
"MaxValues size mismatch.");
782 this->maxValuesInit = std::move(maxValues);
785template<
typename ValueType,
typename ConstantType>
789 auto mon = monotonicityChecker.checkLocalMonotonicity(order, s, param, region);
790 monResult->updateMonotonicityResult(param, mon);
793template<
typename ValueType,
typename ConstantType>
795 STORM_LOG_ASSERT(state1 != numberOfStates && state2 != numberOfStates,
"States should not be numberOfStates.");
796 unknownStatesMap[order] = {state1, state2};
799template<
typename ValueType,
typename ConstantType>
801 if (unknownStatesMap.find(order) != unknownStatesMap.end()) {
802 return unknownStatesMap.at(order);
804 return {numberOfStates, numberOfStates};
807template<
typename ValueType,
typename ConstantType>
809 STORM_LOG_ASSERT(unknownStatesMap.find(orderCopy) == unknownStatesMap.end(),
"OrderCopy already in unknownStatesMap.");
810 unknownStatesMap.insert({orderCopy, {unknownStatesMap[orderOriginal].first, unknownStatesMap[orderOriginal].second}});
813template<
typename ValueType,
typename ConstantType>
815 usePLA[orderCopy] = usePLA[orderOriginal];
816 if (usePLA[orderCopy]) {
817 minValues[orderCopy] = minValues[orderOriginal];
818 STORM_LOG_ASSERT(maxValues.find(orderOriginal) != maxValues.end(),
"MaxValues missing for orderOriginal.");
819 maxValues[orderCopy] = maxValues[orderOriginal];
821 continueExtending[orderCopy] = continueExtending[orderOriginal];
824template<
typename ValueType,
typename ConstantType>
825std::pair<uint_fast64_t, bool> OrderExtender<ValueType, ConstantType>::getNextState(std::shared_ptr<Order> order, uint_fast64_t currentState,
bool done) {
826 if (done && currentState != numberOfStates) {
827 order->setDoneState(currentState);
829 if (cyclic && order->existsStateToHandle()) {
830 return order->getStateToHandle();
832 if (currentState == numberOfStates) {
833 return order->getNextStateNumber();
835 if (currentState != numberOfStates) {
836 return order->getNextStateNumber();
838 return {numberOfStates,
true};
841template<
typename ValueType,
typename ConstantType>
843 STORM_LOG_ASSERT(unknownStatesMap.find(order) != unknownStatesMap.end(),
"Order not in unknownStatesMap.");
844 STORM_LOG_ASSERT(!order->getDoneBuilding(),
"Order building unexpectedly done.");
846 bool yesThereIsHope = continueExtending[order];
847 return yesThereIsHope;
849template<
typename ValueType,
typename ConstantType>
851 return monotonicityChecker;
853template<
typename ValueType,
typename ConstantType>
854const std::vector<std::set<typename OrderExtender<ValueType, ConstantType>::VariableType>>&
856 return occuringVariablesAtState;
void copyMinMax(std::shared_ptr< Order > orderOriginal, std::shared_ptr< Order > orderCopy)
void setMaxValuesInit(std::vector< ConstantType > &&minValues)
std::vector< std::set< VariableType > > const & getVariablesOccuringAtState()
std::pair< uint_fast64_t, uint_fast64_t > getUnknownStates(std::shared_ptr< Order > order) const
void setMaxValues(std::shared_ptr< Order > order, std::vector< ConstantType > &&maxValues)
std::tuple< std::shared_ptr< Order >, uint_fast64_t, uint_fast64_t > extendOrder(std::shared_ptr< Order > order, storm::storage::ParameterRegion< ValueType > region, std::shared_ptr< MonotonicityResult< VariableType > > monRes=nullptr, std::shared_ptr< expressions::BinaryRelationExpression > assumption=nullptr)
Extends the order for the given region.
MonotonicityChecker< ValueType > & getMonotoncityChecker()
void setMinValues(std::shared_ptr< Order > order, std::vector< ConstantType > &&minValues)
void setMinValuesInit(std::vector< ConstantType > &&minValues)
void setUnknownStates(std::shared_ptr< Order > order, uint_fast64_t state1, uint_fast64_t state2)
OrderExtender(std::shared_ptr< models::sparse::Model< ValueType > > model, std::shared_ptr< logic::Formula const > formula)
Constructs a new OrderExtender.
utility::parametric::VariableType< ValueType >::type VariableType
std::tuple< std::shared_ptr< Order >, uint_fast64_t, uint_fast64_t > toOrder(storage::ParameterRegion< ValueType > region, std::shared_ptr< MonotonicityResult< VariableType > > monRes=nullptr)
Creates an order based on the given formula.
void setMinMaxValues(std::shared_ptr< Order > order, std::vector< ConstantType > &&minValues, std::vector< ConstantType > &&maxValues)
void checkParOnStateMonRes(uint_fast64_t s, std::shared_ptr< Order > order, typename OrderExtender< ValueType, ConstantType >::VariableType param, std::shared_ptr< MonotonicityResult< VariableType > > monResult)
void initializeMinMaxValues(storage::ParameterRegion< ValueType > region)
bool isHope(std::shared_ptr< Order > order)
NodeComparison
Constants for comparison of nodes/states.
std::string const & getName() const
Retrieves the name of the variable.
vector_type const & getValueVector() const
virtual bool canHandle(std::shared_ptr< storm::models::ModelBase > parametricModel, CheckTask< storm::logic::Formula, ParametricType > const &checkTask) const override
virtual void specify(Environment const &env, std::shared_ptr< storm::models::ModelBase > parametricModel, CheckTask< storm::logic::Formula, ParametricType > const &checkTask, std::optional< RegionSplitEstimateKind > generateRegionSplitEstimates=std::nullopt, std::shared_ptr< MonotonicityBackend< ParametricType > > monotonicityBackend={}, bool allowModelSimplifications=true, bool graphPreserving=true) override
std::unique_ptr< CheckResult > check(Environment const &env, AnnotatedRegion< ParametricType > ®ion, storm::solver::OptimizationDirection const &dirForParameters)
Checks the specified formula on the given region by applying parameter lifting (Parameter choices are...
Base class for all sparse models.
A bit vector that is internally represented as a vector of 64-bit values.
void set(uint64_t index, bool value=true)
Sets the given truth value at the given index.
size_t size() const
Retrieves the number of bits this bit vector can store.
A class that holds a possibly non-square matrix in the compressed row storage format.
This class represents the decomposition of a graph-like structure into its strongly connected compone...
#define STORM_LOG_INFO(message)
#define STORM_LOG_ASSERT(cond, message)
#define STORM_LOG_THROW(cond, exception, message)
std::pair< storm::storage::BitVector, storm::storage::BitVector > performProb01(storm::models::sparse::DeterministicModel< T > const &model, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates)
Computes the sets of states that have probability 0 or 1, respectively, of satisfying phi until psi i...
std::vector< uint_fast64_t > getTopologicalSort(storm::storage::SparseMatrix< T > const &matrix, std::vector< uint64_t > const &firstStates)
Performs a topological sort of the states of the system according to the given transitions.
bool hasCycle(storm::storage::SparseMatrix< T > const &transitionMatrix, boost::optional< storm::storage::BitVector > const &subsystem)
Returns true if the graph represented by the given matrix has a cycle.
void gatherOccurringVariables(FunctionType const &function, std::set< typename VariableType< FunctionType >::type > &variableSet)
Add all variables that occur in the given function to the the given set.
Nodes of the Reachability Order.
StronglyConnectedComponentDecompositionOptions & forceTopologicalSort(bool value=true)
Enforces that the returned SCCs are sorted in a topological order.