3#pragma clang diagnostic push
4#pragma clang diagnostic ignored "-Wcomma"
5#include <gtl/phmap.hpp>
6#pragma clang diagnostic pop
30template<storm::dd::DdType DdType>
33template<storm::dd::DdType DdType>
44 auto const& metaVariable =
ddManager->getMetaVariable(var);
68 "This version of Storm was compiled without support for CUDD. Yet, a method was called that requires this support. Please choose a "
69 "version of Storm with CUDD support.");
79 cudd::BDD(this->
internalDdManager->getCuddManager(), this->getRepresentativesRec(this->partitionBdd.getInternalBdd().getCuddDdNode(),
80 this->rowVariablesCube.getInternalBdd().getCuddDdNode()))),
84 "This version of Storm was compiled without support for CUDD. Yet, a method was called that requires this support. Please choose a "
85 "version of Storm with CUDD support.");
91 DdNodePtr getRepresentativesRec(DdNodePtr partitionNode, DdNodePtr stateVariablesCube) {
92 if (partitionNode == Cudd_ReadLogicZero(ddman)) {
97 if (visitedNodes.find(partitionNode) != visitedNodes.end()) {
98 return Cudd_ReadLogicZero(ddman);
102 if (Cudd_IsConstant(stateVariablesCube)) {
103 visitedNodes.emplace(partitionNode,
true);
104 return Cudd_ReadOne(ddman);
106 bool skipped =
false;
107 DdNodePtr elsePartitionNode;
108 DdNodePtr thenPartitionNode;
109 if (Cudd_NodeReadIndex(partitionNode) == Cudd_NodeReadIndex(stateVariablesCube)) {
110 elsePartitionNode = Cudd_E(partitionNode);
111 thenPartitionNode = Cudd_T(partitionNode);
113 if (Cudd_IsComplement(partitionNode)) {
114 elsePartitionNode = Cudd_Not(elsePartitionNode);
115 thenPartitionNode = Cudd_Not(thenPartitionNode);
118 elsePartitionNode = thenPartitionNode = partitionNode;
123 visitedNodes.emplace(partitionNode,
true);
127 DdNodePtr elseResult = getRepresentativesRec(elsePartitionNode, Cudd_T(stateVariablesCube));
128 Cudd_Ref(elseResult);
130 DdNodePtr thenResult =
nullptr;
132 thenResult = getRepresentativesRec(thenPartitionNode, Cudd_T(stateVariablesCube));
133 Cudd_Ref(thenResult);
135 if (thenResult == elseResult) {
136 Cudd_Deref(elseResult);
137 Cudd_Deref(thenResult);
140 bool complement = Cudd_IsComplement(thenResult);
141 auto result = cuddUniqueInter(ddman, Cudd_NodeReadIndex(stateVariablesCube), Cudd_Regular(thenResult),
142 complement ? Cudd_Not(elseResult) : elseResult);
143 Cudd_Deref(elseResult);
144 Cudd_Deref(thenResult);
145 return complement ? Cudd_Not(result) : result;
149 if (elseResult == Cudd_ReadLogicZero(ddman)) {
152 result = Cudd_Not(cuddUniqueInter(ddman, Cudd_NodeReadIndex(stateVariablesCube), Cudd_ReadOne(ddman), Cudd_Not(elseResult)));
154 Cudd_Deref(elseResult);
161 gtl::flat_hash_map<DdNode const*, bool> visitedNodes;
170#ifndef STORM_HAVE_SYLVAN
172 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
173 "version of Storm with Sylvan support.");
179#ifdef STORM_HAVE_SYLVAN
184 this->rowVariablesCube.getInternalBdd().getSylvanBdd().GetBDD()))),
188 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
189 "version of Storm with Sylvan support.");
194#ifdef STORM_HAVE_SYLVAN
195 BDD getRepresentativesRec(BDD partitionNode, BDD stateVariablesCube) {
196 if (partitionNode == sylvan_false) {
201 if (visitedNodes.find(partitionNode) != visitedNodes.end()) {
206 if (sylvan_isconst(stateVariablesCube)) {
207 visitedNodes.emplace(partitionNode,
true);
210 bool skipped =
false;
211 BDD elsePartitionNode;
212 BDD thenPartitionNode;
213 if (sylvan_bdd_matches_variable_index(partitionNode, sylvan_var(stateVariablesCube))) {
214 elsePartitionNode = sylvan_low(partitionNode);
215 thenPartitionNode = sylvan_high(partitionNode);
217 elsePartitionNode = thenPartitionNode = partitionNode;
222 visitedNodes.emplace(partitionNode,
true);
226 BDD elseResult = getRepresentativesRec(elsePartitionNode, sylvan_high(stateVariablesCube));
227 mtbdd_refs_push(elseResult);
231 thenResult = getRepresentativesRec(thenPartitionNode, sylvan_high(stateVariablesCube));
232 mtbdd_refs_push(thenResult);
234 if (thenResult == elseResult) {
238 auto result = sylvan_makenode(sylvan_var(stateVariablesCube), elseResult, thenResult);
244 if (elseResult == sylvan_false) {
247 result = sylvan_makenode(sylvan_var(stateVariablesCube), elseResult, sylvan_false);
255 gtl::flat_hash_map<BDD, bool> visitedNodes;
259template<storm::dd::DdType DdType,
typename ValueType,
typename ExportValueType = ValueType>
262template<storm::dd::DdType DdType,
typename ValueType,
typename ExportValueType = ValueType>
278 for (
auto const& variable :
model.getRowVariables()) {
279 auto const& ddMetaVariable = manager.getMetaVariable(variable);
280 rowVariablesCube &= ddMetaVariable.getCube();
283 for (
auto const& variable :
model.getColumnVariables()) {
284 auto const& ddMetaVariable = manager.getMetaVariable(variable);
285 columnVariablesCube &= ddMetaVariable.getCube();
288 for (
auto const& variable :
model.getNondeterminismVariables()) {
289 auto const& ddMetaVariable = manager.getMetaVariable(variable);
290 nondeterminismVariablesCube &= ddMetaVariable.getCube();
298 this->
nondeterminismOdd = (
model.getQualitativeTransitionMatrix().existsAbstract(
model.getColumnVariables()) && this->representatives).createOdd();
323 std::vector<ExportValueType> reorderedValues(valueVector.size());
324 for (uint64_t pos = 0; pos < valueVector.size(); ++pos) {
327 return reorderedValues;
338 .toVector(this->
odd);
349 std::sort(row.begin(), row.end(),
358 [
this](uint64_t first, uint64_t second) { return this->rowToState[first] < this->rowToState[second]; });
361 uint64_t rowCounter = 0;
370 builder.newRowGroup(rowCounter);
375 for (
auto const& entry : row) {
376 builder.addNextValue(rowCounter, entry.getColumn(), entry.getValue());
394 void addMatrixEntry(uint64_t row, uint64_t column, ExportValueType
const& value) {
441 std::vector<std::vector<storm::storage::MatrixEntry<uint_fast64_t, ExportValueType>>>
matrixEntries;
450template<
typename ValueType>
453#ifdef STORM_HAVE_CUDD
458 ddman(this->
manager.getInternalDdManager().getCuddManager().getManager()) {
459 this->createBlockToOffsetMapping();
467 "This version of Storm was compiled without support for CUDD. Yet, a method was called that requires this support. Please choose a "
468 "version of Storm with CUDD support.");
474#ifdef STORM_HAVE_CUDD
476 this->createMatrixEntryStorage();
477 extractTransitionMatrixRec(matrix.
getInternalAdd().getCuddDdNode(), this->isNondeterministic ? this->nondeterminismOdd : this->odd, 0,
478 this->partitionBdd.getInternalBdd().getCuddDdNode(), this->representatives.getInternalBdd().getCuddDdNode(),
479 this->allSourceVariablesCube.getInternalBdd().getCuddDdNode(),
480 this->nondeterminismVariablesCube.getInternalBdd().getCuddDdNode(), this->isNondeterministic ? &this->odd :
nullptr, 0);
481 return this->createMatrixFromEntries();
484 "This version of Storm was compiled without support for CUDD. Yet, a method was called that requires this support. Please choose a "
485 "version of Storm with CUDD support.");
491#ifdef STORM_HAVE_CUDD
493 extractVectorRec(vector.
getInternalAdd().getCuddDdNode(), this->representatives.getInternalBdd().getCuddDdNode(),
498 "This version of Storm was compiled without support for CUDD. Yet, a method was called that requires this support. Please choose a "
499 "version of Storm with CUDD support.");
502#ifdef STORM_HAVE_CUDD
503 void createBlockToOffsetMapping() {
504 this->createBlockToOffsetMappingRec(this->partitionBdd.
getInternalBdd().getCuddDdNode(), this->representatives.getInternalBdd().getCuddDdNode(),
505 this->rowVariablesCube.getInternalBdd().getCuddDdNode(), this->odd, 0);
507 "Mismatching block-to-offset mapping: " << blockToOffset.size() <<
" vs. " << this->numberOfBlocks <<
".");
510 void createBlockToOffsetMappingRec(DdNodePtr partitionNode, DdNodePtr representativesNode, DdNodePtr variables,
storm::dd::Odd const& odd,
512 STORM_LOG_ASSERT(partitionNode != Cudd_ReadLogicZero(ddman) || representativesNode == Cudd_ReadLogicZero(ddman),
513 "Expected representative to be zero if the partition is zero.");
514 if (representativesNode == Cudd_ReadLogicZero(ddman) || partitionNode == Cudd_ReadLogicZero(ddman)) {
518 if (Cudd_IsConstant(variables)) {
520 STORM_LOG_ASSERT(blockToOffset.find(partitionNode) == blockToOffset.end(),
"Duplicate entry.");
521 blockToOffset[partitionNode] = offset;
524 DdNodePtr partitionT;
525 DdNodePtr partitionE;
526 if (Cudd_NodeReadIndex(partitionNode) == Cudd_NodeReadIndex(variables)) {
527 partitionT = Cudd_T(partitionNode);
528 partitionE = Cudd_E(partitionNode);
530 if (Cudd_IsComplement(partitionNode)) {
531 partitionE = Cudd_Not(partitionE);
532 partitionT = Cudd_Not(partitionT);
535 partitionT = partitionE = partitionNode;
538 DdNodePtr representativesT;
539 DdNodePtr representativesE;
540 if (Cudd_NodeReadIndex(representativesNode) == Cudd_NodeReadIndex(variables)) {
541 representativesT = Cudd_T(representativesNode);
542 representativesE = Cudd_E(representativesNode);
544 if (Cudd_IsComplement(representativesNode)) {
545 representativesE = Cudd_Not(representativesE);
546 representativesT = Cudd_Not(representativesT);
549 representativesT = representativesE = representativesNode;
552 createBlockToOffsetMappingRec(partitionE, representativesE, Cudd_T(variables), odd.
getElseSuccessor(), offset);
557 void extractVectorRec(DdNodePtr vector, DdNodePtr representativesNode, DdNodePtr variables, storm::dd::Odd
const& odd, uint64_t offset,
558 std::vector<ValueType>& result) {
559 if (representativesNode == Cudd_ReadLogicZero(ddman) || vector == Cudd_ReadZero(ddman)) {
563 if (Cudd_IsConstant(variables)) {
564 result[offset] = Cudd_V(vector);
568 if (Cudd_NodeReadIndex(vector) == Cudd_NodeReadIndex(variables)) {
569 vectorT = Cudd_T(vector);
570 vectorE = Cudd_E(vector);
572 vectorT = vectorE = vector;
575 DdNodePtr representativesT;
576 DdNodePtr representativesE;
577 if (Cudd_NodeReadIndex(representativesNode) == Cudd_NodeReadIndex(variables)) {
578 representativesT = Cudd_T(representativesNode);
579 representativesE = Cudd_E(representativesNode);
581 if (Cudd_IsComplement(representativesNode)) {
582 representativesT = Cudd_Not(representativesT);
583 representativesE = Cudd_Not(representativesE);
586 representativesT = representativesE = representativesNode;
589 extractVectorRec(vectorE, representativesE, Cudd_T(variables), odd.
getElseSuccessor(), offset, result);
594 void extractTransitionMatrixRec(DdNodePtr transitionMatrixNode, storm::dd::Odd
const& sourceOdd, uint64_t sourceOffset, DdNodePtr targetPartitionNode,
595 DdNodePtr representativesNode, DdNodePtr variables, DdNodePtr nondeterminismVariables, storm::dd::Odd
const* stateOdd,
596 uint64_t stateOffset) {
599 if (transitionMatrixNode == Cudd_ReadZero(ddman) || representativesNode == Cudd_ReadLogicZero(ddman)) {
604 if (Cudd_IsConstant(variables)) {
605 STORM_LOG_ASSERT(Cudd_IsConstant(transitionMatrixNode),
"Expected constant node.");
606 this->addMatrixEntry(sourceOffset, blockToOffset.at(targetPartitionNode), Cudd_V(transitionMatrixNode));
608 this->assignRowToState(sourceOffset, stateOffset);
612 bool nextVariableIsNondeterminismVariable =
613 !Cudd_IsConstant(nondeterminismVariables) && Cudd_NodeReadIndex(nondeterminismVariables) == Cudd_NodeReadIndex(variables);
615 if (nextVariableIsNondeterminismVariable) {
620 if (Cudd_NodeReadIndex(transitionMatrixNode) == Cudd_NodeReadIndex(variables)) {
621 t = Cudd_T(transitionMatrixNode);
622 e = Cudd_E(transitionMatrixNode);
624 t = e = transitionMatrixNode;
628 extractTransitionMatrixRec(e, sourceOdd.
getElseSuccessor(), sourceOffset, targetPartitionNode, representativesNode, Cudd_T(variables),
629 Cudd_T(nondeterminismVariables), stateOdd, stateOffset);
630 extractTransitionMatrixRec(t, sourceOdd.
getThenSuccessor(), sourceOffset + sourceOdd.
getElseOffset(), targetPartitionNode, representativesNode,
631 Cudd_T(variables), Cudd_T(nondeterminismVariables), stateOdd, stateOffset);
639 if (Cudd_NodeReadIndex(transitionMatrixNode) == Cudd_NodeReadIndex(variables)) {
641 t = Cudd_T(transitionMatrixNode);
642 e = Cudd_E(transitionMatrixNode);
644 t = e = transitionMatrixNode;
647 if (Cudd_NodeReadIndex(t) == Cudd_NodeReadIndex(variables) + 1) {
656 if (Cudd_NodeReadIndex(e) == Cudd_NodeReadIndex(variables) + 1) {
671 if (Cudd_NodeReadIndex(targetPartitionNode) == Cudd_NodeReadIndex(variables)) {
673 targetT = Cudd_T(targetPartitionNode);
674 targetE = Cudd_E(targetPartitionNode);
676 if (Cudd_IsComplement(targetPartitionNode)) {
677 targetT = Cudd_Not(targetT);
678 targetE = Cudd_Not(targetE);
682 targetT = targetE = targetPartitionNode;
685 DdNodePtr representativesT;
686 DdNodePtr representativesE;
687 if (Cudd_NodeReadIndex(representativesNode) == Cudd_NodeReadIndex(variables)) {
689 representativesT = Cudd_T(representativesNode);
690 representativesE = Cudd_E(representativesNode);
693 representativesT = representativesE = representativesNode;
696 if (representativesT != representativesE && Cudd_IsComplement(representativesNode)) {
697 representativesT = Cudd_Not(representativesT);
698 representativesE = Cudd_Not(representativesE);
701 extractTransitionMatrixRec(ee, sourceOdd.
getElseSuccessor(), sourceOffset, targetE, representativesE, Cudd_T(variables),
702 nondeterminismVariables, stateOdd ? &stateOdd->
getElseSuccessor() : stateOdd, stateOffset);
703 extractTransitionMatrixRec(et, sourceOdd.
getElseSuccessor(), sourceOffset, targetT, representativesE, Cudd_T(variables),
704 nondeterminismVariables, stateOdd ? &stateOdd->
getElseSuccessor() : stateOdd, stateOffset);
706 Cudd_T(variables), nondeterminismVariables, stateOdd ? &stateOdd->
getThenSuccessor() : stateOdd,
709 Cudd_T(variables), nondeterminismVariables, stateOdd ? &stateOdd->
getThenSuccessor() : stateOdd,
718 gtl::flat_hash_map<DdNode const*, uint64_t> blockToOffset;
722template<
typename ValueType,
typename ExportValueType>
731#ifdef STORM_HAVE_SYLVAN
732 this->createBlockToOffsetMapping();
735 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
736 "version of Storm with Sylvan support.");
742#ifdef STORM_HAVE_SYLVAN
743 this->createMatrixEntryStorage();
744 extractTransitionMatrixRec(matrix.
getInternalAdd().getSylvanMtbdd().GetMTBDD(), this->isNondeterministic ? this->nondeterminismOdd : this->odd, 0,
745 this->partitionBdd.getInternalBdd().getSylvanBdd().GetBDD(), this->representatives.getInternalBdd().getSylvanBdd().GetBDD(),
746 this->allSourceVariablesCube.getInternalBdd().getSylvanBdd().GetBDD(),
747 this->nondeterminismVariablesCube.getInternalBdd().getSylvanBdd().GetBDD(), this->isNondeterministic ? &this->odd :
nullptr,
749 return this->createMatrixFromEntries();
752 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
753 "version of Storm with Sylvan support.");
760#ifdef STORM_HAVE_SYLVAN
762 extractVectorRec(vector.
getInternalAdd().getSylvanMtbdd().GetMTBDD(), this->representatives.getInternalBdd().getSylvanBdd().GetBDD(),
763 variablesCube.
getInternalBdd().getSylvanBdd().GetBDD(), odd, 0, result);
767 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
768 "version of Storm with Sylvan support.");
772#ifdef STORM_HAVE_SYLVAN
773 void extractVectorRec(MTBDD vector, BDD representativesNode, BDD variables,
storm::dd::Odd const& odd, uint64_t offset,
774 std::vector<ExportValueType>& result) {
775 if (representativesNode == sylvan_false || mtbdd_iszero(vector)) {
779 if (sylvan_isconst(variables)) {
784 if (sylvan_mtbdd_matches_variable_index(vector, sylvan_var(variables))) {
785 vectorT = sylvan_high(vector);
786 vectorE = sylvan_low(vector);
788 vectorT = vectorE = vector;
791 BDD representativesT;
792 BDD representativesE;
793 if (sylvan_bdd_matches_variable_index(representativesNode, sylvan_var(variables))) {
794 representativesT = sylvan_high(representativesNode);
795 representativesE = sylvan_low(representativesNode);
797 representativesT = representativesE = representativesNode;
800 extractVectorRec(vectorE, representativesE, sylvan_high(variables), odd.
getElseSuccessor(), offset, result);
805 void createBlockToOffsetMapping() {
806 this->createBlockToOffsetMappingRec(this->partitionBdd.
getInternalBdd().getSylvanBdd().GetBDD(),
807 this->representatives.getInternalBdd().getSylvanBdd().GetBDD(),
808 this->rowVariablesCube.getInternalBdd().getSylvanBdd().GetBDD(), this->odd, 0);
810 "Mismatching block-to-offset mapping: " << blockToOffset.size() <<
" vs. " << this->numberOfBlocks <<
".");
813 void createBlockToOffsetMappingRec(BDD partitionNode, BDD representativesNode, BDD variables, storm::dd::Odd
const& odd, uint64_t offset) {
814 STORM_LOG_ASSERT(partitionNode != sylvan_false || representativesNode == sylvan_false,
"Expected representative to be zero if the partition is zero.");
815 if (representativesNode == sylvan_false || partitionNode == sylvan_false) {
819 if (sylvan_isconst(variables)) {
821 STORM_LOG_ASSERT(blockToOffset.find(partitionNode) == blockToOffset.end(),
"Duplicate entry.");
822 blockToOffset[partitionNode] = offset;
827 if (sylvan_bdd_matches_variable_index(partitionNode, sylvan_var(variables))) {
828 partitionT = sylvan_high(partitionNode);
829 partitionE = sylvan_low(partitionNode);
831 partitionT = partitionE = partitionNode;
834 BDD representativesT;
835 BDD representativesE;
836 if (sylvan_bdd_matches_variable_index(representativesNode, sylvan_var(variables))) {
837 representativesT = sylvan_high(representativesNode);
838 representativesE = sylvan_low(representativesNode);
840 representativesT = representativesE = representativesNode;
843 createBlockToOffsetMappingRec(partitionE, representativesE, sylvan_high(variables), odd.
getElseSuccessor(), offset);
848 void extractTransitionMatrixRec(MTBDD transitionMatrixNode, storm::dd::Odd
const& sourceOdd, uint64_t sourceOffset, BDD targetPartitionNode,
849 BDD representativesNode, BDD variables, BDD nondeterminismVariables, storm::dd::Odd
const* stateOdd, uint64_t stateOffset) {
852 if (mtbdd_iszero(transitionMatrixNode) || representativesNode == sylvan_false) {
857 if (sylvan_isconst(variables)) {
858 STORM_LOG_ASSERT(mtbdd_isleaf(transitionMatrixNode),
"Expected constant node.");
859 this->addMatrixEntry(
860 sourceOffset, blockToOffset.at(targetPartitionNode),
863 this->assignRowToState(sourceOffset, stateOffset);
867 bool nextVariableIsNondeterminismVariable =
868 !sylvan_isconst(nondeterminismVariables) && sylvan_var(nondeterminismVariables) == sylvan_var(variables);
870 if (nextVariableIsNondeterminismVariable) {
875 if (sylvan_mtbdd_matches_variable_index(transitionMatrixNode, sylvan_var(variables))) {
876 t = sylvan_high(transitionMatrixNode);
877 e = sylvan_low(transitionMatrixNode);
879 t = e = transitionMatrixNode;
883 extractTransitionMatrixRec(e, sourceOdd.
getElseSuccessor(), sourceOffset, targetPartitionNode, representativesNode, sylvan_high(variables),
884 sylvan_high(nondeterminismVariables), stateOdd, stateOffset);
885 extractTransitionMatrixRec(t, sourceOdd.
getThenSuccessor(), sourceOffset + sourceOdd.
getElseOffset(), targetPartitionNode, representativesNode,
886 sylvan_high(variables), sylvan_high(nondeterminismVariables), stateOdd, stateOffset);
894 if (sylvan_mtbdd_matches_variable_index(transitionMatrixNode, sylvan_var(variables))) {
896 t = sylvan_high(transitionMatrixNode);
897 e = sylvan_low(transitionMatrixNode);
899 t = e = transitionMatrixNode;
902 if (sylvan_mtbdd_matches_variable_index(t, sylvan_var(variables) + 1)) {
911 if (sylvan_mtbdd_matches_variable_index(e, sylvan_var(variables) + 1)) {
926 if (sylvan_bdd_matches_variable_index(targetPartitionNode, sylvan_var(variables))) {
928 targetT = sylvan_high(targetPartitionNode);
929 targetE = sylvan_low(targetPartitionNode);
932 targetT = targetE = targetPartitionNode;
935 BDD representativesT;
936 BDD representativesE;
937 if (sylvan_bdd_matches_variable_index(representativesNode, sylvan_var(variables))) {
939 representativesT = sylvan_high(representativesNode);
940 representativesE = sylvan_low(representativesNode);
943 representativesT = representativesE = representativesNode;
946 extractTransitionMatrixRec(ee, sourceOdd.
getElseSuccessor(), sourceOffset, targetE, representativesE, sylvan_high(variables),
947 nondeterminismVariables, stateOdd ? &stateOdd->
getElseSuccessor() : stateOdd, stateOffset);
948 extractTransitionMatrixRec(et, sourceOdd.
getElseSuccessor(), sourceOffset, targetT, representativesE, sylvan_high(variables),
949 nondeterminismVariables, stateOdd ? &stateOdd->
getElseSuccessor() : stateOdd, stateOffset);
951 sylvan_high(variables), nondeterminismVariables, stateOdd ? &stateOdd->
getThenSuccessor() : stateOdd,
954 sylvan_high(variables), nondeterminismVariables, stateOdd ? &stateOdd->
getThenSuccessor() : stateOdd,
961 gtl::flat_hash_map<BDD, uint64_t> blockToOffset;
965template<storm::dd::DdType DdType,
typename ValueType,
typename ExportValueType>
968 : useRepresentatives(bisimulationOptions.useRepresentatives),
969 useOriginalVariables(bisimulationOptions.useOriginalVariables),
970 quotientFormat(quotientFormat) {
974template<storm::dd::DdType DdType,
typename ValueType,
typename ExportValueType>
978 auto start = std::chrono::high_resolution_clock::now();
979 std::shared_ptr<storm::models::Model<ExportValueType>> result;
981 result = extractSparseQuotient(model, partition, preservationInformation);
983 result = extractDdQuotient(model, partition, preservationInformation);
985 auto end = std::chrono::high_resolution_clock::now();
986 STORM_LOG_INFO(
"Quotient extraction completed in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() <<
"ms.");
988 STORM_LOG_THROW(result, storm::exceptions::NotSupportedException,
"Quotient could not be extracted.");
993template<storm::dd::DdType DdType,
typename ValueType,
typename ExportValueType>
994std::shared_ptr<storm::models::sparse::Model<ExportValueType>> QuotientExtractor<DdType, ValueType, ExportValueType>::extractSparseQuotient(
1002 auto start = std::chrono::high_resolution_clock::now();
1008 "Representatives do not cover all blocks.");
1012 auto end = std::chrono::high_resolution_clock::now();
1013 STORM_LOG_INFO(
"Quotient transition matrix extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() <<
"ms.");
1015 start = std::chrono::high_resolution_clock::now();
1017 quotientStateLabeling.addLabel(
"init", sparseExtractor.extractSetExists(model.
getInitialStates()));
1018 quotientStateLabeling.addLabel(
"deadlock", sparseExtractor.extractSetExists(model.
getDeadlockStates()));
1020 for (
auto const& label : preservationInformation.
getLabels()) {
1021 quotientStateLabeling.addLabel(label, sparseExtractor.extractSetAll(model.
getStates(label)));
1023 for (
auto const& expression : preservationInformation.
getExpressions()) {
1024 std::stringstream stream;
1025 stream << expression;
1026 std::string expressionAsString = stream.str();
1028 if (quotientStateLabeling.containsLabel(expressionAsString)) {
1029 STORM_LOG_WARN(
"Duplicate label '" << expressionAsString <<
"', dropping second label definition.");
1031 quotientStateLabeling.addLabel(stream.str(), sparseExtractor.extractSetAll(model.
getStates(expression)));
1034 end = std::chrono::high_resolution_clock::now();
1035 STORM_LOG_INFO(
"Quotient labels extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).
count() <<
"ms.");
1037 start = std::chrono::high_resolution_clock::now();
1038 std::unordered_map<std::string, storm::models::sparse::StandardRewardModel<ExportValueType>> quotientRewardModels;
1042 std::optional<std::vector<ExportValueType>> quotientStateRewards;
1043 if (rewardModel.hasStateRewards()) {
1044 quotientStateRewards = sparseExtractor.extractStateVector(rewardModel.getStateRewardVector());
1047 std::optional<std::vector<ExportValueType>> quotientStateActionRewards;
1048 if (rewardModel.hasStateActionRewards()) {
1049 quotientStateActionRewards = sparseExtractor.extractStateActionVector(rewardModel.getStateActionRewardVector());
1052 quotientRewardModels.emplace(rewardModelName, storm::models::sparse::StandardRewardModel<ExportValueType>(
1053 std::move(quotientStateRewards), std::move(quotientStateActionRewards), std::nullopt));
1055 end = std::chrono::high_resolution_clock::now();
1056 STORM_LOG_INFO(
"Reward models extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).
count() <<
"ms.");
1058 std::shared_ptr<storm::models::sparse::Model<ExportValueType>> result;
1060 result = std::make_shared<storm::models::sparse::Dtmc<ExportValueType>>(std::move(quotientTransitionMatrix), std::move(quotientStateLabeling),
1061 std::move(quotientRewardModels));
1063 result = std::make_shared<storm::models::sparse::Ctmc<ExportValueType>>(std::move(quotientTransitionMatrix), std::move(quotientStateLabeling),
1064 std::move(quotientRewardModels));
1066 result = std::make_shared<storm::models::sparse::Mdp<ExportValueType>>(std::move(quotientTransitionMatrix), std::move(quotientStateLabeling),
1067 std::move(quotientRewardModels));
1069 storm::models::symbolic::MarkovAutomaton<DdType, ValueType>
const& markovAutomaton =
1070 *model.template as<storm::models::symbolic::MarkovAutomaton<DdType, ValueType>>();
1072 boost::optional<storm::storage::BitVector> markovianStates = sparseExtractor.extractSetExists(markovAutomaton.
getMarkovianStates());
1073 storm::storage::sparse::ModelComponents<ExportValueType> modelComponents(std::move(quotientTransitionMatrix), std::move(quotientStateLabeling),
1074 std::move(quotientRewardModels),
false, std::move(markovianStates));
1075 modelComponents.exitRates = sparseExtractor.extractStateVector(markovAutomaton.
getExitRateVector());
1077 result = std::make_shared<storm::models::sparse::MarkovAutomaton<ExportValueType>>(std::move(modelComponents));
1083template<storm::dd::DdType DdType,
typename ValueType,
typename ExportValueType>
1084std::shared_ptr<storm::models::symbolic::Model<DdType, ExportValueType>> QuotientExtractor<DdType, ValueType, ExportValueType>::extractDdQuotient(
1087 if (this->useOriginalVariables) {
1088 return extractQuotientUsingOriginalVariables(model, partition, preservationInformation);
1090 return extractQuotientUsingBlockVariables(model, partition, preservationInformation);
1094template<storm::dd::DdType DdType,
typename ValueType,
typename ExportValueType>
1095std::shared_ptr<storm::models::symbolic::Model<DdType, ExportValueType>>
1096QuotientExtractor<DdType, ValueType, ExportValueType>::extractQuotientUsingBlockVariables(
1099 auto modelType = model.
getType();
1101 bool useRepresentativesForThisExtraction = this->useRepresentatives;
1107 "Mismatching partition.");
1109 std::set<storm::expressions::Variable> blockVariableSet = {partition.getBlockVariable()};
1110 std::set<storm::expressions::Variable> blockPrimeVariableSet = {partition.getPrimedBlockVariable()};
1111 std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> blockMetaVariablePairs = {
1112 std::make_pair(partition.getBlockVariable(), partition.getPrimedBlockVariable())};
1114 auto start = std::chrono::high_resolution_clock::now();
1117 storm::dd::Bdd<DdType> partitionAsBdd = partition.storedAsBdd() ? partition.asBdd() : partition.asAdd().notZero();
1121 if (useRepresentativesForThisExtraction) {
1122 storm::dd::Bdd<DdType> partitionAsBddOverPrimedBlockVariables = partitionAsBdd.
renameVariables(blockVariableSet, blockPrimeVariableSet);
1123 storm::dd::Bdd<DdType> tmp =
1124 (representatives && partitionAsBddOverPrimedBlockVariables).renameVariablesConcretize(model.
getRowVariables(), blockVariableSet);
1125 partitionAsBdd = (tmp && partitionAsBddOverPrimedBlockVariables).existsAbstract(blockPrimeVariableSet);
1131 std::map<std::string, storm::dd::Bdd<DdType>> preservedLabelBdds;
1132 for (
auto const& label : preservationInformation.getLabels()) {
1133 preservedLabelBdds.emplace(label, (model.
getStates(label) && partitionAsBdd).existsAbstract(model.
getRowVariables()));
1135 for (
auto const& expression : preservationInformation.getExpressions()) {
1136 std::stringstream stream;
1137 stream << expression;
1138 std::string expressionAsString = stream.str();
1140 auto it = preservedLabelBdds.find(expressionAsString);
1141 if (it != preservedLabelBdds.end()) {
1142 STORM_LOG_WARN(
"Duplicate label '" << expressionAsString <<
"', dropping second label definition.");
1144 preservedLabelBdds.emplace(stream.str(), (model.
getStates(expression) && partitionAsBdd).existsAbstract(model.
getRowVariables()));
1147 auto end = std::chrono::high_resolution_clock::now();
1148 STORM_LOG_INFO(
"Quotient labels extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).
count() <<
"ms.");
1150 start = std::chrono::high_resolution_clock::now();
1151 std::set<storm::expressions::Variable> blockAndRowVariables;
1153 std::inserter(blockAndRowVariables, blockAndRowVariables.end()));
1154 std::set<storm::expressions::Variable> blockPrimeAndColumnVariables;
1156 std::inserter(blockPrimeAndColumnVariables, blockPrimeAndColumnVariables.end()));
1157 storm::dd::Add<DdType, ValueType> partitionAsAdd = partitionAsBdd.template toAdd<ValueType>();
1162 partitionAsBdd &= representatives;
1163 partitionAsAdd *= partitionAsBdd.template toAdd<ValueType>();
1166 end = std::chrono::high_resolution_clock::now();
1169 if (std::is_same<ValueType, storm::RationalNumber>::value) {
1171 }
else if (std::is_same<ValueType, storm::RationalFunction>::value) {
1175 "Illegal entries in quotient matrix.");
1178 .equalModuloPrecision(quotientTransitionMatrix.
notZero().existsAbstract(blockPrimeVariableSet).template toAdd<ValueType>(),
1180 "Illegal non-probabilistic matrix.");
1182 STORM_LOG_INFO(
"Quotient transition matrix extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).
count() <<
"ms.");
1184 storm::dd::Bdd<DdType> quotientTransitionMatrixBdd = quotientTransitionMatrix.
notZero();
1187 blockPrimeAndNondeterminismVariables.insert(blockPrimeVariableSet.begin(), blockPrimeVariableSet.end());
1188 storm::dd::Bdd<DdType> deadlockStates = !quotientTransitionMatrixBdd.
existsAbstract(blockPrimeAndNondeterminismVariables) && reachableStates;
1190 start = std::chrono::high_resolution_clock::now();
1191 std::unordered_map<std::string, storm::models::symbolic::StandardRewardModel<DdType, ValueType>> quotientRewardModels;
1192 for (
auto const& rewardModelName : preservationInformation.getRewardModelNames()) {
1195 boost::optional<storm::dd::Add<DdType, ValueType>> quotientStateRewards;
1196 if (rewardModel.hasStateRewards()) {
1197 quotientStateRewards = rewardModel.getStateRewardVector().multiplyMatrix(partitionAsAdd, model.
getRowVariables());
1200 boost::optional<storm::dd::Add<DdType, ValueType>> quotientStateActionRewards;
1201 if (rewardModel.hasStateActionRewards()) {
1202 quotientStateActionRewards = rewardModel.getStateActionRewardVector().multiplyMatrix(partitionAsAdd, model.
getRowVariables());
1205 quotientRewardModels.emplace(rewardModelName, storm::models::symbolic::StandardRewardModel<DdType, ValueType>(
1206 quotientStateRewards, quotientStateActionRewards, boost::none));
1208 end = std::chrono::high_resolution_clock::now();
1209 STORM_LOG_INFO(
"Reward models extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).
count() <<
"ms.");
1211 std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> result;
1213 result = std::shared_ptr<storm::models::symbolic::Dtmc<DdType, ValueType>>(
new storm::models::symbolic::Dtmc<DdType, ValueType>(
1214 model.
getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, blockVariableSet,
1215 blockPrimeVariableSet, blockMetaVariablePairs, preservedLabelBdds, quotientRewardModels));
1217 result = std::shared_ptr<storm::models::symbolic::Ctmc<DdType, ValueType>>(
new storm::models::symbolic::Ctmc<DdType, ValueType>(
1218 model.
getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, blockVariableSet,
1219 blockPrimeVariableSet, blockMetaVariablePairs, preservedLabelBdds, quotientRewardModels));
1221 result = std::shared_ptr<storm::models::symbolic::Mdp<DdType, ValueType>>(
new storm::models::symbolic::Mdp<DdType, ValueType>(
1222 model.
getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, blockVariableSet,
1223 blockPrimeVariableSet, blockMetaVariablePairs, model.
getNondeterminismVariables(), preservedLabelBdds, quotientRewardModels));
1226 std::shared_ptr<storm::models::symbolic::MarkovAutomaton<DdType, ValueType>>(
new storm::models::symbolic::MarkovAutomaton<DdType, ValueType>(
1228 model.template as<storm::models::symbolic::MarkovAutomaton<DdType, ValueType>>()->getMarkovianMarker(), reachableStates, initialStates,
1229 deadlockStates, quotientTransitionMatrix, blockVariableSet, blockPrimeVariableSet, blockMetaVariablePairs,
1233 return result->template toValueType<ExportValueType>();
1235 STORM_LOG_THROW(
false, storm::exceptions::NotSupportedException,
"Cannot extract quotient for this model type.");
1239template<storm::dd::DdType DdType,
typename ValueType,
typename ExportValueType>
1240std::shared_ptr<storm::models::symbolic::Model<DdType, ExportValueType>>
1241QuotientExtractor<DdType, ValueType, ExportValueType>::extractQuotientUsingOriginalVariables(
1244 auto modelType = model.
getType();
1246 bool useRepresentativesForThisExtraction = this->useRepresentatives;
1249 STORM_LOG_WARN_COND(!this->useRepresentatives,
"Using representatives is unsupported for this extraction, falling back to regular extraction.");
1254 "Mismatching partition.");
1256 std::set<storm::expressions::Variable> blockVariableSet = {partition.getBlockVariable()};
1257 std::set<storm::expressions::Variable> blockPrimeVariableSet = {partition.getPrimedBlockVariable()};
1258 std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> blockMetaVariablePairs = {
1259 std::make_pair(partition.getBlockVariable(), partition.getPrimedBlockVariable())};
1261 auto start = std::chrono::high_resolution_clock::now();
1264 storm::dd::Bdd<DdType> partitionAsBdd = partition.storedAsBdd() ? partition.asBdd() : partition.asAdd().notZero();
1268 if (useRepresentativesForThisExtraction) {
1269 storm::dd::Bdd<DdType> partitionAsBddOverPrimedBlockVariables = partitionAsBdd.
renameVariables(blockVariableSet, blockPrimeVariableSet);
1270 storm::dd::Bdd<DdType> tmp =
1271 (representatives && partitionAsBddOverPrimedBlockVariables).renameVariablesConcretize(model.
getRowVariables(), blockVariableSet);
1272 partitionAsBdd = (tmp && partitionAsBddOverPrimedBlockVariables).existsAbstract(blockPrimeVariableSet);
1275 storm::dd::Bdd<DdType> reachableStates =
1277 storm::dd::Bdd<DdType> initialStates = (model.
getInitialStates() && partitionAsBdd)
1281 std::map<std::string, storm::dd::Bdd<DdType>> preservedLabelBdds;
1282 for (
auto const& label : preservationInformation.getLabels()) {
1283 preservedLabelBdds.emplace(label, (model.
getStates(label) && partitionAsBdd)
1287 for (
auto const& expression : preservationInformation.getExpressions()) {
1288 std::stringstream stream;
1289 stream << expression;
1290 std::string expressionAsString = stream.str();
1292 auto it = preservedLabelBdds.find(expressionAsString);
1293 if (it != preservedLabelBdds.end()) {
1294 STORM_LOG_WARN(
"Duplicate label '" << expressionAsString <<
"', dropping second label definition.");
1296 preservedLabelBdds.emplace(stream.str(), (model.
getStates(expression) && partitionAsBdd)
1301 auto end = std::chrono::high_resolution_clock::now();
1302 STORM_LOG_INFO(
"Quotient labels extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).
count() <<
"ms.");
1304 start = std::chrono::high_resolution_clock::now();
1305 std::set<storm::expressions::Variable> blockAndRowVariables;
1307 std::inserter(blockAndRowVariables, blockAndRowVariables.end()));
1308 std::set<storm::expressions::Variable> blockPrimeAndColumnVariables;
1310 std::inserter(blockPrimeAndColumnVariables, blockPrimeAndColumnVariables.end()));
1311 storm::dd::Add<DdType, ValueType> partitionAsAdd = partitionAsBdd.template toAdd<ValueType>();
1312 storm::dd::Add<DdType, ValueType> quotientTransitionMatrix =
1318 partitionAsBdd &= representatives;
1319 partitionAsAdd = partitionAsBdd.template toAdd<ValueType>();
1323 quotientTransitionMatrix = (quotientTransitionMatrix * partitionAsAdd)
1330 end = std::chrono::high_resolution_clock::now();
1333 if (std::is_same<ValueType, storm::RationalNumber>::value) {
1337 "Illegal entries in quotient matrix.");
1340 .equalModuloPrecision(quotientTransitionMatrix.
notZero().existsAbstract(model.
getColumnVariables()).template toAdd<ValueType>(),
1342 "Illegal probabilistic matrix.");
1344 STORM_LOG_INFO(
"Quotient transition matrix extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).
count() <<
"ms.");
1346 storm::dd::Bdd<DdType> quotientTransitionMatrixBdd = quotientTransitionMatrix.
notZero();
1348 std::set<storm::expressions::Variable> columnAndNondeterminismVariables = model.
getColumnVariables();
1350 storm::dd::Bdd<DdType> deadlockStates = !quotientTransitionMatrixBdd.
existsAbstract(columnAndNondeterminismVariables) && reachableStates;
1352 start = std::chrono::high_resolution_clock::now();
1353 std::unordered_map<std::string, storm::models::symbolic::StandardRewardModel<DdType, ValueType>> quotientRewardModels;
1354 for (
auto const& rewardModelName : preservationInformation.getRewardModelNames()) {
1357 boost::optional<storm::dd::Add<DdType, ValueType>> quotientStateRewards;
1358 if (rewardModel.hasStateRewards()) {
1359 quotientStateRewards = rewardModel.getStateRewardVector()
1364 boost::optional<storm::dd::Add<DdType, ValueType>> quotientStateActionRewards;
1365 if (rewardModel.hasStateActionRewards()) {
1366 quotientStateActionRewards = rewardModel.getStateActionRewardVector()
1371 quotientRewardModels.emplace(rewardModelName, storm::models::symbolic::StandardRewardModel<DdType, ValueType>(
1372 quotientStateRewards, quotientStateActionRewards, boost::none));
1374 end = std::chrono::high_resolution_clock::now();
1375 STORM_LOG_INFO(
"Reward models extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).
count() <<
"ms.");
1377 std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> result;
1379 result = std::shared_ptr<storm::models::symbolic::Dtmc<DdType, ValueType>>(
new storm::models::symbolic::Dtmc<DdType, ValueType>(
1380 model.
getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, model.
getRowVariables(),
1383 result = std::shared_ptr<storm::models::symbolic::Ctmc<DdType, ValueType>>(
new storm::models::symbolic::Ctmc<DdType, ValueType>(
1384 model.
getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, model.
getRowVariables(),
1387 result = std::shared_ptr<storm::models::symbolic::Mdp<DdType, ValueType>>(
new storm::models::symbolic::Mdp<DdType, ValueType>(
1388 model.
getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, model.
getRowVariables(),
1390 quotientRewardModels));
1393 std::shared_ptr<storm::models::symbolic::MarkovAutomaton<DdType, ValueType>>(
new storm::models::symbolic::MarkovAutomaton<DdType, ValueType>(
1395 model.template as<storm::models::symbolic::MarkovAutomaton<DdType, ValueType>>()->getMarkovianMarker(), reachableStates, initialStates,
1400 return result->template toValueType<ExportValueType>();
1402 STORM_LOG_THROW(
false, storm::exceptions::NotSupportedException,
"Cannot extract quotient for this model type.");
InternalAdd< LibraryType, ValueType > const & getInternalAdd() const
Retrieves the internal ADD.
Bdd< LibraryType > greater(Add< LibraryType, ValueType > const &other) const
Retrieves the function that maps all evaluations to one whose function value in the first ADD are gre...
Add< LibraryType, ValueType > renameVariables(std::set< storm::expressions::Variable > const &from, std::set< storm::expressions::Variable > const &to) const
Renames the given meta variables in the ADD.
Add< LibraryType, ValueType > sumAbstract(std::set< storm::expressions::Variable > const &metaVariables) const
Sum-abstracts from the given meta variables.
Add< LibraryType, ValueType > multiplyMatrix(Add< LibraryType, ValueType > const &otherMatrix, std::set< storm::expressions::Variable > const &summationMetaVariables) const
Multiplies the current ADD (representing a matrix) with the given matrix by summing over the given me...
Bdd< LibraryType > toBdd() const
Converts the ADD to a BDD by mapping all values unequal to zero to 1.
Bdd< LibraryType > notZero() const
Computes a BDD that represents the function in which all assignments with a function value unequal to...
Add< LibraryType, ValueType > renameVariablesAbstract(std::set< storm::expressions::Variable > const &from, std::set< storm::expressions::Variable > const &to) const
Renames the given meta variables in the ADD.
Bdd< LibraryType > existsAbstract(std::set< storm::expressions::Variable > const &metaVariables) const
Existentially abstracts from the given meta variables.
virtual uint_fast64_t getNonZeroCount() const override
Retrieves the number of encodings that are mapped to a non-zero value.
Bdd< LibraryType > swapVariables(std::vector< std::pair< storm::expressions::Variable, storm::expressions::Variable > > const &metaVariablePairs) const
Swaps the given pairs of meta variables in the BDD.
Bdd< LibraryType > renameVariables(std::set< storm::expressions::Variable > const &from, std::set< storm::expressions::Variable > const &to) const
Renames the given meta variables in the BDD.
InternalBdd< LibraryType > const & getInternalBdd() const
Retrieves the internal BDD.
Odd const & getThenSuccessor() const
Retrieves the then-successor of this ODD node.
uint_fast64_t getTotalOffset() const
Retrieves the total offset, i.e., the sum of the then- and else-offset.
uint_fast64_t getElseOffset() const
Retrieves the else-offset of this ODD node.
bool isTerminalNode() const
Checks whether the given ODD node is a terminal node, i.e.
Odd const & getElseSuccessor() const
Retrieves the else-successor of this ODD node.
InternalRepresentativeComputer(storm::dd::Bdd< storm::dd::DdType::CUDD > const &partitionBdd, std::set< storm::expressions::Variable > const &rowVariables)
storm::dd::Bdd< storm::dd::DdType::CUDD > getRepresentatives()
storm::dd::Bdd< storm::dd::DdType::Sylvan > getRepresentatives()
InternalRepresentativeComputer(storm::dd::Bdd< storm::dd::DdType::Sylvan > const &partitionBdd, std::set< storm::expressions::Variable > const &rowVariables)
std::set< storm::expressions::Variable > const & rowVariables
storm::dd::Bdd< DdType > partitionBdd
storm::dd::InternalDdManager< DdType > const * internalDdManager
storm::dd::Bdd< DdType > rowVariablesCube
storm::dd::DdManager< DdType > const * ddManager
InternalRepresentativeComputerBase(storm::dd::Bdd< DdType > const &partitionBdd, std::set< storm::expressions::Variable > const &rowVariables)
storm::expressions::Variable const & getBlockVariable() const
storm::dd::Bdd< DdType > const & asBdd() const
uint64_t getNumberOfBlocks() const
storm::dd::Bdd< DdType > getStates() const
storm::dd::Add< DdType, ValueType > const & asAdd() const
virtual ModelType getType() const
Return the actual type of the model.
This class manages the labeling of the state space with a number of (atomic) labels.
storm::dd::Bdd< Type > const & getMarkovianStates() const
storm::dd::Add< Type, ValueType > const & getExitRateVector() const
Base class for all symbolic models.
storm::dd::DdManager< Type > & getManager() const
Retrieves the manager responsible for the DDs that represent this model.
RewardModelType const & getRewardModel(std::string const &rewardModelName) const
Retrieves the reward model with the given name, if one exists.
storm::dd::Add< Type, ValueType > const & getTransitionMatrix() const
Retrieves the matrix representing the transitions of the model.
storm::dd::Bdd< Type > const & getDeadlockStates() const
std::set< storm::expressions::Variable > const & getColumnVariables() const
Retrieves the meta variables used to encode the columns of the transition matrix and the vector indic...
storm::dd::Bdd< Type > const & getInitialStates() const
Retrieves the initial states of the model.
virtual std::set< storm::expressions::Variable > const & getNondeterminismVariables() const
Retrieves all meta variables used to encode the nondeterminism.
std::vector< std::pair< storm::expressions::Variable, storm::expressions::Variable > > const & getRowColumnMetaVariablePairs() const
Retrieves the pairs of row and column meta variables.
std::set< storm::expressions::Variable > const & getRowVariables() const
Retrieves the meta variables used to encode the rows of the transition matrix and the vector indices.
virtual storm::dd::Bdd< Type > getStates(std::string const &label) const
Returns the sets of states labeled with the given label.
storm::dd::Bdd< Type > const & getReachableStates() const
Retrieves the reachable states of the model.
virtual uint_fast64_t getNumberOfStates() const override
Returns the number of states of the model.
A bit vector that is internally represented as a vector of 64-bit values.
A class that can be used to build a sparse matrix by adding value by value.
A class that holds a possibly non-square matrix in the compressed row storage format.
#define STORM_LOG_INFO(message)
#define STORM_LOG_WARN(message)
#define STORM_LOG_TRACE(message)
#define STORM_LOG_ASSERT(cond, message)
#define STORM_LOG_WARN_COND(cond, message)
#define STORM_LOG_THROW(cond, exception, message)
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)
TargetType convertNumber(SourceType const &number)