Storm 1.11.1.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
ParallelCompositionBuilder.cpp
Go to the documentation of this file.
2
4
5namespace storm {
6namespace builder {
7
8template<typename ValueType>
9std::shared_ptr<storm::models::sparse::Ctmc<ValueType>> ParallelCompositionBuilder<ValueType>::compose(
10 std::shared_ptr<storm::models::sparse::Ctmc<ValueType>> const& ctmcA, std::shared_ptr<storm::models::sparse::Ctmc<ValueType>> const& ctmcB, bool labelAnd) {
11 STORM_LOG_TRACE("Parallel composition");
12
13 storm::storage::SparseMatrix<ValueType> matrixA = ctmcA->getTransitionMatrix();
14 storm::storage::SparseMatrix<ValueType> matrixB = ctmcB->getTransitionMatrix();
15 storm::models::sparse::StateLabeling labelingA = ctmcA->getStateLabeling();
16 storm::models::sparse::StateLabeling labelingB = ctmcB->getStateLabeling();
17 size_t sizeA = ctmcA->getNumberOfStates();
18 size_t sizeB = ctmcB->getNumberOfStates();
19 size_t size = sizeA * sizeB;
20 size_t rowIndex = 0;
21
22 // Build matrix
23 storm::storage::SparseMatrixBuilder<ValueType> builder(size, size, 0, true, false, 0);
24
25 for (size_t stateA = 0; stateA < sizeA; ++stateA) {
26 for (size_t stateB = 0; stateB < sizeB; ++stateB) {
27 STORM_LOG_ASSERT(rowIndex == stateA * sizeB + stateB, "Row " << rowIndex << " is not correct");
28
29 auto rowA = matrixA.getRow(stateA);
30 auto itA = rowA.begin();
31 auto rowB = matrixB.getRow(stateB);
32 auto itB = rowB.begin();
33
34 // First consider all target states of A < the current stateA
35 while (itA != rowA.end() && itA->getColumn() < stateA) {
36 builder.addNextValue(rowIndex, itA->getColumn() * sizeB + stateB, itA->getValue());
37 ++itA;
38 }
39
40 // Then consider all target states of B
41 while (itB != rowB.end()) {
42 builder.addNextValue(rowIndex, stateA * sizeB + itB->getColumn(), itB->getValue());
43 ++itB;
44 }
45
46 // Last consider all remaining target states of A > the current stateA
47 while (itA != rowA.end()) {
48 builder.addNextValue(rowIndex, itA->getColumn() * sizeB + stateB, itA->getValue());
49 ++itA;
50 }
51
52 ++rowIndex;
53 }
54 }
55
56 storm::storage::SparseMatrix<ValueType> matrixComposed = builder.build();
57 STORM_LOG_ASSERT(matrixComposed.getRowCount() == size, "Row count is not correct");
58 STORM_LOG_ASSERT(matrixComposed.getColumnCount() == size, "Column count is not correct");
59
60 // Build labeling
62
63 if (labelAnd) {
64 for (std::string const& label : labelingA.getLabels()) {
65 if (labelingB.containsLabel(label)) {
66 // Only consider labels contained in both CTMCs
67 storm::storage::BitVector labelStates(size, false);
68 for (auto entryA : labelingA.getStates(label)) {
69 for (auto entryB : labelingB.getStates(label)) {
70 labelStates.set(entryA * sizeB + entryB);
71 }
72 }
73 labeling.addLabel(label, labelStates);
74 }
75 }
76 } else {
77 // Set labels from A
78 for (std::string const& label : labelingA.getLabels()) {
79 if (label == "init") {
80 // Initial states must be initial in both CTMCs
81 STORM_LOG_ASSERT(labelingB.containsLabel(label), "B does not have init.");
82 storm::storage::BitVector labelStates(size, false);
83 for (auto entryA : labelingA.getStates(label)) {
84 for (auto entryB : labelingB.getStates(label)) {
85 labelStates.set(entryA * sizeB + entryB);
86 }
87 }
88 labeling.addLabel(label, labelStates);
89 } else {
90 storm::storage::BitVector labelStates(size, false);
91 for (auto entry : labelingA.getStates(label)) {
92 for (size_t index = entry * sizeB; index < entry * sizeB + sizeB; ++index) {
93 labelStates.set(index, true);
94 }
95 }
96 labeling.addLabel(label, labelStates);
97 }
98 }
99 // Set labels from B
100 for (std::string const& label : labelingB.getLabels()) {
101 if (label == "init") {
102 continue;
103 }
104 if (labeling.containsLabel(label)) {
105 // Label is already there from A
106 for (auto entry : labelingB.getStates(label)) {
107 for (size_t index = 0; index < sizeA; ++index) {
108 labeling.addLabelToState(label, index * sizeB + entry);
109 }
110 }
111 } else {
112 storm::storage::BitVector labelStates(size, false);
113 for (auto entry : labelingB.getStates(label)) {
114 for (size_t index = 0; index < sizeA; ++index) {
115 labelStates.set(index * sizeB + entry, true);
116 }
117 }
118 labeling.addLabel(label, labelStates);
119 }
120 }
121 }
122
123 // Build CTMC
124 std::shared_ptr<storm::models::sparse::Ctmc<ValueType>> composedCtmc = std::make_shared<storm::models::sparse::Ctmc<ValueType>>(matrixComposed, labeling);
125
126 // Print for debugging
127 /*std::cout << "Matrix A:\n";
128 std::cout << matrixA << '\n';
129 std::cout << "Matrix B:\n";
130 std::cout << matrixB << '\n';
131 std::cout << "Composed matrix: \n" << matrixComposed;
132 std::cout << "Labeling A\n";
133 labelingA.printLabelingInformationToStream(std::cout);
134 for (size_t stateA = 0; stateA < sizeA; ++stateA) {
135 std::cout << "State " << stateA << ": ";
136 for (auto label : labelingA.getLabelsOfState(stateA)) {
137 std::cout << label << ", ";
138 }
139 std::cout << '\n';
140 }
141 std::cout << "Labeling B\n";
142 labelingB.printLabelingInformationToStream(std::cout);
143 for (size_t stateB = 0; stateB < sizeB; ++stateB) {
144 std::cout << "State " << stateB << ": ";
145 for (auto label : labelingB.getLabelsOfState(stateB)) {
146 std::cout << label << ", ";
147 }
148 std::cout << '\n';
149 }
150 std::cout << "Labeling Composed\n";
151 labeling.printLabelingInformationToStream(std::cout);
152 for (size_t state = 0; state < size; ++state) {
153 std::cout << "State " << state << ": ";
154 for (auto label : labeling.getLabelsOfState(state)) {
155 std::cout << label << ", ";
156 }
157 std::cout << '\n';
158 }*/
159
160 return composedCtmc;
161}
162
163// Explicitly instantiate the class.
166
167} // namespace builder
168} // namespace storm
Build a parallel composition of Markov chains.
static std::shared_ptr< storm::models::sparse::Ctmc< ValueType > > compose(std::shared_ptr< storm::models::sparse::Ctmc< ValueType > > const &ctmcA, std::shared_ptr< storm::models::sparse::Ctmc< ValueType > > const &ctmcB, bool labelAnd)
This class represents a continuous-time Markov chain.
Definition Ctmc.h:13
std::set< std::string > getLabels() const
Retrieves the set of labels contained in this labeling.
void addLabel(std::string const &label)
Adds a new label to the labelings.
bool containsLabel(std::string const &label) const
Checks whether a label is registered within this labeling.
This class manages the labeling of the state space with a number of (atomic) labels.
storm::storage::BitVector const & getStates(std::string const &label) const
Returns the labeling of states associated with the given label.
void addLabelToState(std::string const &label, storm::storage::sparse::state_type state)
Adds a label to a given state.
A bit vector that is internally represented as a vector of 64-bit values.
Definition BitVector.h:16
void set(uint64_t index, bool value=true)
Sets the given truth value at the given index.
const_iterator begin() const
Retrieves an iterator that points to the beginning of the rows.
A class that can be used to build a sparse matrix by adding value by value.
void addNextValue(index_type row, index_type column, value_type const &value)
Sets the matrix entry at the given row and column to the given value.
SparseMatrix< value_type > build(index_type overriddenRowCount=0, index_type overriddenColumnCount=0, index_type overriddenRowGroupCount=0)
A class that holds a possibly non-square matrix in the compressed row storage format.
const_rows getRow(index_type row) const
Returns an object representing the given row.
index_type getColumnCount() const
Returns the number of columns of the matrix.
index_type getRowCount() const
Returns the number of rows of the matrix.
#define STORM_LOG_TRACE(message)
Definition logging.h:12
#define STORM_LOG_ASSERT(cond, message)
Definition macros.h:11