Storm 1.14.0.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
ProductBuilder.h
Go to the documentation of this file.
1#pragma once
2
3#include <cstddef>
4#include <deque>
5#include <map>
6#include <utility>
7#include <vector>
8
14
15namespace storm {
16namespace transformer {
17
18template<typename Model>
20 public:
22
23 template<typename ProductOperator>
24 static typename Product<Model>::ptr buildProduct(const matrix_type& originalMatrix, ProductOperator& prodOp,
25 const storm::storage::BitVector& statesOfInterest) {
26 bool deterministic = originalMatrix.hasTrivialRowGrouping();
27
28 typedef storm::storage::sparse::state_type state_type;
29 typedef std::pair<state_type, state_type> product_state_type;
30
31 state_type nextState = 0;
32 std::map<product_state_type, state_type> productStateToProductIndex;
33 std::vector<product_state_type> productIndexToProductState;
34 std::vector<state_type> prodInitial;
35
36 // use deque for todo so that the states are handled in the order
37 // of their index in the product model, which is required due to the
38 // use of the SparseMatrixBuilder that can only handle linear addNextValue
39 // calls
40 std::deque<state_type> todo;
41 for (state_type s_0 : statesOfInterest) {
42 state_type q_0 = prodOp.getInitialState(s_0);
43
44 // std::cout << "Initial: " << s_0 << ", " << q_0 << " = " << nextState << "\n";
45
46 product_state_type s_q(s_0, q_0);
47 state_type index = nextState++;
48 productStateToProductIndex[s_q] = index;
49 productIndexToProductState.push_back(s_q);
50 prodInitial.push_back(index);
51 todo.push_back(index);
52 }
53
55 std::size_t curRow = 0;
56 while (!todo.empty()) {
57 state_type prodIndexFrom = todo.front();
58 todo.pop_front();
59
60 product_state_type from = productIndexToProductState.at(prodIndexFrom);
61 // std::cout << "Handle " << from.first << "," << from.second << " (prodIndexFrom = " << prodIndexFrom << "):\n";
62 if (deterministic) {
63 typename matrix_type::const_rows row = originalMatrix.getRow(from.first);
64 for (auto const& entry : row) {
65 state_type t = entry.getColumn();
66 state_type p = prodOp.getSuccessor(from.second, t);
67 // std::cout << " p = " << p << "\n";
68 product_state_type t_p(t, p);
69 state_type prodIndexTo;
70 auto it = productStateToProductIndex.find(t_p);
71 if (it == productStateToProductIndex.end()) {
72 prodIndexTo = nextState++;
73 todo.push_back(prodIndexTo);
74 productIndexToProductState.push_back(t_p);
75 productStateToProductIndex[t_p] = prodIndexTo;
76 // std::cout << " Adding " << t_p.first << "," << t_p.second << " as " << prodIndexTo << "\n";
77 } else {
78 prodIndexTo = it->second;
79 }
80 // std::cout << " " << t_p.first << "," << t_p.second << ": to = " << prodIndexTo << "\n";
81
82 // std::cout << " addNextValue(" << prodIndexFrom << "," << prodIndexTo << "," << entry.getValue() << ")\n";
83 builder.addNextValue(prodIndexFrom, prodIndexTo, entry.getValue());
84 }
85 } else {
86 std::size_t numRows = originalMatrix.getRowGroupSize(from.first);
87 builder.newRowGroup(curRow);
88 for (std::size_t i = 0; i < numRows; i++) {
89 auto const& row = originalMatrix.getRow(from.first, i);
90 for (auto const& entry : row) {
91 state_type t = entry.getColumn();
92 state_type p = prodOp.getSuccessor(from.second, t);
93 // std::cout << " p = " << p << "\n";
94 product_state_type t_p(t, p);
95 state_type prodIndexTo;
96 auto it = productStateToProductIndex.find(t_p);
97 if (it == productStateToProductIndex.end()) {
98 prodIndexTo = nextState++;
99 todo.push_back(prodIndexTo);
100 productIndexToProductState.push_back(t_p);
101 productStateToProductIndex[t_p] = prodIndexTo;
102 // std::cout << " Adding " << t_p.first << "," << t_p.second << " as " << prodIndexTo << "\n";
103 } else {
104 prodIndexTo = it->second;
105 }
106 // std::cout << " " << t_p.first << "," << t_p.second << ": to = " << prodIndexTo << "\n";
107
108 // std::cout << " addNextValue(" << prodIndexFrom << "," << prodIndexTo << "," << entry.getValue() << ")\n";
109 builder.addNextValue(curRow, prodIndexTo, entry.getValue());
110 }
111 curRow++;
112 }
113 }
114 }
115
116 state_type numberOfProductStates = nextState;
117
118 Model product(builder.build(), storm::models::sparse::StateLabeling(numberOfProductStates));
119 storm::storage::BitVector productStatesOfInterest(product.getNumberOfStates());
120 for (auto& s : prodInitial) {
121 productStatesOfInterest.set(s);
122 }
123 std::string prodSoiLabel = product.getStateLabeling().addUniqueLabel("soi", productStatesOfInterest);
124
125 // const storm::models::sparse::StateLabeling& orignalLabels = dtmc->getStateLabeling();
126 // for (originalLabels.)
127
128 return typename Product<Model>::ptr(
129 new Product<Model>(std::move(product), std::move(prodSoiLabel), std::move(productStateToProductIndex), std::move(productIndexToProductState)));
130 }
131};
132} // namespace transformer
133} // namespace storm
This class manages the labeling of the state space with a number of (atomic) labels.
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.
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.
const_rows getRow(index_type row) const
Returns an object representing the given row.
bool hasTrivialRowGrouping() const
Retrieves whether the matrix has a trivial row grouping.
index_type getRowGroupSize(index_type group) const
Returns the size of the given row group.
storm::storage::SparseMatrix< typename Model::ValueType > matrix_type
static Product< Model >::ptr buildProduct(const matrix_type &originalMatrix, ProductOperator &prodOp, const storm::storage::BitVector &statesOfInterest)
std::shared_ptr< Product< Model > > ptr
Definition Product.h:19