Computing Transition Priorities for Live Petri Nets

In this paper, we propose an approach to implementation of the algorithm for computing transition priorities for live Petri nets. Priorities are a form of constraints which can be imposed to ensure liveness and boundedness of a Petri net model. These properties are highly desirable in analysis of different types of systems, ranging from business processes systems to embedded systems. The need for them is imposed by resource limitations of real-life systems. The algorithm for computing transition priorities considered in the study has exponential time complexity, since it is based on construction and traversal of the coverability graph. However, its performance may be sufficient for the majority of real-life cases. This paper covers the design considerations of the implementation, including the approach to handling the high time complexity of the algorithm and optimizations introduced in the original algorithm. We target parallelization as the main method of performance increase. While, for some steps of the algorithm the parallelization approach proves to be viable, for others its applicability is questioned. Analysis of different design decisions is provided in the text. On the basis of the actual implementation an application for computing priorities was developed. It can be used for further analysis of the algorithm applicability for real-life cases.


Introduction
Petri nets are widely applicable for modeling and analysis of various distributed systems ranging from business processes systems to biological systems. Regardless the nature of such systems their models always have some properties of liveness and boundedness. Properties of liveness include reiteration of all subprocesses and return to some initial state of the system. Properties of boundedness are those related to finiteness of the set of possible states. In most of the cases, it is highly desirable for the system to have finite set of states, i.e. its model should be bounded. Let us consider, for example, a Petri net shown in fig. 1. This Petri net is a model of a simple producer/consumer system, where the left cycle represents a producer, the right cyclea consumer, and the place p3 between them is a buffer. This net is live, i.e. in every reachable marking each transition can eventually fire. The net is unbounded, since the number of tokens in p3 can be arbitrary large. It means that the buffer overflow will eventually occur. Thus, it is desirable to transform the model into live and bounded preserving the original structure of the net. The problem of transformation of a given live and unbounded Petri net into live and bounded without modification of its original structure was considered in [1] and [2]. The authors focused on two approaches to control of Petri net behavior: through priority-based and through time-based constraints on transition firings. Algorithms for computing priorities and time intervals were proposed by them. This paper continues their study. The proposed algorithms are based on construction of the spine tree, which is a subgraph of the reachability tree, containing exactly all feasible cyclic runs in a net. It represents the behavior that should be saved in a transformed Petri net to preserve the liveness property of the original net. The procedure of obtaining those cyclic runs each of which contains all transitions and is reachable from the initial marking was introduced in [3]. It is based on construction of the coverability graph that is finite by definition but can be extremely large. This fact affects negatively the overall time complexity of the algorithms.
Nevertheless, the performance of these algorithms may be optimal for the majority of real life cases. In this paper we target implementation considerations of the above mentioned algorithms. The study is focused on computation of transition priorities leaving apart computation of time intervals, since these two procedures have common foundation. The main contributions of this paper are the following. 1) An approach to implementation design of the algorithm for computing transition priorities based on construction steps optimization and adoption of parallelization. 2) A brief analysis of the actual implementation coded in Java programming language.
3) A Java application with GUI built upon the algorithm implementation that can be used for running experiments and researching the applicability of the algorithm in practical cases. The application supports the Petri Net Markup Language (.pnml) file format and can be used along with other tools for Petri net modeling and analysis. The source code of the application along with build and run instructions can be found in the repository 1 . The structure of the paper is as follows. In Section 2 the main theoretical preliminaries are provided. Section 3 contains a brief description of the algorithm under consideration. In section 4 the approach to implementation design is described and results of implementation analysis are presented. Section 5 concludes the paper.

Preliminaries
For a more detailed introduction to the concepts presented in this section see, e.g., [4]. Let ℕ denote the set of natural numbers (including 0). We define a marked Petri net as a tuple ( , ) > 0. A marking of a net is a mapping : ⟶ ℕ. The initial marking is represented by 0( ) tokens on place . An initial run is a sequence of transition firings, starting with the initial marking. Reachable markings are all those markings, which can be reached by the initial run. A cyclic run is a finite run starting and ending at the same marking. A reachability graph of a Petri net is a labeled directed graph, in which vertices correspond to reachable markings of the net. A directed edge from vertex to vertex ′ is labeled with transition , which is enabled by marking represented by and leads to marking ′ represented by ′.
A Petri net is bounded if, for each place , the number of tokens on does not exceed some fixed bound ∈ ℕ, i.e. for each reachable marking m the following is true: ( ) ≤ . Thus, a Petri net is bounded if and only if its reachability graph is finite. A marking ′ strictly covers a marking if and only if for each place ∈ , ′( ) ≥ ( ) and ′ ≠ . In case of unbounded nets coverability graphs provide finite information about behavior. The construction of coverability graph is based on the notion of the generalized marking, which is formally a mapping: ⟶ ℕ ⋃ { }, where denotes an arbitrary number of tokens on a place. A coverability graph is defined constructively: it is constructed successively like the reachability graph starting from the initial marking. However, in case of the coverability graph, when a marking ′ represented by a current leave ′ in the reachability graph strictly covers a marking m represented by a vertex , lying on the path from the root to ′, then in the coverability graph the vertex ′ gets a marking , where Fig. 2 shows a coverability graph of the example shown in fig. 1. . The coverability net is formally defined as: The extended coverability net is the coverability net, that contains additional places to capture the token count change for -marked places of the original net. For each unbounded place p in the original net a place is added to the extended coverability net. If transition is in the pre-set of in the original net , then all transitions ′ ∈ ′ with ′( ′) = are in the pre-set of the added place . Arc weights are taken into account. The same holds for the post-sets of added places. The initial marking of added places coincides with the initial marking of these places in the original net.   We define the set of all minimal feasible cyclic runs together with prefixes leading to the cycles in a Petri net as ( ) = { | * , } where is a minimal feasible cyclic run in and is a finite initial run leading to . A spine tree is a subgraph of a reachability tree, that contains exactly all runs from ( ). The spine tree contains 168 the behavior that should be saved in course of transformation in order to keep a Petri net live. For the Petri net in fig. 1 ( ) Thus, the spine tree of the net has the construction as shown in fig. 4. A priority relation for a Petri net is a partial order ( , ≪), i.e., the relation is reflexive, antisymmetric and transitive. A priority relation ≪ can be specified by assigning a priority label ( ) ∈ ℕ to each transition . Thus, ≪ ′ if and only if ( ) < ( ′). A Petri net with priorities is a Petri net together with a priority relation. In a Petri net with priorities if is a set of all transitions enabled in a marking m, then only transitions with the highest priority may fire.

