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