Software Tools for Technology Transfer manuscript No.
(will be inserted by the editor)
Directed Explicit-State Model Checking in the Validation
of Communication Protocols
Stefan Edelkamp, Stefan Leue, Alberto Lluch-Lafuente
Institut für Informatik
Albert-Ludwigs-Universität Freiburg
Georges-Köhler-Allee Geb. 051
D-79110 Freiburg, Germany
e-mail: [edelkamp|leue|lafuente]@informatik.uni-freiburg.de
The date of receipt and acceptance will be inserted by the editor
Abstract. The success of model checking is largely
based on its ability to efficiently locate errors in software
designs. If an error is found, a model checker produces
a trail that shows how the error state can be reached,
which greatly facilitates debugging. However, while current
model checkers find error states efficiently, the counterexamples
are often unnecessarily lengthy, which hampers
error explanation. This is due to the use of “naive”
search algorithms in the state space exploration.
In this paper we present approaches to the use of
heuristic search algorithms in explicit-state model checking.
We present the class of A* directed search algorithms
and propose heuristics together with bitstate
compression techniques for the search of safety property
violations. We achieve great reductions in the length of
the error trails, and in some instances render problems
analyzable by exploring a much smaller number of states
than standard depth-first search. We then suggest an improvement
of the nested depth-first search algorithm and
show how it can be used together with A* to improve
the search for liveness property violations. Our approach
to directed explicit-state model checking has been implemented
in a tool set called HSF-SPIN. We provide experimental
results from the protocol validation domain
using HSF-SPIN.
Keywords: Model Checking, Directed Search, Protocol
Validation
1 Introduction
Model Checking [6] is a formal analysis technique that
has been developed to automatically validate 1 functional
1 Within the scope of this paper we use the word “validation” to
denote the experimental approach to establishing the correctness
of a piece of software, while we use the word “verification” to
properties for software or hardware systems. The properties
are commonly specified using some sort of a temporal
logic or using automata. There are two primary approaches
to model checking. First, symbolic model checking
[28] uses a symbolic representation for the state set,
usually based on binary decision diagrams. Property validation
in symbolic model checking amounts to symbolic
fixpoint computation. Explicit state model checking uses
an explicit representation of the system’s global state
graph, usually given by a state transition function. An
explicit state model checker evaluates the validity of the
temporal properties over the model by interpreting its
global state transition graph as a Kripke structure, and
property validation amounts to a partial or complete
exploration of the state space. In this paper we focus
on explicit state model checking and its application to
the validation of communication protocols. The protocol
model we consider is that of collections of extended
communicating finite state machines as described, for instance,
in [5] and [17]. Communication between two processes
is either realized via synchronous or asynchronous
message passing on communication channels (queues) or
via global variables. Sending or receiving a message is
an event that causes a state transition. The system’s
global state space is generated by the asynchronous cross
product of the individual communicating finite state machines
(CFSMs). We follow the Promela computational
model [20].
The use of model checking in system design has one
great advantage over the use of deductive formal verification
techniques. Once the requirements are specified and
the model has been programmed, model checking validation
can be implemented as a push-button process that
either yields a positive result, or returns an error trail.
Two primary strategies for the use of model checking in
the system design process can be observed.
denote the use of formal theorem proving techniques for the same
purpose.
2 S. Edelkamp and S. Leue and A. Lluch-Lafuente: Directed Explicit-State Model Checking
– Complete validation is used to certify the quality of
the product or design model by establishing its absolute
correctness. However, due to the large size of
the search space for realistic systems it is hardly ever
possible to explore the full state space in order to
decide about the correctness of the system. In these
cases, it either takes too long to explore all states in
order to give an answer within a useful time span, or
the size of the state space is too large to be stored
within the bounds of available main memory.
– The second strategy, which also appears to be the one
more commonly used, is to employ the model checker
as a debugging aid to find residual design and code
faults. In this setting, one uses the model checker as
a search tool for finding violations of desired properties.
Since complete validation is not intended, it suffices
to use hashing-based partial exploration methods
that allow for covering a much larger portion of
the system’s state space than if complete exploration
is needed.
When pursuing debugging, there are some more objectives
that need to be addressed. First, it is desirable to
make sure that the length of the counterexample is short,
so that error trails are easy to interpret. Second, it is desirable
to guide the search process to quickly find a property
violation so that the number of explored states is
small, which means that larger systems can be debugged
this way. To support these objectives we present our approach
to directed model checking, i.e. model checking
combined with heuristic search.
Our model-checker HSF-SPIN extends the SPIN
framework with various heuristic search algorithms to
support directed model checking, e.g. A* [19] and iterative
deepening A* [24]. Experimental results show
that in many cases the number of expanded nodes and
the length of the counter-examples are significantly reduced.
HSF-SPIN has been applied to the detection of
deadlocks, invariant and assertion violations, and to the
validation of LTL properties. In most instances the estimates
used in the search are derived from the properties
to be validated, but HSF-SPIN also allows some designer
intervention so that targets for the state space search can
be specified explicitly in the Promela code.
We propose an improvement of the nested depth-first
search algorithm that exploits the structure of never
claims. For a broad subset of the specification patterns
described in [10], such as Response and Absence,
the proposed algorithm performs less transitions during
state space search and finds shorter counterexamples
compared to classical nested depth-first search. Given
a Promela never claim A the algorithm automatically
computes a partitioning of A in linear time with respect
to the number of states in A. The obtained partitioning
into non-, fully and partially accepting strongly connected
components will be exploited during state space
exploration.
Precursor Work. Much of the content of this paper is a
revision of work that was first published in [13] and [12].
The former paper considers safety property analysis for
simple protocols. The latter paper extends this work
by providing an approach to validating LTL-specified
liveness properties and experimenting with a larger set
of protocols. Previously unpublished results include the
correctness result for the improved nested depth-first
search algorithm as well as an extended experimental
evaluation of our approach.
Structure of Paper. In Section 2 we review automatabased
model checking. Section 3 introduces into directed
search algorithms, including A*. Heuristic estimate functions
to be used in safety property analysis of communication
protocols are suggested in Section 4. We describe
the HSF-SPIN tool set in Section 5 and present experimental
results for safety properties in Section 6. In Section
7 we propose an improvement to the nested depthfirst
search algorithm used in the analysis of liveness
properties and show how this algorithm can be combined
with heuristic search. Experimental results on liveness
property validation are given in Section 8. We discuss
related work in Section 9 and conclude in Section 10.
2 Automata-based Model Checking
In this Section we review the automata theoretic framework
for explicit state model checking (c.f. [6]), describe
the validation algorithms in use, and present a practical
model checker, the SPIN tool set.
2.1 Automata-theoretic Framework
Since we model reactive systems with infinite behaviors,
the appropriate formalization for words over state sequences
of these systems are Büchi automata. They inherit
the syntactic structure of finite state automata but
have a different acceptance condition. An infinite run of
a Büchi automaton A over an alphabet ΣA of state symbols
is accepting if the set of elements of ΣA that appear
infinitely often in the run has a non-empty intersection
with the set of accepting states of A. This extends to
finite runs by assuming that the final state will be re-
peated forever. The language L(A) ⊆ Σ ∗ A
consists of all
accepting runs of A. It is sometimes helpful to specify
requirements on reactive systems by using some form
of a Temporal Logic. In this paper we use Linear Time
Temporal Logic (LTL) as defined in [27]. In LTL, the
operator ✷ represents the modality globally (G) and the
operator ✸ represents the modality eventually (F ).
In automata-based Model Checking we are interested
in determining whether the system M, represented by
Büchi automaton B, satisfies a property specification S,
given by another Büchi automaton A. A can either be
given directly, or it can be automatically derived from
S. Edelkamp and S. Leue and A. Lluch-Lafuente: Directed Explicit-State Model Checking 3
¬p ∨ (p ∧ q)
sa
q
p ∧ ¬q
true
n0
s1
¬q
p ∧ ¬q
Fig. 1. Büchi automaton for response property (top left) and for
its negation (bottom right).
an LTL property specification. While this derivation is
exponential in the size of the formula, typical property
specifications result in small LTL formulae so that this
complexity is not a practical problem. The Büchi automaton
B satisfies A iff L(B) ⊆ L(A). This is equivalent
to L(B) ∩ L(A) = ∅, where L(A) denotes the complement
of L(A). Note that Büchi automata are closed
under complementation. In practice, L(A) can be computed
more efficiently by deriving a Büchi automaton
from the negation of an LTL formula. Therefore, in the
SPIN validation tool LTL formulae representing a desired
property are first negated, and then translated into
an equivalent Büchi automaton. In the terminology of
the SPIN model checker [21] and its Promela input language
this automaton is called a never claim, and we
will adopt this terminology throughout this paper.
As an example we consider the commonly used response
property which states that, whenever a certain
request event occurred, a response event will eventually
follow. Assume that the state following the occurrence
of the request is represented by the state predicate p,
and that a state following the response is denoted by q.
The corresponding LTL formula is φ : ✷(p → ✸q) and
its negation is ¬φ : ✸(p ∧ ✷¬ q). The Büchi automaton
and the corresponding Promela never claim for the
negated response property are illustrated in Figure 1.
The emptiness of L(B)∩L(A) is determined using an
on-the-fly algorithm based on the synchronous product
of N and B, where L(N ) = L(A). Assume that N is in
state s and B is in state t. B can perform a transition out
of t if N has a successor state s ′ of s such that the label
of the edge from s to s ′ represents a proposition satisfied
in t. A run of the synchronous product is accepting if it
contains a cycle through at least one accepting state of
N . L(B) ∩ L(A) is empty if the synchronous product
does not have an accepting run.
We use the standard distinction of safety and liveness
properties. Safety properties refer to states, whereas
liveness properties refer to paths in the state transition
diagram. Safety properties can be validated through a
simple depth-first search on the system’s state space,
while liveness properties require a two-fold nested depth-
na
¬q
Nested-DFS(s)
hash(s)
for all successors s ′ of s do
if s ′ not in the hash table then Nested-DFS(s ′ )
if accept(s) then Detect-Cycle(s)
Detect-Cycle(s)
flag(s)
for all successors s ′ of s do
if s ′ on Nested-DFS-Stack then
exit LTL-Property violated
else if s ′ not flagged then Detect-Cycle(s ′ )
Fig. 2. Nested Depth-First Search
first search. When property violations are detected, the
model checker will return a witness (counterexample)
which consists of a trace of events or states encountered.
2.2 Search Algorithms
For the validation of safety properties a simple complete
state graph traversal algorithm is sufficient. This is usually
either a depth-first (DFS) or a breadth-first (BFS)
search algorithm. When a property violating state is encountered,
the search stack contains the witness that
will be made available to the user. BFS finds errors with
minimal witness length, but is rather memory inefficient.
DFS is more memory efficient, but tends to produce witnesses
of non-optimal length.
Since liveness properties refer to execution paths, a
different search approach is needed. The detection of
liveness property violations entails searching for accepting
cycles in the state graph. This is typically achieved
by nested depth-first search (Nested-DFS) that can be
implemented with two stacks as shown in Figure 2. As
for safety properties, the search stacks will be used to
construct the witness. In case a property violation is
discovered, the first stack will contain the path into an
accepting state, while the second stack will illustrate the
cycle through the accepting state.
2.3 The Model Checker SPIN
SPIN [21] is a model checking tool implementing the
above discussed approach to automata-based model
checking. Its input language Promela permits the definition
of concurrent processes, called proctypes in Promela
parlance, as well as synchronous or asynchronous communication
channels and a limited set of C-like data
structures. Concurrency in SPIN is interpreted using
an interleaving approach. Properties can be specified in
various ways. To express safety properties, the Promela
code can be augmented with assertions or deadlock state
characterizations. In order to express liveness properties,
Promela models can be extended by never claims
4 S. Edelkamp and S. Leue and A. Lluch-Lafuente: Directed Explicit-State Model Checking
that express undesired properties of the model. SPIN
also provides an automatic linear temporal logic (LTL)
to never claim translator. SPIN implements the synchronous
product construction approach to determine
the emptiness of the intersection of the Promela model
and the never claim. SPIN uses on-the-fly state space
exploration algorithms, and implements various optimizations
such as, for instance, partial order reduction.
Promela models can be simulated randomly, user-guided
or following an error trail. SPIN has a line-oriented as
well as a graphical user interface, called XSPIN. For a
more detailed discussion of SPIN we refer to the literature
on the SPIN web site 2 .
2.4 Error Trails
If property violations are found, error trails contain important
debugging information. Succinctness of these
trails is essential for an easy comprehension of the discovered
design faults. Lengthy trails can impede proper
error trail interpretation.
We illustrate the impact of long error trails with the
following example. We refer to the preliminary design of
a Plain Old Telephony System (POTS) that we first presented
in [23]. This model was generated with the visual
modeling tool VIP. It is a “first cut” implementation of
a simple two-party call processing, and we know that
it is full of faults of various kind. However, in [23] we
used SPIN to show that this model is actually capable
of connecting two telephones. The model consists of two
user processes UserA and UserB representing the environment
behaviour of the switch, as well as two phone
handler processes PhoneHA and PhoneHB representing the
software instances that control the internal operation of
the switch according to signals (on-hook, off-hook, etc.)
received from the environment. Due to space constraints
we have to rely on an intuitive understanding of call processing
behaviour and the type of signals that are used,
for a more detailed description we refer to [23].
Our objective now is to use SPIN in order to debug
the POTS model. We are first interested in knowing
whether certain inconsistent global system states
are reachable. For instance, such an inconsistent state
is reached when all user processes and one phone handler
process are in conversation states, indicating that
they presume the two phones to be connected, while the
second phone handler is not in a conversation state. Let
p and q denote state propositions that are true when
phone handlers A and B are in the conversation state,
respectively. Let r and s denote state propositions representing
the fact that phones A and B are in the conversation
state, respectively. The absence requirement for
this inconsistent global system state, which is a safety
property, can be characterized by the LTL formula
¬✸(p ∧ ¬q ∧ r ∧ s).
2 netlib.bell-labs.com/netlib/spin.
UserA UserB PhoneHA
{conversation}
off_hook
on_hook
off_hook
dialdigit
on_hook
off_hook
off_hook
dial_tone
dialdigit
... 440 further messages ...
on_hook
off_hook
on_hook
off_hook
{conversation}
dial_tone
busytone
dial_tone
conreq
ringtone
stop_ringtone
connack
stopaudiblering disconnect
{conversation}
PhoneHB
{wait}
Fig. 3. POTS example, error trail produced by SPIN. Names in
curly brackets denote local control states reached at the end of the
trail.
We used SPIN to validate this property. It turns out
not to be valid and SPIN produces an error trail leading
into a global system state violating the property as
partially illustrated in Figure 3. For the engineer experienced
in analyzing call processing sequences it becomes
clear that the undesired state is reachable because of
race conditions and a lack of synchronization between
the UserB and the PhonHB processes, which probably
calls for using synchronous communication at this interface.
On the other hand, the error trail that SPIN
produces has a length of 2,765 steps and comprises 462
message exchanges - it is obvious that analyzing a trail
of that length to locate the cause of an error is an arduous
task. The length of the trail is surprising since
using some backward analysis, and when knowing the
underlying state machine model, it is easy to come up
with a much shorter trail by hand, for instance the trail
comprising just 16 messages given in Figure 4.
S. Edelkamp and S. Leue and A. Lluch-Lafuente: Directed Explicit-State Model Checking 5
UserA UserB PhoneHA
{conversation}
off_hook
dialdigit
dial_tone
audiblering
offhook
on_hook
off_hook
on_hook
off_hook
{conversation}
dial_tone
conreq
ringtone
stop_ringtone
connack
stopaudiblering disconnect
{conversation}
PhoneHB
{wait}
Fig. 4. POTS example, manually generated shorter error trail.
The trail length phenomenon is partly due to the high
degree of nondeterminism inside the system which can
be attributed to the highly concurrent nature of a telephony
switch. Another contributing factor is the search
strategy that SPIN uses when exploring the system’s
state space. Resolution of nondeterminism in Promela
is random, but SPIN implements this using a fixed
priority scheme based on the lexical structure of the
Promela model 3 . SPIN will first explore many execution
sequences that do not lead to the establishment of
a phone call. This means for instance that one phone
calls the other, but then decides to hang up, or both
phones try to call each other concurrently, before the
call sequence converges towards the successful establishment
of a call. The depth-first search strategy that SPIN
employs will first try to explore all action variants of the
first process, and then try out the next process, and so
on. However, the target state would be reached much
more quickly if all processes did a few steps so that a
phone call was established. In conclusion, SPIN is following
a rather uniformed search strategy that neither
takes knowledge about the model nor knowledge about
the property to be validated into account when deciding
which of the possible successor states to explore first.
If, however, the state space of the PhoneA, PhoneB and
PhoneHA processes were explored in such a way that every
state transition brought them nearer to their own
3 Roughly speaking, this means the lexically first transition in
the “first” proctype instance is preferred over other concurrently
enabled transitions.
local conversation state and if PhoneHB avoided the conversation
state, and if globally such transitions were preferred
over non-approximating transitions, then a much
shorter error trail into the property violating state could
be expected. It is the objective of this paper to present
guided search algorithms using heuristic guidelines in the
state exploration similar to the one just described. When
discussing experimental results, we will see that for the
POTS example the automatically obtained shortest error
trail is 1.5 orders of magnitude shorter than the one
generated by SPIN’s exploration.
3 Heuristic Search Algorithms
In this Section we introduce heuristic search algorithms
as alternatives to complete state space exploration in
model checking. We will restrict the discussion to safety
property searches and extend the discussion to liveness
properties later on in this paper.
3.1 Depth-First, Breadth-First and Best-First Search
The detection of a safety property violation is equivalent
to finding a state in which the property is violated.
The algorithms used for finding the property violating
states are typically depth-first and breadth-first
searches. Depth-first search (DFS) is memory efficient,
but does not provide optimal solutions. Breadth-first
search (BFS), on the other hand, is complete and optimal
but very inefficient.
State space exploration in model checking safety
properties can be understood as a search for a path to
a failure state in the underlying problem graph. Since
this graph is implicitly generated by node expansions,
in contrast to ordinary graph algorithms the search terminates
once a target state has been found. BFS and
DFS explore the state space without additional knowledge
about the search goal. The selection of a successor
node in these algorithms is following a fixed, deterministic
selection scheme. Heuristic search algorithms, however,
take additional search information in form of an
estimation function into account. This function returns
a number representing the desirability of expanding a
node. When the nodes are ordered so that the one with
the best evaluation is expanded first and if the evaluation
function estimates the cost of the cheapest path
from the current state to a desired one, the resulting
greedy best-first search (BF) often finds solutions fast.
However, it may suffer from the same defects as depthfirst
search – it is not optimal and the search may be
stuck in dead ends or local minima.
3.2 Algorithm A*
Algorithm A* [19] combines best-first and breadth-first
search for a new evaluation function f(u) by summing
6 S. Edelkamp and S. Leue and A. Lluch-Lafuente: Directed Explicit-State Model Checking
Closed
Open
g
Expansion Criterion:
s ∈ Open with max. g(s)
Closed
Open
g
h
Expansion Criterion:
s ∈ Open with min. g(s) + h(s)
Closed
Open
g
Expansion Criterion:
s ∈ Open with min. g(s)
Closed
Open
h
Expansion Criterion:
s ∈ Open with min. h(s)
Fig. 5. Different search strategies: DFS (top left), BFS (top right),
A* (bottom left) and BF (bottom right)
A*(s)
Open ← {}; Closed← {}; f(s) ← h(s);
Insert(Open, s, f(s))
while (Open �= ∅)
u ← Deletemin(Open); Insert(Closed,u)
if (failure(u)) exit Safety Property Violated
for all v in Γ (u)
f ′ (v) ← f(u) + 1 + h(v) − h(u)
if (Search(Open, v))
if (f ′ (v) < f(v))
DecreaseKey(Open, v, f ′ (v))
else if (Search(Closed, v))
if (f ′ (v) < f(v))
Delete(Closed, v); Insert(Open, v, f ′ (v))
else Insert(Open, v, f ′ (v))
Table 1. The A* algorithm searching for violations of safety properties.
the generating path length g(u) and the estimated cost
h(u) of the cheapest solution starting from u. Figure 5
displays the effect of A* compared to DFS, BFS and
BF and Table 1 depicts the algorithm in pseudo code.
The node expansion of u is indicated by access to the
successor set Γ (u). The set Closed denotes the set of
all already expanded nodes and the list Open contains
all generated but not yet expanded nodes. Similar to
Dijkstra’s single-source shortest path algorithm [9], A*
successively extracts the node u with minimal merit f(u)
from the set Open and terminates if this node represents
a failure state.
As the combined merit f(u) = g(u) + h(u) merely
changes the ordering of the nodes to be expanded, on finite
problem graphs A* is complete. Moreover, by changing
the weights of the edges in the problem graph from
1 to 1 + h(v) − h(u), it can also be observed that A* in
fact performs the same computation as Dijkstra’s singlesource
shortest-path algorithm on the re-weighted graph.
If for all edges (u, v) we have 1+h(v)−h(u) ≥ 0, optimality
of A* is inherited from the optimality of Dijkstra’s
¢¡¢¡¢¡¢¡¢¡¢¡¢¡¢¡¢¡¢
 ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ 