Algorithm overview
Let be a live and unbounded Petri net. The task is to check, if it is possible to transform this net into live and bounded by adding priorities to its transitions. To accomplish the task we should find those transition priorities, which exclude runs leading to unboundedness. It is possible to distinguish two major stages in the algorithm. The first is the search for cyclic runs in a Petri net. The presence of cyclic runs is a necessary condition for existence of transition priorities for a given Petri net. On the second stage the spine tree is built with the cyclic runs found on the previous stage forming its skeleton. The whole algorithm has the following sequence of actions. 1) Given a Petri net build its coverability graph; 2) Given the coverability graph constructed on the previous step build a coverability net; 3) Transform the coverability net into an extended coverability net; 4) Find behavioral cycles of the extended coverability net; 5) If the set of cyclic runs computed on the previous step is not empty build a spine tree in which the cyclic runs form the skeleton; 6) Given the spine tree build a spine-based coverability tree in which all leaves are colored in either red or green 2 ; 7) Traverse the spine-based coverability tree. For each non-red node a with its incoming edge labeled after transition t1 if there exists a red sibling b with its incoming edge labeled after transition t2 add (t1, t2) to the priority relation; 8) Assign priority labels to the transitions on the basis of the priority relation computed on the previous step. The steps 1-4 form the first stage of the algorithm -search for cyclic runs. The procedure was introduced in [3]. The second stage -computation of a priority relation through spine tree construction -is represented by the steps 5-7. It was described in [1].

Cyclic runs search
The problem of the search for cyclic runs in a Petri net can be reduced to the search for cyclic runs in its extended coverability net. The original algorithm for the cyclic runs search is comprised of four steps. We have reduced the number of steps to two by optimizing the construction phases of coverability and extended coverability nets. The first step is the construction of a coverability graph. This step can not be avoided since the coverability graph is the foundation for the rest of the algorithm. Since the coverability graph can grow exponentially the overall time complexity of the algorithm is also exponential. We have chosen parallelization to target the problem. The implementation of coverability graph construction and traversal steps was designed to be easily parallelized.
Listing 1 demonstrates the pseudocode of the algorithm for building the coverability graph. Each node is processed in the following way: the set of transitions is filtered to find the transitions enabled by the marking corresponding to a node, then all the filtered transitions are fired to produce new generalized markings. Directed arcs are added from the vertex labeled by the marking of the node to the vertices labeled by the produced generalized markings. New nodes are generated from the obtained markings for further processing. Processing of a node does not depend on processing of other nodes so this task can be scheduled in parallel. The actual implementation of the pseudocode has the time complexity (| | * | | * ( ) * | |) where | | is the number of vertices in a coverability graph, | | -the cardinality of the transition set of a Petri net, ( ) -depth of the coverability graph, i.e., the distance from the root to the most distant vertex, and | | -the cardinality of the set of places.

