6.1 Mixing MTBDDs and Arrays
6.1.2 Our Improved Method
What we need is a way of determining the actual row and column index of each matrix element, in terms of reachable states only. We will assume that the set of reachable states, say ˆS ⊆ S, is indexed from 0 to | ˆS|−1 and that these are in the same order that they were in S. This means we can adopt a similar approach to the previous section, recursively computing submatrix entries locally and using offsets to determine the actual indices.
In the previous section, we increased the offsets r and c at each level of recursion by a fixed power of two, corresponding to the size of the submatrices on the next level. Now, the increase will instead depend on the number of rows or columns in these submatrices which correspond to reachable states. Our approach will be to precompute this information and store it on the MTBDD so that it can be read off as we traverse the data structure.
More precisely, we will construct a new MTBDD from the old one, in which each node is labelled with an offset. For a row node, this offset will indicate how many ‘reachable rows’ there are in the top submatrix and, for a column node, it will indicate how many ‘reachable columns’ there are in the left submatrix. In both cases, the submatrix in question corresponds to taking the else edge (as illustrated previously in Figure 3.19). This means that, when tracing a path from the root node of the MTBDD to one of its terminals, representing some matrix entry, the actual row and column indices of this entry can be determined by summing the offsets on nodes labelled with row and column variables, respectively, from which the then edge was taken. In this section, we will describe this new data structure in more detail and present a modified traversal algorithm for it. In the following section, we will explain precisely how it is constructed.
We christen this data structure an offset-labelled MTBDD. It is essentially an MTBDD, but with two important differences. Firstly, as described above, every non-terminal node is labelled with an integer value, which will be used to compute reachable row and col-
umn indices. Secondly, the MTBDD does not need to be fully reduced. In fact, our requirements in this respect are slightly more complex, as we now explain.
Recall from Section 3.7 that there are two types of reduction performed to minimise the size of an MTBDD: merging of shared nodes, i.e. those on the same level and with identical children; and removal of nodes for which the then and else edges point to the same node, introducing one or more skipped levels. In an offset-labelled MTBDD, the second type of reduction is only permitted when both the then and else edges point to the zero terminal. This means that every edge from every node points either to a node in the level immediately below it or directly to the zero terminal. Consequently, we now have a one-to-one correspondence between paths through the offset-labelled MTBDD leading to a non-zero terminal and the entries of the matrix which it represents.
There are two reasons for doing this. Firstly, the traversal process can be sped up because we no longer need to check for skipped levels at every node. Secondly, and more importantly, we need the offsets which are used to compute matrix entry indices to be on every level and these are stored on the nodes. Note that the exception for edges going directly to the zero terminal is safe because we are only interested in extracting non- zero matrix entries. In fact, since our matrices are typically very sparse, removing this exception would slow the extraction process down considerably.
Furthermore, in offset-labelled MTBDDs the first type of MTBDD reduction, merging of shared nodes, is not compulsory. When we describe the construction process in the next section, we will see instances where it is important not to merge shared nodes. Note that the principal reason for maintaining fully reduced MTBDDs in normal use is to preserve the canonicity property of the data structure. As described in Section 3.7.3, this allows extremely efficient manipulation of MTBDDs by facilitating features such as caching of intermediate results in the computed table. Offset-labelled MTBDDs are not canonical but do not need to be. The data structure will be constructed once, used to perform numerical computation via traversal and then discarded: no manipulation is required.
In Figure 6.4, we give the algorithm, TraverseOffsets, which is used to traverse the new, offset-labelled MTBDD data structure and extract the matrix entries. Compare the new algorithm in Figure 6.4 with the old version in Figure 6.1. The key differences are as follows. Firstly, we do not need to check for skipped levels. This removes a significant amount of effort. The exception to this is that we must still check for edges which skip directly to the zero terminal. Secondly, in the recursive portion of the algorithm, instead
of adding 2n−i to the indices r and c, we use the node offsets, denoted off (m) for node m.
Figure 6.5 shows an example of the new data structure representing the same ma- trix M as in the previous section. Compare this to the MTBDD in Figure 6.2. Note the addition of the offset labels and also the insertion of an extra node on the path to the 3 ter-
TraverseOffsets(m, i, r, c) 1. if (m = Const(0)) then 2. return 3. else if (i = n + 1) then 4. UseMatrixEntry(r, c, val (m)) 5. return 6. endif 7. e := else(m) 8. t := then(m) 9. if (e 6= Const(0)) then 10. TraverseOffsets(else(e), i + 1, r, c)
11. TraverseOffsets(then(e), i + 1, r, c + off (e)) 12. endif
13. if (t 6= Const(0)) then
14. TraverseOffsets(else(t), i + 1, r + off (m), c)
15. TraverseOffsets(then(t), i + 1, r + off (m), c + off (t)) 16. endif
Figure 6.4: The refined traversal algorithm TraverseOffsets
minal. Figure 6.6 explains the traversal of the data structure by the TraverseOffsets algorithm. Again, each row corresponds to a single matrix entry. The table gives both the path through the MTBDD corresponding to this entry and the offsets which have been summed to determine its row and column indices. The table in Figure 6.6 can be compared to the equivalent one for the TraverseMtbdd algorithm in Figure 6.3. Since only 3 of the 4 states are reachable, all references to state 3 in the previous table are replaced with 2 in the new one.
The offset-labelled MTBDD and the traversal algorithm TraverseOffsets can now be used to efficiently perform matrix-vector multiplication where the matrix is stored as an MTBDD and the vector as an array. This allows us to implement iterative numerical methods, as required for probabilistic model checking, using these two data structures. First though, we need to consider how this new data structure can be generated.