t
 ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ 
¢¡¢¡¢¡¢¡¢¡¢¡¢¡¢¡¢¡¢
¢¡¢¡¢¡¢¡¢¡¢¡¢¡¢¡¢¡¢
 ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ 
 ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ 
¢¡¢¡¢¡¢¡¢¡¢¡¢¡¢¡¢¡¢
¢¡¢¡¢¡¢¡¢¡¢¡¢¡¢¡¢¡¢
 ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ 
 ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ 
¢¡¢¡¢¡¢¡¢¡¢¡¢¡¢¡¢¡¢
¢¡¢¡¢¡¢¡¢¡¢¡¢¡¢¡¢¡¢
 ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ 
 ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ 
¢¡¢¡¢¡¢¡¢¡¢¡¢¡¢¡¢¡¢
¢¡¢¡¢¡¢¡¢¡¢¡¢¡¢¡¢¡¢
 ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ 
 ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ 
¢¡¢¡¢¡¢¡¢¡¢¡¢¡¢¡¢¡¢
¢¡¢¡¢¡¢¡¢¡¢¡¢¡¢¡¢¡¢
 ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ 
Fig. 6. The effect of heuristic search in a grid graph.
algorithm. It can also be shown that the path length
for every expanded node is optimal, so that we correctly
terminate the search at the first target node.
If 1+h(v)−h(u) < 0, negatively weighted edges affect
the correctness proof of Dijkstra’s algorithm. In this case
we have f(u) + 1 + h(v) − h(u) < f(v) such that nodes
that have already been expanded might be encountered
on a shorter path. Contrary to Dijkstra’s algorithm, A*
deals with them by possibly re-inserting nodes from the
set of already expanded nodes into the set of Open nodes
(re-opening). On every path from s to u the accumulated
weights in the two graph structures differ by h(s) and
h(u) only. Consequently, re-weighting cannot introduce
negatively weighted cycles so that the problem remains
(optimally) solvable. One can show that given a lower
bound estimate (admissible heuristic) the solution returned
by the A* algorithm with re-opening is indeed
a shortest one [16]. The main argument is that there is
always a correctly estimated node on an optimal path
in the set Open. This node has to be considered before
expanding any non-optimal goal node.
Figure 6 depicts the impact of heuristic search in
a grid graph. If h is the trivial constant zero function,
A* reduces to Dijkstra’s algorithm, which in case of uniform
graphs further collapses to BFS. Therefore, starting
with s all depicted nodes shown are generated until the
goal node t is expanded. If we use h(u) as the Euclidean
distance to node t, then only the nodes in the hatched
region are ever removed from the Open set.
3.3 Iterative Deepening A*
Algorithm A* has one severe drawback. Once the space
resources for storing all expanded and generated nodes
are exhausted, no further progress can be made. Therefore,
the iterative deepening variant of A*, IDA* [24]
for short, counterbalances time for space. It traverses
the tree expansion of the problem graph instead of the
problem graph itself with a memory requirement that
grows linear with the depth of the search tree. As shown
in the pseudo-code of Table 2, IDA* performs a sequence
of bounded DFS iterations. In each iteration, it expands
all nodes having a total cost not exceeding threshold U,
which is determined as the lowest cost U ′ of all generated
but not expanded nodes in the previous itera-
s
S. Edelkamp and S. Leue and A. Lluch-Lafuente: Directed Explicit-State Model Checking 7
IDA*(s)
Push(S, s, h(s)); U ← U ′ ← h(s)
while (U ′ �= ∞)
U ← U ′ ; U ′ ← ∞
while (S �= ∅)
(u, f(u)) ← Pop(S)
if (failure(u)) exit Safety Property Violated
for all v in Γ (u)
if (f(u) + 1 − h(u) + h(v) > U)
if (f(u) + 1 − h(u) + h(v) < U ′ )
U ′ ← f(u) + 1 − h(u) + h(v)
else
Push(S, v, f(u) + 1 − h(u) + h(v))
Table 2. The IDA* algorithm searching for violations of safety
properties.
S
h 1 (S)
S
h 1 (S)
Fig. 7. Single and double bit-state hashing.
h 2 (S)
tion. IDA* is complete and optimal, since it expands all
nodes with an increasing threshold value for each possible
merit value. Since the average number of successors is
often large, the tree expansion grows exponentially with
increasing depth. Therefore, the last iteration in IDA*
often dominates the search effort.
Due to the depth-first structure of IDA*, duplicate
state expansions may not be detected, resulting in redundancy.
Therefore, similar to depth-first and bestfirst
search as long as memory is available, all generated
nodes are kept in a transposition table. To allow
dynamic updates of node information, for each node in
the table the shortest generating path length and the
corresponding predecessor are also maintained.
To improve duplicate detection, IDA* can be combined
with bit-state hashing [20] which hashes an entire
state vector into a single bit wide table. The bit position
indicates whether the state has been reached before, or
not. In single bit-state hashing, a hash function h1 maps
a state S to position h1(S); S is stored by setting the bit
h1(S) and searched by querying h1(S). Double bit-state
hashing often improves state space coverage by applying
a second hash-function h2. A state S is stored in setting
h1(S) and h2(S) and detected as a duplicate if both bits
are set.
Bit-state hashing as shown in Fig. 7 implies that a
retrieved node might be an unexpected synonym, since
there is no way to distinguish a real duplicate from a
false one. False duplicate detection induces an incomplete
state space traversal, which can be compensated
by different hash functions in different runs. Therefore,
re-expanding a duplicate inside IDA* is dangerous, since
the information of generating path length and predecessor
path length might be false. Subsequently, we avoid
reopening and refer to this variant of IDA* as Partial
IDA*. Note that the advantage of Partial IDA* compared
to A* is that it can track the solution path on the
recursion stack which means that no predecessor link
is needed. Reopening in IDA* will not be encountered
when the heuristic function is consistent. In this case
the priorities f = g + h increase on any generating path,
since f(u) = g(u)+h(u) ≤ g(u)+h(u)+1+h(v)−h(u) =
g(u)+1+h(v) = g(v)+h(v) = f(v) for all edges (u, v) in
the tree expansion of the problem graph. Most practical
heuristics satisfy this criterion. The negative impact of
partial state space coverage due to bitstate search is reduced
by repeating the search with restarts on different
hash functions.
4 Search Heuristics for Safety Properties
In this Section we introduce search heuristics used by
our tool HSF-SPIN in the analysis of safety properties
for Promela models. We use S to denote a global system
state of the model. In S we have a set P(S) ⊆ {Pi | i ≥ 0}
of currently active processes. For the sake of simplicity
we assume a fixed number of processes and write P instead
of P(S). For a process Pi we use pci to refer to the
current local control state. Ti denotes the set of transitions
within the proctype instance Pi and Si denotes the
set of local states of Pi.
Violation of Invariants. System invariants are state
predicates that hold over every global system state S.
When searching for invariant violations it is helpful to
estimate the number of system transitions until a state
is reached where the invariant is violated. Given a logical
global state predicate f, let Hf (S) be an estimation
of the number of transitions necessary until a state S ′
is reached where f holds, starting from state S. Similarly,
let Hf (S) denote the number of transitions necessary
until f is violated, which is helpful when validating
negations of state predicates. Let a be a Boolean variable,
and g and h logical predicates. We give a recursive
definition of Hf as a function of f, with the first part of
the definition given in Figure 8.
In the definition of Hg∧h and Hg∨h, the use of plus
(+) suggests that g and h are independent, which may
not be true. Consequently, the estimate is not necessarily
a lower bound, affecting the optimality condition for A*.
Since it is our goal to obtain short but not necessarily
optimal paths, we tolerate these inadequacies. To obtain
lower bounds, we may replace plus (+) with max.
Formulae describing system invariants may contain
other terms, such as relational operators and Boolean
functions over queues. We extend the definition of Hf
and Hf as shown in Figure 9. The function q?[t] refers to
8 S. Edelkamp and S. Leue and A. Lluch-Lafuente: Directed Explicit-State Model Checking
f Hf (S) Hf (S)
true 0 ∞
false ∞ 0
a if a then 0 else 1 if a then 1 else 0
¬g Hg(S) Hg(S)
g ∨ h min{Hg(S), Hh(S)} Hf (S) + Hg(S)
g ∧ h Hg(S) + Hh(S) min{Hg(S), Hh(S)}
Fig. 8. Definition of Hf for Boolean expressions f.
f Hf (S)
full(q) capacity(q) − length(q)
empty(q) length(q)
q?[t] length of minimal prefix of q without t
(+1 if q lacks message tagged with t)
a ⊗ b if a ⊗ b then 0, else 1
f Hf (S)
full(q) if full(q) then 1, else 0
empty(q) if empty(q) then 1, else 0
q?[t] if head(q) �= t then 0,
else maximal prefix of t’s
a ⊗ b if a ⊗ b then 1, else 0
Fig. 9. Definition of Hf for Boolean queue expressions and relational
operators in f.
f Hf (S) Hf (S)
i@s Di(pci, s) if pci = s 1, else 0
Fig. 10. Definition of Hf for control state predicates in f.
the expression that is true when the message at the head
of queue q is tagged with a message of type t. All other
functions are self-explaining. The symbol ⊗ represents
relational operators (=, �=, ≤, <, >, ≥).
Note that the estimate is coarse but nevertheless very
effective in practice. It is possible to refine these definitions
for specific cases. For instance, Ha=b can be defined
as a − b in case a ≥ b and a is only ever decremented
and b is only ever incremented. However, we have not
pursued these refinements any further.
Another statement that typically appears in system
invariants is the at predicate which expresses that a process
P with a process id pid of a given proctype P T is in
its local control state s 4 . We will write this as i@s, with
s ∈ Si. The corresponding definition is given in Figure
10. We use pci to express the local state of process Pi
in the current global state S. The value Di(u, v) is the
minimal number of transitions necessary for the finite
state machine Pi to reach state u starting from state v,
where u, v ∈ Si. The matrix Di can be efficiently precomputed
with the all-pairs shortest-path algorithm of
Floyd/Warshall in O(|Si| 3 ) time [8]. Note that |Si| is
small in comparison to the overall search space.
4 In Promela this is expressed as PT[pid]@s.
label(t) executable(t, S)
q?x, q asynchronous channel ¬empty(q)
q?t, q asynchronous channel q?[t]
q!m, q asynchronous channel ¬full(q)
condition c c
Fig. 11. Function executable for asynchronous communication operations
and boolean conditions, where x is a variable, and t is a
tag.
Violations of Assertions. The Promela statement
assert allows to label the model with logical assertions.
Given that an assertion a labels a transition (u, v),
with u, v ∈ Ti, then we say a is violated if the formula
f = (i@u) ∧ ¬a is satisfied.
Deadlock Detection. In concurrent systems, a deadlock
occurs if at least a subset of processes and resources is in
a cyclic wait situation. In Promela, S is a deadlock state
if there is no possible transition from S to a successor
state S ′ and at least one of the processes of the system
is not in a valid end state 5 . Hence, no process has
a statement that is executable. In Promela, there are
statements that are always executable, amongst others
assignments, else statements, and run statements used
to start processes. For other statements, such as send or
receive operations or statements that involve the evaluation
of a guard, executability depends on the current
state of the system. For example, a send operation q!m is
only executable if the queue q is not full. The following
enumeration describes executability conditions for communication
statements over asynchronous channels and
for boolean conditions:
1. Asynchronous untagged receive operations (q?x,
with x variable) are not executable if the queue is
empty. The corresponding formula is ¬ empty(q).
2. Asynchronous tagged receive operations (q?t, with t
tag) are not executable if the head of the queue is a
message tagged with a different tag than t yielding
the formula ¬ q?[t].
3. Asynchronous send operations (q!m) are not executable
if the queue q is full which is indicated by
the predicate ¬full(q).
4. Conditions (Boolean expressions) are not executable
if the value of the condition corresponding to the
term c is false.
The Boolean function executable, ranging over tuples
of Promela statements and global system states, is summarized
for asynchronous operations and boolean conditions
in Figure 11. Synchronous communication operations
(rendezvous send/receive) over a synchronous
communication channel are only executable if another
5 In Promela, a local control state can be labeled as end to
indicate that it is a valid end state, i.e., that the system may
terminate if the process is in that state.
S. Edelkamp and S. Leue and A. Lluch-Lafuente: Directed Explicit-State Model Checking 9
process is capable of executing the inverse communication
operation (receive/send) on the same channel. If this
is the case both operations are performed as an atomic
system transition.
In order to obtain a formula f characterizing the executability
of a synchronous send operation q!x of a process
Pj in a global system state S we proceed as follows.
For q!x to be executable on a given channel q there
must be another process j such that in S process j has
an executable inverse q?x operation. In other words, the
formula describes a disjunction over all processes i �= j
and control locations u of process i such that there is an
outgoing transition (u, v) labeled q?x:
�
pci(S)@u
i=1..n,i�=j, u∈Si|∃t=(u,v)∈Ti∧label(t)=q?x
The corresponding formula for a synchronous receive operation
is obvious.
We now use f for estimating the number of transitions
required to execute a synchronous operation by
applying it to the Hf heuristic estimate function that
we defined above. As result we will obtain the minimum
number of local transitions that every process requires
in order to reach a state in which the inverse operation is
executable. Obviously, this number is a lower bound for
the number of global system state transitions necessary
to perform the synchronous rendez-vous operation.
The negation of the property f is likely to appear in
the characterization of deadlocks. Estimating the number
of transitions required for reaching a state where a
given synchronous rendez-vous is not enabled will result
in computing the sum of H for each instance pci(S)@u.
The resulting estimate will be the number of pci(S)@u
terms that evaluate to true in state S. Since for a given
i at most one of these terms is true, the estimate will
return values between 0 and i − 1. In other words the
number of transitions required for blocking a given synchronous
operation will be estimated as the number of
local transitions required for each process to escape from
a state where the inverse operation can be executed.
We now propose estimator functions for the number
of transitions necessary from the current state to reach
a deadlock state.
Active Processes. In a deadlock state, all processes are
blocked. The active process heuristics uses the number
of active or non-blocked processes in a given state S:
Hap(S) =
�
1
where active(i, S) is defined as
�
active(i, S) ≡
Pi∈P∧active(i,S)
t=(pci(S),v)∈Ti
executable(t, S)
Given that the range of Hap is [0..|P|], the active processes
heuristic may not be very informative for protocols
involving a small number of processes.
Characterization of Deadlocks. Deadlocks are global
system states in which no progress is possible. Obviously,
in a deadlock state each process is blocked in a
local state that does not possess an enabled transition.
It is not trivial to define a logical predicate that characterizes
a state as a deadlock state which could at the
same time be used as an input to the estimation function
Hf . We first explain what it means for a process Pi
to be blocked in its local state u. This can be expressed
by the predicate blocked s which states that the program
counter of process Pi must be equal to u and that no
outgoing transition t from state u is executable.
blockeds(i, u, S) ≡ pci(S) = u ∧ �
¬executable(t, S)
t=(u,v)∈Ti
Suppose we are able to identify those local states in
which a process i can block, i.e., in which it can perform
a potentially blocking operation. Let Ci be the set
of potentially blocking states within process i. A process
is blocked if its control resides in some of the local states
contained in Ci. Hence, we define a predicate for determining
whether a process Pi is blocked in a global state
S as the disjunction of blockeds(i, u, S) for every local
state u contained in Ci:
blocked(i,S) ≡ �
blockeds(i, u, S)
u∈Ci
Deadlocks, however, are global states in which every process
is blocked. Hence, the disjunction of blocked(i,S) for
every process Pi yields a formula that establish whether
a global state S is a deadlock state or not:
deadlock(S) = �
blocked(i, S).
i=1..n
Now we address the problem of identifying those local
states in which a process can block. We call these states
dangerous. A local state is dangerous if the executability
condition of every outgoing local transition can be
false. Note that some transitions are always executable,
for example those corresponding to assignments. To the
contrary, conditional statements and communication operations
are not always executable. Consequently, a local
state which has only potentially non-executable transitions
should be classified as dangerous. Additionally, we
allow the protocol designer to identify states as dangerous.
The deadlock characterization formula deadlock is
constructed before the verification starts and is used
during the search by applying the estimate Hf , with
f being deadlock. Due to the first conjunction of the
formula, estimating the distance to a deadlock state is
done by summing the estimated distances for blocking
each process separately. This assumes that the behavior
of processes is entirely independent and obviously leads
to a non-optimistic estimate. We estimate the number of
transitions required for blocking a process by taking the
10 S. Edelkamp and S. Leue and A. Lluch-Lafuente: Directed Explicit-State Model Checking
minimum estimated distance for a process to reach a local
dangerous state and negate the executability of each
outgoing transition in that state. This could lead again
to a non-optimistic estimate since we are assuming that
the transitions performed to reach the dangerous state
have no effect on disabling the outgoing transitions of
that state.
It should be noted that deadlock characterizes many
deadlock states that could be never reached by the system.
Consider two processes Pi, Pj having local dangerous
states u, v, respectively. Assume that u has an outgoing
transition for which the executability condition is the
negation of the executability condition for the outgoing
transition from v. In this particular case it is impossible
to have a deadlock in which Pi is blocked in local state u
and Pj is blocked in local state v, since either one of the
two transitions must be executable. As a consequence
the estimate could give good values to states unlikely
to lead to deadlocks. Another concern is the size of the
resulting formula. In an extreme case each state of each
process could be dangerous. This results in a formula of
size �
i=1..n |Si|. The estimate computation for this formula
will be rather costly while providing a poor guide
for the search algorithm. We believe that the use of the
user-guided characterization of states as dangerous can
be helpful to overcome this problem.
5 The HSF-SPIN Tool Set
We chose SPIN as a basis for HSF-SPIN. It inherits
most of the efficiency and functionality from the original
source of SPIN as well as the sophisticated search capabilities
from the Heuristic Search Framework (HSF) [11].
HSF-SPIN uses a large subset of Promela as modeling
language. HSF-SPIN possesses a refined state description
of SPIN to incorporate solution length information,
transition labels and predecessors for solution extraction.
It provides an interface consisting of a node expansion
function, initial and goal specification. In order to
direct the search, we implemented different heuristic estimates.
HSF-SPIN writes SPIN-compatible trail information
that can be visualized in the XSPIN interface.
As when working with SPIN, the validation of a model
with HSF-SPIN is done in two phases: first the generation
of an analyzer of the model, and second the validation
run. The protocol analyzer is generated with the
program hsf-spin which is a modification of the SPIN
analyzer generator. By executing hsf-spin -a <model>
several c++ files are generated. These files are part of the
source of the model checker for the given model. They
are compiled and linked with the rest of the implementation,
incorporating, for example, data structures, search
algorithms, heuristic estimates, statistics and solution
generation. HSF-SPIN also supports bit-state hashing by
implementing Partial IDA*. HSF-SPIN can be invoked
with different parameters: kind of error to be detected,
property to be validated, algorithm to be applied, heuristic
function to be used, weighting of the heuristic estimator.
HSF-SPIN allows textual simulation to interactively
traverse the state space which greatly facilitates in explaining
witnesses that have been found.
HSF-SPIN is still a prototype. Therefore, its performance
in terms of time and space cannot compete
with SPIN. For example, an exhaustive exploration of
the state space generated by the GIOP protocol parameterized
with 2 clients and 2 servers is performed by
SPIN (without partial order reduction) in 226 seconds
with a memory consumption of 236 MB, while our tool
requires 341 seconds and about 441 MB of space. Further
experiments show that SPIN achieves a speedup of
about factor 3 in comparison to HSF-SPIN.
6 Safety Property Validation Experiments
In this Section we present out experimental results for
directed model checking of safety properties. The experiments
have been performed with SPIN version 3.3.10
and HSF-SPIN version 1.0 and were executed on a SUN
workstation, UltraSPARC-II CPU with 248 Mhz under
Solaris 5.7. If nothing else is stated the depth bound is
set to 10,000 and no compression technique is used. In
the case of deadlock detection in HSF-SPIN, Hap is the
estimation function used, unless indicated otherwise. In
all other cases the formula based heuristic Hf is used.
When comparing to SPIN it should be noted that this
model checker was invoked with partial order reduction
enabled.
6.1 Shorter Trails and Computational Effort
The first set of experiments is intended to show that A*
always finds shorter trails compared to DFS while requiring
less computational effort than BFS, and that in
some cases A* performs better than DFS. By computational
effort we mean the sum of the number of states
stored, the number of states expanded and the number of
transition performed. An additional objective is to show
that BF can require less computational effort than A*,
but that BF often delivers sub-optimal solutions.
For each kind of safety error we use a representative
set of protocol models. Deadlock detection is performed
using the CORBA GIOP protocol [22] with a configuration
of 2 clients and 1 server, an 8-philosophers configuration
of the dining philosophers problem, a model
of an optical telegraph protocol [20] with 6 stations and
a model of a concurrent program that solves the stable
marriage problem [29] with a configuration of 3 suitors.
Assertion violation detection experiments are carried out
with Lynch’s protocol, with a model of a relay circuit
and with a faulty solution for the mutual exclusion problem
(mutex) 6 . Invariant violation is evaluated using the
6 Available from netlib.bell-labs.com/netlib/spin
S. Edelkamp and S. Leue and A. Lluch-Lafuente: Directed Explicit-State Model Checking 11
GIOP BFS DFS A* BF SPIN
s 40,847 218 31,066 117 326
e 37,266 218 27,061 65 326
t 151,671 327 108,971 126 364
l 58 134 58 65 134
Philosophers BFS DFS A* BF SPIN
s 3,678 1,341 67 493 1,341
e 2,875 1,341 17 225 1,341
t 15,775 1,772 73 622 1,772
l 34 1,362 34 66 1,362
Optical BFS DFS A* BF SPIN
s 148,591 20 83 83 20
e 110,722 20 14 14 20
t 621,216 20 83 13 20
l 38 44 38 38 44
Marriers BFS DFS A* BF SPIN
a 9,459 10,588 9,208 7,154 2,530
e 9,004 10,588 8,335 4,124 2,530
t 24,064 29,069 22,298 9,710 3,116
l 50 72 50 61 72
Table 3. Deadlock detection in various protocols.
Relay BFS DFS A* BF SPIN
s 905 342 738 162 342
e 707 342 663 48 342
t 2,701 718 2,262 263 870
l 12 190 12 28 190
Lynch BFS DFS A* BF SPIN
s 80 48 73 49 46
e 77 48 70 46 46
t 94 49 87 59 48
l 29 46 29 29 46
Mutex BFS DFS A* BF SPIN
s 363 202 38 39 202
e 344 202 21 24 202
t 688 363 42 48 363
l 15 54 15 15 54
Table 4. Detection of assertion violations in various protocols.
POTS telephony model [23] 7 and using an elevator protocol
8 . For the POTS model, the invariant described in
Section 2.4 was used. In the elevator model, the invariant
was of the form ✷(¬opened ∨ stopped).
Tables 3, 4 and 5 depict the results of error detection
in these protocols with various search strategies. For
each protocol, the number of stored states (s), expanded
states (e), transitions performed (t) and the length of
the error trail (l) is shown. Similar to SPIN, we count
a sequence of atomic steps as one unique transition.
The number of expansion steps in SPIN is the number
7 The Promela sources and further information about
these models can be obtained from www.informatik.unifreiburg.de/~lafuente/models/models.html
8 Derived from www.inf.ethz.ch/personal/biere/teaching
/mctools/elsim.html
POTS BFS DFS A* BF SPIN
s 24,546 - 6,654 781 148,049
e 17,632 - 3,657 209 148,049
t 99,125 - 18,742 1,067 425,597
l 81 - 81 83 2,765
Elevator BFS DFS A* BF SPIN
s 38,662 279 38,598 2,753 292
e 38,564 279 38,506 2,297 292
t 160,364 356 160,208 5,960 348
l 203 510 203 421 510
Table 5. Detection of invariant violations in various protocols.
of stored states. Columns 2 to 5 correspond to different
search strategies of HSF-SPIN, namely breadth-first
search (BFS), depth-first search (DFS), A* and bestfirst
search (BF). The last column corresponds to the
exploration with SPIN’s depth-first search (SPIN).
In all examples BFS and A* provide optimal counterexamples.
Compared to BFS the A* algorithm requires
less computational effort. The reduction in the
number of expansions, states and transitions varies from
example to example. This is mainly due to the quality
of the heuristic estimate. For example, in the case of invariant
violation detection for the elevator protocol, the
savings in trail length achieved by A* are rather weak.
This can be attributed to the integer range [0..2] of the
heuristic estimation function which is very small considering
that the optimal solution has 203 steps. On the
other hand, while detecting the violation of the invariant
of the POTS protocol the heuristic function returns estimates
in the range [0..42]. With this range, the estimate
function allows for a much more differentiated successor
selection in A* which results in a much more informed
search leading to a strong reduction in the computational
effort required to detect the error. As can be expected,
DFS finds error trails significantly larger than the optimal
one(s). For example, the trail provided by SPIN’s
DFS for the invariant violation in the POTS protocol is
about 20 times larger than the optimal trail generated
by HSF-SPIN visualized in Figure 12. This trail is even
superior to the manually generated short trail in Figure
4. However, HSF-SPIN happens to find a different
target state than the one found by SPIN and this target
state also corresponds to a different race condition than
the one found by SPIN. Nevertheless, this race condition
can also be traced back to a lack of synchronization between
the UserB and PhoneHB processes. While in most
cases DFS performs better than A* in terms of computational
effort, in the philosophers problem and in the
POTS protocol the performance of A* is superior to that
of DFS. The reason for this lies in the particular structure
of these problems. For both problems it is necessary
that there is a sequence of actions in which every process
performs one or a few steps in order to get closer to the
target state. DFS, however, will try to first explore all
12 S. Edelkamp and S. Leue and A. Lluch-Lafuente: Directed Explicit-State Model Checking
UserA UserB PhoneHA PhoneHB
{conversation}
off_hook
dial_digit
dial_tone
audiblering
onhook
offhook
{conversation}
offhook
stopaudiblering
{conversation}
connectreq
ringtone
stopringtone
connectack
{idle}
Fig. 12. POTS example, error trail generated by HSF SPIN using
A* and Hf .
possibilities for one process, before it includes the behavior
of other processes. As a consequence, DFS will require
more computational effort to reach a target state than
A*. It should also be explained why HSF-SPIN runs out
of memory in the POTS example, while the DFS in SPIN
finds a counterexample. This is due to the fact that the
implementation of DFS in SPIN is more efficient, and
that we employed partial order reduction. Finally, the
experiments highlight that although BF often requires
less computational effort than A*, the established error
trails are not optimal.
6.2 Heuristic Estimates
In the previous section we have noted the important influence
of the heuristic estimate function on the performance
of A*. Now we analyze different heuristic functions
proposed for deadlock detection. In particular we
compare the heuristic based on the number of active processes
Hap with formula based heuristic Hf combined
with the proposed method for automatically inferring
the deadlock formula f. With Hf +U we denote that the
user explicitly defines dangerous states. In the example
we chose an “optimal” labeling, i.e., exactly those states
are labeled as dangerous so that the resulting global control
state is a deadlock state.
In our experiments we use the deadlock solution to
the philosophers problem, the optical telegraph protocol,
the marriers problem and the GIOP protocol. All
models have been configured as in the previous set of experiments.
Table 6 visualizes the number of expansions
required to find the deadlock state and the range of val-
Philosophers no Hap Hf Hf + U
e 2,875 17 17 10
r 0..0 0..8 0..10 0..16
Optical no Hap Hf Hf + U
e 110,722 14 342 342
r 0..0 0..12 0..14 0..12
Marriers no Hap Hf Hf + U
e 493,840 432,483 462,235 192,902
r 0..0 0..4 0..25 0..25
GIOP no Hap Hf Hf + U
e 37,266 27,061 28,067 24,859
r 0..0 0..6 0..12 0..25
Table 6. Deadlock detection with A* and different heuristic functions.
ues (r) that the heuristic estimate function is defined
over. In all cases the optimal solution is being found.
The results show that when applying the inferred
deadlock heuristic Hf user intervention improves the results
in most cases. It is not easy to compare the inferred
heuristic Hf with Hap. Hap seems to perform worse than
Hf + U except in the optical telegraph protocol. In the
optical telegraph protocol the estimate Hap works well,
since the number of processes in the model is quite high.
In the case of the GIOP protocol and the marriers model
the number of processes is rather small and Hap produces
poor reductions in the number of expanded states. It
should be emphasized that the quality of Hf + U highly
depends on the quality of the designers labeling of dangerous
states. In summary, the experiments indicate the
influence of the quality of the heuristic estimate function.
6.3 Finding Errors where DFS fails
A further objective of the directed model checking approach
is to detect errors in models where classical
depth-first exploration fails due to the exhaustion of
memory resources.
We perform a set of experiments with a scalable
deadlock solution to the dining philosophers problem.
We let the experiments run without time limitations,
but with a hard memory constraint of 512 MB. Contrary
to other experiments, we allow SPIN to apply bitstate
hashing compression in order to emphasize the benefits
of directed search.
Table 7 shows results on deadlock detection in the
philosophers model with a growing number of philosophers.
The first column depicts the number of philosophers
in the model. The labeling of the other columns is
obvious.
While A* and BF seem to scale linearly with respect
to the increase of p, BFS and DFS do not. HSF-
SPIN’s BFS and DFS exploration are not able to find
the deadlock situation in configurations with more than
S. Edelkamp and S. Leue and A. Lluch-Lafuente: Directed Explicit-State Model Checking 13
p BFS DFS A* BF SPIN
2 s 9 6 6 6 6
e 7 6 6 4 6
t 10 7 4 6 7
l 10 10 10 10 10
3 s 19 19 12 26 19
e 14 10 7 23 10
t 29 12 13 43 12
l 14 18 14 14 18
4 s 56 45 19 70 45
e 42 45 9 57 45
t 116 62 21 142 116
l 18 54 18 26 54
8 s 3,768 1,341 67 493 1,341
e 2,875 1,341 17 225 1,341
t 15,775 1,772 73 622 1,772
l 34 1,362 34 66 1,362
14 s - - 199 1,660 2,164,280
e - - 29 1,963 2,164,280
t - - 211 684 27,050,400
l - - 58 114 9,998
16 s - - 259 2,201 -
e - - 33 893 -
t - - 273 2,578 -
l - - 66 130 -
Table 7. Deadlock detection in the dining philosophers problem.
13 philosophers. SPIN can go a little further, but fails
in configurations with more than 15 philosophers. The
results show that there are models in which A* is able to
detect errors and in which depth-first search even if combined
with reduction and compression techniques fails.
6.4 IDA* and Bitstate Hashing
We now show that for given memory and time constraints,
IDA* in combination with bitstate hashing is
able to detect errors in problems in which A* and IDA*
fail. Once the priority queue is full, A* will run out of
memory and once the transposition table is full, duplicate
states will force IDA* to run out of time. We use the
GIOP protocol with a seeded deadlock error and configured
with 3 clients and one server. We set the space limit
to 256 MB and the time limit to 120 minutes. Both hash
table sizes in A* and IDA* have been set to the given
memory bound. Table 8 depicts the number of expansions
performed by A*, IDA*, and IDA* combined with
(double) bitstate hashing. To obtain the data in the table
we modify A* to print a snapshot of the expansions every
time the search depth increases, while for the last two
methods, the number of state expansions corresponds to
the number of nodes in the current iteration. The results
show that only the combination of IDA* and bitstate
hashing is able to find the error in the protocol. IDA*
exceeds the time and A* exceeds the space limit.
A duplicate is a state with different generating paths.
Duplicates occur frequently in typical protocols. As long
Depth A* IDA* IDA*+bitstate
58 150,344 146,625 146,625
59 168,191 164,982 164,982
60 184,872 184,383 184,383
61 - 206,145 206,145
62 - - 229,626
63 - - 255,411
64 - - 282,444
65 - - 311,340
66 - - 341,562
67 - - 373,422
68 - - 407,310
69 - - 442,941
70 - - goal found
Table 8. Deadlock detection in the GIOP protocol under memory
constraints.
as the visited lists of A* and IDA* are not full, all duplicate
states are detected. When the memory bound is
reached, A* aborts since it is unable to allocate further
states for the open and closed lists. IDA* bypasses the
problem by exploring the tree expansion of the underlying
graph and possibly re-exploring state space subtree
structures. In some cases, there are too many duplicates
such that after the transposition table is full
and IDA* fails to complete the next iteration within the
given time limit. However, IDA* with bitstate hashing
prunes off duplicates optimistically, storing only a finger
print (signature) of each state. This reduces the space
requirements by some orders of magnitudes (about 3 in
the example case), so that duplicates can be detected
even in large search depths. The loss of states by false
positives is marginal: in the example no state is wrongly
identified with double bitstate hashing until the depth
is reached in which IDA* gives up.
7 Liveness Property Validation
One feature of the Nested-DFS algorithm described in
Section 2 is that a state, once flagged will not be expanded
again during the cycle detection. For the correctness
of the algorithm the post-order traversal of the
search tree is crucial, such that the second depth-first
traversal only encounters nodes that have already been
visited in the main search routine. The second search
can be improved by directed cycle detection search.
Since we are aiming for states that have been placed
on the Nested-DFS stack by the first traversal we can
use heuristics to perform a directed search for the cycleclosing
states. Unfortunately, in each of our benchmark
examples, there is at most one accepting cycle, so that
there is nothing to improve. The disadvantage of a preordered
nested search approach (search the acceptance
state in the never claim and, once encountered, search
for a cycle) is its quadratic worst-case time and linear
14 S. Edelkamp and S. Leue and A. Lluch-Lafuente: Directed Explicit-State Model Checking
memory overhead, since the second search has to be invoked
with a newly initialized list of flagged states. To
address this drawback, we developed an improvement of
the nested depth-first search algorithm that exploits the
structure of the never claim. This algorithm is applicable
to a large set of practical property specifications, and can
be combined with heuristic techniques for more efficient
search performance.
7.1 Classification of Never Claims
Strongly connected components (SCC) partition a directed
graph into groups such that there is no cycle combining
two components. A subset of nodes in a directed
graph is strongly connected if for all nodes u and v there
is a path from u to v and a path from v to u. SCCs are
maximal in this sense and can be computed in linear
time by applying Tarjan’s algorithm [8].
To illustrate how SCCs can help improve the Nested-
DFS algorithm, consider the never claim of Figure 1.
We find two strongly connected components: the first is
formed by n0 and the second by na. Furthermore, there
is no path from the second SCC to the first. Accepting
cycles in the synchronous product automaton are composed
of states in which the never claim is always in
the second SCC. We can conclude that if the local never
claim state corresponding to a cycle-closing synchronous
product automaton state belongs to the second SCC the
cycle is accepting. If, however, it belongs to the first
SCC, it is not accepting.
In order to generalize this observation suppose that
we have pre-computed all SCCs of a given never claim.
Due to the synchronicity of the product of the model automaton
and the never claim a cycle in the synchronous
product is generated by a cycle in exactly one SCC. If
the cycle is accepting, so is the corresponding cycle in
the SCC of the never claim. Suppose that each SCC is
either composed only of non-accepting states or only of
accepting states. Then global accepting cycles only contain
accepting states, while non-accepting cycles only
contain non-accepting states. Therefore, a single depthfirst
search can be used to detect accepting cycles: if a
state s is found in the stack, then the established cycle
is accepting if and only if s itself is accepting.
The partitioning rules for SCCs given above can be
relaxed according to the following classification of SCCs:
– We call an SCC accepting if at least one of its states
is accepting, and non-accepting (N) otherwise.
– We call an accepting SCC fully accepting (F) if all of
its cycles contain at least one accepting state.
– We call an accepting SCC partially accepting (P) if
there is at least one cycle that does not contain an
accepting state, and one cycle that contains an accepting
state.
If the never claim contains no partially accepting SCC,
then accepting cycle detection for the global state space
G B A B U
A S,N S,N S,N S,N S,N,P
U S,N S,N S,N S,N,P,F S,N,P
E F S,P,N N,F S,N,P S,N,F
R N,F S,N,P,F N,F S,N,P,F S,N,P,F
P S,N,P S,N N,P S,N S,N,P
Table 9. SCC classification for LTL specification patterns.
can be performed by a single depth-first search: if a state
is found in the stack, then it is accepting, if the never
state belong to an accepting SCC. A special case occurs
if the never claim has an end state. When this state is
reached, the never claim is said to be violated and a
bad sequence has been found. Bad sequences are tackled
similarly to safety properties by standard heuristic
search.
The classification of patterns in property specifications
proposed in [10] reveals that an empirically collected
database of 555 practically used LTL properties
partitions into Absence (A) (85/555), Universality
(U) (119/555), Existence (E) (27/555), Response
(R) (245/555), Precedence (P) (26/555), and Others
(53/555). Using this pattern scheme and the scope modifiers
Globally (G), Before (B), After (A), Between (B),
and Until (U) we obtain a partitioning into SCCs according
to Table 9. We indicate the presence of end states
with the letter S. Since the specification patterns are
given using LTL formulae, we derive the equivalent never
claims using the SPIN built-in LTL to never claim converter.
Then, we apply an algorithm that computes the
SCCs of the state transition graph of the never claim
automaton and that classifies them into the different
classes. For example, Figure 13 depicts the state transition
graph of the never claim corresponding to a response
pattern with between scope for which the corresponding
LTL formula is ✷((q ∧ ¬r ∧ ⋄r) → (p →
(¬rU(s ∧ ¬r)))Ur). The graph is classified as follows:
SCCs {0}, {1} and {6} are of class N, {2, 3} is of class
P and {4} of class F. State 9 is and end state and the
rest of the states are transient states.
Our approach is particularly useful for never claims
that only contain N and F components, as for instance
the Response pattern with a global scope. Given the
prevalence of the Response pattern we conclude that our
improvement of the Nested-DFS algorithm is applicable
to a large set of practical problems.
7.2 Improved Nested Depth-First Search
We now present the Improved-Nested-DFS (INDFS) algorithm
that is based on the above ideas, given in Figure
15. In this Figure, SCC(s) is the SCC of state s,
F-SCC(s) determines if the SCC of state s is of type F
(fully accepting), P-SCC(s) determines if the SCC of the
state is of type P (partially accepting) and neverstate(s)
S. Edelkamp and S. Leue and A. Lluch-Lafuente: Directed Explicit-State Model Checking 15
2
4
7
8
9
0
Fig. 13. Never Claim for a response between property.
denotes the local state of the never claim in the global
state s.
The algorithm finds acceptance cycles without nested
search for all problems which partition into N- or Fcomponents.
Except for P-SCCs it avoids the post-order
traversal. For P-SCCs we guarantee that the second cycle
detection traversal is restricted to the strongly connected
component of the seed. The algorithm considers
the successors of a node in depth-first manner and marks
all visited nodes with the label hash. If a successor s ′ is
already contained in the stack, a cycle C is found. If C
corresponds to a cycle in a F-SCC of the neverstate of
s ′ , it is an accepting one. Cycles for the P-SCCs parts
in the never claim are found as in Nested-DFS, with the
exception that the successors of a node are pruned which
neverstates are outside the component. If an endstate in
the never claim is reached the algorithm terminates immediately.
A detailed proof of the correctness of INDFS
is given in Section 7.4.
Figure 14 depicts the different cases of cycles detected
in the search. The main idea for the correctness
of Improved-Nested-DFS is based on the fact that all cycles
in the state-transition graphs correspond to cycles
in the never claim. Therefore, if there is no cycle combining
two components in the never claim, so there is
none in the overall search space.
As mentioned above, the strongly connected components
can be computed in time linear to the size of the
Never Claim, a number which is very small in practice.
Partitioning the SCCs in non-accepting, partially accept-
1
5
6
3
Search Path
Cycle established
in 1st DFS
Cycle establised
in 2nd DFS
Search Tree
N-SCC
Never Claim
F-SCC
Fig. 14. Visualization of the different cases in Improved-Nested-
DFS.
P-SCC
Improved-Nested-DFS(s)
hash(s)
for all successors s ′ of s do
if s ′ in Improved-Nested-DFS-Stack and
F-SCC (neverstate(s ′ )) then
exitLTL-Property violated
if s ′ not in the hash table then Improved-Nested-DFS(s ′ )
if accept(s) and P-SCC (neverstate(s)) then
Improved-Detect-Cycle(s)
Improved-Detect-Cycle(s)
flag(s)
for all successors s ′ of s do
if s ′ on Improved − Nested − DF S-Stack then
exit LTL-Property violated
else if s ′ not flagged and
SCC(neverstate(s)) = SCC(neverstate(s ′ )) then
Improved-Detect-Cycle(s ′ )
Fig. 15. Improved Nested Depth-First Search.
ing and fully accepting can also be achieved in linear
time by a variant of Nested-DFS in the never claim.
7.3 A* and Improved-Nested-DFS
So far we have not considered heuristic search for
Improved-Nested-DFS. Once more, we consider the example
of Response properties to be validated. In a first
phase, states are explored by A*. The heuristic estimation
function can easily be designed to reach the accepting
cycles in the SCCs faster, since all states that we
are aiming at are accepting. This approach generalizes
to a hybrid algorithm A* and Improved-Nested-DFS,
A*+INDFS for short, that alternates between heuristic
search in N-SCCs, single-pass searches in F-SCCs, and
Nested-Search in P-SCCs. If a P- or S-component is encounterd,
Improved Nested-DFS is invoked and searches
for cycles. The heuristic estimate respects the combination
of all F-SCCs and P-SCCs, since accepting cycles
are present in either of the two components. The nodes
at the horizon of a F- and P-component lead to pruning
of the sub-searches and are inserted back into the
Open-List of A*, which contains all horizon nodes with
a neverstate in the corresponding N-SCCs. Therefore A*
16 S. Edelkamp and S. Leue and A. Lluch-Lafuente: Directed Explicit-State Model Checking
Search Tree
true
1st Phase
A*
...
...
...
...
...
...
n0
p ∧ ¬q
...
...
Never Claim
Goals for A*
... ...
2nd Phase
Improved-Nested-DFS
SCC0 SCCa
Fig. 16. Visualization of A* and Improved-Nested-DFS for a response
property.
+ INDFS continues with directed search, if cycle detection
in the F- and P-components fails. Cycle detection
search itself can be accelerated with an estimation function
heading back to the states where it was started.
Figure 16 visualizes this strategy for a response property.
The never claim has the following SCCs: SCC0
which is a N-SCC, and SCCa which is F-SCC. The state
space can be seen as divided in two partitions, each one
composed of states where the never claim is a state belonging
to one of the SCCs. In a first phase, A* is used
for directing the search to states of the partition corresponding
to SCCa. Once a goal state is found, the second
phase begins, where the search for accepting cycles
is performed by Improved-Nested-DFS.
7.4 Correctness of INDFS
The nested depth-first search algorithm in model checking
validates the emptiness of Büchi automata. It
searches accepting cycles in the problem graph that represents
the state-space of a Büchi automaton and reports
non-emptiness if and only if there exists at least one accepting
cycle in the graph. A correctness proof of this
algorithm can be found in [6]. Our improvement to the
nested depth-first search algorithm is depicted in Figure
15. To prove the correctness of the algorithm we
start with some definitions.
Definition 1. A Büchi automaton is a five tuple
〈Σ, Q, δ, Q0, F 〉, where Σ is a finite alphabet, Q is the
finite set of states, δ ⊆ Q × Σ × Q is the transition relation,
Q0 ⊆ Q is the set of initial states, and F ⊆ Q is
the set of accepting states.
Definition 2. A run of a Büchi automaton over an infinite
word v ∈ Σ ∗ is a mapping ρ : {0, 1, .., ∞} ↦→ Q
such that a) the first state is an initial state, that is,
ρ(0) ∈ Q0, and b) moving from the i-th state ρ(i) to the
(i+1)-st state ρ(i+1) upon reading the i-th input letter
v(i) is consistent with the transition relation, that is, for
all i ≥ 0 we have (ρ(i), v(i), ρ(i) + 1) ∈ δ.
na
¬q
Definition 3. Let inf(ρ) be the set of states that appear
infinitely often in a run ρ (when treating the run
as an infinite path). A run ρ of a Büchi automaton B
over an infinite word is said to be accepting if and only
if some accepting state appears infinitely often in ρ, that
is, when inf(ρ) ∩ F �= ∅. The language L(B) accepted by
the Büchi automaton B is then the set of infinite words,
over which all runs of B are accepting.
Let M be a finite state automaton representing the
model, and let N be the never claim. For this construction
the automaton M is interpreted as a Büchi automaton
in which all states are accepting.
Definition 4. Let M = 〈Σ, QM , δM , QM 0 , FM 〉 be a
Büchi automaton which states are all accepting, that
is QM = FM , and let N = 〈Σ, QN , δN, QN 0 , FN〉 be another
Büchi automaton. The synchronous product M ⊗N
of M and N is defined as: M ⊗ N = 〈Σ, Q, δ, Q0, F 〉,
where Q = QM × QN, Q0 = QM 0 × QN 0 , F = FM × FN =
QM × FN , and ((sM , sN ), a, (s ′ M , s′ N
(sM , a, s ′ M ) ∈ δM and (sN, a, s ′ N
)) ∈ δ if and only if
) ∈ δN.
Büchi automata can be represented as directed
graphs: the set of vertices is Q and the edges are labelled
by the transition relation δ. Runs of the automaton
over an infinite word correspond to infinite paths
in the graph, and accepting runs to infinite paths containing
infinite accepting cycles. An accepting cycle is
defined as a cycle in which at least one state is accepting.
Definition 5. A strongly connected component (SCC)
of a directed graph is a maximal set of vertices, such
that each vertex in the set is reachable from each other
vertex of the set in 1 or more steps 9 .
It is not difficult to show that pairwise reachability is
an equivalence relation such that the set of nodes can be
partitioned into equivalence classes of strongly connected
components. An important consequence of the definition
of SCCs is that all vertices of a cycle belong to the same
SCC. In the following we write scc(s) to denote the SCC
to which a state s belongs.
Let Q be the set of states of M ⊗ N. We define a
partition function π from Q onto {0, . . . , k} in such a
manner that two states belong to the same partition if
and only if the state component of N belongs to the same
SCC in the state transition graph of N. More precisely,
if s = (sM , sN ) and i = scc(sN) then π((sM , sN)) = i.
Obviously, π defines a partition of equivalence classes
P0, . . . Pk of Q, where Pi = {s ∈ Q | π(s) = i}, i ∈
{0, . . . , k}.
Definition 6. A strongly connected component is
called non-accepting if none of its states is accepting,
9 Requiring reachability in 1 or more steps is not the standard
definition of an SCC. However, the minimum path length of 1 is
necessary for a concise proof of our algorithm
S. Edelkamp and S. Leue and A. Lluch-Lafuente: Directed Explicit-State Model Checking 17
full-accepting each cycle formed by states of the SCC is
accepting, and partial-accepting otherwise.
Definition 7. An equivalence class Pi of M ⊗ N is
non-accepting, full-accepting or partial-accepting if the
corresponding strongly connected component i in N is
non-accepting, full-accepting or partial-accepting, respectively.
Lemma 1. If there is a cycle C in Q, then π partitions
the states in Q in such a manner that all states of the
cycle belong to the same equivalence class in Q, i.e., C ⊆
Pi for one i ∈ {0, . . . , k}.
Proof. Let C be a cycle in state transition graph of
Q, that is C = (s0, s1, . . . , sn) with sn = s0 and
(si, a, si+1) ∈ δ for all i ∈ {0, . . . , n − 1}. Therefore,
since si = (sM i , sN i ) and sNi ∈ N, i ∈ {0, . . . , n}, a cycle
) ∈
CN = (sN 0 , sN 1 , .., sN n = sN 0 ) exists with (sN i , a, sNi+1 δN for all i ∈ {0, . . . , n}. Hence, for all si = (sM i , sN i )
and sj = (sM j , sNj ) in C we have scc(sNi ) = scc(sNj ).
This implies π(si) = π(sj) for all si, sj ∈ C such that all
states of C belong to the same equivalence class. ⊓⊔
Lemma 2. A cycle C in M ⊗N is accepting if and only
if the corresponding cycle in N is accepting.
This is easy to see, since as defined, a state s =
(sM , sN) of M ⊗ N is accepting if and only if sN is an
accepting state of N.
Lemma 3. All cycles in a non-accepting component
are non-accepting, all cycles in a fully-accepting component
are accepting. In partial-accepting components,
there can be accepting and non-accepting cycles.
Lemma 3 is immediately deduced from Definitions 6
and 7, and Lemma 2.
The following lemma is a well-known property of
depth-first search and is essential for proving the correctness
of our algorithm.
Lemma 4. Let s be a vertex that does not appear on any
cycle. Then the depth first search algorithm will backtrack
from s only after all the nodes that are reachable
from s have been explored and backtracked from.
It is easy to see that this lemma still holds for the first
search in both the original and in the improved nested
depth first search algorithm.
Theorem 1. The improved nested depth first search algorithm
returns a counterexample for the emptiness of
the checked automaton M ⊗ N exactly when L(M ⊗ N)
is not empty.
Proof. We have to show I) that a counterexample returned
by the algorithm corresponds in fact to an accepting
run of the automaton, and II) that no accepting run
is missed by the algorithm.
I) The first thing to show is that if the algorithm
finds an accepting cycle, then the cycle is in fact accepting.
The algorithm closes accepting cycles in the first and
in the second search. When the algorithm closes cycles
in the second search, it acts like the original algorithm.
As shown in [6], cycles closed in the second search are
accepting, since the second search is started from accepting
states only. On the other hand cycles closed in the
first search correspond only to cycles present in a fullaccepting
equivalence class, and as shown in Lemma 2,
every cycle in a full-accepting component is accepting.
II) The difficult case is to prove that if the algorithm
finds no accepting cycle then L(M ⊗ N) is in fact
empty. As shown above, accepting cycles can exist only
in full-accepting component or in partial-accepting component.
There are two cases if the algorithm fails to find
an existing accepting cycle: IIa) the cycle exists in a fullaccepting
component and is missed in the first search, or
IIb) the cycle exists in a partial-accepting component
and is missed in the second search.
IIa) Suppose that an accepting cycle exists in a fullaccepting
component and that the first search fails to
find it. Let s be the first state visited by the depth first
search that is reachable from itself and that belongs to
a full-accepting component. The first search misses that
cycle if in the moment in which the search is started
from s, every path from s to itself contains a an already
visited state. Let s ′ be the first such state. Then s ′ was
visited by the depth-first search before s and is reachable
from itself through the cycle (s ′ → . . . → s → . . . → s ′ ),
and s ′ belong to the same full-accepting component by
Lemma 1, which contradicts our assumption.
IIb) Suppose now that an accepting cycle exists in a
partial-accepting component and that the second search
fails to find it. In this case a similar reasoning as in [6]
can be done to show that this cannot be happen. Let s be
the first accepting state belonging to a partial-accepting
component from which the second search starts but fails
to find a cycle even though one exists. In the moment in
which the second search starts from s there is at least
one flagged state on a cycle through s. Let r be the first
such state, and let s ′ be the state from which the second
search that flagged r was started. In the algorithm
the second search remains in the same equivalence class
from which the search was started. Therefore s, r and
s ′ must belong to the same component. According to
our assumptions, the second search from s ′ was started
before the second search from s. There are two cases:
II ′ b : The state s′ is reachable from s. Then there is a
cycle (s ′ → . . . → r → . . . → s → . . . → s ′ ) that could
not have been found previously, otherwise the algorithm
would already have terminated. By Lemma 3, the cycle
belongs to a partial-accepting component. However
this contradicts our assumption from which the second
search missed a cycle belonging to a partial-accepting
component.
18 S. Edelkamp and S. Leue and A. Lluch-Lafuente: Directed Explicit-State Model Checking
II ′′
b : The state s′ is not reachable from s. If s ′ appears
on a cycle, then a cycle was missed before starting
the second search at s and the cycle belongs to a partialaccepting
component, since s and s ′ belong to the same
component. According to the assumption, s is reachable
from r and, subsequently, s is reachable from s ′ . Thus, if
s ′ does not occur on a cycle, by Lemma 4 we must have
discovered and backtracked from s in the first search
before backtracking from s ′ . Hence, according to the algorithm,
we must have started a second search from s
before starting it from s ′ . This contradicts the assumptions.
⊓⊔
8 Liveness Property Experiments
In this Section we describe experimental results in the
validation of liveness properties. The experimental setup
is largely as described in Section 6. We compare two
algorithms in this section, namely NDFS and INDFS.
Both algorithms have been implemented in HSF-SPIN.
We have also implemented INDFS inside SPIN, so that
both tools have the same algorithmic capabilities. Since
the results produced by both tools are very similar in
terms of computational effort, we only give the values
obtained by HSF-SPIN in this Section.
8.1 INDFS for Validating Correctness
This first set of experiments is intended to show the
benefits of INDFS when validating liveness properties.
In the worst case, INDFS performs as many transitions
and expansions as NDFS, while in a best case situation
INDFS can halve these values. The worst case occurs
when the never claim contains no F-SCCs, while the best
case occurs when the never claim contains exclusively
SCCs of this type. Note that all never claims are generated
using SPIN’s LTL-to-never-claim translation. We
use a model of the leader election algorithm as test case.
As a worst case we check the property ✸✷oneLeader
for which the corresponding never claim is formed by
a unique P-SCC. For the best case situation we used
the property ✸elected for which the corresponding never
claim is formed by a unique F-SCC. Figure 17 illustrates
the never claims that SPIN generates for each property.
Table 10 depicts the results of the experiments. The
number of transitions and expansions is shown. The
number of stored states is also included in the table
to show that both algorithms explore exactly the same
number of states. The results show that in the worst case
situation both NDFS and INDFS perform the same. On
the other hand, in the best case situation INDFS requires
about half of the transitions and expansions that
NDFS requires.
n0
¬elected
na
true
¬elected
n0
true
¬oneLeader
Fig. 17. Never claims for ✸✷oneLeader (bottom-right) and
✸elected (top-left).
✸✷oneLeader NDFS INDFS
s 4,779 4,779
e 9,556 9,556
t 42,307 42,307
✸elected NDFS INDFS
s 2,380 2,380
e 14,086 7,044
t 4,759 2,380
Table 10. Checking correctness of two liveness properties in the
leader election algorithm with NDFS and INDFS.
8.2 INDFS for Error Detection
Our objective now is to show that INDFS requires less
computational effort and provides better error trails
than NDFS. We also test the performance of the hybrid
algorithm that combines NDFS with A*.
We first use a version of the GIOP model configured
with 1 server and 3 clients and with a seeded error that
causes the model to violates a response property stating
that when a client sends a request, a reply will always
be received. Second, we use a model of an elevator with
3 floors that violates the response property stating that
whenever a request for the elevator exists in one level, the
elevator will eventually stop at that level and open the
door. Table 11 shows experimental results on detecting
the violation of LTL formulae. NDFS is compared with
INDFS and the algorithm that combines A* and NDFS
(A*+INDFS).
The results show that INDFS provides small improvements
over NDFS in all categories. However, only
for the GIOP protocol the reduction is significant,
INDFS almost halves the length of the error trail. The
hybrid algorithm finds better solutions in all situations,
but its computational effort varies drastically. While in
the elevator experiment it requires about 15 times more
state expansions than INDFS, in the GIOP experiment it
performs 89 times less. The reason of this varying behav-
na
S. Edelkamp and S. Leue and A. Lluch-Lafuente: Directed Explicit-State Model Checking 19
Elevator NDFS INDFS A*+INDFS
s 192 187 29,407
e 229 187 28,309
t 280 215 130,211
l 320 311 297
GIOP NDFS INDFS A*+INDFS
s 7,331 7,260 86
e 7,346 7,260 81
t 33,061 32,984 93
l 289 155 155
Table 11. Detection of violation of liveness properties in two protocols.
ior is that A*+NDFS directs the search to the nearest
full accepting component of the state space. This component
may, however, be free of cycles. Only after this part
of the state space is entirely explored the nested search
returns control to A* which then directs the search into
the next full accepting part. While in the case of the
GIOP protocol the algorithm finds a component with
a cycle early on in the search, in the elevator example
the algorithm first explores parts of the state space that
include accepting states, but no accepting cycles.
9 Related Work
In earlier work on the use of directed search in model
checking the authors apply best-first exploration to protocol
validation [25]. They are interested in typical safety
properties of protocols, namely unspecified reception,
absence of deadlock and absence of channel overflow. In
the heuristics they use an estimate determined by identifying
send and receive operations. In the analysis of the
X.21 protocol they obtained savings in the number of expansion
steps of about a factor of 30 in comparison with
a typical depth first search strategy. We have incorporated
this strategy in HSF-SPIN. The approach in [25]
is limited to the detection of deadlocks, channel overflows
and unspecified reception in protocols with asynchronous
communication. To the contrary our approach
is more general and handles a larger range of errors and
communication types. While the measures in [25] are
merely stochastic and will not yield optimal solutions,
the heuristics we propose are in most cases lower bound
estimators and hence allow us to find optimal solutions.
Recent work [18] applies heuristic search to the verification
of java programs. It is proposing heuristics that
increase coverage of the program while disregarding a
targeted search for error states. This approach does not
guarantee optimal counterexamples and accomplishes
faster error finding through improved code coverage.
The same holds for recent work [31] that proposes
the application of genetic algorithms for finding errors
in very large state spaces. Genetic algorithms require
fitness functions which are a variant of heuristic evalua-
tion functions. Different heuristics for deadlock detection
and assertion violation based on enabledness of transitions
and message exchanges are proposed.
The identification of three phases in the verification
process is at the heart of work documented in [7]. In exploratory
mode the system designer tries to find a first error,
in fault finding mode s/he aims at meaningful counterexamples,
while in the maintenance mode one does
not expect errors at all. From this point of view, our approach
concentrates on the first two modes. Moreover,
the authors in [7] analyze which algorithm is best-suited
for which mode. They use different variants of depth-first
search, breadth-first search and A*. Some of the ideas for
the heuristic estimates are similar to ours, but the authors
do not elaborate on the specific heuristic estimates
that they use. Contrary to us, they do not consider IDA*
and restrict their work to safety properties. In comparison,
cur conclusions are slightly different from theirs. We
agree that a shortest path algorithm is suitable for the
fault finding mode, but we believe that directed search
can also be useful in the first exploratory mode: even
in this phase by guiding the search an error state can
be found with less computational effort than with blind
search strategies.
The authors of [35] use BDD-based symbolic search
within the Murφ validation tool. The best first search
procedure they propose incorporates symbolic information
based on the Hamming distance of two states. This
approach has been improved in [32], where a BDDbased
version of the A* algorithm [15] for the µcke
model checker [3] is presented. The algorithm outperforms
symbolic breadth-first search exploration for two
scalable hardware circuits. The heuristic is determined
in a static analysis prior to the search taking the actual
circuit layout and the failure formula into account.
The approach to symbolic guided search in CTL model
checking documented in [4] applies ‘hints’ to avoid sections
of the search space that are difficult to represent for
BDDs. This permits splitting the fix-point iteration process
used in symbolic exploration into two parts yielding
under- and over-approximation of the transition relation,
respectively. Benefits of this approach are simplification
of the transition relation, avoidance of BDD blow-up and
a reduced amount of exploration for complicated systems.
However, in contrast to our approach providing
‘hints’ requires user intervention. Also, this approach is
not directly applicable to explicit state model checking,
which is our focus.
The need for heuristics is apparent in conformant
planning, where the symbolic representation compensates
partial knowledge of the current state. The work
of [2] trades information gain for exploration time with
an estimate preferring belief states with low cardinality.
Timed automata call for a finite partitioning of the
state space through a symbolic representation of states
as a reduced set of difference constraints. One example
is the real-time model checker Uppaal, which has also
20 S. Edelkamp and S. Leue and A. Lluch-Lafuente: Directed Explicit-State Model Checking
been accelerated by heuristic search to optimize different
cost-functions with A* [1]. The techniques are reported
to reduce the explored state-space with up to 90%.
Exploiting structural properties of the Büchi Automaton
in explicit state mode checking has been considered
in the literature in the context of weak alternating
automata (WAA) [30]. WAA were invented to reason
about temporal logics, generalize the transition function
with boolean expressions of the successor set, and partition
the automaton structure. The classification of the
states of a WAA differs from ours, since the partitioning
into disjoint sets of states that are either all accepting or
all rejecting does not imply our partitioning. The simplification
of Büchi automata proposed in [33] is inferred
from an LTL property, whereas our INDFS algorithm
is based on the analysis of the structure of Büchi automata.
The work in [33] also considers a partitioning
according to WAA-type weakness conditions and hence
differs from the approach taken in our paper.
The approach taken in [34] addresses explicit CTL*
model checking in SPIN using hesitant alternating automata
(HAAs). The paper shows that the performance
of the proposed ‘LTL non-emptiness game’ is in fact
a reformulation and improvement of nested depth-first
search. Both the partitioning and the context of HAA
model checking are significantly different from our setting.
10 Conclusion and Outlook
We argued that in order to facilitate debugging the error
trails or witnesses that a model checker generates minimizing
their length is highly desirable. A reduction in
the number of visited states during state space search is
also desirable since this renders larger models tractable.
Standard depth-first search algorithms used in explicit
state model checkers like SPIN are rather efficient in
terms of memory usage and computing time, but tend
to produce lengthy counterexamples.
We introduced into heuristic search algorithms, and
showed how to apply heuristic search to safety property
validation. The experimental results showed that
directed model checking with A* always returns shorter
error trails than DFS, and that in most instances the
trail length is optimal. Regarding computational effort
the results were mixed: in some instances A* was superior
to SPIN and DFS, but in many cases A* was not
performing as well. It also became clear that the gain
obtained through directed model checking is better the
more differentiation the heuristic estimation function allows.
We also observed that for the dining philosophers
problem under constrained memory availability directed
model checking was able to solve a problem that could
not be solved by DFS. We expect that this effect is linked
to the highly symmetric nature of the problem, and the
high degree of coordination that is typical for this example.
Next we proposed an improvement of the nested
depth-first search algorithm that exploits the structure
of the never claim to be validated. The INDFS algorithms
is applicable to the validation of liveness properties.
We showed that INDFS, which is not a directed
model checking algorithm, leads to modest improvements
in terms of error trail length compared to NDFS.
In further experiments we showed how the combined usage
of A* and NDFS can lead to significant reductions
in error trail length.
The incorporation of heuristic search strategies is
based on the observation that standard state space exploration
algorithms perform a search that is rather uninformed
of the structure of the search problem. As raw
as the heuristics that we propose may be, it is surprising
to see them work rather well on many practical problems.
We are not primarily interested in optimal solutions,
which is why we can tolerate non-admissible heuristic
estimates when optimistic estimates are not available.
In concurrent work [14] we describe an approach to
shorten existing error trails using refined state distance
metrics as heuristic estimates. This approach has already
been implemented in HSF-SPIN. For selected benchmark
and industrial communication protocols experimental
evidence is given that trail-directed model checking
effectively shortcuts existing witness paths.
We are nevertheless interested in improving the quality
of the heuristics so that our approach becomes applicable
to an even larger set of problems. One approach
assesses the fact that our assumption of independence
in combining sub-formulae is rarely fulfilled in practice.
The main idea in the not yet implemented approach of
directed stochastic model checking is to derive a stochastic
model for search prediction that takes correlations
of propositions into consideration in order to direct the
search.
Further work [26] investigates the combination of
partial order reduction techniques with the directed
model checking approach of HSF-SPIN. Both theoretically
and empirically we show that A* and IDA* can be
combined with partial order reduction methods. While
the benefit of the application of partial order reduction
to A* is limited, due to its similarity to DFS IDA* avails
itself rather nicely to partial order reduction.
Acknowledgments. The authors wish to thank the
anonymous reviewers for their constructive criticism.
The third author was supported by grant Ot64/13-2
from the Deutsche Forschnungsgemeinschaft.
References
1. G. Behrmann, A. Fehnker, T. Hune, K.G. Larsen, P. Petterson,
J. Romijn, and F. W. Vaandrager. Efficient guid-
S. Edelkamp and S. Leue and A. Lluch-Lafuente: Directed Explicit-State Model Checking 21
ing towards cost-imality in uppaal. In Tools and Algorithms
for the Construction and Analysis of Systems
(TACAS), Lecture Notes in Computer Science 2031.
Springer, 2001.
2. P. Bertoli, A. Cimatti, and M. Roveri. Heuristic search
symbolic model checking = efficient conformant planning.
In International Joint Conference on Artificial Intelligence
(IJCAI), 2001.
3. Armin Biere. µcke - efficient µ-calculus model checking.
In Computer Aided Verification (CAV), pages 468–471,
1997.
4. R. Bloem, K. Ravi, and F. Somenzi. Symbolic guided
search for CTL model checking. In Design Automation
Conference (DAC), pages 29–34. ACM/IEEE, 2000.
5. D. Brand and P. Zafiropulo. On communicating finitestate
machines. Journal of the ACM, 30(2):323–342, Apr
1983.
6. E. Clarke, O. Grumberg, and D. Peled. Model Checking.
MIT Press, 2000.
7. J. M. Cobleigh, L. A. Clarke, and L. J. Osterweil. The
right algorithm at the right time: Comparing data flow
analysis algorithms for finite s tate verification. In
23 rd International Conference on Software Engineering
(ICSE), pages 37–46. IEEE Computer Society, 2001.
8. T. H. Cormen, C. E. Leiserson, and R. L. Rivest. Introduction
to Algorithms. The MIT Press, 1990.
9. E. W. Dijkstra. A note on two problems in connection
with graphs. Numerische Mathematik, 1:269–271, 1959.
10. M. B. Dwyer, G. S. Avrunin, and J. C. Corbett. Patterns
in property specifications for finite-state verification. In
21 st International Conference on Software Engineering
(ICSE), pages 411–420. IEEE Computer Society, 1999.
11. S. Edelkamp. Data Structures and Learning Algorithms
in State Space Search. PhD thesis, University of Freiburg,
1999. Infix.
12. S. Edelkamp, A. Lluch-Lafuente, and S. Leue. Directed
explicit model checking with HSF-SPIN. In 8th International
SPIN Workshop on Model Checking Software,
Lecture Notes in Computer Science 2057. Springer Verlag,
2001.
13. S. Edelkamp, A. Lluch-Lafuente, and S. Leue. Protocol
verification with heuristic search. In AAAI Symposium
on Model-based Validation of Intelligence, 2001.
14. S. Edelkamp, A. Lluch-Lafuente, and S. Leue. Traildirected
model checking. In Workshop on Software Model
Checking, Electrical Notes in Theoretical Computer Science.
Elsevier, 2001.
15. S. Edelkamp and F. Reffel. OBDDs in heuristic search. In
German Conference on Artificial Intelligence (KI), pages
81–92, 1998.
16. S. Edelkamp and S. Schrödl. Localizing A*. In National
Conference on Artificial Intelligence (AAAI), pages 885–
890, 2000.
17. M. G. Gouda. Protocol verification made simple: a tutorial.
Computer Networks and ISDN Systems, 25(9):969–
980, 1993.
18. A. Groce and W. Visser. Model checking java programs
using structural heuristics. In International Symposium
on Software Testing and Analysis (ISSTA). ACM Press,
2002.
19. P. E. Hart, N. J. Nilsson, and B. Raphael. A formal
basis for heuristic determination of minimum path cost.
IEEE Transactions on on Systems Science and Cybernetics,
4:100–107, 1968.
20. G. J. Holzmann. Design and Validation of Computer
Protocols. Prentice Hall, 1990.
21. G. J. Holzmann. The model checker Spin. IEEE Transactions
on Software Engineering, 23(5):279–295, May 1997.
Special issue on Formal Methods in Software Practice.
22. M. Kamel and S. Leue. Formalization and validation
of the general inter-orb protocol (GIOP) using Promela
and SPIN. In Software Tools for Technology Transfer
(STTT), volume 2, pages 394–409, 2000.
23. M. Kamel and S. Leue. Vip: A visual editor and compiler
for v-promela. In 6th International Conference,
Tools and Algorithms for the Construction and Analysis
of Systems (TACAS), Lecture Notes in Computer Science
1785, pages 471–486. Springer, 2000.
24. R. E. Korf. Depth-first iterative-deepening: An optimal
admissible tree search. International Joint Conference
on Artificial Intelligence (IJCAI), 27(1):97–109, 1985.
25. F. J. Lin, P. M. Chu, and M.T. Liu. Protocol verification
using reachability analysis: the state space explosion
problem and relief strategies. In ACM SIGCOMM, pages
126–135, 1987.
26. A. Lluch-Lafuente, S. Leue, and S. Edelkamp. Partial
order reduction in directed model checking. In SPIN
Workshop on Model Checking Software, Lecture Notes in
Computer Science 2318, pages 112–127. Springer, 2002.
27. Z. Manna and A. Pnueli. The Temporal Logic of Reactive
and Concurrent Systems: Specification. Springer-Verlag,
1992.
28. K.L. McMillan. Symbolic Model Checking. Kluwer Academic
Press, 1993.
29. D.G. McVitie and L.B. Wilson. The stable marriage
problem. Communications of the ACM, 14(7):486–492,
1971.
30. D. E. Muller, A. Saoudi, and P. E. Schnupp. Alternating
automata. The weak monadic theory of the tree, and
its complexity. In Laurent Kott, editor, International
Colloquium on Automata, Languages and Programming,
pages 275–283. Springer, 1986.
31. P. and S. Khurshid. Exploring very large state spaces using
genetic algorithms. In Tools and Algorithms for the
Construction and Analysis of Systems (TACAS), Lecture
Notes in Computer Science 2280, pages 266–280.
Springer, 2002.
32. F. Reffel and S. Edelkamp. Error detection with directed
symbolic model checking. In World Congress on Formal
Methods, pages 195–211. Springer, 1999.
33. F. Somenzi and R. Bloem. Efficient buchi automata from
LTL formulae. In Computer Aided Verification, 2000.
34. W. Visser and H. Barringer. CTL* model checking for
SPIN. Software Tools for Technology Transfer (STTT),
2(4), 2000.
35. C. H. Yang and D. L. Dill. Validation with guided search
of the state space. In Design Automatin Conference
(DAC), pages 599–604. ACM/IEEE, 1998.