Listing. 1. Pseudocode of the algorithm for building the coverability graph
We have made two implementations of the algorithm: single-threaded and parallel. In the parallel version, node processing tasks are submitted to a thread pool. Since the worker threads process the submitted tasks asynchronously, there is a need for some synchronization mechanism in order to prevent the function call in the master thread from returning before the graph is fully constructed. For the purposes of synchronization, we have used Phaser. It is a reusable synchronization barrier, which is provided by the standard Java library. The two main operations of Phaser are register and arrive. It is possible to block on Phaser, while the number of registered is not equal to the number of arrived. Phaser is incorporated into the implementation in the following way: the master thread submits the first task to the pool and blocks on Phaser, when a working thread generates a new task it is registered in Phaser, and after completion it arrives. Thus, the function call does not return until all the submitted tasks are processed, i.e. the graph is completely built. We used ForkJoinPool from the fork/join Java framework as the implementation of the thread pool, since it provides the workstealing mechanism. If a worker thread runs out of tasks in its pool, it can steal tasks from other threads that are busy. Thus, all the available processing powers are utilized and the performance increases. We have also conducted a benchmarking of the two implementations with the use of JMH open source tool. Coverability graph construction for the Petri net in Fig. 1 was benchmarked. The single shot time mode was selected for the test. In this mode the time for a single operation is measured. Thus the "cold" performance of an algorithm is estimated, since no preliminary warm-up is conducted. This mode is most similar to the real-life usage scenario of the algorithm. The results are presented in Table 1. The results in Table. 1 demonstrate that the single-threaded implementation performs slightly better for the Petri net of fig. 1. The probable reason is the low complexity of the net. The time complexity of processing a single node is (| | * ( ) * | |) and, hence, there are strong reasons to believe, that with increase in concurrency of the model and in number of transitions and places the parallel implementation will outperform the single-threaded one. Further experiments conducted with more complex nets proved this assumption. The construction of the coverability net and the extended coverability net was optimized: we used coverability graph built on the previous stage and a separate data structure for capturing the number of tokens on unbounded places to find all feasible cyclic runs. Initially, we have designed an implementation of the algorithm for the cyclic runs search, which also targeted parallelization. That implementation resembled closely the implementation of the coverability graph construction algorithm. Both of them were built upon separate nodes processing and since this procedure is completely independent for each node it can be easily parallelized. However, several tests proved this approach to be practically inapplicable. The reason is high memory space consumption. The number of enqueued nodes (logically they represent paths to be checked for cyclic behavior) increases exponentially rapidly exhausting memory capacity. Thus, we have designed another implementation based on the backtracking principle. It is much more memory efficient, since only one node (path) is processed and stored in memory in every single moment of time. The problem with this approach is that it is difficult to be parallelized. And the developed implementation is also single-threaded. However, processing of each path in the actual implementation has the time complexity (| |) where | | is the number of edges in the coverability graph. This means that in general case, the amount of work needed to be done to process a single path is insignificant for a modern process, and hence no major increase in performance should be observed with addition of parallelization. Nevertheless, the transformation of the proposed singlethreaded implementation into a parallel one can be a subject of future research. The pseudocode of the cyclic runs search procedure based on backtracking is presented in Listing 2.  A comment on the pseudocode in Listing 2 should be provided. Since it is possible to get into a vertex in multiple different ways, and every time each edge incident from it and not in path should be checked, we have introduced the notion of phase to take account of visited edges and prevent an infinite traversal.

Priorities computation
The rest of the algorithm is based on the construction of the spine tree of a Petri net and its traversal. The procedure of constructing the spine tree from the list of cyclic runs is quite straightforward and we omit its description here. Similarly, the algorithm for the construction of the spine-based coverability tree was described in details in [1] and we have mostly followed this description in the process of implementation design. In the spine-based coverability tree the red leaves (ω-leaves) are those nodes which strictly cover some markings preceding them in their branches. To guarantee boundedness they should be cut off. This is achieved with priorities. Listing 3 demonstrates the pseudocode for computing priority relation on the basis of the spine-based coverability tree. It was proved in [1] that if the relation ≪ constructed for the live and unbounded Petri net ( , ) is a partial order (i.e. antisymmetric), then ≪ is a priority relation for , and the Petri net ( , ≪, ) is live and bounded. However, it is possible for the algorithm in Listing 3 to produce relations with contradictory pairs, thus violating the antisymmetric property. In [2] it is suggested to remove such contradictory pairs from the relation. In this case the Petri net with the resulting priority relation should be checked for boundedness and liveness. The concluding step of the algorithm implementation is computation of priority labels of transitions. For transitions which are not included in the priority relation the highest priority is assigned since this means that the order of their occurrence is not important. For the rest of transitions a topological sorting is used to order the transitions in the ascending priority and assign a label to each of them with respect to their position. This is possible because the priority relation can be represented as a directed acyclic graph. It should be noted that the obtained priorities can be stronger than it is required since topological sorting does not take into account relative independence of transitions in the priority relation.

Conclusion
In this paper, we have presented our approach to implementation design of the algorithm for computing transition priorities for live Petri nets. In the worst case the performance of the algorithm may be not optimal for the task since it is based on construction and traversal of the coverability graph which can grow exponentially. However, it may prove optimal for the majority of real-life system models. We have proposed parallelization as the main method of handling the complexity. A number of experiments were conducted to estimate its effect on the performance of the implementation. While for some steps this approach proved to be viable, for others its applicability was questioned.
Priority constraints can be helpful in analysis of technical systems, since they ensure liveness and boundedness of such systems. For the purposes of computing priorities the application was developed. This application is based on the algorithm implementation presented in the paper and can be used for further studies on the problem. However, it should be noted that the application inherits the weak points of the algorithm it is based on, i.e. the high time complexity. Hence, further experiments should be conducted to determine the limits of applicability of the application and the algorithm in particular.