Linear Temporal Logic Symbolic Model Checking
Linear Temporal Logic Symbolic Model Checking
available at www.sciencedirect.com
Survey
A R T I C L E
I N F O
A B S T R A C T
Article history:
We are seeing an increased push in the use of formal verification techniques in safety-
critical software and hardware in practice. Formal verification has been successfully used
to verify systems such as air traffic control, airplane separation assurance, autopilot,
26 June 2010
CPU designs, life-support systems, medical equipment (such as devices which administer
radiation), and many other systems which ensure human safety. This survey provides a
perspective on the formal verification technique of linear temporal logic (LTL) symbolic
Keywords:
model checking, from its history and evolution leading up to the state-of-the-art. We unify
research from 1977 to 2009, providing a complete end-to-end analysis embracing a users
Verification
Formal Methods
proofs of important theorems, and point to directions of ongoing research. The primary
focus is on model checking using LTL specifications, though other approaches are briefly
discussed and compared to using LTL.
Published by Elsevier Inc.
1.
Introduction
1 Bchi
3 http://spot.lip6.fr/.
Implementation
1. Define the system model M containing traces over the set Prop of propositions.
2. Let specification be a formula over the set Prop.
3. Check that M |H :
Translate the specification into a Bchi automaton A and compose it with the
system model M to form AM, .
Check AM, for nonemptiness. That is, search for a trace that is accepted by AM, .
If such a trace exists, return it as a counterexample.
If no such trace exists, return TRUE.
2.
2.1.
Modeling limitations
2.2.
An example: the automated airspace concept for air
traffic control
Model checking is most frequently used for the formal
verification of safety-critical systems, or systems whose
failure could result in serious injury or death. Examples of
safety-critical systems include air traffic control, airplane
separation assurance algorithms, life support systems,
essential communications systems, hazardous environment
controls, medical equipment systems (such as those that
administer radiation or assist in surgery), train signaling
systems, and automotive control systems. Other types of
systems where model checking is frequently applied include
components of safety-critical systems, such as processor
chip designs, financial systems that could cause catastrophic
failure, missiles and other weapons systems, commercial
products whose malfunctioning would trigger catastrophic
financial costs for the manufacturer, and any other systems
where the cost of a single failure outweighs the cost of formal
verification.
We illustrate the symbolic model-checking algorithm for
LTL on a small example that describes the architecture for the
Automated Airspace Concept for air traffic control in NASAs
Next Generation Air Transportation System (NGATS) [41],
displayed in Fig. 1.
The following rules govern the operation of this air traffic
control architecture:
The auto-resolver is enabled by default and sends flight
commands to the aircraft.
The aircraft may request a specific flight command.
The controller may request a specific flight command.
If a near-term conflict is detected (i.e. a loss of separation
is projected to occur within an amount of time below
the systems threshold), TSAFE (the Tactical Separation
Assisted Flight Environment tool) automatically engages
and sends a flight command to resolve the conflict. TSAFE
commands always override all requests and commands
issued by the auto-resolver.
Description
AR_command
TSAFE_command
controller_request
aircraft_request
TSAFE_clear
3.
Real-world systems are routinely developed from Englishlanguage specifications. Yet, once these systems are built,
there is no way to verify that the resulting systems follow
the English specifications. Consequently, there is also no way
to tell whether following the natural language specifications
is a desirable goal, i.e. whether the set of specifications is
internally consistent, logically sound, or complete. For formal
verification, English is quite simply too imprecise. Consider
the statement by Groucho Marx, I once shot an elephant in
my pajamas. How he got in my pajamas Ill never know, or
the double-meaning of Students hate annoying professors.
In order to check that a system models its specifications,
it is necessary to have a formal, and very precise, notion
of exactly what the specifications say. Therefore, we use
logic for the specification language. Logic has the advantage
of being able to express system specifications in a concise
p
pq
pq
pq
not
and
or
implies
Box I.
Box II.
3.1.
Temporal logics
3.1.1.
LTL
U
R
10
iff
, i |H () U ()
iff
, i |H () U ()
iff
, i |H (() U ())
iff
iff
iff
iff
7 Though
iff
iff
iff
3.2.
11
3.2.1.
CTL
AX
E X
A
E
A( U ) E ( U )
A
E
3.2.2.
LTL vs CTL
The logical expressiveness of LTL and CTL is incomparable [62]. (See Fig. 5.) Since CTL allows explicit existential quantification over paths, it is more expressive in some cases
where we want to reason about the possibility of the existence of a specific path through the transition system model
M, such as when M is best described as a computation tree.
For example, there are no LTL equivalents of the CTL formulas (E X p) and (AE p) since LTL cannot express the possibility of p happening on some path (but not necessarily all
12
13
to be more intuitive, and less error-prone, than using CTL, particularly for verifying concurrent software architectures [74].
The vast majority of CTL specifications used in practice are
equivalent to LTL specifications; it is rare that the added ability to reason over computation tree branches is needed and
it frequently requires engineers to look at their designs in an
unnatural way [63]. The expressiveness, simplicity, and usability of LTL, particularly for practical applications like open
system or compositional verification, and specification debugging, make it a good choice for industrial verification.
Fig. 6 A situation where the LTL formula
the CTL formula (A Ap) does not.
3.2.3.
CTL
3.2.4.
In several cases, industrial companies have defined extensions of LTL, specialized for their verification needs. Usually
these linear time logics add operators to make the expression of specific properties easier and to extend the specification language to full -regularity. The optimal position in the
trade-off between logical expressiveness and model checking
time complexity remains under discussion.
Definition 5. An -regular expression is an expression of the
14
3.3.
Specification debugging
3.4.
15
16
cl().
cl() cl().
cl() cl().
cl() , cl().
cl() , cl().
X cl() cl().
U cl() , cl().
R cl() , cl().
3.5.
17
18
behaviors, or the words in the set (2Prop ) .17 The proof of this
statement follows from the definitions of safety and liveness
above, specifically L (true) = L (cl(true)) = . Remarkably,
while every LTL formula is not strictly either a safety or a
liveness property, Alpern and Schneider [127] proved that
every LTL formula is a combination of a safety and a liveness
property.
19
3.6.
Instead of using a temporal logic to describe a behavioral property, we can use an automaton directly. Many
model checkers, like NuSMV and CadenceSMV, will accept specifications in either format and some, like Lucents
FormalCheck [128], deal exclusively with automata inputs.
However, complementing a Bchi automaton is quite difficult
(and likely involves the expensive step of determinization)
whereas complementing an LTL formula can be done in constant time by simply preceeding the formula with a negation
symbol. Currently, the best time complexity for complementation of Bchi automata is 2O (n log n) [129] but this is still an
open area of research [130132]. Advantages of this method
include the ability to directly and efficiently construct the
automaton A rather than relying on an LTL-to-Bchi translation, while disadvantages include the unintuitiveness of representing a behavior specification as an automaton.
3.7.
g) g)| g occurs in f }.
=!Sg
= Sg1 |Sg2
= Sg1 &Sg2
= Sg2 |(Sg1 &SX
(g1 U g2)
(g1 R g2)
)
)
if p is an atomic
proposition.
if h is elementary formula
Xg in el_list.
if h = g
if h = g1 g2
if h = g1 g2
if h = g1 U g2
if h = g1 R g2
Sh = Sg &SX(g)
if h = g
Sh = Sg |SX
if h =
g)
g
20
Box III.
3.8.
4.
Representing the combined system and
property using BDDs
The basis for symbolic model checking is the realization
that both the system model and the specification property
can be represented symbolically, using Boolean equations,
21
Box IV.
Box V.
rather than explicitly, using automata. Furthermore, they
can be manipulated efficiently using operations over Binary
Decision Diagrams (BDDs). Symbolic representation and
manipulation of the intermediate products of model checking
leads to much more succinct structures needing to be
stored in computer memory, thereby directly combating the
state explosion problem. Certainly there are pathological
constructions of systems that do not benefit substantially
from this space reduction, but symbolic model checking
increases the scalability of model checking for a great many
common systems, especially those with regular structure
such as hardware circuits [53,27].
In this section, we will demonstrate how the automaton
AM, can easily grow to a size that cannot be practically
represented in memory and present the most popular
alternative representation, which uses BDDs to mitigate
this problem. The technique of symbolic model checking was
introduced by McMillan [25] in 1992 specifically as a response
to the state explosion problem. The power of symbolic model
checking derives from using equations describing sets of
states and sets of transitions to implicitly define the state
space, thereby using significantly less memory than explicit
representations that may enumerate the entire state space.
Most symbolic model checkers utilize BDDs to accomplish
this task, though other approaches are possible [133].
Boolean equations of the sort used to describe the
transition systems plied by symbolic model checking are
22
Using BDDs to reason about Boolean formulas representing the state space offers many advantages over explicit automata representations:
Complexity (both time and space): BDDs provide reasonably
small representations for a large class of the most
interesting, and most commonly-encountered, Boolean
functions. For example, all symmetric functions, including
the popular even and odd parity functions, are easily
represented by BDDs where the number of vertices grows
at most with the square of the number of arguments
to the function. Moreover, since our BDDs are reduced
and ordered, they have the property of minimality. This
means if B is a BDD representing a function f , then
for every BDD B that also represents f and has the
same variable ordering as B, size(B) size(B ). Even
better, we can frequently avoid enumerating the entire
state space. Specifically, we can express tasks in several
problem domains entirely in terms of graph algorithms
over BDDs, describe automata in terms of sets of states
and transitions, or use other techniques along those lines
to express only relevant portions of the state space. Since
all of the algorithms used for symbolic analysis of BDDs
have complexities polynomial in the sizes of the input
BDDs, the total computation remains tractable as long as
the sizes of the input BDDs are reasonable. The sum of
these time-and-space advantages allows us to use BDDs
for solving problems that may scale beyond the limits
of more traditional techniques such as case analysis or
combinatorial search.
Canonicity: There is a unique, canonical BDD representation for every Boolean function, given a total variable ordering. This property yields very simple algorithms for the
most common BDD operations. Testing BDDs for equivalence just involves testing whether their graphs match
exactly. Testing for satisfiability reduces to comparing the
BDD graph to that of the constant function 0. Similarly, a
function is a tautology iff its BDD is the constant function
1. Testing whether a function is independent of a variable
x involves a simple check of whether its BDD contains any
vertices labeled by x. Note that this is an important advantage over explicit automata representations since there
is no canonical automaton representation for any class of
automata.
Efficiency: Besides the benefits that directly follow from
canonicity,
BDD
representation
enables
efficient
algorithms for many basic operations, including intersection, complementation, comparison, subtraction, projection, and testing for implication. The time complexity of
any single operation is bounded by the product of the
graph sizes of the functions being operated on or, for
single-BDD operations like complementation, proportional
to the size of the single function graph. In other words, the
performance of directly manipulating BDDs in a sequence
of operations degrades slowly, if at all.
Simplicity: The BDD data structure and the set of
algorithms for manipulating BDDs are conceptually and
implementationally simple.
Generality: BDDs can be used for reasoning about all kinds
of finite systems, basically any problem that can be stated
in terms of Boolean functions. They are not tied to any
particular family of automata; they are just as useful
for LTL symbolic model checking as they are for the
extensions of LTL described in Section 3.2.4, for example.
4.1.
23
(q0M , q0 , 0), F)
ton defined by the quintuple AM, = (Q,
where:
State set Q = QM Q {0, 1} consists of triples (qiM , qj , t).
qj . For any ,
whenever
M (qiM , ) = qkM
and
(qj , ) = ql
unless
t=0
and
qiM FM ,
or
t=1
and
qj F
in which case
iM , qj , t), ) = (qkM , ql , t).
((q
24
qj
AM, is in state
F infinitely often. By definition of ,
((qiM , qj ), w) = (qkM , ql ),
whenever
and
M (qiM , w) = qkM
(qj , w) = ql .
w is
Since whenever qiM FM and qj F , (qiM , qj ) F,
accepted by AM, .
Only-if direction: w is accepted by AM, w LM L .
By definition, an infinite word w is accepted by AM,
if the run over w in AM, visits at least one state in F
infinitely often. That is, ((q0M , q0 ), w) transitions infinitely
By construction,
often through some state (q , q ) F.
iM
M 0M
w LM . Symmetrically,
(q0 , w) transitions through qj F
4.2.
4.2.1.
25
4.3.
BDD operations
We introduce the algorithms underlying the symbolic modelchecking procedure, as defined by Bryant [137] and reviewed
by Andersen [146]. The full model-checking algorithm
presented in Section 5 builds upon these basic operations.
If is purely propositional (i.e. contains no temporal
operators) then we can easily construct a (reduced) BDD
directly from using a straightforward algorithm like B UILD,
which simply loops through the variable ordering, recursively
constructing each variables low and high subtrees20 [146].
(See Box VI.) Otherwise, we translate into a symbolic
automaton and then encode the result, A as a BDD, as
described in Section 4.2.
Once we have built BDDs representing each of M and
A , we need to compute their product, as described
in Section 4.1. Let BDD be the set of BDD variables
encoding . The application of all binary operators over
BDDs, including conjunction, disjunction, union, intersection,
complementation (via xor with 1), and testing for implication,
is implemented in a streamlined fashion utilizing a singular
universal function. (See Box VII.) A PPLY takes as input a binary
operator and BDDs representing two functions f1 and f2 , both
over the alphabet = (1 , . . . , n ) and produces a reduced
graph representing the function f1 < op > f2 defined as:
[f1 < op > f2 ](1 , . . . , n ) = f1 (1 , . . . , n ) < op > f2 (1 , . . . , n ).
A PPLY begins by comparing the root vertices of the two
BDDs and proceeds downward. There are four cases. If
vertices v1 and v2 are both terminal vertices, the result
is simply the terminal vertex representing the result of
value(v1 ) < op > value(v2 ). If the variable labels of v1 and
v2 are the same, we create a vertex in the result BDD with
that variable label and operate on the pair of low subtrees,
low(v1 ) and low(v2 ), and the pair of high subtrees, high(v1 )
20 Unfortunately, this simple algorithm requires exponential (2n )
time.
26
Box VI.
Box VII.
and high(v2 ), to create the low and high subtrees of our new
vertex, respectively. Otherwise, one of the variables, var(v1 )
or var(v2 ) is before the other in the total variable ordering.
Note that this later vertex may or may not be a terminal
vertex; either way, the algorithm is the same. If v1 is the
earlier vertex, then the function represented by the subtree
with root v2 is independent of the variable var(v1 ). (If this
were not true, we would encounter the variable in both
graphs.) In this case, we create a vertex in the result BDD
labeled var(v1 ) and recur on the pair of subtrees {low(v1 ), v2 }
to construct this new nodes low subtree and on the pair
of subtrees {high(v1 ), v2 } to construct this new nodes high
subtree. The last case, where var(v2 ) occurs before var(v1 )
in the total variable ordering, is symmetric. We presume
27
Box VIII.
of the BDD principle that every non-terminal vertex has the
terminal vertex labeled 1 as a descendant. Thus, a classic
depth-first search with backtracking upon visiting the 0
terminal is guaranteed to find a satisfying path from the
root to the terminal 1 in linear time21 . Starting from the
root, S ATISFY- ONE arbitrarily guesses the low branch of each
non-terminal vertex first, and stores a satisfying assignment
(aka counterexample trace) of length n = |BDD |, in an array
as it traverses the graph. It returns false if the function is
unsatisfiable, and true otherwise. (See Box VIII.)
Note that the reason we check for the existence of a single
satisfying set and not for the whole set SM, of satisfying
sets is because enumerating the entire set requires time
proportional to the length of the counterexamples times the
number of elements in SM, . (For a propositional formula
with n = |BDD |, the time complexity is O (n |SM, |).)
Considering the counterexample traces may be quite lengthy
(i.e. n may be large), and there may be many of them, this
is a highly inefficient check, unlikely to be performed in any
reasonable timeframe. Furthermore, the utility of performing
such a check is questionable: a single bug may generate
any number of counterexamples. For verification purposes,
where counterexamples may trace through many time steps,
it is much more efficient to use the model checker to find
a bug, then fix that bug before searching for additional
counterexamples.
By changing the domain of the model-checking problem to
reasoning over BDD operations from explicit manipulations of
automata, we increase the size of the system we can reason
about. Combining concepts from Boolean algebra and graph
theory allows us to achieve such a high level of algorithmic
efficiency that the performance of symbolic model checking
using these techniques is limited mostly by the sizes of the
BDDs involved. Table 3 compares the two methods for each
step in the model-checking problem.
4.4.
5.
28
Table 3 Table comparing explicit and symbolic model-checking algorithms. Recall that el() is the set of elementary
formulas of as defined in Section 3.7. We presume the ROBDDs for M and are created using the appropriate variants
of the B UILD algorithm [146]. The ROBDD for AM, is created by an extension of the algorithm A PPLY(, ROBDDM ,
ROBDD ) [146], implementing the dynamic programming optimizations that result in lower time-complexities. Finally,
the algorithm used for finding a counterexample given an ROBDD is based on A NYS AT [146]. Note that, for both explicit
and symbolic model checking, multiple steps below are performed at once, using on-the-fly techniques, which increases
the efficiency of the process and may avoid constructing all of AM, . We separate out the steps here for simplicity only.
Operation
Translate M from a
higher-level language
Translate from LTL
to A
Create AM,
Check AM, for
nonemptiness
Construct a
counterexample
Explicit method
Construct a Bchi
automaton
Construct a Bchi
automaton
Construct automaton for
L (M) L (A )
Search for an accepting
path via iterative
depth-first search of the
strongly connected
components
Compute an accepting
cycle through the SCC
graph
Time
complexity
Depends on
M
2O (||)
O (|M|
|A |)
O (|AM, |)
O (|trace|)
Symbolic method
Time complexity
Construct an ROBDD
O (2| | )
Construct an ROBDD
O (2|el()| )
O (|ROBDDM ||ROBDD |) =
O (2| | 2|el()| )
O (|BDDrepresentation|)a
a Here, the time complexity depends upon the size of the symbolic (BDD) representation in terms of the distances between states in the
automaton graph, the number and arrangement of the strongly connected components in this graph, and the number of fairness conditions
asserted.
29
Fig. 8 A counterexample trace takes the form of an accepting lasso. Again, the start state is designated by an incoming,
unlabeled arrow not originating at any vertex. Here, F1 . . . F4 represent final states satisfying four acceptance conditions.
(b) Isomorphism
elimination rule.
(c) Redundancy
elimination rule.
Fig. 9 Conversion of a Binary Decision Tree for x1 x2 x3 into a Binary Decision Diagram.
5.1.
Automata as graphs
30
Fig. 12 BDD representing the symbolic automaton in Section 3.8, Box V, for the formula
(TSAFE_clear TSAFE_command). (The variable EL_X_G__TSAFE_clear_OR_F_TSAFE_command is abbreviated EL_X_G_....)
31
is a
32
5.2.
5.3.
33
34
Box IX.
Box X.
L1 = (1 , 2 , . . . i ) and L2 = (i , i+1 , . . .) are standard list data
structures such that the last element of L1 is the same as the
first element of L2 , then L1 L2 = (1 , 2 , . . . i , i+1 , . . .) represents their concatenation, overlapping this shared element,
or simply concatenating the lists if there is no overlap. We
define the function choose(P) to consistently choose one element of a predicate P. Then we have the subroutine given in
Box X.
We are now ready to present the full counterexample
extraction algorithm. For completeness, we show the step
of checking AM, for feasibility in context. We define the
function last(L1 ) to return the last element in the list L1 in
the algorithm given in Box XI.
After checking AM, for feasibility, we exit if M |H . If
not, we know that the set returned by feasible(), which we
save in f inal, contains all of the states in fair SCCs that are
reachable from q0 . We look at the set of successors of states
in the set f inal. We pick a state from this set and iterate,
35
Box XI.
5.4.
our example liveness specification that whenever a nearterm conflict is detected (i.e. whenever TSAFE_clear is false)
that the conflict is addressed (i.e. a correcting command
from TSAFE is issued), which we wrote in LTL as LTLSPEC
(G (controller_request ->(F (! controller_request)))). In
this case, the specification holds, and we can conclude that
M |H .
Now let us try another specification: we want to
ensure the human in the loop can always override the
software algorithms. In other words, we check that the
corrective trajectory requests from the controller are always
granted. Since, in our simple model, controller requests are
fulfilled by transferring the request into a corresponding
command by the auto-resolver, in LTL we write this as
(controller_request
(AR_command&controller_request)).
The result of checking that specification using NuSMV is given
in Box XIII.
Our specification has failed! The counterexample returned
guides us along a path through our system where the
specification does not hold. Notice the path starts in our
system models initial state, which NuSMV names State 1.1,
where all of the variables but TSAFE_clear are false. In the next
state along our path, the only variable that changes value is
controller_request, which becomes true. (This corresponds
to a transition to State 4 in the automaton in Fig. 2.) Next,
we transition to a state where controller_request is 0 and
all of the other variables values are the same as they were
in the last state. (We are now in State 1 in Fig. 2.) Finally,
we transition again but none of the values of the variables
change. (This represents the transition from State 1 to itself
where the airspace is clear and there are no commands or
requests.) Notice the occurrence of Loop starts here just
before the description of NuSMV State 1.3 designates that
we loop from State 1 to State 1 forever, thus completing the
description of our infinite accepting run.
36
Box XII.
Box XIII.
6.
Discussion
37
Acknowledgements
Thanks to Moshe Y. Vardi, Eric W. D. Rozier, and Misty
D. Davies for insightful comments on earlier drafts of this
paper. Thanks also to Heinz Erzberger for enlightening
conversations on the automated airspace concept for air
traffic control, which made a wonderful running example.
REFERENCES
38
39
40
[132] S. Fogarty, M.Y. Vardi, Bchi complementation and sizechange termination, in: TACAS, Proc. of 15th Intl Conf.,
Springer, Berlin, Heidelberg, 2009, pp. 1630.
[133] A. Biere, A. Cimatti, E. Clarke, O. Strichman, Y. Zhu, Bounded
model checking, Adv. Comput. 58 (2003).
[134] C. Lee, Representation of switching circuits by binary
decision programs, Bell Syst. Tech. J. 38 (1959) 985999.
[135] S.B. Akers, Binary decision diagrams, IEEE TC C-27 (6) (1978)
509516.
[136] S. Fortune, J.E. Hopcroft, E.M. Schmidt, The complexity
of equivalence and containment for free single variable
program schemes, in: ICALP, Proc. 5th, Springer, London, UK,
1978, pp. 227240.
[137] R.E. Bryant, Graph-based algorithms for Boolean-function
manipulation, IEEE TC C-35 (8) (1986) 677691.
[138] R.E. Bryant, Symbolic Boolean manipulation with Ordered
Binary-Decision Diagrams, ACM Comput. Surv. 24 (3) (1992)
293318.
[139] P. Linz, An Introduction to Formal Languages and Automata,
2nd ed., D. C. Heath and Company, Lexington, MA, USA,
1996 (Chapter 14).
[140] P Gribomont, P Wolper, in: A. Thayse (Ed.), Temporal logic,
in from modal logic to deductive databases, 1989.
[141] M. Michel, Complementation is more difficult with automata on infinite words, in: CNET, Paris, 1988.
[142] J. Esparza, Decidability of model checking for infinite-state
concurrent systems, Acta Inform. 34 (1997) 85107.
[143] S. Minato, N. Ishiura, S. Yajima, Shared binary decision
diagram with attributed edges for efficient Boolean function
manipulation, in: DAC, Proc. 27th ACM/IEEE Conf., 1990,
pp. 5257.
[144] G.D. Hachtel, E. Macii, A. Pardo, F. Somenzi, Markovian
analysis of large finite state machines, IEEE Trans. Comput.
Aided. Des. 15 (1996) 14791493.
[145] M. Chechik, S. Easterbrook, B. Devereux, Model checking
with multi-valued temporal logics, in: ISMVL, 2000, pp.
187192.
[146] Henrik Reif Andersen, An Introduction to Binary Decision
Diagrams, Internet, Sept 1996.
[147] D. Sieling, I. Wegener, Reduction of OBDDs in linear time,
Inform. Process. Lett. 48 (3) (1993) 139144.
[148] Y. Kesten, A. Pnueli, L. Raviv, Algorithmic verification of
linear temporal logic specifications, in: ICALP, Proc. 25th,
in: LNCS, vol. 1443, Springer, 1998, pp. 116.
[149] E.M. Clarke, O. Grumberg, D. Peled, Model Checking, MIT
Press, 1999 (Chapter 16, 89).
[150] R.S. Streett, Propositional dynamic logic of looping and
converse, Inf. Control 54 (1982) 121141.
[151] N. Francez, D. Kozen, Generalized fair termination, in: POPL,
1984, pp. 4653.
[152] E.M. Clarke, O. Grumberg, K.L. McMillan, X. Zhao, Efficient
generation of counterexamples and witnesses in symbolic
model checking, in: DAC, Proc. 32nd, IEEE, 1995, pp. 427432.
[153] R. Hojati, R.K. Brayton, R.P. Kurshan, BDD-based debugging
of design using language containment and fair CTL, in: CAV,
Springer-Verlag, London, UK, 1993, pp. 4158.
[154] Z. Manna, A. Pnueli, The Temporal Logic of Reactive and
Concurrent Systems: Safety, Springer, New York, 1995.
[155] K. Ravi, R. Bloem, F. Somenzi, A comparative study of
symbolic algorithms for the computation of fair cycles,
in: FMCAD, Proc. Intl. Conf., in: LNCS, vol. 1954, Springer,
2000, pp. 143160.
[156] R. Hojati, H. Touati, R. Kurshan, R. Brayton, Efficient regular language containment, in: CAV, Proc. 4th Intl Conf.,
in: LNCS, vol. 663, Springer, 1992.
[157] R.H. Hardin, R.P. Kurshan, S.K. Shukla, M.Y. Vardi, A new
heuristic for bad cycle detection using BDDs, in: CAV,
Proc. 9th Intl Conf., in: LNCS, vol. 1254, Springer, 1997,
pp. 268278.
41