Storm
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
ParallelCompositionBuilder.cpp
Go to the documentation of this file.
5
6namespace storm {
7namespace builder {
8
9template<typename ValueType>
10std::shared_ptr<storm::models::sparse::Ctmc<ValueType>> ParallelCompositionBuilder<ValueType>::compose(
11 std::shared_ptr<storm::models::sparse::Ctmc<ValueType>> const& ctmcA, std::shared_ptr<storm::models::sparse::Ctmc<ValueType>> const& ctmcB, bool labelAnd) {
12 STORM_LOG_TRACE("Parallel composition");
13
14 storm::storage::SparseMatrix<ValueType> matrixA = ctmcA->getTransitionMatrix();
15 storm::storage::SparseMatrix<ValueType> matrixB = ctmcB->getTransitionMatrix();
16 storm::models::sparse::StateLabeling labelingA = ctmcA->getStateLabeling();
17 storm::models::sparse::StateLabeling labelingB = ctmcB->getStateLabeling();
18 size_t sizeA = ctmcA->getNumberOfStates();
19 size_t sizeB = ctmcB->getNumberOfStates();
20 size_t size = sizeA * sizeB;
21 size_t rowIndex = 0;
22
23 // Build matrix
24 storm::storage::SparseMatrixBuilder<ValueType> builder(size, size, 0, true, false, 0);
25
26 for (size_t stateA = 0; stateA < sizeA; ++stateA) {
27 for (size_t stateB = 0; stateB < sizeB; ++stateB) {
28 STORM_LOG_ASSERT(rowIndex == stateA * sizeB + stateB, "Row " << rowIndex << " is not correct");
29
30 auto rowA = matrixA.getRow(stateA);
31 auto itA = rowA.begin();
32 auto rowB = matrixB.getRow(stateB);
33 auto itB = rowB.begin();
34
35 // First consider all target states of A < the current stateA
36 while (itA != rowA.end() && itA->getColumn() < stateA) {
37 builder.addNextValue(rowIndex, itA->getColumn() * sizeB + stateB, itA->getValue());
38 ++itA;
39 }
40
41 // Then consider all target states of B
42 while (itB != rowB.end()) {
43 builder.addNextValue(rowIndex, stateA * sizeB + itB->getColumn(), itB->getValue());
44 ++itB;
45 }
46
47 // Last consider all remaining target states of A > the current stateA
48 while (itA != rowA.end()) {
49 builder.addNextValue(rowIndex, itA->getColumn() * sizeB + stateB, itA->getValue());
50 ++itA;
51 }
52
53 ++rowIndex;
54 }
55 }
56
57 storm::storage::SparseMatrix<ValueType> matrixComposed = builder.build();
58 STORM_LOG_ASSERT(matrixComposed.getRowCount() == size, "Row count is not correct");
59 STORM_LOG_ASSERT(matrixComposed.getColumnCount() == size, "Column count is not correct");
60
61 // Build labeling
63
64 if (labelAnd) {
65 for (std::string const& label : labelingA.getLabels()) {
66 if (labelingB.containsLabel(label)) {
67 // Only consider labels contained in both CTMCs
68 storm::storage::BitVector labelStates(size, false);
69 for (auto entryA : labelingA.getStates(label)) {
70 for (auto entryB : labelingB.getStates(label)) {
71 labelStates.set(entryA * sizeB + entryB);
72 }
73 }
74 labeling.addLabel(label, labelStates);
75 }
76 }
77 } else {
78 // Set labels from A
79 for (std::string const& label : labelingA.getLabels()) {
80 if (label == "init") {
81 // Initial states must be initial in both CTMCs
82 STORM_LOG_ASSERT(labelingB.containsLabel(label), "B does not have init.");
83 storm::storage::BitVector labelStates(size, false);
84 for (auto entryA : labelingA.getStates(label)) {
85 for (auto entryB : labelingB.getStates(label)) {
86 labelStates.set(entryA * sizeB + entryB);
87 }
88 }
89 labeling.addLabel(label, labelStates);
90 } else {
91 storm::storage::BitVector labelStates(size, false);
92 for (auto entry : labelingA.getStates(label)) {
93 for (size_t index = entry * sizeB; index < entry * sizeB + sizeB; ++index) {
94 labelStates.set(index, true);
95 }
96 }
97 labeling.addLabel(label, labelStates);
98 }
99 }
100 // Set labels from B
101 for (std::string const& label : labelingB.getLabels()) {
102 if (label == "init") {
103 continue;
104 }
105 if (labeling.containsLabel(label)) {
106 // Label is already there from A
107 for (auto entry : labelingB.getStates(label)) {
108 for (size_t index = 0; index < sizeA; ++index) {
109 labeling.addLabelToState(label, index * sizeB + entry);
110 }
111 }
112 } else {
113 storm::storage::BitVector labelStates(size, false);
114 for (auto entry : labelingB.getStates(label)) {
115 for (size_t index = 0; index < sizeA; ++index) {
116 labelStates.set(index * sizeB + entry, true);
117 }
118 }
119 labeling.addLabel(label, labelStates);
120 }
121 }
122 }
123
124 // Build CTMC
125 std::shared_ptr<storm::models::sparse::Ctmc<ValueType>> composedCtmc = std::make_shared<storm::models::sparse::Ctmc<ValueType>>(matrixComposed, labeling);
126
127 // Print for debugging
128 /*std::cout << "Matrix A:\n";
129 std::cout << matrixA << '\n';
130 std::cout << "Matrix B:\n";
131 std::cout << matrixB << '\n';
132 std::cout << "Composed matrix: \n" << matrixComposed;
133 std::cout << "Labeling A\n";
134 labelingA.printLabelingInformationToStream(std::cout);
135 for (size_t stateA = 0; stateA < sizeA; ++stateA) {
136 std::cout << "State " << stateA << ": ";
137 for (auto label : labelingA.getLabelsOfState(stateA)) {
138 std::cout << label << ", ";
139 }
140 std::cout << '\n';
141 }
142 std::cout << "Labeling B\n";
143 labelingB.printLabelingInformationToStream(std::cout);
144 for (size_t stateB = 0; stateB < sizeB; ++stateB) {
145 std::cout << "State " << stateB << ": ";
146 for (auto label : labelingB.getLabelsOfState(stateB)) {
147 std::cout << label << ", ";
148 }
149 std::cout << '\n';
150 }
151 std::cout << "Labeling Composed\n";
152 labeling.printLabelingInformationToStream(std::cout);
153 for (size_t state = 0; state < size; ++state) {
154 std::cout << "State " << state << ": ";
155 for (auto label : labeling.getLabelsOfState(state)) {
156 std::cout << label << ", ";
157 }
158 std::cout << '\n';
159 }*/
160
161 return composedCtmc;
162}
163
164// Explicitly instantiate the class.
166
167#ifdef STORM_HAVE_CARL
169#endif
170
171} // namespace builder
172} // 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:15
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:18
void set(uint_fast64_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:17
#define STORM_LOG_ASSERT(cond, message)
Definition macros.h:11
LabParser.cpp.
Definition cli.cpp:18