14#include <unordered_map>
37namespace transformer {
42 auto multivariatePol = carl::MultivariatePolynomial<RationalFunctionCoefficient>(uniPoly);
48 if (lhs.degree() != rhs.degree()) {
49 return lhs.degree() < rhs.degree();
52 for (uint64_t i = 0; i < lhs.coefficients().size(); i++) {
53 if (lhs.coefficients()[i] != rhs.coefficients()[i]) {
54 return lhs.coefficients()[i] < rhs.coefficients()[i];
62 auto& container = (*this)[p];
64 auto it = container.first.find(f);
65 if (it != container.first.end()) {
70 uint64_t newIndex = container.second.size();
71 container.first[f] = newIndex;
72 container.second.push_back(f);
79 auto key = std::make_pair(factorization, p);
80 if (localCache.count(key)) {
81 return localCache.at(key);
84 polynomial = polynomial.one();
85 for (uint64_t i = 0; i < factorization.size(); i++) {
86 for (uint64_t j = 0; j < factorization[i]; j++) {
87 polynomial *= this->at(p).second[i];
90 localCache.emplace(key, polynomial);
95 : parameter(parameter), polynomialCache(polynomialCache) {
100 STORM_LOG_ASSERT(other.parameter == this->parameter,
"Can only add annotations with equal parameters.");
101 for (
auto const& [factors, number] : other) {
102 if (this->count(factors)) {
103 this->at(factors) += number;
105 this->emplace(factors, number);
111 for (
auto& [factors, number] : *
this) {
119 return annotationCopy;
123 for (
auto const& [info, constant] : other) {
124 if (!this->count(info)) {
125 this->emplace(info, utility::zero<RationalFunctionCoefficient>());
127 this->at(info) += constant * timesConstant;
132 for (
auto const& [info, constant] : other) {
134 auto newCounter = info;
137 auto const cacheNum = this->polynomialCache->lookUpInCache(polynomial, parameter);
138 while (newCounter.size() <= cacheNum) {
139 newCounter.push_back(0);
141 newCounter[cacheNum]++;
143 if (!this->count(newCounter)) {
144 this->emplace(newCounter, constant);
146 this->at(newCounter) += constant;
152 for (
auto const& [info1, constant1] : anno1) {
153 for (
auto const& [info2, constant2] : anno2) {
154 std::vector<uint64_t> newCounter(std::max(info1.size(), info2.size()), 0);
156 for (uint64_t i = 0; i < newCounter.size(); i++) {
157 if (i < info1.size()) {
158 newCounter[i] += info1[i];
160 if (i < info2.size()) {
161 newCounter[i] += info2[i];
165 if (!this->count(newCounter)) {
166 this->emplace(newCounter, constant1 * constant2);
168 this->at(newCounter) += constant1 * constant2;
176 for (
auto const& [info, constant] : *
this) {
177 prob += polynomialCache->polynomialFromFactorization(info, parameter) * constant;
183 std::vector<UniPoly> terms;
184 for (
auto const& [info, constant] : *
this) {
185 terms.push_back(polynomialCache->polynomialFromFactorization(info, parameter) * constant);
191 if (!derivativeOfThis) {
192 return evaluate<Interval>(input);
194 Interval boundDerivative = derivativeOfThis->evaluateOnIntervalMidpointTheorem(input, higherOrderBounds);
196 double fMid = evaluate<double>(input.center());
197 double fMin = fMid - (input.diameter() / 2) * maxSlope;
198 double fMax = fMid + (input.diameter() / 2) * maxSlope;
199 if (higherOrderBounds) {
200 Interval boundsHere = evaluate<Interval>(input);
213 if (nth == 0 || derivativeOfThis) {
216 derivativeOfThis = std::make_shared<Annotation>(this->parameter, this->polynomialCache);
217 for (
auto const& [info, constant] : *
this) {
219 for (uint64_t i = 0; i < info.size(); i++) {
224 RationalFunctionCoefficient newConstant = constant * utility::convertNumber<RationalFunctionCoefficient>(info[i]);
226 std::vector<uint64_t> insert(info);
229 while (!insert.empty() && insert.back() == 0) {
233 auto polynomial = polynomialCache->at(parameter).second.at(i);
238 uint64_t derivativeIndex = this->polynomialCache->lookUpInCache(
derivative, parameter);
239 while (insert.size() < derivativeIndex) {
242 insert[derivativeIndex]++;
244 if (derivativeOfThis->count(insert)) {
245 derivativeOfThis->at(insert) += newConstant;
247 derivativeOfThis->emplace(insert, newConstant);
251 derivativeOfThis->computeDerivative(nth - 1);
256 for (
auto const& [info, constant] : *
this) {
266 return derivativeOfThis;
270std::ostream& operator<<(std::ostream& os,
const Annotation& annotation) {
271 auto iterator = annotation.begin();
272 while (iterator != annotation.end()) {
273 auto const& factors = iterator->first;
274 auto const& constant = iterator->second;
275 os << constant <<
" * (";
276 bool alreadyPrintedFactor =
false;
277 for (uint64_t i = 0; i < factors.size(); i++) {
278 if (factors[i] > 0) {
279 if (alreadyPrintedFactor) {
282 alreadyPrintedFactor =
true;
284 os <<
"(" << annotation.polynomialCache->at(annotation.parameter).second[i] <<
")" <<
"^" << factors[i];
287 if (factors.empty()) {
292 if (iterator != annotation.end()) {
299std::pair<std::map<uint64_t, std::set<uint64_t>>, std::set<uint64_t>>
findSubgraph(
302 const boost::optional<std::vector<RationalFunction>>& stateRewardVector,
const RationalFunctionVariable parameter) {
303 std::map<uint64_t, std::set<uint64_t>> subgraph;
304 std::set<uint64_t> bottomStates;
306 std::set<uint64_t> acyclicStates;
308 std::vector<uint64_t> dfsStack = {root};
309 while (!dfsStack.empty()) {
310 uint64_t state = dfsStack.back();
312 if (!subgraph.count(state)) {
313 subgraph[state] = {};
315 std::vector<uint64_t> tmpStack;
316 bool isAcyclic =
true;
319 for (
auto const& entry : transitionMatrix.
getRow(state)) {
321 if (subgraph.count(entry.getColumn()) && !acyclicStates.count(entry.getColumn()) && !bottomStates.count(entry.getColumn())) {
330 bottomStates.emplace(state);
334 for (
auto const& entry : transitionMatrix.
getRow(state)) {
337 (entry.getValue().gatherVariables().size() == 1 && *entry.getValue().gatherVariables().begin() == parameter),
338 "Called findSubgraph with incorrect parameter.");
340 subgraph.at(state).emplace(entry.getColumn());
342 if (!subgraph.count(entry.getColumn())) {
343 bool continueSearching = treeStates.at(parameter).count(entry.getColumn()) && !treeStates.at(parameter).at(entry.getColumn()).empty();
345 if (!entry.getValue().isConstant()) {
348 continueSearching &= entry.getValue().gatherVariables().size() == 1 && *entry.getValue().gatherVariables().begin() == parameter;
353 bool onlyHasOne = transitionMatrix.
getRow(entry.getColumn()).size() == 1 &&
354 transitionMatrix.
getRow(entry.getColumn()).begin()->getValue() == utility::one<RationalFunction>();
355 continueSearching |= onlyHasOne;
358 continueSearching &= !(stateRewardVector && !stateRewardVector->at(entry.getColumn()).isZero());
360 if (continueSearching) {
363 tmpStack.push_back(entry.getColumn());
366 subgraph[entry.getColumn()] = {};
367 bottomStates.emplace(entry.getColumn());
369 acyclicStates.emplace(entry.getColumn());
375 for (
auto const& entry : tmpStack) {
376 dfsStack.push_back(entry);
380 acyclicStates.emplace(state);
384 return std::make_pair(subgraph, bottomStates);
387std::pair<models::sparse::Dtmc<RationalFunction>, std::map<UniPoly, Annotation>>
BigStep::bigStep(
400 std::set<std::string> labelsInFormula;
401 for (
auto const& atomicLabelFormula : checkTask.
getFormula().getAtomicLabelFormulas()) {
402 labelsInFormula.emplace(atomicLabelFormula->getLabel());
407 for (
auto const& label : labelsInFormula) {
412 boost::optional<std::vector<RationalFunction>> stateRewardVector;
413 boost::optional<std::string> stateRewardName;
414 if (checkTask.
getFormula().isRewardOperatorFormula()) {
421 stateRewardVector = dtmc.
getRewardModel(
"").getStateRewardVector();
426 auto topologicalOrdering = utility::graph::getTopologicalSort<RationalFunction>(transitionMatrix, {initialState});
433 std::map<RationalFunctionVariable, std::map<uint64_t, std::set<uint64_t>>> treeStates;
435 std::map<RationalFunctionVariable, std::set<uint64_t>> treeStatesNeedUpdate;
438 for (uint64_t row = 0; row < flexibleMatrix.getRowCount(); row++) {
439 for (
auto const& entry : flexibleMatrix.getRow(row)) {
440 if (!entry.getValue().isConstant()) {
441 if (!this->rawPolynomialCache) {
443 this->rawPolynomialCache = entry.getValue().nominator().pCache();
445 for (
auto const& parameter : entry.getValue().gatherVariables()) {
446 treeStatesNeedUpdate[parameter].emplace(row);
447 treeStates[parameter][row].emplace(row);
452 updateTreeStates(treeStates, treeStatesNeedUpdate, flexibleMatrix, backwardsTransitions, allParameters, stateRewardVector, runningLabelingTreeStates);
456 std::map<RationalFunctionVariable, std::set<std::set<uint64_t>>> alreadyTimeTravelledToThis;
459 std::stack<uint64_t> topologicalOrderingStack;
460 topologicalOrdering = utility::graph::getTopologicalSort<RationalFunction>(transitionMatrix, {initialState});
461 for (
auto rit = topologicalOrdering.begin(); rit != topologicalOrdering.end(); ++rit) {
462 topologicalOrderingStack.push(*rit);
469 initialStates.
set(initialState,
true);
475 std::map<UniPoly, Annotation> storedAnnotations;
477 std::map<RationalFunctionVariable, std::set<uint64_t>> bottomStatesSeen;
480 uint64_t writeDtmcCounter = 0;
483 while (!topologicalOrderingStack.empty()) {
484 auto state = topologicalOrderingStack.top();
485 topologicalOrderingStack.pop();
487 if (!reachableStates.
get(state)) {
491 std::set<RationalFunctionVariable> parametersInState;
492 for (
auto const& entry : flexibleMatrix.getRow(state)) {
493 for (
auto const& parameter : entry.getValue().gatherVariables()) {
494 parametersInState.emplace(parameter);
498 std::set<RationalFunctionVariable> bigStepParameters;
499 for (
auto const& parameter : allParameters) {
500 if (treeStates[parameter].count(state)) {
502 if (treeStates.at(parameter).at(state).size() > 1) {
503 bigStepParameters.emplace(parameter);
507 if (parametersInState.count(parameter)) {
508 for (
auto const& treeState : treeStates[parameter][state]) {
509 for (
auto const& successor : flexibleMatrix.getRow(treeState)) {
510 if (treeStates[parameter].count(successor.getColumn())) {
511 bigStepParameters.emplace(parameter);
522 for (
auto const& parameter : bigStepParameters) {
524 auto const [bottomAnnotations, visitedStatesAndSubtree] =
525 bigStepBFS(state, parameter, flexibleMatrix, backwardsTransitions, treeStates, stateRewardVector, storedAnnotations);
526 auto const [visitedStates, subtree] = visitedStatesAndSubtree;
531 bool existsEliminableState =
false;
532 for (
auto const& s : visitedStates) {
533 bool allPredecessorsInVisitedStates =
true;
534 for (
auto const& predecessor : backwardsTransitions.getRow(s)) {
535 if (predecessor.getValue().isZero()) {
538 if (!reachableStates.
get(predecessor.getColumn())) {
543 if (!subtree.count(predecessor.getColumn()) || !subtree.at(predecessor.getColumn()).count(s)) {
544 allPredecessorsInVisitedStates =
false;
548 if (allPredecessorsInVisitedStates) {
549 existsEliminableState =
true;
554 if (!existsEliminableState) {
562 uint64_t oldMatrixSize = flexibleMatrix.getRowCount();
564 std::vector<std::pair<uint64_t, Annotation>> transitions = findBigStep(bottomAnnotations, parameter, flexibleMatrix, backwardsTransitions,
565 alreadyTimeTravelledToThis, treeStatesNeedUpdate, state, originalNumStates);
568 auto newStoredAnnotations =
569 replaceWithNewTransitions(state, transitions, flexibleMatrix, backwardsTransitions, reachableStates, treeStatesNeedUpdate);
570 for (
auto const& entry : newStoredAnnotations) {
571 storedAnnotations.emplace(entry);
575 updateUnreachableStates(reachableStates, visitedStates, backwardsTransitions, initialState);
577 uint64_t newMatrixSize = flexibleMatrix.getRowCount();
578 if (newMatrixSize > oldMatrixSize) {
580 runningLabeling = extendStateLabeling(runningLabeling, oldMatrixSize, newMatrixSize, state, labelsInFormula);
581 runningLabelingTreeStates = extendStateLabeling(runningLabelingTreeStates, oldMatrixSize, newMatrixSize, state, labelsInFormula);
584 reachableStates.
resize(newMatrixSize,
true);
586 for (uint64_t i = oldMatrixSize; i < newMatrixSize; i++) {
587 topologicalOrderingStack.push(i);
588 for (
auto& [_parameter, updateStates] : treeStatesNeedUpdate) {
589 updateStates.emplace(i);
592 if (stateRewardVector) {
593 stateRewardVector->push_back(storm::utility::zero<RationalFunction>());
596 updateTreeStates(treeStates, treeStatesNeedUpdate, flexibleMatrix, backwardsTransitions, allParameters, stateRewardVector,
597 runningLabelingTreeStates);
606 if (stateRewardVector) {
611 storm::io::openFile(
"dots/travel_" + std::to_string(flexibleMatrix.getRowCount()) +
".dot", file2);
617 transitionMatrix = flexibleMatrix.createSparseMatrix();
624 initialStates.
set(initialState,
true);
627 transitionMatrix = transitionMatrix.
getSubmatrix(
false, reachableStates, reachableStates);
628 runningLabeling = runningLabeling.
getSubLabeling(reachableStates);
629 uint_fast64_t newInitialState = 0;
630 for (uint_fast64_t i = 0; i < initialState; i++) {
631 if (reachableStates.
get(i)) {
635 initialState = newInitialState;
636 if (stateRewardVector) {
637 std::vector<RationalFunction> newStateRewardVector;
638 for (uint_fast64_t i = 0; i < stateRewardVector->size(); i++) {
639 if (reachableStates.
get(i)) {
640 newStateRewardVector.push_back(stateRewardVector->at(i));
645 stateRewardVector = newStateRewardVector;
652 newInitialStates.
set(initialState,
true);
655 if (stateRewardVector) {
661 "Internal error: resulting matrix not probabilistic!");
664 for (
auto const& entry : storedAnnotations) {
668 return std::make_pair(newDTMC, storedAnnotations);
671std::pair<std::map<uint64_t, Annotation>, std::pair<std::vector<uint64_t>, std::map<uint64_t, std::set<uint64_t>>>> BigStep::bigStepBFS(
675 const boost::optional<std::vector<RationalFunction>>& stateRewardVector,
const std::map<UniPoly, Annotation>& storedAnnotations) {
677 auto const [subtree, bottomStates] =
findSubgraph(flexibleMatrix, start, treeStates, stateRewardVector, parameter);
680 std::vector<uint64_t> visitedStatesInBFSOrder;
682 std::set<std::pair<uint64_t, uint64_t>> visitedEdges;
685 std::map<uint64_t, Annotation> annotations;
688 std::queue<uint64_t> activeStates;
689 activeStates.push(start);
691 annotations.emplace(start,
Annotation(parameter, polynomialCache));
693 annotations.at(start)[std::vector<uint64_t>()] = utility::one<RationalFunctionCoefficient>();
695 while (!activeStates.empty()) {
696 auto const& state = activeStates.front();
698 visitedStatesInBFSOrder.push_back(state);
699 for (
auto const& entry : flexibleMatrix.getRow(state)) {
700 auto const goToState = entry.getColumn();
701 if (!subtree.count(goToState) || !subtree.at(state).count(goToState)) {
704 visitedEdges.emplace(std::make_pair(state, goToState));
706 bool allBackwardsStatesVisited =
true;
707 for (
auto const& backwardsEntry : backwardsFlexibleMatrix.getRow(goToState)) {
708 if (!subtree.count(backwardsEntry.getColumn()) || !subtree.at(backwardsEntry.getColumn()).count(goToState)) {
714 if (!visitedEdges.count(std::make_pair(backwardsEntry.getColumn(), goToState))) {
715 allBackwardsStatesVisited =
false;
719 if (!allBackwardsStatesVisited) {
724 annotations.emplace(goToState, Annotation(parameter, polynomialCache));
727 for (
auto const& backwardsEntry : backwardsFlexibleMatrix.getRow(goToState)) {
728 if (!subtree.count(backwardsEntry.getColumn()) || !subtree.at(backwardsEntry.getColumn()).count(goToState)) {
734 auto const transition = backwardsEntry.getValue();
739 auto& targetAnnotation = annotations.at(goToState);
745 if (transition.isConstant()) {
747 targetAnnotation.addAnnotationTimesConstant(annotations.at(backwardsEntry.getColumn()), transition.constantPart());
751 STORM_LOG_ERROR_COND(transition.denominator().isConstant(),
"Only transitions with constant denominator supported but this has "
752 << transition.denominator() <<
" in transition " << transition);
753 auto nominator = transition.nominator();
754 UniPoly nominatorAsUnivariate = transition.nominator().toUnivariatePolynomial();
756 nominatorAsUnivariate /= transition.denominator().coefficient();
757 if (storedAnnotations.count(nominatorAsUnivariate)) {
758 targetAnnotation.addAnnotationTimesAnnotation(annotations.at(backwardsEntry.getColumn()), storedAnnotations.at(nominatorAsUnivariate));
760 targetAnnotation.addAnnotationTimesPolynomial(annotations.at(backwardsEntry.getColumn()), std::move(nominatorAsUnivariate));
765 bool allForwardEdgesVisited =
true;
766 for (
auto const& entry : flexibleMatrix.getRow(backwardsEntry.getColumn())) {
767 if (!subtree.at(backwardsEntry.getColumn()).count(entry.getColumn())) {
773 if (!annotations.count(entry.getColumn())) {
774 allForwardEdgesVisited =
false;
778 if (allForwardEdgesVisited) {
779 annotations.erase(backwardsEntry.getColumn());
782 activeStates.push(goToState);
786 for (
auto const& [state, _successors] : subtree) {
791 if (!bottomStates.count(state)) {
792 annotations.erase(state);
795 return std::make_pair(annotations, std::make_pair(visitedStatesInBFSOrder, subtree));
798std::vector<std::pair<uint64_t, Annotation>> BigStep::findBigStep(
const std::map<uint64_t, Annotation> bigStepAnnotations,
800 storage::FlexibleSparseMatrix<RationalFunction>& flexibleMatrix,
801 storage::FlexibleSparseMatrix<RationalFunction>& backwardsFlexibleMatrix,
804 uint64_t originalNumStates) {
805 STORM_LOG_INFO(
"Find time travelling called with root " << root <<
" and parameter " << parameter);
808 std::map<std::vector<uint64_t>, std::map<uint64_t, RationalFunctionCoefficient>> parametricTransitions;
810 for (
auto const& [state, annotation] : bigStepAnnotations) {
811 for (
auto const& [info, constant] : annotation) {
812 if (!parametricTransitions.count(info)) {
813 parametricTransitions[info] = std::map<uint64_t, RationalFunctionCoefficient>();
815 STORM_LOG_ASSERT(!parametricTransitions.at(info).count(state),
"State already exists");
816 parametricTransitions.at(info)[state] = constant;
821 std::vector<std::pair<uint64_t, Annotation>> insertTransitions;
824 std::unordered_set<uint64_t> affectedStates;
837 std::set<std::set<uint64_t>> targetSetStates;
839 for (
auto const& [factors, transitions] : parametricTransitions) {
840 if (transitions.size() > 1) {
844 std::set<uint64_t> targetStates;
847 for (
auto const& [state, info] : transitions) {
848 affectedStates.emplace(state);
849 if (state < originalNumStates) {
850 targetStates.emplace(state);
854 if (alreadyTimeTravelledToThis[parameter].
count(targetStates)) {
855 for (
auto const& [state, probability] : transitions) {
856 Annotation newAnnotation(parameter, polynomialCache);
857 newAnnotation[factors] = probability;
859 insertTransitions.emplace_back(state, newAnnotation);
863 targetSetStates.emplace(targetStates);
865 Annotation newAnnotation(parameter, polynomialCache);
867 RationalFunctionCoefficient constantPart = utility::zero<RationalFunctionCoefficient>();
868 for (
auto const& [state, transition] : transitions) {
869 constantPart += transition;
871 newAnnotation[factors] = constantPart;
873 STORM_LOG_INFO(
"Time travellable transitions with " << newAnnotation);
876 uint64_t newRow = flexibleMatrix.insertNewRowsAtEnd(1);
877 uint64_t newRowBackwards = backwardsFlexibleMatrix.insertNewRowsAtEnd(1);
878 STORM_LOG_ASSERT(newRow == newRowBackwards,
"Internal error: Drifting matrix and backwardsTransitions.");
881 insertTransitions.emplace_back(newRow, newAnnotation);
884 for (
auto const& [state, thisProb] : transitions) {
887 flexibleMatrix.getRow(newRow).push_back(storage::MatrixEntry<uint_fast64_t, RationalFunction>(state, probAsFunction));
889 backwardsFlexibleMatrix.getRow(state).push_back(storage::MatrixEntry<uint_fast64_t, RationalFunction>(newRow, probAsFunction));
891 for (
auto& entry : treeStatesNeedUpdate) {
892 entry.second.emplace(state);
896 backwardsFlexibleMatrix.getRow(state) = joinDuplicateTransitions(backwardsFlexibleMatrix.getRow(state));
899 flexibleMatrix.getRow(newRow) = joinDuplicateTransitions(flexibleMatrix.getRow(newRow));
901 auto const [state, probability] = *transitions.begin();
903 Annotation newAnnotation(parameter, polynomialCache);
904 newAnnotation[factors] = probability;
906 insertTransitions.emplace_back(state, newAnnotation);
911 for (
auto const& targetSet : targetSetStates) {
912 alreadyTimeTravelledToThis[parameter].emplace(targetSet);
915 return insertTransitions;
918std::map<UniPoly, Annotation> BigStep::replaceWithNewTransitions(uint64_t state,
const std::vector<std::pair<uint64_t, Annotation>> transitions,
919 storage::FlexibleSparseMatrix<RationalFunction>& flexibleMatrix,
920 storage::FlexibleSparseMatrix<RationalFunction>& backwardsFlexibleMatrix,
921 storage::BitVector& reachableStates,
923 std::map<UniPoly, Annotation> storedAnnotations;
927 for (
auto const& deletingTransition : flexibleMatrix.getRow(state)) {
928 auto& row = backwardsFlexibleMatrix.getRow(deletingTransition.getColumn());
929 auto it = row.begin();
930 while (it != row.end()) {
931 if (it->getColumn() == state) {
939 flexibleMatrix.getRow(state) = std::vector<storage::MatrixEntry<uint_fast64_t, RationalFunction>>();
943 std::map<uint64_t, Annotation> insertThese;
944 for (
auto const& [target, probability] : transitions) {
945 for (
auto& entry : treeStatesNeedUpdate) {
946 entry.second.emplace(target);
948 if (insertThese.count(target)) {
949 insertThese.at(target) += probability;
951 insertThese.emplace(target, probability);
954 for (
auto const& [state2, annotation] : insertThese) {
955 auto uniProbability = annotation.getProbability();
956 storedAnnotations.emplace(uniProbability, std::move(annotation));
964 return storedAnnotations;
967void BigStep::updateUnreachableStates(storage::BitVector& reachableStates, std::vector<uint64_t>
const& statesMaybeUnreachable,
968 storage::FlexibleSparseMatrix<RationalFunction>
const& backwardsFlexibleMatrix, uint64_t initialState) {
969 if (backwardsFlexibleMatrix.getRowCount() > reachableStates.size()) {
970 reachableStates.resize(backwardsFlexibleMatrix.getRowCount(),
true);
974 for (
auto const& visitedState : statesMaybeUnreachable) {
975 if (visitedState == initialState) {
978 bool isUnreachable =
true;
979 for (
auto const& entry : backwardsFlexibleMatrix.getRow(visitedState)) {
980 if (reachableStates.get(entry.getColumn())) {
981 isUnreachable =
false;
986 reachableStates.set(visitedState,
false);
991std::vector<storm::storage::MatrixEntry<uint64_t, RationalFunction>> BigStep::joinDuplicateTransitions(
993 std::vector<uint64_t> keyOrder;
994 std::map<uint64_t, storm::storage::MatrixEntry<uint64_t, RationalFunction>> existingEntries;
995 for (
auto const& entry : entries) {
996 if (existingEntries.count(entry.getColumn())) {
997 existingEntries.at(entry.getColumn()).setValue(existingEntries.at(entry.getColumn()).getValue() + entry.getValue());
999 existingEntries[entry.getColumn()] = entry;
1000 keyOrder.push_back(entry.getColumn());
1003 std::vector<storm::storage::MatrixEntry<uint64_t, RationalFunction>> newEntries;
1004 for (uint64_t key : keyOrder) {
1005 newEntries.push_back(existingEntries.at(key));
1010models::sparse::StateLabeling BigStep::extendStateLabeling(models::sparse::StateLabeling
const& oldLabeling, uint64_t oldSize, uint64_t newSize,
1011 uint64_t stateWithLabels,
const std::set<std::string>& labelsInFormula) {
1012 models::sparse::StateLabeling newLabels(newSize);
1013 for (
auto const& label : oldLabeling.getLabels()) {
1014 newLabels.addLabel(label);
1016 for (uint64_t state = 0; state < oldSize; state++) {
1017 for (
auto const& label : oldLabeling.getLabelsOfState(state)) {
1018 newLabels.addLabelToState(label, state);
1021 for (uint64_t i = oldSize;
i < newSize;
i++) {
1023 for (
auto const& label : oldLabeling.getLabelsOfState(stateWithLabels)) {
1024 if (labelsInFormula.count(label)) {
1025 newLabels.addLabelToState(label, i);
1032void BigStep::updateTreeStates(std::map<
RationalFunctionVariable, std::map<uint64_t, std::set<uint64_t>>>& treeStates,
1034 const storage::FlexibleSparseMatrix<RationalFunction>& flexibleMatrix,
1035 const storage::FlexibleSparseMatrix<RationalFunction>& backwardsTransitions,
1036 const std::set<RationalFunctionVariable>& allParameters,
const boost::optional<std::vector<RationalFunction>>& stateRewardVector,
1037 const models::sparse::StateLabeling stateLabeling) {
1038 for (
auto const& parameter : allParameters) {
1039 std::set<uint64_t>& workingSet = workingSets[parameter];
1040 while (!workingSet.empty()) {
1041 std::set<uint64_t> newWorkingSet;
1042 for (uint64_t row : workingSet) {
1043 if (stateRewardVector && !stateRewardVector->at(row).isZero()) {
1046 for (
auto const& entry : backwardsTransitions.getRow(row)) {
1047 if (entry.getValue().isConstant()) {
1050 bool isSubset =
true;
1051 for (
auto const& state : treeStates.at(parameter)[row]) {
1052 if (!treeStates.at(parameter)[entry.getColumn()].count(state)) {
1060 for (
auto const& state : treeStates.at(parameter).at(row)) {
1061 treeStates.at(parameter).at(entry.getColumn()).emplace(state);
1063 if (stateLabeling.getLabelsOfState(entry.getColumn()) == stateLabeling.getLabelsOfState(row)) {
1064 newWorkingSet.emplace(entry.getColumn());
1069 workingSet = newWorkingSet;
bool isRewardModelSet() const
Retrieves whether a reward model was set.
std::string const & getRewardModel() const
Retrieves the reward model over which to perform the checking (if set).
FormulaType const & getFormula() const
Retrieves the formula from this task.
virtual void writeDotToStream(std::ostream &outStream, size_t maxWidthLabel=30, bool includeLabeling=true, storm::storage::BitVector const *subsystem=nullptr, std::vector< ValueType > const *firstValue=nullptr, std::vector< ValueType > const *secondValue=nullptr, std::vector< uint_fast64_t > const *stateColoring=nullptr, std::vector< std::string > const *colors=nullptr, std::vector< uint_fast64_t > *scheduler=nullptr, bool finalizeOutput=true) const override
This class represents a discrete-time Markov chain.
virtual void reduceToStateBasedRewards() override
Converts the transition rewards of all reward models to state-based rewards.
void removeLabel(std::string const &label)
Removes a label from the labelings.
storm::storage::SparseMatrix< ValueType > const & getTransitionMatrix() const
Retrieves the matrix representing the transitions of the model.
void setInitialStates(storm::storage::BitVector const &states)
Overwrites the initial states of the model.
void addRewardModel(std::string const &rewardModelName, RewardModelType const &rewModel)
Adds a reward model to the model.
storm::models::sparse::StateLabeling const & getStateLabeling() const
Returns the state labeling associated with this model.
virtual uint_fast64_t getNumberOfStates() const override
Returns the number of states of the model.
RewardModelType const & getRewardModel(std::string const &rewardModelName) const
Retrieves the reward model with the given name, if one exists.
virtual std::string const & getUniqueRewardModelName() const override
Retrieves the name of the unique reward model, if there exists exactly one.
storm::storage::BitVector const & getInitialStates() const
Retrieves the initial states of the model.
This class manages the labeling of the state space with a number of (atomic) labels.
StateLabeling getSubLabeling(storm::storage::BitVector const &states) const
Retrieves the sub labeling that represents the same labeling as the current one for all selected stat...
A bit vector that is internally represented as a vector of 64-bit values.
uint64_t getNextSetIndex(uint64_t startingIndex) const
Retrieves the index of the bit that is the next bit set to true in the bit vector.
void set(uint64_t index, bool value=true)
Sets the given truth value at the given index.
void resize(uint64_t newLength, bool init=false)
Resizes the bit vector to hold the given new number of bits.
bool get(uint64_t index) const
Retrieves the truth value of the bit at the given index and performs a bound check.
The flexible sparse matrix is used during state elimination.
row_type & getRow(index_type)
Returns an object representing the given row.
A class that holds a possibly non-square matrix in the compressed row storage format.
bool isProbabilistic(ValueType const &tolerance) const
Checks for each row whether it sums to one.
SparseMatrix getSubmatrix(bool useGroups, storm::storage::BitVector const &rowConstraint, storm::storage::BitVector const &columnConstraint, bool insertDiagonalEntries=false, storm::storage::BitVector const &makeZeroColumns=storm::storage::BitVector()) const
Creates a submatrix of the current matrix by dropping all rows and columns whose bits are not set to ...
storm::storage::SparseMatrix< value_type > transpose(bool joinGroups=false, bool keepZeros=false) const
Transposes the matrix.
index_type getRowCount() const
Returns the number of rows of the matrix.
#define STORM_LOG_INFO(message)
#define STORM_LOG_ASSERT(cond, message)
#define STORM_LOG_ERROR_COND(cond, message)
void closeFile(std::ofstream &stream)
Close the given file after writing.
void openFile(std::string const &filepath, std::ofstream &filestream, bool append=false, bool silent=false)
Open the given file for writing.
std::set< storm::RationalFunctionVariable > getAllParameters(Model< storm::RationalFunction > const &model)
Get all parameters (probability, rewards, and rates) occurring in the model.
std::pair< storm::RationalNumber, storm::RationalNumber > count(std::vector< storm::storage::BitVector > const &origSets, std::vector< storm::storage::BitVector > const &intersects, std::vector< storm::storage::BitVector > const &intersectsInfo, storm::RationalNumber val, bool plus, uint64_t remdepth)
storm::storage::BitVector getReachableStates(storm::storage::SparseMatrix< T > const &transitionMatrix, storm::storage::BitVector const &initialStates, storm::storage::BitVector const &constraintStates, storm::storage::BitVector const &targetStates, bool useStepBound, uint_fast64_t maximalSteps, boost::optional< storm::storage::BitVector > const &choiceFilter)
Performs a forward depth-first search through the underlying graph structure to identify the states t...
ValueType max(ValueType const &first, ValueType const &second)
ValueType min(ValueType const &first, ValueType const &second)
bool isZero(ValueType const &a)
ValueType abs(ValueType const &number)
carl::Interval< double > Interval
Interval type.
carl::Variable RationalFunctionVariable
carl::RationalFunction< Polynomial, true > RationalFunction