I/O Efficient Accepting Cycle Detection*
Total Page:16
File Type:pdf, Size:1020Kb
I/O Efficient Accepting Cycle Detection? J. Barnat, L. Brim, P. Simeˇcekˇ Department of Computer Science, Faculty of Informatics Masaryk University Brno, Czech Republic Abstract. We show how to adapt an existing non-DFS-based accepting cycle detection algorithm OWCTY [10, 15, 29] to the I/O efficient setting and compare its I/O efficiency and practical performance to the existing I/O efficient LTL model checking approach of Edelkamp and Jabbar [14]. The new algorithm exhibits similar I/O complexity with respect to the size of the graph while it avoids quadratic increase in the size of the graph. Therefore, the number of I/O operations performed is significantly lower and the algorithm exhibits better practical performance. 1 Introduction Model checking became one of the standard technique for verification of hard- ware and software systems even though the class of systems that can be fully verified is fairly limited due to the well known state explosion problem [12]. The automata-theoretic approach [33] to model checking finite-state systems against linear-time temporal logic (LTL) reduces to the detection of reachable accepting cycles in a directed graph. Due to the state explosion problem, the graph tends to be extremely large and its size poses real limitations to the verification process. Many more-or-less successful techniques have been introduced [12] to reduce the size of the graph advancing thus the frontier of still tractable systems. Never- theless, for real-life industrial systems these techniques are not efficient enough to fit the data into the main memory. An alternative solution is to increase the computational resources available to the verification process. The two major ap- proaches include the usage of clusters of workstations and the usage of external memory devices (disks). Regarding external memory devices, the goal is to develop algorithms that minimize the number of I/O operations an algorithm has to perform to complete its task. This is because the access to information stored on an external device is orders of magnitude slower than the access to information stored in the main memory. Thus the complexity of I/O efficient algorithms is measured in the number of I/O operations [1]. A lot of effort has been put into research on I/O efficient algorithms working on explicitly stored graphs [11, 20, 24, 25]. For an explicitly stored graph, an I/O efficient algorithm typically has to perform a random access operation every ? This work has been partially supported by the Grant Agency of Czech Republic grant No. 201/06/1338 and the Academy of Sciences grant No. 1ET408050503. time it needs to enumerate edges incident with a given vertex. However, in model checking, the graphs are often given implicitly which means that the edges incident with a given vertex are computed on demand from the vertex itself. Thus, an algorithm working on an implicitly given graph may save up to |V | random access operations, which may have significant impact on the performance of the algorithm in practice. A distinguished technique that allows for an I/O efficient implementation of a graph traversal procedures is the so called delayed duplicate detection [21, 22, 26, 32]. A traversal procedure has to maintain a set of visited vertices to prevent their re-exploration. Since the graphs are large, the set cannot be completely kept in the main memory and must be stored on the external memory device. When a new vertex is generated it is checked against the set to avoid its re- exploration. The idea of the delayed duplicate detection technique is to postpone the individual checks and perform them together in a group for the price of a single scan operation. Unfortunately, the delayed duplicate detection technique is incompatible with the depth-first search (DFS) of a graph [14]. Therefore, most approaches to I/O efficient (LTL) model checking suggested so far, have focused on the state space generation and verification of safety properties only. The first I/O efficient al- gorithm for state space generation has been implemented in Murϕ [32]. Later on, several heuristics for the state space generation were suggested and imple- mented in various verification tools [16, 18, 23]. The first attempt to verify more than safety properties was described in [19], however, the suggested approach uses the random search to find a counterexample to a given property. Therefore, it is incomplete in the sense that it is not able to prove validity of the property. To the best of our knowledge, the only complete I/O efficient LTL model checker was suggested by Edelkamp and Jabbar in [14] where the problematic DFS-based algorithm was avoided by the reduction of the accepting cycle detec- tion problem to the reachability problem [7, 31] whose I/O efficient solution was further improved by using the directed (A∗) search and parallelism. The algo- rithm works in the on-the-fly manner meaning that only a part of the state space is constructed, which is needed in order to check the desired property. The reduc- tion transforms the graph so that the size of the graph after the transformation is asymptotically quadratic with respect to the original one. More precisely, the size of the resulting graph is |F | × |G|, where |G| is the size of the original graph and |F | is the number of accepting vertices. As the external memory algorithms are meant to be applied to large scale graphs, the quadratic increase in the size of the graph is significant and, according to our experience, it often aborts due to the lack of space. This is especially the case when the model is valid and the entire graph has to be traversed to prove the absence of an accepting cycle. The approach is thus mainly useful for finding counterexamples in the case a standard verification tool fails due to the lack of memory. However, completeness is a very important aspect of LTL model checking as well. A typical scenario is that if the system is invalid and the counterexample found, the system is corrected and the property verified again. In the end, the graph must be traversed completely anyway. Since DFS-based algorithms cannot be used for I/O efficient solution to the accepting cycle detection, a non-DFS algorithm is required. The situation very much resembles a similar one encountered in cluster-based approach to LTL model checking [2]. The main problem of the approach is that the optimal se- quential algorithm (e.g. Nested DFS [17]) is inherently sequential and hence difficult to be parallelized [30]. Consequently, several new parallel algorithms that do not build on top of the depth-first search have been introduced [3, 4, 8–10]. In this paper we show how to adapt a parallel enumerative version of the One Way Catch them Young Algorithm (OWCTY) [10, 15, 29] to the I/O efficient setting and compare its I/O efficiency and practical performance with the I/O efficient LTL model checking algorithm by Edelkamp and Jabbar [14]. 2 I/O Efficient OWCTY Algorithm As discussed above, an I/O efficient solution to LTL model checking has to build upon a non-DFS algorithm. A particularly suitable algorithm for enumerative LTL model checking was described in [10]. The goal of the algorithm is to com- pute the set of vertices that are reachable from a vertex on an accepting cycle. If the set is empty, there is no accepting cycle in the graph, otherwise the presence of an accepting cycle is ensured [15, 29]. The algorithm repeatedly computes approximations of the target set until a fixpoint is reached. All reachable vertices are inserted into the approxima- tion set (ApproxSet) within the procedure Initialize-ApproxSet. After that, vertices violating the condition are gradually removed from the approximation set using procedures Elim-No-Accepting and Elim-No-Predecessors. Pro- cedure Elim-No-Accepting removes those vertices from the approximation set that have no accepting ancestors in the set, i.e. vertices that lie on lead- ing non-accepting cycles. Procedure Elim-No-Predecessors removes vertices that have no ancestors at all, i.e. leading vertices lying outside a cycle. The pseudo-code is given as Algorithm 1. Algorithm 1 DetectAcceptingCycle Require: Implicit definition of G=(V,E,ACC) 1: Initialize-ApproxSet() 2: oldSize ← ∞ 3: while (ApproxSet.size 6= oldSize) ∧ (ApproxSet.size > 0) do 4: oldSize ← ApproxSet.size 5: Elim-No-Accepting() 6: Elim-No-Predecessors() 7: return ApproxSet.size > 0 The approximation set induces an approximation graph. The in-degree of a vertex in the approximation graph corresponds to the number of its immediate predecessors in the approximation set. To identify vertices without ancestors in the approximation set, the in-degree is maintained for every vertex of the ap- proximation graph. Procedure Elim-No-Predecessors then works as follows. All vertices from the set with a zero in-degree are moved to a queue from where they are dequeued one by one. Dequeued vertices are eliminated from the set, and the in-degrees of its descendants are updated. If an in-degree drops to zero, the corresponding vertex is inserted into the queue to be eliminated as well. The procedure eliminates vertices in a topological order and hence the queue becomes empty as soon as all vertices preceding a cycle are eliminated. Procedure Elim-No-Accepting works as follows. If a vertex has an accept- ing ancestor in the approximation set, it has to be reachable from some accepting vertex in the set. Therefore, the procedure first removes all non-accepting ver- tices from the set and sets the numbers of predecessors of all vertices remaining in the set to zero.