Formal Methods For Components and Object
Formal Methods For Components and Object
Editorial Board
David Hutchison
Lancaster University, UK
Takeo Kanade
Carnegie Mellon University, Pittsburgh, PA, USA
Josef Kittler
University of Surrey, Guildford, UK
Jon M. Kleinberg
Cornell University, Ithaca, NY, USA
Friedemann Mattern
ETH Zurich, Switzerland
John C. Mitchell
Stanford University, CA, USA
Moni Naor
Weizmann Institute of Science, Rehovot, Israel
Oscar Nierstrasz
University of Bern, Switzerland
C. Pandu Rangan
Indian Institute of Technology, Madras, India
Bernhard Steffen
University of Dortmund, Germany
Madhu Sudan
Massachusetts Institute of Technology, MA, USA
Demetri Terzopoulos
New York University, NY, USA
Doug Tygar
University of California, Berkeley, CA, USA
Moshe Y. Vardi
Rice University, Houston, TX, USA
Gerhard Weikum
Max-Planck Institute of Computer Science, Saarbruecken, Germany
Frank S. de Boer Marcello M. Bonsangue
Susanne Graf Willem-Paul de Roever (Eds.)
Formal Methods
for Components
and Objects
13
Volume Editors
Frank S. de Boer
Centre for Mathematics and Computer Science, CWI
Kruislaan 413, 1098 SJ Amsterdam, The Netherlands
E-mail: F.S.de.Boer@cwi.nl
Marcello M. Bonsangue
Leiden University, Leiden Institute of Advanced Computer Science
P.O. Box 9512, 2300 RA Leiden, The Netherlands
E-mail: marcello@liacs.nl
Susanne Graf
VERIMAG
2 Avenue de Vignate, Centre Equitation, 38610 Grenoble-Gières, France
E-mail: Susanne.Graf@imag.fr
Willem-Paul de Roever
Christian-Albrechts-University of Kiel
Institute of Computer Science and Applied Mathematics
Hermann-Rodewald-Straße 3, 24118 Kiel, Germany
E-mail: wpr@informatik.uni-kiel.de
ISSN 0302-9743
ISBN 3-540-22942-6 Springer Berlin Heidelberg New York
This work is subject to copyright. All rights are reserved, whether the whole or part of the material is
concerned, specifically the rights of translation, reprinting, re-use of illustrations, recitation, broadcasting,
reproduction on microfilms or in any other way, and storage in data banks. Duplication of this publication
or parts thereof is permitted only under the provisions of the German Copyright Law of September 9, 1965,
in its current version, and permission for use must always be obtained from Springer. Violations are liable
to prosecution under the German Copyright Law.
Springer is a part of Springer Science+Business Media
springeronline.com
© Springer-Verlag Berlin Heidelberg 2004
Printed in Germany
Typesetting: Camera-ready by author, data conversion by Scientific Publishing Services, Chennai, India
Printed on acid-free paper SPIN: 11315810 06/3142 543210
Preface
Large and complex software systems provide the necessary infrastucture in all in-
dustries today. In order to construct such large systems in a systematic manner,
the focus in the development methodologies has switched in the last two decades
from functional issues to structural issues: both data and functions are encap-
sulated into software units that are integrated into large systems by means of
various techniques supporting reusability and modifiability. This encapsulation
principle is essential to both the object-oriented and the more recent component-
based software engineering paradigms.
Formal methods have been applied successfully to the verification of medium-
sized programs in protocol and hardware design. However, their application to
large systems requires a further development of specification and verification
techniques supporting the concepts of reusability and modifiability.
In order to bring together researchers and practioners in the areas of soft-
ware engineering and formal methods, we organized the 2nd International Sym-
posium on Formal Methods for Components and Objects (FMCO) in Leiden,
The Netherlands, from November 4 to 7, 2003. The program consisted of in-
vited tutorials and technical presentations given by leading experts in the fields
of theoretical computer science and software engineering. The symposium was
attended by more than 80 people from all over the world.
This volume contains the contributions of the invited speakers to
FMCO 2003. We believe that the presented material provides a unique com-
bination of ideas on software engineering and formal methods which we hope
will form an inspiration for those aiming at further bridging the gap between
the theory and practice of software engineering.
The very idea to organize FMCO arose out of the NWO/DFG bilateral
project Mobi-J. In particular we acknowledge the financial support of the NWO
funding of Mobi-J. Additional financial support was provided by the Lorentz
Center, the IST project Omega (2001-33522), the Dutch Institute for Program-
ming Research and Algorithmics (IPA), the Royal Netherlands Academy of Arts
and Sciences (KNAW), the Centrum voor Wiskunde en Informatica (CWI), and
the Leiden Institute of Advanced Computer Science (LIACS).
Priority Systems
Gregor Gössler, Joseph Sifakis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 314
1 Introduction
Embedded systems are intrinsically heterogeneous since they are based on pro-
cessors that see the world digitally and an environment that is analog. In ad-
dition, the processing elements are heterogeneous too since they often include
micro-controllers and digital signal processors in addition to special purpose com-
puting engines. These parts must communicate and exchange information in a
consistent and reliable way over media that are often noisy and unreliable. Some
of the tasks that embedded systems must carry out are safety-critical, e.g., in
medical and transportation systems (cars, airplanes, trains) and for this reason
have hard constraints on timing and reliability. As technology advances, increas-
ingly more computing power becomes available thus offering the opportunity of
adding functionality to the system to such an extent that the complexity of the
design task is unmanegeable without a rigorous design methodology based on
This research was supported in part by the European Commission under the projects
COLUMBUS, IST-2002-38314, and ARTIST, IST-2001-34820, by the NSF under the
project ITR (CCR-0225610), and by the GSRC.
F.S. de Boer et al. (Eds.): FMCO 2003, LNCS 3188, pp. 1–16, 2004.
c Springer-Verlag Berlin Heidelberg 2004
2 A. Benveniste et al.
sound principles. In particular, the need for fast time-to-market and reasonable
development cost imposes design re-use. And design re-use implies the use of
software for as many parts of the functionality as possible given size, production
cost and power consumption constraints. Consequently, software accounts for
most of the design costs today and it is responsible for delays in product deliv-
ery because of the lack of a unified design process that can guarantee correct
behavior.
Today, designers face a very diversified landscape when it comes to method-
ologies, supporting tools, and engineering best practices. This would not neces-
sarily be a problem if it were not for the fact that transitioning between tools
that are based on different paradigms is increasingly becoming a design produc-
tivity bottleneck as it has been underlined by the road map work performed
in the framework of the ARTIST network of excellence [3]. A solution to this
problem would be to impose a “homogeneous” design policy, such as the fully
synchronous approach. However, implementation costs in terms of performance
and components require a more diversified view. Heterogeneity will manifest it-
self at the component level where different models of computation may be used
to represent component operation and, more frequently, at different levels of
abstraction, where, for example, a synchronous-language specification of the de-
sign may be refined into a globally asynchronous locally synchronous (GALS)
architecture, thus alleviating some of the cost issues outlined above. Having
a mathematical framework for the heterogeneous modeling of reactive systems
gives freedom of choice between different synchronization policies at different
stages of the design process and provides a solid foundation to handle formally
communication and coordination among heterogeneous components. Interest-
ing work along similar lines has been the Ptolemy project [13, 15], the MoBIES
project [1], the Model-Integrated Computing (MIC) framework [16], and Inter-
face Theories [14].
This paper is an extension of [7] where we proposed Tagged Systems, a vari-
ation of Lee and Sangiovanni-Vincentelli’s (LSV) Tagged-Signal Model [22], as
a mathematical model for heterogeneous systems. Originally, we restricted our-
selves to Tagged Systems in which parallel composition is by intersection, mean-
ing that unifiable events of each component must have identical variable, data,
and tag. While this restriction has allowed us to handle GALS models of design, it
does not cover all cases of interest. For example, causality relations and schedul-
ing constraints are not compatible with parallel composition by intersection.
Neither are earliest execution times. Yet causality and scheduling constraints
are very important to include when implementing an embedded systems. Hence,
it is sometimes useful to have a notion of parallel composition that accepts the
unification of events having different tags (while the data that they carry must
still be equal). In this work, we propose an extension of Tagged Systems where
the unification rule for tags is itself parameterized. We show that this model cap-
tures important properties such as causality and scheduling constraints. Then,
we extend the general theorems of [7] on the preservation of semantics during
distributed deployment.
Causality and Scheduling Constraints 3
that “the 2nd occurrence of x depends on the 3rd occurrence of b”. Define
N0 =def N ∪ {0}. Define a dependency to be a map:
δ = V → N0 .
Note that, since n > 0, the condition δ(v ) = n makes this dependency
effective. Definition (7) makes σ a labeled directed graph. Denote by σ the
transitive reflexive closure of →σ , it is a preorder 1 .
τ τ =def max(τ, τ ).
Hence is here a total function. Composing two systems has the effect that
the two components wait for the latest date of occurrence for each shared vari-
able. For example, assume that variable v is an output of P and an input of
Q in P Q. Then the earliest possible date of every event of variable v in Q is
by convention 0, whereas each event associated to v has a certain date of pro-
duction in P . In the parallel composition P Q, the dates of production by P
prevail.
1
We insist: “preorder”, not “partial order”—this should not be a surprise, since the
superposition of two partial orders generally yields a preorder.
6 A. Benveniste et al.
b : t f t f t f ...
P :
x : 1 1 1 ...
b : t f t f t f ...
Q:
x : 1 1 1 ...
Adding Causality Relations. Suppose that some analysis of the considered pro-
gram allows us to add the following causality relations to P and Q:
b : t f t f t f ...
Pc : ↓ ↓ ↓ ...
x : 1 1 1 ...
b : t f t f t f ...
Qc : ↓ ↓ ↓ ...
x : 1 1 1 ...
8 A. Benveniste et al.
b : t f t f t f ...
Pcc : ↓ f ↓ f ↓ f ...
x:1 1 1 ...
b : t f t f t f ...
Qcc : t ↓ t ↓ t ↓ ...
x: 1 1 1 ...
Causality and Scheduling Constraints 9
b : t f t f t f . . .
α
Pcc Qα
cc = t t t . . .
x: 1 1 1 ...
The reason for the double causality between x and f -occurrences of b is that
the n-th x causes the (2n)-th b (i.e. the n-th f -occurrence of b) in Pcc whereas the
(2n)-th b causes the n-th x in Qcc . Formally, by the max rule (6), the composed
α
behavior of Pcc Qαcc is written
P1 (ρ ρ) P2 ≡ P1 P2 . (19)
Running Example, Cont’d. The reader can check the following as an exercise:
P Q = ∅, and, as we already discussed, Pα Qα = Pα . Now we compute
P (α α) Q. From (16) we get that, using obvious notations, (σP , σQ ) is a pair of
behaviours that are unifiable modulo desynchronization, i.e., σP α α σQ . Then,
unifying these yields the behaviour σ such that:
Thus it remains to show that, if the two conditions of Theorem 1 hold, then
inclusion ⊆ in (19) does too. Now, assume (21) and (22). Pick a pair (σ1 , σ2 )
of behaviours which are unifiable in P1 (ρ ρ) P2 . Then, by definition of (ρ ρ) ,
the pair ((σ1 )ρ , (σ2 )ρ ) is unifiable in (P1 )ρ (P2 )ρ . Next, (22) guarantees that
(σ1 )ρ (σ2 )ρ is a behaviour of (P1 P2 )ρ . Hence there must exist some pair
(σ1 , σ2 ) unifiable in P1 P2 , such that (σ1 σ2 )ρ = (σ1 )ρ (σ2 )ρ . Using the
same argument as before, we derive that ((σ1 )ρ , (σ2 )ρ ) is also unifiable with re-
spect to its associated (asynchronous) parallel composition, and (σ1 )ρ (σ2 )ρ =
(σ1 )ρ (σ2 )ρ . But (σ1 )ρ is the restriction of (σ1 )ρ (σ2 )ρ to its events labeled by
variables belonging to V1 , and similarly for (σ2 )ρ . Thus (σi )ρ = (σi )ρ for i = 1, 2
follows. Finally, using (21), we know that if (σ1 , σ2 ) is such that, for i = 1, 2:
(σi )ρ = (σi )ρ , then: σi = σi . Hence (σ1 , σ2 ) is unifiable in P1 P2 .
Corollary 1. Let P1 and P2 be synchronous systems whose behaviors are
equipped with some equivalence relation ∼, and assume that P1 and P2 are closed
with respect to ∼. Then, the pair (P1 , P2 ) satisfies condition (19) if it satisfies
the following two conditions:
∀i ∈ {1, 2} : (Pi )ρ is in bijection with Pi / ∼ (23)
(P1 P2 )ρ = (P1 )ρ (P2 )ρ (24)
where Pi / ∼ is the quotient of Pi modulo ∼.
Proof. Identical to the proof of Theorem 1 until the paragraph starting with
“Finally”. Finally, using (23), we know that if (σ1 , σ2 ) is such that, for i = 1, 2:
(σi )ρ = (σi )ρ , then: σi ∼ σi . Hence (σ1 , σ2 ) is unifiable in P1 P2 , since all
synchronous systems we consider are closed under ∼.
This result is of particular interest when ∼ is the equivalence modulo stut-
tering, defined in [7].
In (25), symbol − denotes an arbitrary value in the domain D, and k(.), l(.)
are arbitrary strictly increasing maps, from N to N. As the reader can check, P
satisfies (21) but Q does not. The desynchronization α is not semantics preserv-
ing for this pair (P, Q).
Now, consider the following modification of (P, Q): P emits to Q two signals
with names x and y. Signal y is emitted by P if and only if x > 0 (assuming, say,
x integer). In addition, P emits a boolean guard b simultaneously with x, and b
takes the value true iff x > 0. Signals x and y are awaited by Q . In addition, Q
awaits the boolean guard b simultaneously with x, and Q knows that he should
receive y simultaneously with the true occurrences of b. Formally:
⎧
⎪
⎪ σ(x)(n) = (n, −)
⎨
σ(b)(n) = if σ(x)(n)(n) > 0 then (n, t) else (n, f )
P :
⎪
⎪ σ(y)(n) = (m(n), −), where
⎩
m(n) = min{m | m > m(n − 1) ∧ σ(x)(m) > 0}
⎧ (26)
⎪
⎪ σ(x)(n) = (k(n), −)
⎨
σ(b)(n) = (k(n), −)
Q :
⎪
⎪ σ(y)(n) = (l(n), −), where
⎩
l(n) = min{k(m) | k(m) > l(n − 1) ∧ σ(b)(m) = t}
References
1. R. Alur, T. Dang, J. Esposito, Y. Hur, F. Ivancic, V. Kumar, I. Lee, P. Mishra,
G. J. Pappas and O. Sokolsky. Hierarchical Modeling and Analysis of Embedded
Systems. Proc. of the IEEE, 91(1), 11–28, Jan. 2003.
2. R. Alur and D. L. Dill. A Theory of Timed Automata. Theor. Comp. Science,
126(2), 183–235, Apr. 1994.
3. ARTIST Network of Excellence. Roadmap on Hard Real-Time Develop-
ment Environments. Available in may 2003 from url http://www.systemes-
critiques.org/ARTIST/.
4. A. Benveniste. Some synchronization issues when designing embedded systems
from components. In Proc. of 1st Int. Workshop on Embedded Software, EM-
SOFT’01, T.A. Henzinger and C.M. Kirsch Eds., LNCS 2211, 32–49, Springer.
5. A. Benveniste, B. Caillaud, and P. Le Guernic. From synchrony to asynchrony. In
J.C.M. Baeten and S. Mauw, Eds., CONCUR’99, Concurrency Theory, 10th Intl.
Conference, LNCS 1664, pages 162–177. Springer, Aug. 1999.
6. A. Benveniste, B. Caillaud, and P. Le Guernic. Compositionality in dataflow syn-
chronous languages: specification & distributed code generation. Information and
Computation, 163, 125-171 (2000).
7. A. Benveniste, L. P. Carloni, P. Caspi, and A. L. Sangiovanni-Vincentelli. Het-
erogeneous reactive systems modeling and correct-by-construction deployment. In
R. Alur and I. Lee, Eds., Proc. of the Third Intl. Conf. on Embedded Software,
EMSOFT 2003, LNCS 2855, Springer, 2003.
8. A. Benveniste, P. Caspi, S. Edwards, N. Halbwachs, P. Le Guernic, and R. de Si-
mone. The Synchronous Language Twelve Years Later. Proc. of the IEEE,
91(1):64–83, January 2003.
9. G. Berry. The Foundations of Esterel. MIT Press, 2000.
16 A. Benveniste et al.
Jan A. Bergstra1,2
1
University of Amsterdam, Programming Research Group
janb@science.uva.nl
2
Utrecht University, Department of Philosophy, Applied Logic Group
janb@phil.uu.nl
1 Introduction
Machine models can be given at a very high level of abstraction by using so-
called machine functions, a concept due to [6] as a basis. Machine functions
are hypothetical functions, which may be classified by machine function types.
Machine function types provide information about the expected inputs and out-
puts, or more general the behavior of a machine. Machine functions are named
elements of machine function types. Machine functions are used as the primitive
operators of a control code algebra. Machine functions may be viewed as black
box containers of behavior. It is not expected that machine functions are actu-
ally either formally specified or algorithmically given in any detail. Important,
however is the realization that different machine architectures may use different
machine functions as realizations of the same machine function type. A number
of issues is can be clarified using machine functions only: the so-called compiler
fixed point, the distinction between compilation and interpretation, the role of
intermediate code, managed execution and JIT compilation, and finally verifying
compilation.
1.1 Motivation
The identification of machine function types and the description of machine
models as composed from named but otherwise unspecified machine functions
may be helpful for the following reasons:
F.S. de Boer et al. (Eds.): FMCO 2003, LNCS 3188, pp. 17–41, 2004.
c Springer-Verlag Berlin Heidelberg 2004
18 J.A. Bergstra
1
The acronym CCA is a mere abbreviation, having well over a million hits on Google
and in no way specific. Its expansion ‘Control Code Algebra’ generates no single hit,
however, at the time of this writing.
Machine Function Based Control Code Algebras 19
of code may lie within the scope of CCA. Here are some interesting issues for
which that is unclear:
– Can the phenomenon of computer viruses can be modeled at the level of
CCA. Many computer users are supposed to use their computers in such a
way that infections are prevented, while no plausible argument can be given
that these users must understand the details of how a machine works. The
question may therefore be rephrased as follows: can an explanation via an
appropriate CCA be given of what machine users must do in order to prevent
virus infections of their systems. And, moreover can it be formulated what
requirements systems must satisfy if these prescriptions for user behavior are
to guarantee that systems remain clear of infections.
– Another question that may be answered at the level of an appropriate CCA
is what an operating system is. Textbooks on operating systems never intro-
duce the concept of an operating system as a concept that merits a definition
in advance. Substantial questions concerning what minimum might be called
an OS and whether or not an OS is a computer program or a control code
are impossible to answer without proper definitions, however.
– A third question which may or may not lie within the scope of CCA is the
question as to what constitutes a software component. By its nature the
concept of a software component abstracts from the details of computation.
But a first attempt to define software components in the framework of CCA
reveals that some non-algorithmic knowledge about software component in-
ternals may be essential and outside the scope of CCA at the same time.
∀n (fn (y z) = M → fm (y) = M )
∀n (fn (y) = D → fm (y z) = D)
These rules express that
– The sequence of outputs is computed in a single computation. A divergence
implies that no bit sequences can be produced, whereas an error (M ) only
indicates that a certain output is not produced. Only finitely many outputs
bit sequences are produced, and beyond that number an error occurs.
– There is one algorithm doing the computation accessing more arguments
when needed. When arguments are lacking an error (M ) will occur, rather
than D. Providing more inputs (y z instead of y) cannot cause an error
(M ). In other words if a computation on a list of inputs runs into an error
than each computation on a shorter list must run into an error as well.
– A divergence taking place on a given sequence of inputs cannot be prevented
by supplying more inputs. (This in contrast with an error which may result
from a lack of inputs.)
and produces three output sequences that are placed on top of the stack. s.Fd
is the command for the second one, which places two results on the top of the
stack consecutively. How such commands are entered is left unspecified in the
model at hand.
Consider the command sequence
CS = s.load:f;s.Fc;s.store:g;s.pop;
s.pop;s.load:g;s.Fd;s.store:h;s.pop
If the content of f before operation is x then after performing CS the content
of h is Fd1 (Fc1 (x)). This output is probably empty if either one of the two
commands lead to error messages, whereas if the error message output is empty
on may assume that the other outputs are ‘correct’. It also follows from this
model that the operation of the system is deterministic for command sequences of
this kind. Several potentially relevant system properties may now be formulated:
Code is produced unless errors are found Fc2 (x) = [ ] → Fc1 (x) = [ ]
Disassembly succeeds unless errors are found Fd2 (x) = [ ] → F1 (x) = [ ]
Disassembly inverts of assembly Fc2 (x) = [ ] → Fd1 (Fc3 (x)) = Fc1 (x)
The use of machine functions in the examples mentioned above is in making
these requirement descriptions more readable than it would be possible without
them. With these few primitives there appears to be no significant reasoning
involving calculation, however.
question what makes a bit sequence a control code (rather than just its place in
the argument listing of a machine function) is left for later discussion.
For code expression machine functions another notation is introduced which
separates the first and other arguments. A notation for the n’th result of a
code expression function taking k arguments (except the code argument x) is as
follows:
x • •n y1 , .., yk
By default the first argument is meant of no superscript is given:
If the name f is given this can be made explicit with x • •nf y1 , .., yk . The
semantics of a control code x w.r.t. a machine function is the family of all
machine functions taking x fixed, denoted |x|•• . Thus semantic equivalence for
control codes reads
Bit sequence generating machine functions are less useful when it comes to
the description of interactive systems. But code expression machine functions
are very simple as a concept and they can be used until a lack of expressive
power or flexibility forces one to move to a different model.2
2
The discussion may be made more general by using a terminology consistent with
the possibility that a machine function produces an interactive behavior (i.e. a pro-
cess). A bit sequence generating machine function is just a very simple example of a
behavior. If the behavior of a machine is described in terms of a polarized process its
working may be determined through a function that produces a rational polarized
behavior over a given collection A of basic actions from the codes that have been
placed in the machine as an input or as a control code. The reason to consider a
mapping function, say FM : BS × BS × BS → BP P A(A), as the description of a
machine if a control code dependent machine is to be compared with a programmable
machine. BPPA is the algebra of basic polarized process from [2]. As will become
clear below polarized processes are well-suited for the specification of programs and
programmed machine behavior. In the case such a machine needs to be viewed as a
control code dependent machine a polarized process machine function results.
Machine Function Based Control Code Algebras 23
implausible to speak of a stored code. For that reason the model is classified
as a split control code machine model. This is in contrast with a stored code
machine model for which it is required that code storage is achieved by means of
the same mechanisms as any storage during computation. As nothing is known
about these mechanisms due to the abstract nature of machine functions, being
no more than formal inhabitants of their types, the model cannot be classified
as a stored control model.
Having available the notion of a split control code machine, it is possible
to characterize when a code is an executable for it: x is an executable for ••f
if for some y, x • •f y = M . Because this criterion depends on an application
of the code in an execution it is a dynamic criterion. In practice that may be
useless and entirely undecidable. For that reason a subset (or predicate) Ec of the
executables may be put forward as the collection of ‘certified’ executables. Here
it is understood that certification can be checked efficiently. A pair (••f , Ec ) is
a split control machine with certified executables.
It is always more or less taken for granted that modern computer program-
ming is based on the so-called stored program computer model. In the opinion
of the author a bottom up development of the concept of a program starts with
a split program machine model, however, the register machine constituting a
prime example of a split program machine model. Having available a split pro-
gram machine model one may then carry on to develop stored program machine
models. The usual objection against this argument is that a Turing machine ([9])
constitutes a stored program machine model already. That, however, is debat-
able because it is not clear which part of the tape content or state space of a
Turing might be called a program on compelling grounds. Usually some intuition
from an implicit split machine model is used to provide the suggestion that a
part of the tape contains a program in encoded form. That, however, fails to be
a compelling argument for it being a program.
Below in 5.2 we will see that the situation is not symmetric indeed and sound
reasons may exist for taking one code argument to play the role of containing
the control code rather than another argument.3
x • •nspm−f y1 , .., yk
3
When investigating stored control code machines or stored program machines this
question reappears in the following form: which memory compartment contains con-
trol code or program code?
Machine Function Based Control Code Algebras 25
4
The hypothetical programmed machine architecture.
5
Also called assembler mapping, the inverse being an assembly projection.
26 J.A. Bergstra
Indeed suppose, hypothetically that for all x and y, Sf (x, y) = Sf (y, x). Then
the symmetry is complete and a justification for putting the first argument of
Sf in the role of control code and the other argument in the role of input data
cannot be found.
A justification for putting the first argument in the control code role can only
be found if the code expression machine function is asymmetric and if, moreover,
the first code argument (x) can be said to be ‘more in control’ than the second
one (y) or any other argument. The control code identification problem will now
be simplified to the case that the code expression machine function has exactly
two inputs. The task is to select the control code input, if that can be done.
Here are three informal criteria that may be applied to argue that indeed, the
first argument has the role of a control code:
6.1 Executables
Given a split control code machine the control codes may as well be called exe-
cutables. This phrase is often used if control codes are transformed programs. It
is common to make a distinction, however, between arbitrary control codes and
executable control codes, or simply ‘executables’ where executables are those
control codes really meant for execution on the model. Lacking any intrinsic
criterion as to which codes are to be considered executable it is reasonable to
assume that some collection Ec of codes comprises the executables. This collec-
tion is specific to the code expression machine function of the machine model
under consideration.
6
It is a common additional requirement that for codes outside A a non-executable
output is produced together with a second output which contains a list of so-called
errors allowing the control code designer to find out what is wrong.
7
This is not implausible as the compiler is a complex piece of control code which may
profit from advanced design technology.
30 J.A. Bergstra
Using this notation the versions of the executable code that occur in the
description of the fixed point are: x3 : a2e : e = u : a2e : a • •a u : a2e : a, and
x4:a2e:e = (u:a2e:a • •a u:a2e:a) • •u:a2e:a (= x3:a2e:e • •u:a2e:a). The fixed point
fact itself reads: (u:a2e:a • •a u:a2e:a) • •u:a2e:a = u:a2e:a • •a u:a2e:a.
Correct Assembly Code. An assembly code is correct if its image under the
assembler is an executable, thus z ∈ Ac if x1 : a2e : e • •z ∈ Ec .8 The correct
codes depend on the available assembler codes. Improved assemblers may accept
(turn into an executable) more codes, however, thereby increasing the extension
of ‘correct assembly codes’.
8
Ac may be called the pseudo-empirical syntax of A.
9
Compiler based pseudo-empirical syntax of S.
32 J.A. Bergstra
10
Interpreter based pseudo-empirical syntax for S.
Machine Function Based Control Code Algebras 33
special case where multi-part codes have just one part (single part codes: SPC).
Access to a part can be given via its rank number in the flat multipart code
listing, starting with 1 for the first part. MPCN, (multi-part code notation)
admits bit sequences and the associative operator ‘:’. Brackets are admitted
in MPCN but do not constitute elements of the code families, for instance:
(10:011):00 = 10:(011:00) = 10:011:00. When multi-part codes are used it is
practical to modify the type of machine functions in order to admit multi-part
inputs.
The n’th part of a multi-part code x is denote partn (x). This notation pro-
duces empty codes if n is too large.
Non-separate Assembly and Compilation. An assembler or a compiler for
multipart code that produces a single executable will be called a non-separate
assembler or a non-separate compiler. To use a positive jargon a non-separate
assembler or compiler may be called a gluing assembler or compiler. It is assumed
that a gluing assembler/compiler detects itself which parts of a code must be
used, for instance by looking at a code that contains some marker and using some
form of cross referencing between the parts. Let MPA be a multipart assembly
code notation. c:mpa2e:e is an executable which transforms multi-part control
codes to single-part executables. A gluing compiler can be used to define the
meaning of multi-part control codes as follows:
x:mpa • •mpa y = (c:mpa2e:e • •x:mpa) • •y.
Similarly for a notation s, mps may be its multi-part extension. Then one
may define its meaning given a non-separate compiler by
x:mps • •mps y = (c:mps2a:e • •x:mps) • •a y.
Separate Compilation. Separate compilation holds for code families of some
code notation if a compiler ψ distributes over the code part separator : ψ(x:y) =
ψ(x):ψ(y)). A compiler with this property is called separation modular. So it
may now be assumed that mS (modular S) consists of sequences of S separated
by ‘:’ and that u:ms2e:e is a separation modular compiler for mS i.e., using
MPCN, u:ms2e:e • •y:z = (u:ms2e:e • •y):(u:ms2e:e • •z) for all y and z which
may themselves be code families recursively. For the second output component
there is a similar equation: u:ms2e:e • •2 y:z = (u:ms2e:e • •2 y):(u:ms2e:e • •2 z);
corresponding equations are assumed for the other output components.
of) a code execution is supposed to start. Code entry points will arise if code
has been produced via imperative programming using a program notation with
subroutine calls and subsequent compilation and/or assembly. In addition a state
machine function must produce information concerning which part of the multi-
part code is to be executed next. It is now assumed that ST denotes the collection
of states of a machine model. A multipart part code state machine function has
the following type:
(SP C × CEP × ST ) → ((ST ∪ {D, M }) × CP N × CEP )
Here CPN is the collection of code part numbers and CEP is the the collection
of code entry points. The CEP argument indicates where in the control code
execution is supposed to start. These two numbers at the output side indicate
the code part that must be executed in the next phase of the execution and the
entry point within that code part which will be used to start the computation
for the next phase. If the code part number is outside the range of parts of the
MPC under execution (in particular if it equals 0), the computation terminates,
and if the exit point is outside the range of exit points of a part termination will
also result.
Relating Machine Functions with State Machine Functions. The con-
nection with machine functions can be given if input files can be explicitly incor-
porated in the state (using a function ‘in’) and output functions can be extracted
(by means of ‘out’). State machine functions will be denoted with a single bul-
let. A CEP argument will be represented as superscript, a CPN argument may
be given as another superscript, (preceding the CPN superscript), and other
information may be given in subscripts. For single part code x one may write:
x:e • •y = out(state(x:e •1 in(y, s0 ))).
Here out produces a sequence of outputs different from M , unless the com-
putation diverges. This equation provides a definition that works under the as-
sumptions that the computation starts in state s0 and that at the end of the
single part computation the next part result equals 0: i.e. for some s and p ,
x:e •1 (in(y, s0 ))) = (s , 0, p ). Moreover it must be noticed that in the notation
used the separator in the code argument separates name parts for a single part
code rather than code parts of a multi-part code.
State Machine Functions for Multi-part Control Code. Assuming that
multi-part code execution starts by default with the first code part at its first
entry point the following pair of equations (start equation and progress equation)
defines the machine function for multi-part executable code (tagged with mpe).
Start equation:
x:mpe • •y = out(state(x:mpe •1,1 (in(y, s0 ))))
expressing that execution starts with the first code part at entry point 1, and
with the following progress equation:
partp (x:mpe) •q s = (p , q , s ) → x:mpe •p,q s = (s p = 0 (x:mpe •q ,p s ))
36 J.A. Bergstra
where the progress equation is valid under the assumption that the only returned
code part number outside the code part range of x:mpe equals 0.
Limited Buffering of Compiled Parts. A buffer with the most recent compi-
lations (i.e. files of the form c:i2e:e • •partp (x:i)) of code parts can be maintained
during the execution of the multi-part intermediate code. Ass this buffer has a
bounded size, some code fragments will probably have to be deleted during a
run12 and may subsequently need to be recompiled. The idea is that a compila-
tion is done only when absolutely needed, which justifies the phrase JIT.
11
The only aspect of execution management is taking care of JIT compiling an inter-
mediate code part when needed and starting its execution subsequently.
12
Code garbage collection.
Machine Function Based Control Code Algebras 37
9 Verifying Compilers
Recent work of Hoare (e.g. [4]) has triggered a renewed interest in the idea that
program verification may be included in the tasks of a compiler. The notion of
a verifying compiler has been advocated before by Floyd in 1967, [8], but it has
not yet been made practical, and according to Hoare it might well be consid-
ered a unifying objective which may enforce systematic cooperation from many
parts of the field. Getting verifying compilers used in practice at a large scale is
certainly a hard task and Hoare refers to this objective as a ‘grand challenge’ in
computing. Turning quantum computing into practice, resolving P versus NP,
proofchecking major parts of mathematics and the theory of computing in the
tradition of de Bruijn’s type theory, removing worms and viruses from the inter-
net, and (more pragmatically) the .NET strategy for using the same intermediate
program notation for all purposes may be viewed as other grand challenges. In
computational science the adequate simulation of protein unfolding stands out
as a grand challenge; in system engineering the realization of the computing grid
and the design of open source environments of industrial strength for all major
application areas, constitute grand challenges as well.
Program verification has been advocated by Dijkstra (e.g. in EWD 303) be-
cause testing and debugging cannot provide adequate certainty. Indeed, if human
certainty is to be obtained proofs may be unavoidable. For the design of com-
plex systems, however, the need for proofs is harder to establish. The biological
evolution of the human mind has produced a complex system, at least from
the perspective of current computer technology, through a design process using
natural selection (which seems to be a form of testing rather than a form of
verification) as its major methodology for the avoidance of design errors. This
might suggest a way around program verification as well: rather than verify-
ing program X, one may design a far more complex system C using X and
many variations of it which is then tested. A test of X may involve millions
of runs of X and its variations. Usability of C, as demonstrated using tests,
will provide confidence in components like X, as well as the possibility to use
these components in a complex setting. Whether confidence or certainty is what
people expect from computing systems is not an obvious issue, however. As a
consequence this particular grand challenge has a subjective aspect regarding
38 J.A. Bergstra
the value of its objective that the other examples mentioned above seem not to
have.
In this section the phenomenon of a verifying compiler will be discussed at
the level of (state) machine functions and control code algebra.
which can take this task out of the hands of human designers. The most obvious
strategy is automated proof search.
Having available a proof method and a proof checker, one may design an
automated proof generator as a code u:pg4s:e, such that u:pg4s:e••x:s, r produces
a proof p with p x:s sats r if such a proof exists with the computation diverging
otherwise (or preferably producing a negative answer, i.e. a code outside REQ).
Even if a proof checker exists in theory its realization as an executable code with
useful performance seems to be elusive. Therefore this strategy to avoid the need
for people to design proofs has been considered infeasible and a different strategy
is needed.
rely on the use of valid code it cannot accept the possibility that a code part
defeats the extraction of a requirement.
Now complimentary to JIT compilation there is JIT requirements integration,
a process that allows the computation to dynamically synthesize a requirement
from the requirements known to be satisfied by the various parts it uses. The
JIT compiler should combine requirements synthesis and verification. This is a
difficult task that by itself leads to different solution architectures.
10 Conclusion
Machine functions have been used to formalize several software processing mech-
anisms at a high level of abstraction, by means of the formation of code algebras.
This abstract formalization has been proposed in particular for compilation, as-
semblage, interpretation, and for managed and unmanaged, interpreted and just
in time compiled multi-part code execution, and for verifying compilers. While
the notion of a verifying compiler can be captured to some extent at the ab-
Machine Function Based Control Code Algebras 41
straction level of CCA, this seems not to be the case for the unavidable concept
of a verifying JIT compiler, however.
References
1. A.W.Appel. Axiomatic bootstrapping, a guide for compiler hackers. ACM TOPLAS,
16(6):1699–1719, 1994.
2. J.A. Bergstra and M.E. Loots. Program algebra for sequential code. Journal of
Logic and Algebraic Programming, 51(2):125–156, 2002.
3. J.A. Bergstra and S.F.M. van Vlijmen. Theoretische Software-Engineering. ZENO-
Institute, Leiden, Utrecht, The Netherlands, 1998. In Dutch.
4. C.A.Hoare. The verifying compiler, a grand challenge for computer research. JACM,
50(1):63–69, 2003.
5. H.Bratman. An alternate form of the UNCOL diagram. CACM, 4(3):142, 1961.
6. J.Earley and H.Sturgis. A formalism for translator interactions. CACM, 13(10):607–
617, 1970.
7. M.I.Halpern. Machine independence: Its technology and economics. CACM,
8(12):782–785, 1965.
8. R.W.Floyd. Assigning meanings to programs. Proc. Amer. Soc. Symp. Appl. Math.,
19:19–31, 1967.
9. A. Turing. On computable numbers, with an application to the entscheidungsprob-
lem. Proc. London Math. Soc. Ser 2, 42,43:230–265,544–564, 1936.
Exploiting Abstraction for Specification Reuse.
The Java/C Case Study
Abstract. From the models provided in [14] and [4] for the semantics of
Java and C programs we abstract the mathematical structure that un-
derlies the semantics of both languages. The resulting model reveals the
kernel of object-oriented programming language constructs and can be
used for teaching them without being bound to a particular language. It
also allows us to identify precisely some of the major differences between
Java and C.
1 Introduction
In this work the models developed in [14] and in [4] for a rigorous definition
of Java and C and their implementations on the Java Virtual Machine (JVM)
resp. in the Common Language Runtime (CLR) of .NET are analyzed to ex-
tract their underlying common mathematical structure. The result is a platform-
independent interpreter of high-level programming language constructs which
can be instantiated to concrete interpreters of specific languages like Java, C,
C++. It is structured into components for imperative, static, object-oriented,
exception handling, concurrency, pointer related, and other special language fea-
tures (like delegates in C) and thus can be used in teaching to introduce step
by step the basic concepts of modern programming languages and to explain the
differences in their major current implementations.
The task is supported by the fact that the models in [14, 4] have been defined
in terms of stepwise refined Abstract State Machines (ASMs), which
1
A related modular approach, to define the semantics of a language by a collection
of individual language construct descriptions, now named “incremental semantics”,
appears in [12, 6].
F.S. de Boer et al. (Eds.): FMCO 2003, LNCS 3188, pp. 42–76, 2004.
c Springer-Verlag Berlin Heidelberg 2004
Exploiting Abstraction for Specification Reuse 43
ExecL ≡
ExecLI
ExecLC
ExecLO
ExecLE
ExecLT
ExecLD
ExecLU
Delegates and unsafe code are peculiar features of C and not included at
all into Java, therefore we refer for the two corresponding submachines to [4].
Since the thread models of Java and C have been analyzed and compared ex-
tensively in [14, 1, 13], we skip here to reformulate the interpreter ExecLT . The
static semantics of most programming languages can be captured appropriately
by mainly declarative descriptions of the relevant syntactical and compile-time
checked language features, e.g., typing rules, control-flow analysis, name reso-
lution, etc.; as a consequence we concentrate our attention here on the more
involved language dynamics for whose description the run-time oriented ASM
framework turns out to be helpful. So we deal with the static language features
in the form of conditions on the attributed abstract syntax tree, resulting from
parsing and elaboration and taken as starting point of the language interpreter
ExecL.
44 E. Börger and R.F. Stärk
This paper does not start from scratch. We tailor the exposition for a reader
who has some basic knowledge of (object-oriented) programming. A detailed
definition of ASMs and their semantics, as originally published in [11], is skipped
here, because ASMs can be correctly understood as pseudo-code operating over
abstract (domains of) data. A textbook-style definition is available in Chapter 2
of the AsmBook [5].
Exp ::= Lit | Vexp | Uop Exp | Exp Bop Exp | Exp ‘?’ Exp ‘:’ Exp
| Sexp | SpecificExp(L)
Vexp ::= Loc
Sexp ::= Vexp ‘=’ Exp | Vexp Aop Exp | Vexp ‘++’ | Vexp ‘--’
Stm ::= ‘;’ | Sexp ‘;’ | Lab ‘:’ Stm | JumpStm
| ‘if’ ‘(’ Exp ‘)’ Stm ‘else’ Stm | ‘while’ ‘(’ Exp ‘)’ Stm
| SpecificStm(L) | Block
Block ::= ‘{’ {Bstm} ‘}’
Bstm ::= Type Loc ‘;’ | Stm
sions whose value is known at compile time, like ‘const’ Type Loc ‘=’ Cexp ‘;’
in CI .
Not to burden the exposition with repetitions of similar arguments, we do
not list here statements like do, for, switch, goto case, goto default, etc.,
which do appear in real-life languages and are treated analogously to the cases
we discuss here. When referring to the set of sequences of elements from a set
Item we write Items. We usually write lower case letters e to denote elements
of a set E , e.g., lit for elements of Lit. For expository purposes, in Fig. 1 we
also neglect that in C labeled statements are only allowed as block statements,
whereas in Java, every statement (also embedded statements) can have a label.
Different languages usually exhibit not only differences in syntax, but above
all different notions of types with their conversion and promotion rules (sub-
type or compatibility definition), different type constraints on the operand and
result values for the predefined operators, different syntactical constraints for
expressions and statements like scoping rules, definite assignment and reachabil-
ity rules, etc. As a consequence, the static analysis differs, e.g., to establish the
correctness of the definite assignment conditions or more generally of the type
safety of well-typed programs (for Java see the type safety proof in [14, Ch. 8],
for C see the proof of definite assignment correctness in [8]). Since this paper is
focused on modeling the dynamic semantics of a language, we omit here any gen-
eral discussion of standard static semantics issues and come back to them only
where needed to explain how the interpreter uses the attributed abstract syntax
tree of a well-typed program. E.g., we will use that each expression node exp
in the attributed syntax tree is annotated with its compile-time type type(exp),
that type casts are inserted in the syntax tree if necessary (reflecting implicit
type conversions at compile-time), etc.
ExecLI ≡
ExecLExpI
ExecLStmI
The first subrule defines one execution step in the evaluation of expressions;
the second subrule defines one step in the execution of statements.
If
t
first 6@I up
up @ if (exp) stm1 else stm2
@
t next- t next- t
exp stm1 stm2
Local Variable Values. The next question is what are the values computed
for expressions and how they are stored as current values of local variables,
namely upon executing an assignment statement or as side effect of an expres-
sion evaluation. The answer to the second question depends upon whether such
values are stored directly, as for example in Java, or indirectly via an addressing
mechanism, as for example in C. To capture both possibilities we introduce two
domains, namely of values and of addresses, and use the following two dynamic
functions
2
In [12] an abstract syntax notation is proposed which avoids Java or C like notation.
Exploiting Abstraction for Specification Reuse 47
which can be used to assign memory addresses to local variables and to store the
values there. To simplify the formulation of how to instantiate our interpreter
for Java or C and to prepare the way for later refinements, we use a macro
WriteMem(adr , t, val ) to denote writing a value of given type t to a given
address. For the sublanguage LI (as for Java) the macro is only an abbreviation
for mem(adr ) := val , which will be refined in the model for LO .
One possible instance of this scheme, namely for Java, is to identify Loc
and Adr so that locals becomes mem. It goes without saying and will not be
mentioned any more in the sequel that a similar simplification applies to all other
functions, predicates, and macros introduced below in connection with handling
the values stored at addresses.
Since the values we consider in LI are of simple types, in this model the
equation
Value = SimpleValue ∪ Adr
holds, which will be refined for LO to include references (and structs, which
appear in C). The fact that local variables have to be uniquely identified can
be modeled by stipulating Loc = Identifier × Pos. For the initialization of the
interpreter it is natural to require that an address has been assigned to each
local variable, but that the value stored there is still undefined.
locals(x ) ∈ Adr for every variable x
mem(i ) = Undef for every i ∈ Adr
Recording Intermediate Values. During the walk through the tree, also in-
termediate results of the elaboration of syntactical constructs appear, which have
to be recorded somewhere, namely values of evaluated (sub-) expressions, but
also possible results of the execution of statements. Statements may terminate
normally, but also abruptly due to jumps (in LI ) or returns from method calls
(in LC ) or to the occurrence of exceptions (in LE ). There are many ways to keep
track of such temporary items, e.g., using a stack (as do many virtual machines,
see for example the Java Virtual Machine operand stack opd in [14, pg. 140]),
or replacing directly the elaborated syntactical constructs by their intermedi-
ate result (as do SOS-based formalisms, see for example the restbody concept
in [14, pg. 38]), or via some dynamic functions defined on the static syntax tree.
We choose here to use a partial function to record the values computed for the
syntactic construct labeled by the node with each node.
values: Pos → Result
For LI , the range Result of this function contains a) Undef , to signal that
no value is defined yet, b) simple values, resulting from expression evaluation,
c) Norm, for normal termination of statement execution, and d) reasons for
abruption of statement execution. The set Abr of abruptions derives here from
the jump statements (see below) and will be refined in successive models to also
contain statement returns and exceptions.
Result = Value ∪ Abr ∪ {Undef , Norm}
48 E. Börger and R.F. Stärk
Yield(val , p) ≡
values(p) := val
pos := p
YieldIndirect(adr , p) ≡
if AddressPos(p) then Yield(adr , p)
else Yield(memValue(adr , type(p)), p)
We will use the macros in the two forms Yield(val ) ≡ Yield(val , pos) and
YieldUp(val ) ≡ Yield(val , up(pos)), similarly for YieldIndirect(adr ) and
YieldUpIndirect(adr ).
A context where an address and not a value is required characterizes the con-
text of first children of parent nodes labeled with an assignment or prefix/postfix
operator. It can thus be defined as follows:
3
An identification of this kind, which is common in mathematics, has clearly to be
resolved in an executable version of the model.
Exploiting Abstraction for Specification Reuse 49
(), resulting from the successful evaluation of the argument exp of the construct
uop exp (encoded by up(pos) and its child pos), just before uop is applied to val
to YieldUp(Apply(uop, val )).
Note that in an assignment operator op= the result of the operation has to
be converted back to the type of the variable expression, e.g., if c is a variable
of type char, then c += ’A’ is evaluated as c = (char)(c + ’A’), since the
operands of + are promoted to the type int in Java as well as in C.
defined for LI in such a way that in the refined model LE the concept of finally
blocks can easily be specified. In case of a new execution of the body of a while
statement, the previously computed intermediate results have to be cleared.5
Since we formulate the model for the human reader, we use the . . .-notation,
for example in the rules for abruption or for sequences of block statements.
This avoids having to fuss with an explicit formulation of the context, typically
determined by a walk through a list.
In JavaI the set JumpStm consists of the jump statements break lab; and
continue lab;, so that the set of abruptions is defined as Abr = Break (Lab) |
5
ClearValues is needed in the present rule formulation due to our decision to have
a static function label and a dynamic function to record the intermediate values
associated to nodes. In a more syntax-oriented SOS-style, as used for the Java model
in [14] where a function restbody combines the two functions label and values into
one, ClearValues results automatically from re-installing the body of the while
statement as new rest program.
52 E. Börger and R.F. Stärk
Continue(Lab). In CI the set JumpStm contains the jump statements break; |
continue; | goto lab;, so that Abr = Break | Continue | Goto(Lab). The
differences in the scoping rules for break; and continue; statements in the two
languages are reflected by differences in the corresponding interpreter rules.
JumpStm(Java) ≡ match context(pos)
break lab; → Yield(Break (lab))
continue lab; → Yield(Continue(lab))
ClearValuesSeq(α) ≡
ClearValues(α)
if next(α) = Undef then ClearValuesSeq(next(α))
7
Intuitively it should be clear that the execution of this recursive ASM provides
simultaneously – in one step – the set of all updates of all its recursive calls, as is
needed here for the clearing purpose; see [3] for a precise definition.
8
We disregard here the slight variations to be made for interfaces.
54 E. Börger and R.F. Stärk
and C. Normally classes are also put into a hierarchy, which is used to inherit
methods among classes to reduce the labor of rewriting similar code fragments.
As is to be expected, different languages come with different inheritance mech-
anisms related to their type concepts. Since the definition of the inheritance
mechanism belongs mainly to the static semantics of the language, we mention
it only where it directly influences the description of the dynamics.
We present the extension as a conservative (purely incremental) refinement
of the ASM ExecLI , which is helpful for proving properties of the extended
machine on the basis of properties of the basic machine. Conservative refinement
means that we perform the following three tasks (see [2] for a general description
of the ASM refinement method).
Extension of the ASM universes and functions, or introduction of new ones,
for example to reflect the grammar extensions for expressions and state-
ments. This goes together with the addition of the appropriate constraints
needed for the static analysis of the new items (like type constraints, definite
assignment rules, etc.).
Extension of some of the definitions or macros, here for example the predicate
PropagatesAbr (α), to make them work also for the newly occurring cases.
Addition of new ASM rules, in the present case to define the semantics of
the new expressions and statements.
9
See for example [8] for a detailed analysis of the extension of the definite assignment
rules needed when allowing besides by-value parameter passing (as does Java) also
call-by-reference (as does C).
Exploiting Abstraction for Specification Reuse 55
ExecLC ≡
ExecLExpC
ExecLStmC
Expression Evaluation Rules. The rules in ExecLExpC for class field evalu-
ation are analogous to those for the evaluation of local variables in ExecLExpI ,
except for using globals instead of locals and for the additional clause for class ini-
tialization. The rules for method calls use the macro InvokeStatic explained
below, which takes care of the class initialization. The submachine ArgEval
for the evaluation of sequences of arguments depends on the evaluation strat-
egy of L. The definition of the submachine ParamExp for the evaluation of
special parameter expressions depends on the parameter types provided by the
language L. If Arg = Exp as in Java, this machine is empty; for the case of C,
where Arg ::= Exp | ‘ref’ Vexp | ‘out’ Vexp, we show below its definition.
10
See [9] for other cases where the initialization is not triggered in C, in partic-
ular the refinement for classes which are marked with the implementation flag
beforefieldinit to indicate that the reference of the static method does not trigger
the class initialization.
Exploiting Abstraction for Specification Reuse 57
InvokeStatic(c::m, vals) ≡
if triggerInit(c) then Initialize(c) else InvokeMethod(c::m, vals)
where triggerInit(c) = ¬Initialized (c) ∧ ¬BeforeFieldInit(c)
InvokeMethod(c::m, vals) ≡
if extern ∈ modifiers(c::m) then InvokeExtern(c::m, vals)
else let p = if StaticCtor (c::m) then pos else up(pos) in
frames := push(frames, (meth, p, locals, values))
meth := c::m
pos := body(c::m)
values := ∅
InitLocals(c::m, vals)
The definition of the macro InitLocals for the initialization of local vari-
ables depends on the parameter passing mechanism. In Java the macro simply
defines locals (which assumes the role of mem in our general model) to take as
first arguments the actual values of the call parameters (the ValueParams for
call-by-value). In C one has to add a mechanism to pass reference parameters,
including so-called out parameters, which can be treated as ref parameters ex-
cept that they need not be definitely assigned until the function call returns.
In the following definition of InitLocals for C, all (also simultaneous) appli-
cations of the external function new during the computation of the ASM are
supposed to provide pairwise different fresh elements from the underlying do-
main Adr .11 paramIndex (c::m, x ) yields the index of the formal parameter x in
the signature of c::m.
InitLocals(c::m, vals)(C) ≡
forall x ∈ LocalVars(c::m) do // addresses for local variables
locals(x ) := new (Adr , type(x ))
forall x ∈ ValueParams(c::m) do // copy value arguments
let adr = new (Adr , type(x )) in
locals(x ) := adr
WriteMem(adr , type(x ), vals(paramIndex (c::m, x )))
forall x ∈ RefParams(c::m) ∪ OutParams(c::m) do
locals(x ) := vals(paramIndex (c::m, x )) // ref and out arguments
The difference between ref and out parameters at function calls and in
function bodies of C is reflected by including as AddressPositions all nodes
11
See [10] and [5, 2.4.4] for a justification of this assumption. See also the end of Sect. 4
where we provide an abstract specification of the needed memory allocation.
58 E. Börger and R.F. Stärk
whose parent node is labeled by ref or out and by adding corresponding definite
assignment constraints (listed in [4]):
Therefore the following rules of ParamExp for C can ignore ref and out:
ParamExp(C) ≡ match context(pos)
ref vexp → pos := vexp
ref adr → YieldUp(adr )
out vexp → pos := vexp
out adr → YieldUp(adr )
For the sake of illustration we provide here a definition for the submachine
ArgEval with left-to-right evaluation strategy for sequences of arguments. The
definition has to be modified in case one wants to specify another evaluation
order for expressions, involving the use of the ASM choose construct if some
non-deterministic choice has to be formulated. For a discussion of such model
variations we refer to [15] where an ASM model is developed which can be
instantiated to capture the different expression evaluation strategies in Ada95,
C, C++, Java, C and Fortran.
ArgEval ≡ match context(pos)
() → Yield([])
(arg, . . . ) → pos := arg
(val1 , . . . , valn ) → YieldUp([val1 , . . . , valn ])
( . . . val ,arg . . . ) → pos := arg
ReturnPropagation(L)
Norm; → YieldUp(Norm)
The return propagation machine for C is simpler than (in fact part of) that
for Java due to static differences (including the different use of labels) in the
two languages. As mentioned above, both machines, instead of transferring the
control from a return statement directly to the invoker, propagate the return
abruption up to the starting point of the current method body, from where the
method is exited.
ReturnPropagation(C) ≡ match context(pos)
Return → if pos = body(meth) ∧ ¬Empty(frames) then
ExitMethod(Norm)
Return(val ) → if pos = body(meth) ∧ ¬Empty(frames) then
ExitMethod(val )
ReturnPropagation(Java) ≡ match context(pos)
lab : Return → YieldUp(Return)
lab : Return(val ) → YieldUp(Return(val ))
ReturnPropagation(C)
To complete the return propagation in Java one still has to treat the special
case of a return from a class initialization method. In [14, Fig. 4.5] this has
been formulated as part of the StaticInitializer machine, which also realizes
the condition for the semantics of Java that before initializing a class, all its
superclasses have to be initialized. To stop the return propagation at the point of
return from a class initialization, in the case of Java the predicate PropagatesAbr
has to be refined as follows:
PropagatesAbr (α) ⇐⇒ label (α) ∈
/ {LabeledStm, StaticBlock }
In C the initialization of a class does not trigger the initialization of its direct
base class, so that StaticInitializer(C) is empty.
StaticInitializer(Java) ≡ match context(pos)
static stm → let c = classNm(meth) in
if c = Object ∨ Initialized (super (c)) then pos := stm
else Initialize(super (c))
static Return → YieldUp(Return)
The machine ExitMethod, which is the same for Java and for C (modulo
the submachine FreeLocals), restores the frame of the invoker and passes
the result value (if any). Upon normal return from a static constructor it also
updates the typeState of the relevant class as Initialized . We also add a rule
FreeLocals to free the memory used for local variables and value parameters,
using an abstract notion FreeMemory of how addresses of local variables and
value parameters are actually de-allocated.12
12
Under the assumption of a potentially infinite supply of addresses, which is often
made when describing the semantics of a programming language, one can dispense
with FreeLocals.
60 E. Börger and R.F. Stärk
ExitMethod(result) ≡
let (oldMeth, oldPos, oldLocals, oldValues) = top(frames) in
meth := oldMeth
pos := oldPos
locals := oldLocals
frames := pop(frames)
if StaticCtor (meth) ∧ result = Norm then
typeState(type(meth)) := Initialized
values := oldValues
else
values := oldValues ⊕ {oldPos → result}
FreeLocals
FreeLocals ≡
forall x ∈ LocalVars(meth) ∪ ValueParams(meth) do
FreeMemory(locals(x ), type(x ))
For both Java and C, a type c is considered as initialized if its static con-
structor has terminated normally, as is expressed by the update of typeState(c)
to Initialized in ExitMethod above. In addition, c is considered as initialized
already if its static constructor has been invoked, to guarantee that during the
execution of the static constructor accesses to the fields of c or invocations of
methods of c do not trigger a new initialization of c. This explains the update
of typeState(c) to InProgress in the definition of Initialize and the following
definition of Initialized :
Initialize(c) ≡
if typeState(c) = Linked then
typeState(c) := InProgress
forall f ∈ staticFields(c) do
let t = type(c::f ) in WriteMem(globals(c::f ), t, defaultValue(t))
InvokeMethod(c::.cctor, [])
With respect to the execution of initializers of static class fields the ECMA
standard [7, §17.4.5.1] for C says that the static field initializers of a class cor-
respond to a sequence of assignments that are executed in the textual order in
which they appear in the class declaration. If a static constructor exists in the
class, execution of the static field initializers occurs immediately prior to execut-
ing that static constructor. Otherwise, the static field initializers are executed at
Exploiting Abstraction for Specification Reuse 61
13
This is discussed in detail in [9]. The reader finds there also a detection of further
class initialization features that are missing in the ECMA specification, related to
the definition of when a static class constructor has to be executed and to the
initialization of structs.
62 E. Börger and R.F. Stärk
The specific expressions of JavaI and CI are extended by specific object-
oriented expressions of these languages as follows:
return type
void type
class type
enum type struct type
interface type
array type
simple type delegate type
null type
14
The result of a constructor invocation with new is the newly created object, which
is stored in the local environment as value for this. Therefore one can equivalently
refine the macro ExitMethod for constructors to pass the value of this upon
returning from a constructor, see [14, pg. 82].
Exploiting Abstraction for Specification Reuse 65
The this reference is treated as first parameter with index zero. It is passed
by value in instance methods of classes. It is passed by reference in struct meth-
ods, as an out paramter in constructors and as a ref paramter in instance
methods.
For the refinement of the ExecLC transition rules it suffices to add the new
machine ExecLExpO for evaluating the new expressions, since LO introduces
no new statements.
ExecLO ≡
ExecLExpO
In ExecLExpO the type cast rule contains three clauses concerning value
types, which are needed for C but are not present for Java. In fact for Java
the first RefType subrule suffices, the one where both the declared type and the
target type are compatible reference types and the reference is passed through.
FieldExpO contains the rules for field access and assignment as needed for C,
where for Java the additional access rule for value types is not needed (and the
macros for getting and setting field values are simplified correspondingly). NewO
differs for Java and C, reflecting the different scheduling for the initialization,
as specified below. The rules for instance method invocation are the same for
Java and C modulo different definitions for the macro Invoke and except that
for C an additional clause is needed for StructValueInvocations. A struct value
invocation is a method invocation on a struct value which is not stored in a
variable. For such struct values a temporary storage area (called ‘home’) has to
be created which is passed in the invocation as value of this. The submachine
SpecificExpO is specified below for Java and C.
if StructValueInvocation(up(pos)) then
let adr = new (Adr , type(pos)) in // create home for struct value
WriteMem(adr , type(pos), val )
values(pos) := adr
val .T ::M (vals) → Invoke(val , T ::M , vals)
SpecificExpO
The rules for instance field access and assignment in FieldExpO are equiva-
lent for Java and C modulo two differences. The first difference comes through
the different definitions for the macro SetField explained below. The second
difference consists of the fact that C needs the struct type clause formulated
below (in the second rule for field access), which is not needed for Java.15 We
use type(exp.t::f ) = type(t::f ).
The different schedules for the initialization of classes in Java and C appear
in the different definitions for their submachines NewO and Invoke. When
creating a new class instance, Java checks whether the class is initialized. If
not, it initializes the class. Otherwise it does what also the machine NewO (C)
does, namely it creates a new class instance on the heap, initializing all in-
stance fields with their default values. See below for the detailed definition of
HeapInit.
15
As in most parts of this paper, we disregard merely notational differences between
the two models, here the fact that due to the presence of both memory addresses
and values, the CO model uses the machine YieldUpIndirect(fieldAdr (val , t::f ))
where the JavaO model has the simpler update YieldUp(getField (val , t::f )).
Exploiting Abstraction for Specification Reuse 67
The Invoke rule for Java is paraphrased from [14, Fig. 5.2]. The compile-
time computable static function lookup yields the class where the given method
specification is defined in the class hierarchy, depending on the run-time type of
the given reference.
memValue(adr , t) =
if t ∈ SimpleType ∪ RefType then mem(adr )
elseif t ∈ StructType then
{f → getField (adr , t::f ) | f ∈ instanceFields(t)}
getField (adr , t::f ) = memValue(fieldAdr (adr , t::f ), type(t::f ))
WriteMem(adr , t, val ) ≡
if t ∈ SimpleType ∪ RefType then mem(adr ) := val
elseif t ∈ StructType then
forall f ∈ instanceFields(t) do SetField(adr , t::f , val (f ))
The notion of AddressPos from CC is refined to include also lvalue nodes of
StructType, so that address positions are of the following form:
ref 2, out 2, 2++, 2--, 2 op= exp, 2.f , 2.m(args)
AddressPos(α) ⇐⇒ FirstChild(α) ∧
label (up(α)) ∈ {ref, out, ++, --} ∪ Aop ∨
(label (up(α)) = ’.’ ∧ α ∈ Vexp ∧ type(α) ∈ StructType)
YieldUpBox creates a box for a given value of a given type and returns its
reference. The run-time type of a reference to a boxed value of struct type t is
defined to be t. The struct is copied in both cases, when it is boxed and when
it is un-boxed.
YieldUpBox(t, val ) ≡ let ref = new (Ref ) and adr = new (Adr , t) in
runTimeType(ref ) := t
valueAdr (ref ) := adr
WriteMem(adr , t, val )
YieldUp(ref )
5 Extension LE of LO by Exceptions
LE extends LO with exceptions, designed to provide support for recovering from
abnormal situations, separating normal program code from exception handling
code. When an L-program violates certain semantic constraints at run-time, the
interpreter signals this as an exception. The control is transferred, from the point
where the exception occurred, to a point that can be specified by the program-
mer. An exception is said to be thrown from the point where it occurred, and it
is said to be caught at the point to which control is transferred. The model for LE
70 E. Börger and R.F. Stärk
makes explicit how jump statements from LI , return statements from LC and the
initialization of classes from LO interact with catching and handling exceptions.
Technically, exceptions are represented as objects of predefined system excep-
tion classes (in Java java.lang.Throwable and in C System.Exception) or of
user-defined application exception classes. Once ‘thrown’, these objects trigger
an abruption of the normal program execution to ‘catch’ the exception – in case
it is compatible with one of the exception classes appearing in the program in an
enclosing try-catch-finally statement. Optional finally statements are guaranteed
to be executed independently of whether the try statement completes normally
or is abrupted. We consider run-time exceptions, which correspond to invalid
operations violating the semantic constraints of the language (like an attempt
to divide by zero or to index an array outside its bounds) and user-defined ex-
ceptions. We do not treat errors which are failures detected by the underlying
virtual machine machine (JVM or CLR).
To simplify the exposition we assume that general catch clauses ‘catch block ’
are replaced at compile-time by ‘catch (Object x ) block ’ with a new variable x
and that try-catch-finally statements have been reduced to try-catch and try-
finally statements, e.g., as follows:
try {
try TryBlock
try TryBlock
catch (E1 x1 ) CatchBlock1
.. catch (E1 x1 ) CatchBlock1
. =⇒ ..
.
catch (En xn ) CatchBlockn
catch (En xn ) CatchBlockn
finally FinallyBlock
} finally FinallyBlock
Since throwing an exception completes the computation of an expression or
a statement abruptly, we introduce into the model a new type of reasons of
abruptions and type states, namely references Exc(Ref ) to an exception object.
Due to the presence of throw statements without expression in C, also a stack
of references is needed to record exceptions which are to be re-thrown.
Abr = . . . | Exc(Ref ), TypeState = . . . | Exc(Ref ), excStack : List(Ref )
enclosing phrase using FailUp, which allocates a new object for the exception
and throws the exception. If the exception value ref of a throw statement is
not null , the abruption Exc(ref ) is passed up to the (position of the) throw
statement, thereby abrupting the control flow with the computed exception as
reason. The semantics of the parameterless throw; statement is explained as
throwing the top element of the exception stack excStack .
Upon normal completion of a try statement, the machine passes the con-
trol to the parent statement, whereas upon abrupted completion the machine
attempts to catch the exception by one of the catch clauses. The catching con-
dition is the compatibility of the class of the exception with one of the catcher
classes. If the catching fails, the exception is passed to the parent statement, as is
every other abruption which was propagated up from within the try statement.
Otherwise the control is passed to the execution of the relevant catch statement,
recording the current exception object in the corresponding local variable and
pushing it on the exception stack (thus recording the last exception in case it
has to be re-thrown). Upon completion of this catch statement, the machine
passes the control up and pops the current exception object from the exception
stack—the result of this statement execution may be normal or abrupted, in the
latter case the new exception is passed up to the parent statement. No special
rules are needed for general catch clauses ‘catch block ’ in try-catch statements,
due to their compile-time transformation mentioned above.
For a finally statement, upon normal or abrupted completion of the first
direct substatement, the control is passed to the execution of the second di-
rect substatement, the finally statement proper. Upon normal completion of
this statement, the control is passed up, together with the possible reason of
abruption, the one which was present when the execution of finally statement
proper was started, and which in this case has to be resumed after execution of
the finally statement proper. However, should the execution of this finally
statement proper abrupt, then this new abruption is passed to the parent state-
ment and a possible abruption of the try block is discarded. The constraints
listed above for C restrict the possibilities for exiting a finally block to normal
completion or triggering an exception, whereas in Java also other abruptions
may occur here.
In Java there is an additional rule for passing exceptions when they have
been propagated to the position directly following a label, namely:
lab : Exc(ref ) → YieldUp(Exc(ref ))
If the attempt to catch a thrown exception in the current method fails, the
exception is propagated to the caller using the submachine explained below.
6 Conclusion
We have defined hierarchically structured components of an interpreter for a
general object-oriented programming language. In doing this we have identified
a certain number of static and dynamic parameters and have shown that they
can be instantiated to obtain an interpreter for Java or C. As a by-product this
pinpoints in a precise and explicit way the main differences the two languages
have in their dynamic semantics. The work confirms the idea that one can use
ASMs to define in an accurate way appropriate abstractions to support the
development of precise patterns for fundamental computational concepts in the
fields of hardware and software, reusable for design-for-change and useful for
communicating and teaching design skills.
References
1. V. Awhad and C. Wallace. A unified formal specification and analysis of the new
Java memory models. In E. Börger, A. Gargantini, and E. Riccobene, editors,
Abstract State Machines 2003–Advances in Theory and Applications, volume 2589
of Lecture Notes in Computer Science, pages 166–185. Springer-Verlag, 2003.
76 E. Börger and R.F. Stärk
1 Introduction
Automatic collision avoidance systems form an integral part of ETCS-compatible
train systems, are appearing or about to appear in cars, and – in the somewhat
weaker form of only providing recommendations to the pilot – required to be
installed on any aircraft with more than 30 passengers. The verification of the
correctness of such collision avoidance system has been studied extensively e.g.
within the PATH project (see [12]), by Leveson et al. [10], Sastry et al. [17] and
Lynch et al. [11] for various versions of the TCAS system, or by Peleska et al.
[6] and Damm et al. [4] for train system applications. Shankar et al presents in
[12] a general approach of developing such distributed hybrid systems.
Our paper aims at reducing the complexity of the verification of collision
avoidance systems. To this end, we explicate typical design approaches for such
protocols, and cast this into a proof rule reducing the global safety requirement
“a collision will never occur” to simpler proof tasks, which can either be es-
tablished off line, involve purely local safety- or real-time properties, or pure
protocol verification. We illustrate our approach by showing how the correctness
This work was partly supported by the German Research Council (DFG) as part
of the Transregional Collaborative Research Center “Automatic Verification and
Analysis of Complex Systems” (SFB/TR 14 AVACS). See www.avacs.org for more
information.
F.S. de Boer et al. (Eds.): FMCO 2003, LNCS 3188, pp. 77–110, 2004.
c Springer-Verlag Berlin Heidelberg 2004
78 W. Damm, H. Hungar, and E.-R. Olderog
of TCAS and a protocol for wireless safe railroad crossings can be established
by instantiating the proposed verification rule. While the methodology as such
is applicable to any bounded number of agents, we will illustrate our approach
considering only collision avoidance for two agents.
The approach centers around the following key design concepts.
Each traffic agent is equipped with a safety envelope, which is never to be
entered by another agent. The safety envelope of an agent is an open ball around
the agent’s current three-dimensional position, with an agent-specific diameter.
We allow the extent of the diameter to be mode dependent, thus e.g. enforcing
different degrees of safety margins during different flight phases, or allowing a
train to actually cross a railroad crossing if this is in mode “secured”. The global
safety property we want to prove is, that safety envelopes of agents are always
kept apart.
To enforce separation of safety envelopes, the controllers’ coordinating colli-
sion avoidance offers a choice of corrective actions, or maneuvers. E.g. TCAS dis-
tinguishes “steep descent”, “descent”, “maintain level”, “climb”, “steep climb”,
thus restricting the maneuvers to adjustment of the height of the involved air-
crafts (with future versions expected to also offer lateral avoidance maneuvers).
In the train-system application, the maneuvers of the crossing are simple (flash
light and lower barriers), and the train will be brought to a complete stop, trying
first the service brake, and resorting to an emergency brake as backup option.
From the point of view of our methodology, we will assume a set of explicitly
designated states for such collision avoidance maneuvers, henceforth called cor-
rective modes. It is the task of the collision-avoidance protocol to select matching
pairs of corrective modes: the joint effect of the strategies invoked by the chosen
states ensures, that the agents will pass each other without intruding safety en-
velopes – a condition, which we refer to as adequacy. E.g. TCAS will never ask
both aircrafts to climb – the decision of which aircraft should climb, and which
descend, is taken based on the relative position and the identity of the aircraft
(to break symmetry, identities are assumed to be totally ordered).
A key design aspect of collision avoidance protocols is the proper determina-
tion of invocation times for corrective maneuvers. Due to the safety criticality of
the application, such triggering points must be determined taking into account
the most adversary behavior of traffic agents, within the overall limits stipulated
by traffic regulation authorities. As an example, triggering a mode switch to en-
force safe braking of the train must be done in time to allow the train to come
to a complete stop even when driving the maximal allowed speed for the cur-
rent track segment, as well as the maximally allowed slope for track segments.
This in fact simplifies the analysis, because it both requires as well as allows
to perform the analysis using an over-approximation of the agents’ behavior.
Conformance to such upper bounds on velocity must be established separately
– note, that this is a verification task local to the agent. We can then use off-line
analysis based on the over-approximated behavior of the plant and knowledge
of the corrective maneuvers to determine the need for a mode switch to one of
the corrective modes.
On the Verification of Cooperating Traffic Agents 79
have been resolved.1 Typical usages of invariances for continuous variables will
be the enforcement of regulatory stipulations such as regarding maximal allowed
speed, or tolerated degrees of acceleration resp. deceleration.
As to the model of the traffic agent’s plant, we assume, that the set of plant
variables subsumes the traffic agents space coordinates x , y, z , its velocity in each
dimension vx , vy , vz , as well as its acceleration ax , ay , az in each dimension, a set
of actuator variables A, as well as a set of disturbances D. A subset S of the sys-
tem variables, the sensor variables, are observable by the plant’s controller, which
in turn can influence the plant by the setting of actuators. We assume that space
coordinates, velocity, and acceleration are directly observable by the controller.
For the current version, we consider simple plant models without discrete state
components.2 The dynamics of the system is specified by giving for each non-
input system variable an ordinary differential equation, whose right hand side
may contain all variables of the plant. This includes the standard dependencies
between acceleration, velocity, and space coordinates. Plant invariances allow to
place bounds on disturbances. In particular, we will assume for each disturbance
upper and lower bounds under which the agent is expected to operate.
A traffic-agent model combines an agent controller with its plant model, us-
ing standard parallel composition of hybrid automata. Communication between
these automata is based solely on the actuator and sensor variables shared be-
tween these. We thus abstract in this paper from noise in sensor readings and
inaccuracy of actuators when observing resp. controlling its own plant. Note,
that the parallel composition used is just a standard parallel composition of au-
tomata, hence we can view a traffic agent model again as a hybrid automaton.
A distributed traffic system consists of the parallel composition of N traf-
fic agents. We abstract in this paper from modeling communication channels,
and assume, that all communication between traffic agents is based on variables
shared between their controllers, of mode “output” on the one side and of mode
“input” on the other. As noted before, mode-switches can be initiated by com-
munication events, which in this setting is expressed by allowing as trigger to
test for a condition involving communication variables to become true. We make
the simplifying assumption, that the variables shared between traffic-agent con-
trollers include the sensor variables for its coordinates and its speed, as well
as the identity of the controllers. It is straightforward to extend our approach
to message-passing based information and accordingly delayed knowledge about
the other agent’s whereabouts, by interpolating from the last known readings,
using worst-case bounds dictated by regulations to safely over-approximate the
actual readings.
1
The TCAS protocol actually allows to withdraw a given recommendation in re-
stricted situations, complicating the analysis, see [11]. The above assumption indeed
eases the off-line analysis required in our approach, but is not inherent. We leave it
to a later paper to consider more flexible strategies.
2
In the formal development, we view a plant as a hybrid automaton with a single
state and no discrete transitions.
On the Verification of Cooperating Traffic Agents 81
Separation implies that at any given point in time during a run, at most one
discrete transition fires. I.e., our models have dense time, not superdense time,
where a sequence of discrete transitions is permitted to fire at one instant in time.
Discrete variables may be included into hybrid automata according to our
definition via an embedding of their value domain into the reals, and associating
a derivation of constantly zero to them (locals and outputs). Timeouts are easily
coded via explicit local timer variables with a derivative in {−1, 0, 1}, as required
respectively.
Note, that indeed this general model subsumes both controller and plant mod-
els, by choosing the set of variables appropriately and enforcing certain modeling
restrictions. For our plant models, we require the absence of discrete transitions.
This entails in particular, that plant variables only evolve continuously, and can-
not be changed by discrete jumps. This is convenient for the formulation of our
approach but not essential.
We will in the definition of runs of a hybrid automaton interpret all transi-
tions as urgent, i.e. a mode will be left as soon as the triggering event occurs.
This can either be the expiration of a time-out, or a condition on e.g. the plant
sensors becoming true. Valid runs also avoid Zeno behavior and time-blocks, i.e.
each run provides a valuation for each positive point in time. We did not take
provisions to ensure the existence of such a run, nor the property that each ini-
tial behavior segment can be extended to a full run. Such might be added via
adequate modeling guidelines (e.g. by including the negation of an invariant as
trigger condition on some transition leaving the mode). As these properties are
not essential to the purpose of this paper we left them out.
We now give the formal definition of runs of a hybrid automaton HA. To this
end we consider continuous time and let Time = R≥0 . Further on, we use the
notation
previous(v̂ , t) = limu→t (v̂ (u))
for some v̂ : Time → R and 0 < t ∈ Time. Satisfaction of a condition containing
previous entails that the respective limes does exist.3
Definition 3 (Runs of a Hybrid Automaton). A tuple of trajectories
π = (m̂, (v̂ )v ∈V ) , with
m̂ : Time → M
v̂ : Time → R, v ∈ V
capturing the evolution of modes and valuations of continuous variables is called
a run of HA iff
∃ (τi )i∈ω ∈ Time ω : τ0 = 0 ∧ ∀ i : τi < τi+1 ,
a strictly increasing sequence of discrete switching times s.t.
3
In fact, our definition of a run implies that these limits do exist for all local and
output variables in any run.
On the Verification of Cooperating Traffic Agents 83
1. non-Zeno
∀ t ∈ Time ∃ i : t ≤ τi
3. continuous evolution
∀ i ∀ t ∈ [τi , τi+1 ) ∀ v ∈ V :
d v̂ (t)
= R c (m̂(τi ))[ŵ (t)/w | w ∈ V ]
dt
4. invariants
5. urgency
The time sequence (τi )i∈ω identifies the points in time, at which mode-
switches may occur, which is expressed in Clause (2). Only at those points dis-
crete transitions (having a noticeable effect on the state) may be taken. On the
other hand, it is not required that any transition fires at some point τi , which
permits to cover behaviors with a finite number of discrete switches within the
framework above. Our simple plant models with only one mode provide exam-
ples. As usual, we exclude non-zeno behavior (in Clause (1)). As a consequence
of the requirement of transition separation, after each discrete transition some
time must elapse before the next one can fire. Clause (4) requires, for each mode,
the valuation of continuous variables to meet the local invariant while staying
in this mode. Clause (3) forces all local and output variables (whose dynamics
84 W. Damm, H. Hungar, and E.-R. Olderog
(A) Off-line analysis of the dynamics of the plant assuming worst-cases dynamics
(B) Mode invariants for C1 C2
(C) Real-time properties for Cj
(D) Local safety properties, i.e. hybrid verification tasks for Cj Pj
Type (A) verification tasks capture, how we can capitalize on rigorous design
principles for safety-critical systems, where a high degree of robustness must
be guaranteed in cooperation procedures for collision avoidance. This entails,
that potentials for collision must be analysed assuming only a minimum of well-
behavedness about the other agent’s behavior, as expressed in invariance proper-
ties guaranteed by the controller (these will lead to proof obligations of type (D).
As a concrete example, when analyzing a two-aircraft system, given their cur-
rent position and speed, we will bound changes in speed, height and direction
when analyzing their worst case behavior in detecting potentials for collision.
These invariances reflect typical requirements for flight phases – the aircraft
must stay within safety margins of its current flight corridor, and maintain a
separation with aircrafts traveling in the same flight corridor ahead and behind
the considered aircraft. Type (A) verification tasks are simple, because they do
not involve reasoning about hybrid systems. They consider the evolvement of all
possible trajectories from a subregion of P1 P2 and asks about reachability of
forbidden plant regions. In this analysis trajectories are evolving according to
the differential equations of P1 P2 ,4 with input changes restricted by constants
(such as maximal allowed setting of actuators) or invariances guaranteed by the
controller (such as “velocity is within the interval [vmin , vmax ]”), or invariances
bounding disturbances specified as operating conditions (such as “the maximal
slope for a track for high-speed trains is 5 0 /00 ”), which must be stated as plant
invariances in order to enter the analysis.
Type (B) verification tasks ensure, that both agents take decisions which co-
operate in avoiding potential collision situations. To this end, we assume that
each controller has a designated set of modes called correcting modes, which
define the agents capabilities for performing collision avoidance maneuvers. Ex-
amples of maneuvers are the resolution advisories issued by TCAS, such as
“climb”, “descend”, . . . .. Clearly, the combined system of two aircrafts will only
avoid collisions, it the advisories of the two controllers match. E.g. in most sit-
uations, asking both aircrafts to climb, might actually increase the likelihood of
a collision. It is the task of the designer of the cooperation protocol, to desig-
nate matching pairs of modes, and to characterize the plant states of P1 P2
under which invoking a matching pair of maneuvers is guaranteed to resolve a
4
Recall that plant-models are assumed to only have a single discrete state. Note that
we can still model so-called switched dynamical systems, where the dynamics of the
system depends on the setting of switch variables, typically occurring as input to
the plant-model. Worst-case analysis is then performed for all valuations of switch
variables conforming to invariant properties. Here it will sufficient to work with
over-approximations (such as the flow pipe approximation technique developed in
[5]).
On the Verification of Cooperating Traffic Agents 87
(1)
FAR
NEGOTIATING
(3)
(2)
SAFE RECOVERY
(6)
Fig. 1 distinguishes the following phases of such protocols. Phase FAR sub-
sumes all controller modes, which are not pertinent to collision avoidance. The
protocol may only be in phase FAR if it is known to the controller, that the
two agents are “far apart” – the agents’ capabilities for executing maneuvers are
such, that maintaining collision freedom can be guaranteed by not yet invoking
correcting actions. Determining conditions for entering and leaving phase FAR is
thus safety critical. The NEGOTIATION phase is initiated, as soon as the two
agent system might evolve into a potentially hazardous situation. The derivation
of the predicate ϕN guarding transition (1) is non-trivial and discussed below.
Within the negotiation phase, the two agents determine the set of maneuvers
to be performed. The CORRECTING phase is entered via transition (2), when
matching correcting modes have been identified and no abnormal conditions –
discussed below – have occurred. During the correcting phase, control laws asso-
On the Verification of Cooperating Traffic Agents 89
ciated with the correcting modes will cause the distance between traffic agents
to increase, eventually allowing to (re-)enter the FAR-phase via transition (3).
The cycle of transitions numbered (1) to (3) described above characterizes
successful collision avoidance maneuvers. Other phases and transitions shown
in Fig. 1 increase the robustness of the protocol, by providing recovery actions
in case of protocol failures in the negotiation phase (e.g. because of disturbed
communication channels). A key concept here is that of fail-safe states: we say
that a traffic agent offers a fail-safe state, if there is a stable state of Cj Pj ,
i.e. a valuation of the plant variables and actuators, such that their derivative is
zero, and in particular the traffic agent maintains its current position, such as
e.g. for train-system applications. For such traffic agents, any failure encountered
during the negotiation or correcting phase will lead to the activation of recovery
modes, whose control law will be guaranteed to drive the agent into a fail-safe
state, as long as it is entered within a predicate characterizing its application
condition. For simplicity, we assume only a single designated recovery mode for
such traffic agents. Correcting collision avoidance even in case of failures can
only be guaranteed, if both agents offer fail-safe states, and the recovery modes
driving the system to a fail-safe state are entered while the plant is (still) in a
state meeting the application condition for both recovery modes. Transitions (4)
and (5) are guarded by conditions catering for
– an inconsistent selection of correcting modes,
– a timely invocation of recovery actions so as to allow the system to reach
the fail-safe state.
As mentioned above, we assume the existence of an upper bound on the time
to conclude the negotiation phase, and exploit this in analyzing, that correcting
maneuvers are initiated in time for the maneuver to be performed successfully.
To guarantee success of recovery actions, we similarly exploit the fact, that
either the negotiation phase is concluded within the above bound, or a failure
is detected and recovery mechanisms are initiated. Transition (5) provides an
additional safeguard, in that the transition to the recovery mode will be taken
as soon as its application condition applies. The activation of such recovery
mechanisms should only be performed, if in addition the duration allowed for
a successful conclusion of the negotiation phase has expired. Once the recovery
mode is entered, the system will then eventually be driven to a fail-safe state via
transition (6), causing it to remain in phase SAFE.
For systems not offering fail-safe states, no formal analysis can be performed
as to the effects of initiating a recovery strategy. Recovery modes for such sys-
tems reflect the “never-give-up” design strategy for safety-critical systems, where
“best guesses” as to the possible state of the other agent are made in the deter-
mination of control-laws associated with such recovery modes.
The phase-transition diagram defines a set of type (C) verification tasks ap-
pearing as premises of our proof rule for establishing collision freedom. To in-
stantiate the proof rule for a concrete conflict-resolution protocol, the phases
discussed above must be defined as (derived) observables of the concrete pro-
tocol. Often, phases can be characterized by being in a set of modes of the
90 W. Damm, H. Hungar, and E.-R. Olderog
5
We assume in this paper that the successor phase is uniquely determined by the
trigger condition. Time-bounds on taking the transition when the trigger is enabled
are discussed below.
On the Verification of Cooperating Traffic Agents 91
The first verification condition requires a proof, that indeed matching maneu-
vers avoid collision. It states that all trajectories obeying the set of differential
equations governing the maneuvers and the plants will be free of collisions, as
long as they are initiated in a state satisfying the application conditions of match-
ing modes. The runs to be considered are assumed to meet the plant invariants
on boundary conditions for the plants’ variables. Moreover, any local invariances
associated with the correcting modes may be assumed during off-line analysis –
separate verification conditions cater for these.
A key point to note is, that the above verification condition does not involve
state-based reasoning. By abuse of notation, we have replaced hybrid automata
by differential equations in the parallel composition above. To establish the ver-
ification condition, we must analyze the possible evolution of trajectories of the
plant variables in subspaces characterized by the application condition. We can
do so by over-approximation, using boundary conditions on plant variables (such
as maximal speed, maximal acceleration, maximal disturbance) and actuators
(as determined by the control laws associated with the correcting modes), and
invariance conditions associated with correcting modes. See the next section for
a concrete example, demonstrating in particular the ease in establishing such
verification conditions. For more involved maneuvers, we can resort to classical
methods from control-theory such as using Lyapunov functions (c.f. [9]) for es-
tablishing collision freedom, since no state-based behaviour must be analyzed. A
follow-up paper will solve the constraint system induced by (VC 2) generically,
establishing constraints on the involved design parameters under which (VC 2)
is guaranteed to hold.
A similar verification condition must be established for recovery modes driv-
ing the system to fail-safe states. It requires each traffic agent to reach a fail-safe
state without colliding with the other agent, as long as the recovery maneuver
is initiated in a plant state meeting its applicability condition.
So far we have only discussed the adequacy of the maneuvers for avoiding
collision avoidance. This must be complemented by a proof of completeness of
the proposed methods. More specifically, for any trajectory of the unconstrained
92 W. Damm, H. Hungar, and E.-R. Olderog
C1 C2 |= 2(NEGOTIATING(C1 ) ∨ NEGOTIATING(C2 )
⇒ 3≤ΔN (¬NEGOTIATING(C1 ) ∧ ¬NEGOTIATING(C2 )))
For traffic systems allowing recovery to fail-safe states, we would like to ensure
additionally, that the negotiation is initiated in system states allowing to invoke
recovery actions if negotiation fails.
(VC 8) Recovery actions will be possible
Jointly, (VC 5), (VC 6) and (VC 7) guarantee, that the activation conditions
of maneuvers remain true during negotiation, hence are still valid when actually
invoking the maneuvers, and (VC 7) in conjunction with (VC 6) and (VC 8)
guarantees, that the activation condition for recovery to fail-safe states is met,
if the negotiation phase fails.
That the negotiation results in matching modes being selected is stated in
the following condition.
(VC 9) Only matching modes with satisfied activation condition are selected
We must finally ensure, that a selected maneuver is not abandoned until the
hazardous situation has been resolved, i.e., until phase FAR can be reentered.
Hence, while in mode CORRECTING, the maneuver may not be changed.
(VC 10) Correcting modes are not changed
C1 C2 |= ∀ (m1 , m2 ) ∈ MATCH :
2( CORRECTING(Ci ) ∧ Mode(Ci ) = mi
i=1,2
|= ΦF ⇒ ¬Φ(m1 ,m2 )
(m1 ,m2 )∈MATCH
Aircraft 1 Aircraft 2
TCAS 1 TCAS 2
Sensor 1 Sensor 2
Pilot 1 Pilot 2
Conflict Conflict
Detection 1 Detection 2
Communication
Channel 1
Conflict Conflict
Resolution 1 Resolution 2
Communication
Channel 2
Advisories Advisories
of the combined automata to check for the absence of collisions. The real system
would then have to shown to be a refinement of the respective components (or
have to be assumed to act as it were a refinement – the model includes compo-
nents for pilots, which would hardly be provable refinements of an automaton).
Though the automaton format differs (hybrid I/O automata with superdense
time are used), this is very much in line with our approach.
Several assumptions are stated under which the analysis is performed. Some
of them serve to reduce the computational complexity of trajectory analysis,
which may limit the practical relevance but is conceptually reasonable. Some
are even indispensable, as the one restricting pilot behavior to not oppose traffic
advisories. Others limit the relevance of the derived safety result if compared to
our stated goal. Our discussion will center around these latter issues.
Disregarding simplifying assumptions, the safety theorem of [11] can be stated
as follows:
This can be rephrased as saying that the proof establishes that the interplay
between discrete and continuous components will ensure that TCAS’ operational
goals are met. An “operational” goal is formulated via the system’s own defini-
tions:
96 W. Damm, H. Hungar, and E.-R. Olderog
This theorem tells a lot about the effects of TCAS – the vertical separation
will be achieved as required in the system specification. However, it does not
imply that two aircraft guided by TCAS will not collide. The latter is an exten-
sional property, the former is intensional and presupposes that the operational
specification is consistent (which is, considering the rather successful history of
guaranteeing safety in air traffic, not unreasonable). But our verification goal
would be more ambitious. So let us have a look at the verification conditions of
our rule which have been established in [11], and those which would have to be
added.
6
http://tfs.cs.tu-berlin.de/projekte/indspec/SPP/index.html
98 W. Damm, H. Hungar, and E.-R. Olderog
yields for each position of the train the start position of the next crossing ahead
such that ∀ p ∈ Position : p < next(p) holds. Further on,
inCr : Position → B
afterCr : Position → B
describes for a given speed all positions and that are in such a section. The
positions satisfying these predicates are illustrated in Fig. 3. The predicate
describes for a given speed v all positions that are far away from the next cross-
ing, i.e. the complement of all positions satisfying nearCr (v ) or inCr or afterCr .
Note that we expect the following implications to hold:
We assume that subsequent crossings on the track are far apart so that even
for the maximal speed vmax of the train there is a nonempty section farCr(vmax )
between each section afterCr and the section inCr of the next crossing. We model
the gate by its angle α ranging from 0 to 90 degrees.
The railroad crossing will now be modelled by four components: a train plant
and controller interacting with a gate plant and controller. Fig. 4 shows how
these plants are represented by continuous variables pos(ition), speed and α,
and which variables the four components share for communication with each
other. For simplicity we shall ignore the communication times in the subsequent
analysis.
On the Verification of Cooperating Traffic Agents 99
Fail
pos
α
speed
pos speed Cl Op
sc Dir
OK
Train Plant
We assume that the train has knowledge of its position on the track and controls
its speed depending on requests from the train controller. It will react to speed
control commands from the train controller. Thus we consider the variables
below. We do not distinguish between the (syntactic) variables of the automaton
and the corresponding trajectories in runs. So we take for the type of a variable
the type of its time-dependent trajectory, and we permit variables with discrete
ranges without explicitly coding them in reals.
Variables:
Dynamics. Let −areg be the deceleration of the train when braking (in regu-
lar operational mode, not in emergency mode which is not modeled). Thus we
assume that the following invariants hold:
pos • = speed
−areg ≤ speed •
speed ≤ vmax
100 W. Damm, H. Hungar, and E.-R. Olderog
With these characteristics we can calculate for which speeds v and positions
p the predicate nearCr (v )(p) should hold taking the maximal closing time εmax
of the gate into account:
Here v 2 /2 · areg is the maximal distance it takes for the train with an initial
speed of v to stop, and εmax ·v is the maximal distance the train can travel while
the gate is closing. Remember that we do not take the time for communication
into account here. We assume that initially the train is far away from the next
crossing, i.e. the predicate farCr (speed )(pos) holds for a while. This, and the
definition of nearCr (v )(p) is needed for establishing (VC 4).
Train Controller
The train controller monitors the position and speed of the train, sends requests
to enter the next crossing, and waits for an OK signalling permission by the
crossing to enter. If this OK signal does not occur within some time bound
measured by a clock x , the train controller will request the train to enforce
braking in order to stop before entering the crossing. Thus the train controller
has the following time dependent variables.
Variables:
Dynamics. The dynamics of the train controller is described by the hybrid au-
tomaton in Fig. 5. Initially, the controller is in the mode Far. When for the
current values of pos and speed the predicate near (speed )(pos) becomes true,
On the Verification of Cooperating Traffic Agents 101
the controller switches to the mode Appr setting Req to true and starting the
clock x . When things proceed as expected the crossing should respond with an
OK signal within εmax time, the maximal time the gate needs to close. On oc-
currence of OK the controller switches to the mode SafeAppr indicating that
the train can safely approach the crossing. However, if the OK signal does not
arrive within εmax time, the controller enters the mode FailSafe where the train
is forced to brake until it stops. Only if later an OK signal arrives it may resume
its safe approach to the crossing.
true /
Req := ff,
sc := Normal nearCr(speed)(pos) / Appr
Far
Req := tt, x := 0 , sc := Keep
x := 1
afterCr(pos) /
Req := ff x=ε /
max
OK / sc := Normal sc := Brake
SafeAppr FailSafe
OK / sc := Normal
The controller states correspond nicely to the phases from Fig. 1: Far is
FAR, Appr is NEGOTIATING, FailSafe is RECOVERY, and SafeAppr is
CORRECTING. The only action the train does in correcting is keeping the Req
signal up.7
Gate Plant
The gate controls its angle α depending on the direction requested by the variable
Dir of the gate controller. If Dir is Up the gate should open, and if it is Down the
gate should close. The gate outputs whether it is completely open by a signal
Op or completely closed by a signal Cl . We take into account that the gate may
fail to open or close when requested. This it is modelled by the following time
dependent variables.
7
Thus, one might also view the mode Appr as already CORRECTING.
102 W. Damm, H. Hungar, and E.-R. Olderog
Variables:
Dynamics. We assume that initially the gate is open. i.e. α(0) = 90, that c is
the speed with which the gate can change its angle α, and that the gate plant
is characterised by the following differential equation:
⎧
⎨ c if Dir = Up ∧ α < 90 ∧ ¬Fail
α• = −c if Dir = Down ∧ α > 0 ∧ ¬Fail
⎩
0 otherwise
Thus when there is no gate failure the maximal closing time εmax of the gate
(plus one extra second) is calculated as follows:
εmax = 90/c + 1
The outputs Op and Cl are coupled with the angle of the gate by the following
invariants:
Op ⇔ α = 90 and Cl ⇔ α = 0
Gate Controller
The gate controller reacts to the presence or absence of requests by the train
(controller) to enter the crossing by issuing GoUp and GoDown signals to the
gate plant. Depending on the messages Op and Cl of the gate plant it can
signal an OK to the train controller as a permission to enter the crossing. This
motivates the following time dependent variables.
Variables:
true / Dir := Up
OK : = ff Req / Dir := Down
CrUnsafe CloseGate
Op Cl / OK := tt
OpenGate CrSafe
Req / Dir := Up, OK := ff
The mode CrUnsafe belongs to the gate’s phase FAR, CloseGate and
CrSafe form the phase CORRECTING, and OpenGate is again FAR. The
phase NEGOTIATING has no corresponding mode in this model: The gate does
not negotiate, and one may view the transition from CrUnsafe to CloseGate
as passing NEGOTIATING in an instant.
Correctness Proof
Desired Safety Property. We wish to show that whenever the train is in the
critical section the gate is closed. This might be formulated in terms of safety
envelopes as follows. For SETrain (pos) we choose an extension around the current
position pos which encompasses the extension of the train, independent of mode
and speed. The crossing’s safety envelope is
∅ if m = CrSafe
SECr (m) =
Q otherwise
104 W. Damm, H. Hungar, and E.-R. Olderog
for some adequate set of positions Q. This choice of ∅ as the extension of the
safety envelope in mode CrSafe permits the train to pass the crossing when the
bars are closed without safety violation. We assume that inCr (pos) includes all
train positions which could, if the crossing is not safe, violate safety, i.e.
To perform the proof, we use the State Transition Calculus [18], an exten-
sion of the Duration Calculus [19, 15] to deal with instantaneous transitions.
The Duration Calculus itself is a temporal logic and calculus for expressing and
proving real-time interval properties of trajectories or observables of the form
obs : Time → Data. As a consequence of our assumption above, the desired
safety property can then be expressed as follows:
This Duration Calculus formula states that for every time intervals whenever
the state assertion inCr (pos) about the train holds throughout this interval then
also the state assertion Cl holds throughout the same interval.
This property is established in a complete, self-contained proof. This proof
is presented below, with added comments on which parts correspond to the
verification conditions of our rule and the argument of the rule itself.
Notation. Duration formulas are evaluated in time intervals whereas state as-
sertions are evaluated in time points. In the following D, D1 , D2 denote duration
formulas, S denotes a state assertion, and t ∈ Time.
t
D −→ #S $ ⇔ (D ∧ = t) −→ #S $ holds in a given time interval
if whenever D is true for t time
it is followed by #S $
↑S (start transition) holds for a point interval where S
switches from false to true
↓S (end transition) holds for a point interval where S
switches from true to false
Train Plant. The properties of the train plant are expressed in the State Tran-
sition Calculus as follows:
Invariants:
2#pos • = speed $
2#speed ≤ vmax $
Initial state of the train on the track:
#$ ∨ #farCr (speed )(pos)$; true
The assumption about the initial state is needed for (VC 4).
Assertions about the train movements:
#farCr (speed )(pos)$ −→ #farCr (speed )(pos) ∨ nearCr (speed )(pos)$
#nearCr (speed )(pos)$ −→ #nearCr (speed )(pos) ∨ inCr (pos)$
#inCr (pos)$ −→ #inCr (pos) ∨ afterCr (pos)$
#afterCr (pos)$ −→ #afterCr (pos) ∨ farCr (speed )(pos)$
These assertion establish the necessary properties for reasoning about tra-
jectories for (VC 2) and (VC 3) on the abstract level with the predicates farCr ,
nearCr , inCr and afterCr .
The speed is stable under sc = Keep:
∀ v ∈ Speed : #speed ≤ v ∧ sc = Keep$ −→ #speed ≤ v $
Stability of speed directly establishes (VC 7).
Braking:
∀ v ∈ Speed : #speed ≤ v $; #sc = Brake$v /areg −→ #speed = 0$
#speed = 0 ∧ Brake$ −→ #speed = 0$
∀ v ∈ Speed : ↑ nearCr (v )(pos); #speed ≤ v $εmax −→ #nearCr (v )(pos)$
∀ v ∈ Speed : (↑ nearCr (v )(pos);
#speed ≤ v $εmax ; #(speed • = −areg ) ∨ speed = 0$v /areg )
−→ #nearCr (v )(pos)$
106 W. Damm, H. Hungar, and E.-R. Olderog
The behavior while braking is needed for the adequacy and feasibility of re-
covery actions (VC 3) and (VC 8), while further properties of the abstract logical
level, insofar as the interaction with the train’s movement is concerned.
Initial mode:
#$ ∨ #Far $; true
Mode sequencing:
#Far $ −→ #Far ∨ Appr $
#Appr $ −→ #Appr ∨ SafeAppr ∨ FailSafe$
#SafeAppr $ −→ #SafeAppr ∨ Far $
#FailSafe$ −→ #FailSafe ∨ SafeAppr $
Stabilities:
#Far $; #farCr (speed )(pos)$ ⇒ #Far $
#Appr $; (#¬OK $ ∧ < εmax ) ⇒ #Appr $
#SafeAppr $; #¬afterCr (pos)$ ⇒ #SafeAppr $
#FailSafe$; #¬OK $ ⇒ #FailSafe$
Transitions upon input events:
#Far $; ↑ nearCr (speed )(pos) −→ #Appr $
#Appr $; ↑ OK −→ #SafeAppr $
#SafeAppr $; ↑ afterCr (pos) −→ #Far $
#FailSafe$; ↑ OK −→ #SafeAppr $
Timeout transition:
εmax
↑ Appr ; #Appr $ −→ #FailSafe$
The output variables Req and sc depend on the mode only:
2#Far ⇔ ¬Req$
2#(Far ∨ SafeAppr ) ⇔ sc = Normal $
2#Appr ⇔ sc = Keep$
2#FailSafe ⇔ sc = Brake$
v
speed
Up Down Up
Dir
Fail Fail
OK OK OK
OK
reaching the noncritical Far again, which, due to the assumption on separation
of crossings, dissatisfies the application condition of correcting maneuvers. The
timing diagram in Fig. 7 sketches the combined behavior of controllers and
plants, and thus subsumes (one part of) the discrete phase-transitions addressed
in (VC 1) and the dynamic trajectories from (VC 3).
Fig. 8 shows the failure case where upon the train’s request to enter the
crossing the gate continues to show ¬Cl for more than εmax time and thus
the train is prevented from entering the crossing. Here, the condition on the
definition of nearCr (v )(p) becomes essential in all its parts. It directly trans-
lates into a condition Φrec2fss for the train, with resulting proof obligations
(VC 3), (VC 7) and (VC 8), which sum up into a maximal delay in the tim-
ing diagram from sending Req to coming to a full stop when the gate does not
close.
We may note that, if there were more matching modes, each would require a
corresponding timing diagram, enforcing the use of a global diagram fixing the re-
lations between the cases. This argumentation pattern would, by and large, have
to follow our proof rule, only that the rule further decomposes the (somewhat
On the Verification of Cooperating Traffic Agents 109
v
speed
Req Req
Req
Up Down
Dir
Op Cl
α
ε
max
Fail Fail
Fail
OK
OK
6 Conclusion
We have presented an approach to the verification of cooperating traffic agents
and shown its applicability to two radically different examples. Future work
will complement this paper by formally proving the soundness of the proposed
verification rule, formally instantiating this to the examples of this paper, and
by demonstrating how the derived verification conditions can be discharged by
automatic verification methods.
References
1. B. Abdul-Baki, J. Baldwin, and M.-P. Rudel. Independent validation and veri-
fication of the TCAS II collision avoidance subsystem. Aerospace and Electronic
Systems Mag., 15(8):3–21, 2000.
110 W. Damm, H. Hungar, and E.-R. Olderog
1 Introduction
Information technology industry is still in need for more reliable techniques that
guarantee the quality of software. This need is recognized by C.A.R. Hoare as
a Grand Challenge for Computing Research in his proposal of the Verifying
Compiler [14].
A verifying compiler resembles a type checker in the sense that it statically
checks properties of a program. The properties that should be checked have to be
stated by the programmer in terms of assertions in the code. The first sketch of
such a tool is given by Floyd [10]. In recent years, several programming languages
(e.g., EIFFEL [16], Java [9]) have been extended to support the inclusion of
assertions in the code. These assertions can be used for testing but they can also
be used as a basis for a proof outline of a program. Hoare logic [13] can be seen as
a systematic way of generating the verification conditions which ensure that an
annotated program indeed constitutes a proof outline. A verifying compiler then
consists of a front-end tool to a theorem prover which checks the automatically
generated verification conditions (see for example [7]).
Obviously, to be useful in practice Hoare logics should, first of all, be sound,
i.e., only correct programs should be provably correct. Conversely, completeness
means that all correct programs are provably correct. Its practical relevance,
apart from providing a firm formal justification, is that in case we cannot prove
F.S. de Boer et al. (Eds.): FMCO 2003, LNCS 3188, pp. 111–133, 2004.
c Springer-Verlag Berlin Heidelberg 2004
112 F.S. de Boer and C. Pierik
our program correct, we know that this is due to incorrectness of our program
(which in practice is most frequently the case). An incomplete proof method
does not allow this simple inference.
Furthermore, to be useful in practice Hoare logics should allow the specifica-
tion and verification of a program at the same level of abstraction as the pro-
gramming language itself. This requirement has some important consequences
for the specification of programs which involve dynamically allocated variables
(e.g., ‘pointers’ or ‘objects’). Firstly, this means that, in general, there is no
explicit reference in the assertion language to the heap which stores the dynam-
ically allocated variables at run-time. Moreover, it is only possible to refer to
variables in the heap that do exist. Variables that do not (yet) exist never play
a role.
The main contribution of this paper is a recipe for complete Hoare logics for
reasoning about closed object-oriented programs at an abstraction level which
coincides with that of object-oriented languages in general. This recipe is based
on the transformational approach as introduced and applied in [18]: we first
present a new completeness result of a Hoare logic for what is basically a proce-
dural language with dynamically allocated variables. This result itself involves a
non-trivial generalization of Gorelick’s basic completeness result of the standard
Hoare logic for recursive procedures with simple variables only ([11]). Then we
show how this completeness result can be further generalized to existing Hoare
logics for typical object-oriented concepts like method calls, sub-typing and in-
heritance by transforming an encoding of these concepts into this procedural
language with dynamically allocated variables.
Proving Completeness
Below we summarize Gorelick’s seminal completeness proof for recursive pro-
cedures with simple variables to clarify the context of the crucial steps in the
enhanced proof.
Consider a simple sequential programming language with (mutually) recur-
sive (parameterless) procedures. Let
p1 ⇐ S1 , . . . , pn ⇐ Sn
The completeness proof in [11] shows that every valid correctness formula
{P }S{Q} can be derived if we first prove the most general correctness formula
{x̄ = z̄}pi {SP(pi , x̄ = z̄)} of every procedure pi . In the sequel, we denote this
formula by Φi (for i = 1, . . . , n). The above claim is proved by induction on
the complexity of S. The most interesting case where S equals pi , for some
i = 1, . . . , n, requires an application of the invariance axiom:
{P [z̄/x̄]}pi {P [z̄/x̄]}.
Here P [z̄/x̄] denotes the result of replacing the program variables by their
corresponding logical variables. By the conjunction rule this is combined with
Φi to obtain
{P [z̄/x̄] ∧ x̄ = z̄}pi {P [z̄/x̄] ∧ SP(pi , x̄ = z̄)}.
From the validity of the given correctness formula {P }pi {Q} and the defini-
tion of the strongest postcondition one then proves the validity of the assertion
This formula and the consequence rule allows us to replace the postcondition
by Q. By applying a substitution rule and the rule of consequence we finally
change the precondition to P and obtain {P }pi {Q}.
The final step in the proof consists of deriving the MGF of every procedure
call pi (that is, Φi ) in the logic by means of the recursion rule
e ∈ Expr
::= y | op(e1 , . . . , en )
y ∈ Var
::= u | e.x
s ∈ SExpr::= new C() | m(e1 , . . . , en )
S ∈ Stat
::= y = e ; | y = s ; | while (e) { S }
| S S | if (e) { S } else { S }
meth ∈ Meth ::= m(u1 , . . . , un ) { S return e ; }
π ∈ Prog ::= class∗
The results of the transformational approach then justifies our conclusion that
Hoare logic for object-oriented programs basically boils down to a formalization
of dynamically allocated variables.
2.1 Semantics
In this section, we will only describe the overall functionality of the semantics
of the presented language because this suffices to understand the completeness
proof.
Each instance of a class (or object in object-oriented jargon) has its own
identity. For each class C ∈ C we introduce therefore an infinite set dom(C) of
identities of instances of class C, with typical element o. For different classes
these sets of object identities are assumed to be disjoint. By O we denote the
union of the sets dom(C). For t = int, boolean, dom(t) denotes the set of
boolean and integer values, respectively.
A configuration σ (also called the heap) is a partial function that maps each
existing object to its internal state (a function that assigns values to the instance
variables of the object). Formally, σ is an element of the set
Σ=O dom([[x]]).
x∈IVar
Here i∈I denotes a generalized cartesian product over an index set I. In
this way, σ(o), if defined, denotes the internal state of an object, i.e., σ(o)(x)
denotes the value of the instance variable x of the object o. It is not defined for
objects that do not exist in a particular configuration σ. Thus the domain of
σ specifies the set of existing objects. We will only consider configurations that
are consistent. We say that a configuration is consistent if no instance variable
of an existing object refers to a non-existing object.
On the other hand, a temporary context γ specifies the values of the tempo-
rary variables of the executed method: γ is a typical element of the set
Γ = dom([[u]]).
u∈TVar
if
S(S)(σ, γ0 ) = (σ , γ )
where
– γ0 results from γ by assigning to the formal parameters of m the values of
the actual parameters e1 , . . . , en in (σ, γ);
– (σ , γ ) results from (σ , γ) by assigning the value of the result expression
e in (σ , γ ) to the variable y (which either will affect γ, in case of a local
variable, or σ , in case of a navigation expression).
(we omit typing information: e.g., the expression l in l.x should refer to an object
of some class and only boolean expressions can be used as assertions).
The conditional expression is introduced in order to reason about aliases, i.e.,
variables which refer to the same object. To reason about sequences we assume
the presence of notations to express the length of a sequence (denoted by |l|)
and the selection of an element of a sequence (denoted by l[n], where n is an
integer expression). More precisely, we assume in this paper that the elements of
a sequence are indexed by 1, . . . , n, for some integer value n ≥ 0 (the sequence is
of zero length, i.e., empty, if n = 0). Accessing a sequence with an index which
is out of its bounds results in the value ⊥.
Only equations are allowed as basic assertions. This allows us to remain
within the realm of a two-valued boolean logic, as explained in more detail
below.
As stated above, quantification over finite sequences allows us to specify
interesting properties of the heap. For example, that two objects hd and tl are
connected in a linked list. This is asserted by the formula
∃ z : C ∗ (z[1] = hd ∧ z[|z|] = tl ∧
∀ i : int(1 ≤ i ∧ i < |z| → z[i].next = z[i + 1])).
Assuming the constant nil for denoting the value ⊥, we can can assert that
the value of an expression e is undefined simply by the equation e = nil.
As already explained above, a formula ∃z : C(P ) states that P holds for
an existing instance of class C. Thus the quantification domain of a variable
depends not only on the (static) type of the variable but also dynamically on the
configuration. Similarly, a formula ∃z : C ∗ (P ) states the existence of a sequence
of existing objects (in class C).
118 F.S. de Boer and C. Pierik
states that there exists a finite sequence that stores all (existing) objects in class
C.
Furthermore, we observe that the domain of discourse of our assertion lan-
guage consists only of the built-in data types of the integers and booleans, and
the program variables, i.e., it excludes the methods. This allows for a clear sep-
aration of concerns between what a program is supposed to do as expressed by
the assertion language and how this is implemented as described by its methods.
{P [e/u]} u = e {P },
where P [e/u] denotes the result of replacing every occurrence of the temporary
variable u in P by the expression e. Soundness of this axiom is stated by the
following theorem.
How to Cook a Complete Hoare Logic for Your Pet OO Language 119
Theorem 1. We have
Theorem 2. We have
In the axiom
{P [e /e.x]} e.x = e {P }
for assignments to instance variables the substitution operation [e /e.x] differs
from the standard notion of structural substitution. An explicit treatment of
possible aliases is required for this type of assignments. Possible aliases of the
variable e.x are expressions of the form l.x: After the assignment it is possible
that l refers to the object denoted by e, so that l.x is the same variable as e.x
and should be substituted by e . It is also possible that, after the assignment, l
does not refer to the object denoted by e, and in this case no substitution should
take place. Since we can not decide between these possibilities by the form of the
expression only, a conditional expression is constructed which decides ”dynam-
ically”. Let l denote the expression l[e /e.x]. If [[l]] = [[e]], i.e., the expressions l
and e refer to objects of the same class, we define (l.x)[e /e.x] inductively by
if l = e then e else l .x fi
In case the types of the expressions l and e do not coincide, i.e., they do not
refer to objects of the same class, aliasing does not occur, and we can simply
define (l.x)[e /e.x] inductively by l .x.
Soundness of the above axiom for assignments to instance variables is stated
by the following theorem.
where σ (o)(x) = L(e )(σ, γ, ω), for o = L(e)(σ, γ, ω), and in all other cases σ
agrees with σ .
In [7] we also discuss the substitution operation [new C/u], which computes
the weakest precondition of an assignment u = new C() involving a temporary
variable u. The definition of this substitution operation is complicated by the
fact that the newly created object does not exists in the state just before its
creation, so that in this state we can not refer to it! We however are able to
carry out the substitution due to the fact that this variable u can essentially
occur only in a context where either one of its instances variables is referenced,
or it is compared for equality with another expression. In both of these cases
we can predict the outcome without having to refer to the new object. Another
complication dealt with by this substitution operation is the changing scope of
a bound occurrence of a variable z ranging over objects in class C which is
induced by the creation of a new object (in class C). For example, we define
∃z : C(P )[new C/u] by
∃z : C(P [new C/u]) ∨ (P [u/z][new C/u]).
The first disjunct ∃z : C(P [new C/u]) represents the case that P holds for
an ‘old’ object (i.e. which exists already before the creation of the new object)
whereas the second disjunct P [u/z][new/u] represents the case that the new
object itself satisfies P . Since a logical variable does not have aliases, the sub-
stitution [u/z] consists of simply replacing every occurrence of z by u.
Given this substitution we have the following axiom for object creation in-
volving a temporary variable:
{P [new C/u]} u = new C() {P }.
Soundness of this axiom is stated by the following theorem.
Theorem 4. We have
σ, γ, ω |= P [new/u] if and only if σ , γ , ω |= P ,
where σ is obtained from σ by extending the domain of σ with a new object o
and initializing its instance variables. Furthermore the resulting local context γ
is obtained from γ by assigning o to the variable u.
Proof. The proof proceeds by induction on the complexity of P (for the details
we refer to [21]).
Observe that an assignment e.x = new C() can be simulated by the sequence
of assignments u = new C(); e.x = u. Therefore we have the axiom
{P [u/e.x][new C/u]} e.x = new C() {P },
where u is a fresh temporary variable which does not occur in P and e. Note
that the substitution [u/e.x] makes explicit all possible aliases of e.x. Soundness
of this axiom follows from the above.
It is worthwhile to observe that aliasing and object creation are phenomena
characteristic of dynamically allocated variables. Furthermore, the above substi-
tutions provide a formal account of aliasing and object creation at an abstraction
How to Cook a Complete Hoare Logic for Your Pet OO Language 121
level which coincides with that of the programming language, e.g., without any
explicit reference to the heap.
We now turn to method invocations. Suppose we have in class C a method
m(u1 , . . . , un ) { S return e }. The following rule for method invocation (MI)
allows to derive a correctness specification of a call y = m(e1 , . . . , en ) from a
correctness specification of the body S of m.
Here we do not allow temporary variables in Q. Except for the formal pa-
rameters u1 , . . . , un , no other temporary variables are allowed in P .
The simultaneous substitution [ē/ū] models the assignment of the actual
parameters ē = e1 , . . . , en to the formal parameters ū = u1 , . . . , un .
The substitution [e/return] applied to the postcondition Q of S in the first
premise models a (virtual) assignment of the result value to the logical variable
return, which must not occur in the assertion R. The substitution [return/y]
applied to the postcondition R of the call models the actual assignment of the
return value to y. It corresponds to the usual notion of substitution if y is
a temporary variable. Otherwise, it corresponds to the substitution operation
[e /e.x] for reasoning about aliases.
It is worthwhile to observe that the use of the additional return variable
allows to resolve possible clashes between the temporary variables of the post-
condition R of the call and those possibly occurring in the return expression e.
As a typical example, consider the object-oriented keyword this, which denotes
the current active object, as an additional parameter of each method. We observe
that, in case a method returns the identity of the callee, in the postcondition
R[this/y] of the caller, this, however, would refer to the caller.
Next, we observe that a temporary expression f of the caller generated by
the following abstract syntax
f ::= u | op(f1 , . . . , fn )
I1 , . . . , Ik A1 , . . . , Ak F1 , . . . , Fk
(MRMI)
F1
where
– Ai is a specification of a call, i.e., for i = 1, . . . , k, Ai denotes a correctness
formula
{Pi [ēi /ūi ][f¯i /z̄i ]} yi = mi (ēi ) {Ri }
with ūi the formal parameters of method mi and ēi a corresponding sequence
of actual parameters and;
– Fi is a correctness formula
{Pi } Si {Qi [ei /returni ]}
with Si the body of method mi i and ei its return expression;
– Ii denotes the implication
Qi [f¯i /z̄i ] → Ri [returni /yi ]
which relates he postconditions of the call and the body.
The syntactical restrictions of rule (MI) also apply to all assertions in this
rule.
5 Completeness
In this section, we will prove (relative) completeness of the logic [4] (soundness
follows from a standard inductive argument). That is, given a finite set of class
definitions, we prove that |= {P }S{Q} implies {P }S{Q}, assuming as addi-
tional axioms all valid assertions. We do so following the structure of the proof
that is given in the introduction. In the following sections we give solutions for
each of the issues that were mentioned in the introduction.
First we show how to formulate an assertion that freezes the initial state. Sub-
sequently, we give an enhanced version of the invariance axiom. As a counterpart
of the substitution [z̄/x̄] in the invariance axiom, we define a substitution that
modifies an assertion in such a way, that its validity is not affected by execution
of any object-oriented program. In particular, it is immune to object-creation.
Next, we show that the our technique for freezing the initial state leads to Most
General Formulas about method calls that enable us to derive any valid correct-
ness formula. Finally, we show how to derive these MGFs for method calls.
Definition 1. Our completeness proof is based on the following standard se-
mantic definition of the strongest postcondition SP(S, P ) as the set of triples
(σ, γ, ω) such that for some initial state (σ , γ ) we have S(S)(σ , γ ) = (σ, γ)
and σ , γ , ω |= P .
How to Cook a Complete Hoare Logic for Your Pet OO Language 123
{P [z̄/x̄]}S{P [z̄/x̄]}.
124 F.S. de Boer and C. Pierik
HEAP
LOGICAL STATE
This can be solved by restricting quantification to the objects that exist in the
initial state. That is, by restricting quantification to objects in seqC . Therefore
we introduce the following bounded form of quantification:
The assertions z ∈ seqC and z seqC stand for ∃i(z = seqC [i]) and
∀i∃j(z[i] = seqC [j]). Note that the assertion ∃i(z = seqC [i]) states that the
object denoted by z appears in the sequence denoted by seqC . The assertion
∀i∃j(z[i] = seqC [j]) states that all objects stored in the sequence denoted by z
are stored in the sequence seqC . We thus restrict quantification to the sequences
seqC . (For quantification over basic types or sequences of basic types we simply
have (∃zP )Θ = ∃z(P Θ).)
The transformation Θ is truth-preserving in the following manner.
Theorem 5. For every assertion P , and any state (σ, γ) and logical environ-
ment ω which are consistent, we have that σ, γ, ω |= init implies σ, γ, ω |= P iff
σ, γ, ω |= P Θ.
The following theorem states that we can prove that P Θ is an invariant for
every statement S and assertion P . Thus this theorem can replace the invariance
axiom.
Proof. The main idea behind the proof is that P Θ is immutable to all substitu-
tions in the proof rules since the transformation Θ replaces all program variables
by logical variables. Let P denote P Θ.
Since P does not contain any program variables, clearly we have that P [e/u]
and P [e /e.x] both equal (syntactically) P , for any substitutions [e/u] and
[e /e.x].
Moreover, since all quantification in P is bounded we have that P [new C/u]
is logically equivalent to P : By the soundness of the axiom for object creation
(as stated in Theorem 4) we have that σ, γ, ω |= P [new C/u] if and only if
σ , γ , ω |= P , where σ results from adding to the domain of σ a new instance of
class C and γ results from assigning the identity of this newly created instance
to the temporary variable u. Since u does not appear in P , it follows that
σ , γ , ω |= P if and only if σ , γ, ω |= P . Finally, since the newly created object
in class C does not appear in ω(seqC ) (note that by definition ω(seqC ) may refer
only to objects existing in σ) and all quantification in P involving this newly
created object is restricted to ω(seqC ) it follows that σ , γ, ω |= P if and only if
σ, γ, ω |= P .
126 F.S. de Boer and C. Pierik
Next, we can apply the standard rules which allow one to replace in the
precondition every logical variable Θ(u) by the temporary variable u and ex-
istentially quantifying all the logical variables Θ(C, x) (x an arbitrary instance
variable in an arbitrary class C). Finally, we existentially quantify the variables
seqC , for every C. It is not difficult to prove that the assertion P logically im-
plies the resulting precondition. Therefore an application of the consequence rule
finishes the proof.
The final step in the completeness proof is to show that we can derive the
correctness formula
{init}S{SP(S, init)}
for any assignment S ≡ y = m(e1 , . . . , en ) that involves a method call.
Theorem 8. For any assignment S ≡ y = m(e1 , . . . , en ) we have
{init}S{SP(S, init)}.
M (S) = {S1 , . . . , Sk },
Let Si , for i = 0, . . . , n, denote the body of mi and let ei be its return
expression. The expression ēi abbreviates the sequence ei1 , . . . , eini . We denote
the formal parameters ui1 , . . . , uini of method mi by ūi .
We must prove {init}S{SP(S, init)}. By the rule (MRMI) and Theorem 7
it suffices to find, for i = 1, . . . , k, valid correctness formulas
such that
|= init → Pi [ēi /ūi ][f¯i /z̄i ], (2)
and
|= Qi [f¯i /z̄i ] → SP(Si , init)[returni /yi ], (3)
for some substitutions [f¯i /z̄i ]. Observe that Theorem 7 requires us to prove
validity, not derivability. The substitutions [f¯i /z̄i ] involve temporary expressions
f¯i and corresponding logical variables satisfying the conditions of rule (MRMI).
Obvious candidates for the assertions Pi and Qi are the formulas init and
SP(Si , init)[returni /yi ], respectively. However, for (2) and (3) to be valid we
introduce a renaming function Φ which transforms any temporary variable u
into a (new) logical variable Φ(u) of the same type. Note that applying Φ to any
assertion effectively neutralizes the passing of the actual parameters. That is,
128 F.S. de Boer and C. Pierik
(P Φ)θ ≡ P Φ
for every assertion P and substitution θ which only transforms temporary
variables. So candidates for Pi and Qi are initΦ and SP(Si , init)[returni /yi ]Φ,
respectively. Using the inverse Φ−1 of Φ for [f¯i /z̄i ], we trivially obtain (2) and (3).
However, to prove the validity of the correctness formulas in (1) we have to
strengthen initΦ with additional information about the actual parameters spec-
ified by the call Si . After the invocation of the method the formal parameters
should have the values of the actual parameters. This information is given by
the conjunction of the equations uij = (eij Φ), for j = 1, . . . , ni . Observe that (2)
still holds because
(uij = (eij Φ))[ēi /ūi ]Φ−1 yields eij = eij .
Summarizing, for the assertion Pi defined by
ni
initΦ ∧ uij = (eij Φ)
j=1
follows that σ , γ0 , ω |= SP(Si , init)[returni /yi ]. Observe that the truth of the
assertion SP(Si , init)[returni /yi ]Φ does not depend on the local context or the
variable yi due to the substitutions [returni /yi ]Φ. So we have
Finally, because of the definition of ω (note that ω(returni ) equals the value
of the return expression ei in state (σ , γ )) we conclude
T : L+ → L
{P }S{Q} iff {P }T (S){Q},
7 Conclusions
In recent years, many formal analysis techniques for object-oriented program-
ming languages have been proposed. The large amount of interest can be ex-
plained by the wide-spread use of object-oriented languages. However, the for-
mal justification of many existing Hoare logics for object-oriented programming
languages is still under investigation. Notably the problem of completeness until
now defied clear solutions. For example, the logic of object-oriented programs as
given by Abadi and Leino was not complete [1]. They suspect that their use of
a ”global store” model is the source of the incompleteness.
Von Oheimb showed that his logic for reasoning about a substantial subset
of Java is (relatively) complete [24]. However, he uses the logic of Isabelle/HOL
(higher order logic) as specification language. This trivializes the matter of ex-
pressiveness of the intermediate assertions. Therefore their result does not auto-
matically carry over to assertion languages that are closer to the programming
language. This point is further discussed in [17].
132 F.S. de Boer and C. Pierik
Future work concerns first of all the further development of the transforma-
tional approach to Hoare logics of object-oriented programming. Of particular
interest is an application of the transformational approach to Hoare logics for
various object-oriented concurrency models.
Another interesting line of research concerns the systematic development of
compositional Hoare logics for object-oriented programs. Note that the Hoare
logic presented in this paper is compositional only with respect to the flow of
control structures. However, it is not compositional in the sense of class-based.
Also our Hoare logic does not provide any formalization of the basic concept of
an object as an unit of data-encapsulation. We think that such a logic requires
a formalization of the external observable behavior of an object in terms of
its traces of events which indicate the sending and reception of messages (as
described for example in [15]). It is worthwhile to observe that such a notion
of external observable behavior (which abstracts from the internal state space
of an object) in fact involves a concurrency view even if the object-oriented
programming language is purely sequential.
Finally, we remark that most existing logics for object-oriented programs deal
with closed programs. Currently we are also investigating trace semantics as a
possible semantic basis of Hoare logics for open object-oriented programs.
References
1. M. Abadi and R. Leino. A logic of object-oriented programs. In M. Bidoit
and M. Dauchet, editors, TAPSOFT ’97: Theory and Practice of Software Devel-
opment, 7th International Joint Conference CAAP/FASE, Lille, France, volume
1214, pages 682–696. Springer-Verlag, 1997.
2. E. Abraham-Mumm, F. de Boer, W. de Roever, and M. Steffen. Verification for
Java’s reentrant multithreading concept. In Proc. of FoSSaCS 2002, volume 2303
of LNCS, pages 5–20, 2002.
3. K. R. Apt. Ten Years of Hoare’s Logic: A Survey - Part I. ACM Transactions on
Programming Languages and Systems, 3(4):431–483, October 1981.
4. S. A. Cook. Soundness and completeness of an axiom system for program verifi-
cation. Siam Journal of Computing, 7(1):70–90, February 1978.
5. J. de Bakker. Mathematical theory of program correctness. Prentice-Hall, 1980.
6. F. de Boer. Reasoning about dynamically evolving process structures. PhD thesis,
Vrije Universiteit, 1991.
7. F. de Boer and C. Pierik. Computer-aided specification and verification of anno-
tated object-oriented programs. In B. Jacobs and A. Rensink, editors, FMOODS
V, pages 163–177. Kluwer Academic Publishers, 2002.
8. H.-D. Ebbinghaus and J. Flum. Finite Model Theory. Springer-Verlag, 1995.
9. C. Flanagan, K. R. M. Leino, M. Lillibridge, G. Nelson, J. B. Saxe, and R. Stata.
Extended static checking for Java. In Proceedings of the ACM SIGPLAN 2002
Conference on Programming Language Design and Implementation (PLDI), pages
234–245, 2002.
10. R. W. Floyd. Assigning meaning to programs. In Proc. Symposium on Applied
Mathematics, volume 19, pages 19–32. American Mathematical Society, 1967.
How to Cook a Complete Hoare Logic for Your Pet OO Language 133
11. G. Gorelick. A complete axiomatic system for proving assertions about recursive
and non-recursive programs. Technical Report 75, Dep. Computer Science, Univ.
Toronto, 1975.
12. J. Gosling, B. Joy, and G. Steele. The Java Language Specification. Addison-
Wesley, 1996.
13. C. A. R. Hoare. An axiomatic basis for computer programming. Communications
of the ACM, 12(10):576–580, 1969.
14. T. Hoare. Assertions. In M. Broy and M. Pizka, editors, Models, Algebras and Logic
of Engineering Software, volume 191 of NATO Science Series, pages 291–316. IOS
Press, 2003.
15. A. Jeffrey and J. Rathke. A fully abstract may testing semantics for concurrent
objects. In Proceedings of Logics in Computer Science, pages 101–112, 2002.
16. B. Meyer. Eiffel: The Language. Prentice-Hall, 1992.
17. T. Nipkow. Hoare logics for recursive procedures and unbounded nondeterminism.
In J. Bradfield, editor, Computer Science Logic (CSL 2002), volume 2471 of LNCS,
pages 103–119. Springer, 2002.
18. E.-R. Olderog and K. R. Apt. Fairness in parallel programs: The transformational
approach. TOPLAS, 10(3):420–455, 1988.
19. S. Owicki and D. Gries. An axiomatic proof technique for parallel programs I.
Acta Informatica, 6:319–340, 1976.
20. C. Pierik and F. S. de Boer. A syntax-directed Hoare logic for object-oriented
programming concepts. In E. Najm, U. Nestmann, and P. Stevens, editors, Formal
Methods for Open Object-Based Distributed Systems (FMOODS) VI, volume 2884
of LNCS, pages 64–78, 2003.
21. C. Pierik and F. S. de Boer. A syntax-directed Hoare logic for object-oriented
programming concepts. Technical Report UU-CS-2003-010, Institute of Informa-
tion and Computing Sciences, Utrecht University, The Netherlands, March 2003.
Available from http://www.cs.uu.nl/research/techreps/UU-CS-2003-010.html.
22. A. Poetzsch-Heffter and P. Müller. A programming logic for sequential Java. In
S. D. Swierstra, editor, ESOP ’99, volume 1576 of LNCS, pages 162–176, 1999.
23. J. Tucker and J. Zucker. Program correctness over abstract data types with error-
state semantics. North-Holland, 1988.
24. D. von Oheimb. Hoare logic for Java in Isabelle/HOL. Concurrency and Compu-
tation: Practice and Experience, 13(13):1173–1214, 2001.
Behavioural Specification for Hierarchical
Object Composition
Răzvan Diaconescu
1 Introduction
The current Internet/Intranet technologies have led to an explosive increase in
demand for the construction of reliable distributed systems. Among the new
technologies proposed for meeting this new technological challenge, component-
based software engineering is one of the most promising. If we have an adequate
set of components and a good design pattern, a system development process
may become easier and the quality of the product may be greatly improved.
However such development process raises some serious problems. How can we
get an adequate set of components or how can we know the components we get
are adequate for our systems?
A good solution seems to be given by formal specifications supporting the
following characteristics:
– can specify the interface of components,
– can specify the behaviour of components,
– supports a precise semantics of composition, and
– be executable or have tools supporting testing and verification.
Here we adopt the behavioural algebraic specification framework [1, 2, 3, 4].
Due to its simple logical foundations and to its efficient specification and verifi-
F.S. de Boer et al. (Eds.): FMCO 2003, LNCS 3188, pp. 134–156, 2004.
c Springer-Verlag Berlin Heidelberg 2004
Behavioural Specification for Hierarchical Object Composition 135
The paper is structured as follows. The first section recalls briefly the basic
mathematical notions necessary for this work. We present first general algebra
notions, and then we give a very brief overview of hidden algebra. At the end
of this section we define the concept of behavioural object. The next section
introduces briefly the CafeOBJ notation for behavioural objects, which will be
used for the examples, and which is illustrated with two simple examples. The
main section of the paper is dedicated to the composition operators and contains
their mathematical definitions together with their main semantic properties. All
composition operators are illustrated with examples. The final section develops
an example showing how the compositionality of behavioural equivalence result
for compositions with synchronisation can be applied for reusing verifications
within the framework of the CafeOBJ system.
Here we only give the statements of the mathematical results and omit their
proofs. These will appear in an extended full version of the paper.
Acknowledgement
The author is grateful to all people who contributed to the development of
the CafeOBJ object composition methodology based on projection operations,
especially to Shusaku Iida and Kokichi Futatsugi.
ing, in that the sets Fw→s need not be disjoint. Call σ ∈ F[]→s (sometimes
denoted simply F→s ) a constant symbol of sort s. A signature morphism ϕ from
a signature (S, F ) to a signature (S , F ) is a pair (ϕsort , ϕop ) consisting of a
map ϕsort : S → S of sorts and of a map ϕop : F → F on operation symbols
sort ∗
such that ϕop w→s (Fw→s ) ⊆ F(ϕsort )∗ (w)→ϕsort (s) , where (ϕ ) : S ∗ → S ∗ is the
extension of ϕsort to strings.
A (S, F )-algebra A consists of an S-indexed set A and a function Aσ : Aw →
As for each σ ∈ Fw→s ; the set As is called the carrier of A of sort s. If σ ∈ F→s
then Aσ determines a point in As which may also be denoted Aσ . An (S, F )-
homomorphism from one (S, F )-algebra A to another B is an S-indexed function
h : A → B such that hs (Aσ (a)) = Bσ (hw (a)) for each σ ∈ Fw→s and a ∈ Aw .
A (S, F )-homomorphism h : A → B is a (S, F )-isomorphism if and only if
each function hs : As → Bs is bijective (i.e., one-to-one and onto, in an older
terminology). The category (class) of algebras of a signature (S, F ) is denoted
Alg(S, F ).
A F -congruence on a (S, F )-algebra A is an S-sorted family of relations, ≡s on
As , each of which is an equivalence relation, and which also satisfy the congruence
property, that given any σ ∈ Fw→s and any a ∈ Aw , then Aσ (a) ≡s Aσ (a )
whenever a ≡w a .1
Given a signature morphism ϕ : (S, F ) → (S , F ) and a (S , F )-algebra A ,
we can define the reduct of A to (S, F ), denoted A ϕ , or simply A (S,F ) when
ϕ is an inclusion of signatures, to have carriers Aϕ(s) for s ∈ S, and to have
operations (A ϕ )σ = Aϕ(σ) for σ ∈ F . Then A is called an expansion of A
along ϕ. Reducts can also be easily extended to algebra homomorphisms.
For any signature (S, F ) and (S, F )-algebra A, let (S, FA ) be the elementary
extension of (S, F ) via A which adds the elements of A as new constants, i.e.
(FA )→s = F→s ∪ As and (FA )w→s = Fw→s when w is not empty. Let AA
denote the expansion of A to (S, FA ) interpreting each element of A by itself,
i.e. (AA )a = a for each a ∈ A.
Any F -term t = σ(t1 . . . tn ), where σ ∈ Fw→s is an operation symbol and
t1 , . . . , tn are F -(sub)terms corresponding to the arity w, gets interpreted as an
element At ∈ As in a (S, F )-algebra A by At = Aσ (At1 . . . Atn ). When each
element a of A can be denoted as a = At for some term t, then we call A a
reachable algebra.
For any set X of new constants, called variables, the (F ∪ X)-terms can be
regarded as F -derived operations by defining the arity ar(t) by the following
procedure:
– consider the set var(t) ⊆ X of all variables occurring within t,
– transform var(t) into a string by fixing an arbitrary order on this set, and
– finally, replace the variables in the string previously obtained by their sorts.
Any F -derived operation t with arity w and sort s determines a function
At : Aw → As such that for each string a of elements corresponding to ar(t),
1
Meaning ai ≡si ai for i = 1, ..., n, where w = s1 . . . sn and a = (a1 , . . . , an ).
138 R. Diaconescu
2
In the particular case of quantifications, notice that this changes the sorts of the
variables.
Behavioural Specification for Hierarchical Object Composition 139
and s is hidden also, and as ‘attributes’ whenever w has exactly one hidden
sort and s is visible. This object-oriented interpretation of behavioural logic will
be formally clarified in the section below by the introduction of the concept of
‘behavioural object’.
A (H, V, F, F b )-algebra is just an (H ∪ V, F )-algebra. A homomorphism of
hidden algebras h : A → B for a signature (H, V, F, F b ) is just a (H ∪ V, F )-
algebra homomorphism preserving the behavioural equivalence, i.e. such that
h(∼A ) ⊆∼B .
Given a (H, V, F, F b )-algebra A, a hidden congruence ∼ on A is just an
b
F -congruence which is identity on the visible sorts. The largest hidden F -
congruence ∼A on A is called behavioural equivalence. The following is probably
the most fundamental result in hidden algebra, providing the foundations for
the so-called ‘coinduction’ proof method.
Theorem 1. Behavioural equivalence always exists.
Hence in order to prove by coinduction that two elements are behaviourally
equivalent it is enough to prove that they are congruent3 for some arbitrarily
but conveniently chosen hidden congruence.
An operation symbol σ is coherent for an algebra A when it preserves the
behavioural equivalence, i.e. Aσ (a) ∼A Aσ (a ) whenever a ∼a a (possibly
component-wise).
A hidden algebra signature morphism ϕ : (H, V, F, F b ) → (H , V , F , F ) is
b
a signature morphism (H ∪ V, F ) → (H ∪ V , F ) such that
– ϕ(V ) ⊆ V and ϕ(H) ⊆ H ,
– ϕ(F b ) = F and ϕ−1 (F ) ⊆ F b ,
b b
These conditions say that hidden sorted signature morphisms preserve vis-
ibility and invisibility for both sorts and operations, and the object-oriented
intuition behind the inclusion F ⊆ ϕ(F b ) is the encapsulation of classes (in
b
3
In a hidden congruence relation.
4
For the model theoretic relevance of this condition see [1].
140 R. Diaconescu
5
Any hidden algebra satisfying E satisfies ϕ(E) too.
6
They should be considered as parameterised by the data arguments of the arity.
Behavioural Specification for Hierarchical Object Composition 141
Alg(B) such that A ≡ Ψ (Φ(A)) for each B-algebra A and A ≡ Φ(Ψ (A )) for each
B -algebra A .
Therefore behavioural objects are equivalent when they admit the same ‘im-
plementations’. Notice that this defines indeed an equivalence relation and that
isomorphic objects are equivalent.
We may also extend the concept of reduct of algebras from behavioural pre-
sentation morphisms to behavioural object morphisms.
init
Account
balance
deposit
withdraw
Int Nat
142 R. Diaconescu
_U_,_-_
empty
Set
{_}
in
Bool Elt
Notice that there is only one behavioural operation, the membership obser-
vation in, the operations { } standing for regarding elements as singleton sets,
U standing for union of sets, and - standing for the difference between sets not
being specified as behavioural. The equations are as follows:
eq E in empty = false .
eq E in { E’ } = (E == E’) .
eq E in (S U S’) = (E in S) or (E in S’) .
eq E in (S - S’) = (E in S) and not(E in S’) .
Behavioural Specification for Hierarchical Object Composition 143
Object A
Object B
Projection operations from the hidden sort of the states of the compound
object to the hidden sorts of the states of the component objects constitute the
main technical concept underlying the CafeOBJ composition method; projection
operations are related to the lines of UML figures. Projection operations are
subject to several mathematical conditions which will be formally clarified later.
These are in essence as follows:
1. all actions of the compound object are related via projection operations to
actions in each of the components,
2. each observation of the compound object is related via the projection oper-
ations to an observation of some component, and
3. each constant state of the compound object is projected to a constant state
on each component.
In the compound objects we only define communication between the compo-
nents; this means that the only equations at the level of the specification of the
compound objects are the ones relating the actions and observations of the com-
pound objects to those of the components as described above. All the equations
for the projection operations are strict rather than behavioural, however we may
also define them behaviourally without affecting our semantics and methodology.
The components of a compound object are connected in parallel if there is no
synchronisation between them. In order to define the concept of synchronisation,
we have to introduce the following concept.
Definition 4. Two actions of a compound object are in the same action group
when they change the state of the same component object via a projection oper-
ation.
Synchronisation appears when:
– there exists an overlapping between some action groups, in the sense that
some action of the compound object is projected to at least two components
affecting their state changing simultaneously, or
– the projected state of the compound object (via a projection operation)
depends on the state of a different (from the object corresponding to the
projection operation) component.
The first case is sometimes called broadcasting and the second case is some-
times called client-server computing. In the unsynchronised case, we have full
concurrency between all the components, which means that all the actions of the
compound object can be applied concurrently, therefore the components can be
implemented as distributed processes or concurrent processes with multi-thread
which are based on asynchronous communications.
In the case of synchronised compositions, the equations for the projection
operations are conditional rather than unconditional. Informally, their conditions
are subject to the following conditions:
– each condition is a quantifier-free formula formed from equations by itera-
tion of negation, conjunction, and disjunction, the terms in the equations
Behavioural Specification for Hierarchical Object Composition 145
We then compose these two account objects as in the following double fig-
ure containing both the UML and the CafeOBJ graphical7 representation of this
composition, where deposit1 and withdraw1 are the actions for the first account,
balance1 is the observation for the first account, account1 is the projection oper-
ation for the first account, and deposit2, withdraw2, balance2, and account2 are
the corresponding actions, observation, and projection operation for the second
account:
AccountSys
account1 account2
AccountSys
deposit1 Account1 Account2
deposit2
withdraw1
withdraw2 deposit1
balance1 deposit2
1 1 balance2 withdraw1
withdraw2
1 1
Account1 Account2 Int
deposit deposit Nat
withdraw withdraw
7
The CafeOBJ graphical representation corresponds to the module defining this object
composition rather than to the “flattened” specification, hence the operations of the
components are not included in the figure.
146 R. Diaconescu
eq balance1(AS) = balance(account1(AS)) .
eq balance2(AS) = balance(account2(AS)) .
eq account1(deposit1(AS, N)) = deposit(account1(AS), N) .
eq account1(deposit2(AS, N)) = account1(AS) .
eq account1(withdraw1(AS, N)) = withdraw(account1(AS), N) .
eq account1(withdraw2(AS, N)) = account1(AS) .
eq account2(init-account-sys) = init-account2 .
eq account2(deposit1(AS, N)) = account2(AS) .
eq account2(deposit2(AS, N)) = deposit(account2(AS), N) .
eq account2(withdraw1(AS, N)) = account2(AS) .
eq account2(withdraw2(AS, N)) = withdraw(account2(AS), N) .
Notice that besides the first two equations relating the observations on the
compound object to those on the components, the other equations relate the ac-
tions of the account system to the actions of the components. Remark that the
actions corresponding to one component do not change the state of the second
component (via the projection operation), hence this composition is unsynchro-
nised. In fact these equations expressing the concurrency of composition need
not be specified by the user, in their absence they may be generated internally
by the system, thus reducing the specification of the composition to the essential
information which should be provided by the user.
The following provides a formal definition for parallel composition of be-
havioural objects. Another parallel composition concept as operators on speci-
fications has been defined in [1] within a more restricted hidden algebra frame-
work.
8
By we denote the disjoint union.
Behavioural Specification for Hierarchical Object Composition 147
Proposition 1. For any behavioural objects B1 and B2 , for each parallel com-
position B ∈ B1 B2 , we have that
a ∼A a if and only if Aπ1 (a) ∼A1 Aπ1 (a ) and Aπ2 (a) ∼A2 Aπ2 (a )
for each B-algebra A, elements a, a ∈ AhB , and where Ai = ABi for each
i ∈ {1, 2}.
9
B1 (V,FV ) = B2 (V,FV ) where V = VB1 ∩ VB2 and FV is the set of all data operation
symbols in FB1 ∩ FB2 .
148 R. Diaconescu
B(12)3 B1(23)
π12 π3 π’1 π’23
B12 B23
π1 π2 π’2 π’3
B1 B2 B3 B1 B2 B3
AccountSys deposit
AccountSys withdraw
deposit1
deposit2 Nat
withdraw1
withdraw2
add-account
* account del-account
1
Account Uid
Account
deposit
withdraw init-account
no-account
transfer
AccountSys
account1 account2
Account1 Account2
deposit1
balance1 deposit2
balance2 withdraw1
withdraw2
Int
Nat
The meaning of condition (2.1) is that of completeness in the sense that all
cases are covered, while the meaning of (2.2) is that of non-ambiguity in the sense
that each case falls exactly within the scope of only one conditional equation.
Let us denote by B1 ⊗ B2 the class of behavioural objects B which are syn-
chronised compositions of behavioural objects B1 and B2 .
The above definition for composition with synchronisation can be extended
easily to the case of any finite number of objects.
Notice that the example of dynamic account system presented above is a
special case of Definition 7.
The following result showing that the behavioural equivalence on the com-
pound object is compositional with respect to the behavioural equivalences of
its components extends Proposition 1.
Theorem 4. For any behavioural objects B1 and B2 , for each composition with
synchronisation B ∈ B1 ⊗ B2 , we have that
a ∼A a if and only if (∀Wi )Aπi (a, Wi ) ∼Ai Aπi (a , Wi ) for i ∈ {1, 2}
for each B-algebra A, elements a, a ∈ AhB , and where Ai = ABi for each
i ∈ {1, 2}.
Our object composition with synchronisation has final semantics shown by
the result below generalising Theorem 2:
Theorem 5. Let B ∈ B1 ⊗ B2 and let Ai be algebras of Bi for i ∈ {1, 2} such
that they are consistent on the common data part. Then there exists a B-algebra
A expanding A1 and A2 such that for any other B-algebra A expanding A1 and
A2 there exists an unique B-algebra homomorphism A → A expanding A1 and
A2 .
152 R. Diaconescu
5 Compositionality of Verifications
In object-oriented programming, reusability of the source code is important, but
in object-oriented specification, reusability of the proofs is also very important
because of the complexity of the verification process. We call this composition-
ality of verifications of components. Our approach supports compositionality of
verifications via Theorem 4.
Let us specify a dynamic bank account system having a user management
mechanism given by a user database (USER-DB) which enables querying whether
an user already has an account in the bank account system. The users data base
is obtained just by reusing (renaming) the behavioural sets object BSET.
mod* USER-DB { protecting(BSET *{ hsort BSet -> UserDB, hsort Elt -> UId})}
The following is the UML and CafeOBJ graphical representation of this dy-
namic bank account system specification:
AccountSys
user-db account
add-account del-account
del-account AccountSys add-account
transfer
deposit
init-account
withdraw
deposit
withdraw transfer
1 1
UserDB Account
1 *
UserDB Account
and here are the CafeOBJ equations for the projection operation for UserDB:
The following is the CafeOBJ code for the equations for the projection oper-
ation for Account:
ceq account(add-account(AS, U’), U) = init-account
if (U == U’) and not(U in user-db(AS)) .
ceq account(add-account(AS, U’), U) = account(AS, U)
if (U =/= U’) or (U in user-db(AS)) .
ceq account(del-account(AS, U’), U) = no-account
if (U == U’) .
ceq account(del-account(AS, U’), U) = account(AS, U)
if (U =/= U’) .
ceq account(transfer(AS, U’, U”, N), U) = account(AS, U)
if (U’ == U”) .
Behavioural Specification for Hierarchical Object Composition 153
Notice the use of the parameterized relation for handling the conjunction
indexed by the user identifiers, and we use =b= to denote the behavioural equiv-
alence on the components. We may recall that the definition of =b= for ACCOUNT
is just equality under the observation balance and that of =b= for USER-DB is just
equality under arbitrary membership, thus both of them are coded very easily.
Now, we will prove the true concurrency of deposit operations of two (possibly
but not necessarily different) users, which can be considered as a safety prop-
erty for this system of bank accounts and which is formulated as the following
behavioural commutativity property:
154 R. Diaconescu
deposit(deposit(as, u2, n2), u1, n1) ∼ deposit(deposit(as, u1, n1), u2, n2)
The following CafeOBJ code builds the proof tree containing all possible cases
formed by orthogonal combinations of atomic cases for the users with respect to
their membership to the user accounts data base. The basic proof term is TERM.
The automatic generation of the proof tree (RESULT ) is done by a meta-level
encoding in CafeOBJ by using its rewrite engine for one-directional construction
of the proof tree (this process uses the rewriting logic feature of CafeOBJ, hence
the use of transitions (trans) rather than equations).
mod PROOF-TREE { protecting(BEQ-ACCOUNT-SYSTEM)
ops n1 n2 : -> Nat -- arbitrary amounts for deposit
ops u u1 u1’ u2 u2’ : -> UId -- arbitrary user identifiers
op as : -> AccountSys -- arbitrary state of the account system
eq u1 in user-db(as) = true . -- first user is in the data base
eq u2 in user-db(as) = true . -- second user is in the data base
eq u1’ in user-db(as) = false . -- first user is not in the data base
eq u2’ in user-db(as) = false . -- second user is not in the data base
vars U U1 U2 : UId
op TERM : UId UId UId -> Bool -- basic proof term
trans TERM(U, U1, U2) => deposit(U1, n1, deposit(U2, n2, as)) R[U]
deposit(U2, n2, deposit(U1, n1, as)) .
op TERM1 : UId UId -> Bool
trans TERM1(U, U1) => TERM(U, U1, u2) and TERM(U, U1, u2’) .
op TERM2 : UId -> Bool
trans TERM2(U) => TERM1(U, u1) and TERM1(U, u1’) .
op RESULT : -> Bool -- final proof term
trans RESULT => TERM2(u1) and TERM2(u1’) and TERM2(u) . }
References
1. Goguen, J., Diaconescu, R.: Towards an algebraic semantics for the object para-
digm. In Ehrig, H., Orejas, F., eds.: Recent Trends in Data Type Specification.
Volume 785 of Lecture Notes in Computer Science., Springer (1994) 1–34
2. Diaconescu, R., Futatsugi, K.: Behavioural coherence in object-oriented algebraic
specification. Universal Computer Science 6 (2000) 74–96 First version appeared
as JAIST Technical Report IS-RR-98-0017F, June 1998.
3. Hennicker, R., Bidoit, M.: Observational logic. In Haeberer, A.M., ed.: Algebraic
Methodology and Software Technology. Number 1584 in LNCS, Springer (1999)
263–277 Proc. AMAST’99.
4. Goguen, J., Roşu, G.: Hiding more of hidden algebra. In Wing, J.M., Woodcock,
J., Davies, J., eds.: FM’99 – Formal Methods. Volume 1709 of Lecture Notes in
Computer Science., Springer (1999) 1704–1719
5. Diaconescu, R., Futatsugi, K.: CafeOBJ Report: The Language, Proof Tech-
niques, and Methodologies for Object-Oriented Algebraic Specification. Volume 6
of AMAST Series in Computing. World Scientific (1998)
6. Diaconescu, R., Futatsugi, K.: Logical foundations of CafeOBJ. Theoretical Com-
puter Science 285 (2002) 289–318
7. Iida, S., Futatsugi, K., Diaconescu, R.: Component-based algebraic specification:
- behavioural specification for component-based software engineering -. In: Behav-
ioral specifications of businesses and systems. Kluwer (1999) 103–119
8. Diaconescu, R., Futatsugi, K., Iida, S.: Component-based algebraic specification
and verification in CafeOBJ. In Wing, J.M., Woodcock, J., Davies, J., eds.: FM’99
– Formal Methods. Volume 1709 of Lecture Notes in Computer Science., Springer
(1999) 1644–1663
9. Astesiano, E., Bidoit, M., Kirchner, H., Krieg-Brückner, B., Mosses, P., Sannella,
D., Tarlecki, A.: CASL: The common algebraic specification language. Theoretical
Computer Science 286 (2002) 153–196
10. Meseguer, J.: A logical theory of concurrent objects and its realization in the
Maude language. In Agha, G., Wegner, P., Yonezawa, A., eds.: Research Directions
in Concurrent Object-Oriented Programming. The MIT Press (1993)
156 R. Diaconescu
11. Iida, S., Futatsugi, K., Diaconescu, R.: Component-based algebraic specifications:
- behavioural specification for component based software engineering -. In: 7th
OOPSLA Workshop on Behavioral Semantics of OO Business and System Spec-
ification. (1998) 167–182 Also in the technical report of Technical University of
Munich TUM-I9820.
12. Burstall, R., Diaconescu, R.: Hiding and behaviour: an institutional approach. In
Roscoe, A.W., ed.: A Classical Mind: Essays in Honour of C.A.R. Hoare. Prentice-
Hall (1994) 75–92 Also in Technical Report ECS-LFCS-8892-253, Laboratory for
Foundations of Computer Science, University of Edinburgh, 1992.
13. Reichel, H.: An approach to object semantics based on terminal co-algebras. Math-
ematical Structures in Computer Science 5 (1995) 129–152
14. Goguen, J., Winkler, T., Meseguer, J., Futatsugi, K., Jouannaud, J.P.: Introducing
OBJ. In Goguen, J., Malcolm, G., eds.: Software Engineering with OBJ: algebraic
specification in action. Kluwer (2000)
Consistency Management Within Model-Based
Object-Oriented Development of Components
1 Introduction
A model-based approach to the development of component-based systems fa-
vors the construction of models prior to the coding of components. Benefits of
such an approach are the ability to study properties of the system early in the
development process on the model level and the idea that components can be
deployed more easily to different target platforms.
Currently, the Unified Modeling Language [27] is the de-facto industrial stan-
dard for object-oriented modeling of components. In the UML a model is
composedof several submodels for modeling the system at differentlevels of abstrac-
tion and from different viewpoints. As the UML language specification does not
sufficiently define consistency of UML models, inconsistent UML models can be
constructed. This may lead to a situation where no common implementation con-
forming to all submodels exists. Further, with the UML being applied in diverse
F.S. de Boer et al. (Eds.): FMCO 2003, LNCS 3188, pp. 157–176, 2004.
c Springer-Verlag Berlin Heidelberg 2004
158 J.M. Küster and G. Engels
2.1 Consistency
The use of models consisting of different submodels within software development
has numerous advantages. Different persons may work on different submodels
simultaneously driving forward the development of the system. Different types
of submodels allow the separation of different aspects of the system to be built
such as structural aspects or dynamic behavior of system components.
However, making use of different submodels also involves drawbacks. In a
traditional approach, there exists only one model of the system. This model
can then be transformed during coding into a running software product. In the
case of a collection of submodels, this is not as easy anymore because one needs
to describe which submodel is transformed into which part of the code. This
gives rise to the problem of different parts of the code not working together as
one wishes leading to a system not functioning. In order not to run into such
problems, it has to be ensured that different submodels are compatible with each
other or consistent on the model level.
Different submodels of a model are usually called consistent if they can be
integrated into a single model with a well-defined semantics. The required form
of integration is dependent on the type of models, the modeling process and
the application domain. One important aspect of consistency is to ensure the
existence of an implementation conforming to all submodels. If consistency of a
model is ensured, an implementation of submodels is obtained by implementing
the integrated model. Otherwise, such an integrated model and implementation
might not exist.
Technically, consistency of a model is defined by establishing a set of con-
sistency conditions. A consistency condition is a predicate that defines whether
or not a model is consistent with respect to this consistency condition. We can
distinguish between consistency conditions defined on the syntax and on the se-
mantics of models, leading to syntactic and semantic consistency conditions. In
case of defining consistency conditions on the semantics of models, typically also
a semantic mapping is required. This can be the semantic mapping of the mod-
eling language definition but can also involve an abstraction of this semantics.
Different related consistency conditions can be grouped to form a consistency
concept. Such a consistency concept consists of a set of syntactic and semantic
consistency conditions and a semantic mapping of each submodel type into a
common semantic domain if applicable. The definition of a consistency concept
is illustrated in Figure 1. Mappings of submodel types are called mi in the
figure, consistency conditions are called ci . As a consistency concept consists of
a semantic mapping into a common semantic domain and conditions specified
160 J.M. Küster and G. Engels
Consistency Concept
Partial mappings
Submodel m1
Type 1
… Semantic Domain
mn
Submodel
Type n
Consistency conditions
c1 … cm
on the syntax and within the semantic domain, a consistency concept can be
viewed as a sort of integration of submodels.
Within our approach, we can define different consistency concepts for a mod-
eling language. As a consequence, a model can be consistent with respect to one
consistency concept but inconsistent with respect to another consistency con-
cept. This is motivated by different application domains, development processes
and platforms a modeling language can be applied to and in contrast to the idea
that a modeling language comes with pre-defined consistency concepts in the
language specification.
The motivation that gives rise to defining a consistency concept is called a
consistency property. Such a consistency property is a model-independent de-
scription of a property that a model should have. A consistency property can
be informally characterized by stating what it ensures i. e. what characteristics
a model must have that conforms to the consistency property. Examples for
consistency properties include syntactic correctness, trace consistency or timing
consistency.
On the basis of consistency properties and consistency concepts, we can define
consistency checks. A consistency check is a description how, given a model
and a consistency condition, to decide whether or not the model fulfills the
consistency condition. As a consequence, consistency checks can be thought of
definining the fulfillment relation between a model and a consistency condition.
Consistency checks can be performed using theorem proving, model checking [5]
or by executing specialized algorithms [6].
Given a consistency condition and a concrete model, we can identify those
submodel types of the larger model that lead to the inconsistency. This allows
the distinction between consistency problem types and consistency problem in-
stances: A consistency problem type is a configuration of submodel types that
may give rise to the violation of a consistency condition. On the contrary, a
consistency problem instance is a configuration of submodels such that each
submodel corresponds to a submodel type of a given consistency problem type
violating the consistency condition. This distinction between consistency prob-
Consistency Management Within Development of Components 161
Consistency Checks
Consistency Concepts
Consistency Consistency Consistency
Concept 1 Concept 2
… Concept n
Consistency Properties
Syntactic Deadlock Timing Process
Implementability
Correctness Freedom Consistency Properties
lem type and instance is similar to the type-instance notions commonly known
from object-orientation. Note that a consistency concept can also be thought of
as one solution of a consistency problem type.
In this section, we have introduced a generic definition of consistency. The
terms in our definition of consistency lead to a layered approach to consistency,
illustrated in Figure 2. Given a modeling language, in the property layer, dif-
ferent properties exist that drive the definition of the consistency concept. A
consistency concept comprises a number of consistency conditions and a seman-
tic domain (not shown in the figure but cf. Figure 1). Once the conditions are
determined, consistency checks are defined which verify or validate a consistency
condition.
constituent layer
Consistency Checks
Consistency Concepts
Consistency Properties
tency management process. Note that we distinguish between such a specific con-
sistency management approach and the overall field of consistency management.
exists. This approach requires the existence of a formal semantics for models
and the concept of development relations defined for models used within the
development process.
Another, quite different, category of related work can be seen in approaches
that deal with inconsistency management [26] [17]. Rather then trying to achieve
complete consistency, these approaches tackle the problem of managing incon-
sistencies. This management is based on the location of inconsistencies and the
appropriate handling (resolving of inconsistency or tolerating it). Concentrating
on the process of consistency management, they assume that the foundation of
consistency management in terms of consistency conditions is already in place.
From our discussion of related work we can see that our generic definition
of consistency is applicable: In the first category, we are dealing with quite
different semantic domains such as systems of linear inequalities or the set of
instance graphs. In the second category, semantic domains used are LOTOS
or transformation systems and in the third category first-order logic is used
as semantic domain. On the contrary to existing approaches, we concentrate
on the technical mechanisms that are used to define consistency in different
scenarios. This will enable us to describe a general methodology how to deal with
consistency in a situation as currently encountered by the UML: consistency
is not defined as part of the standard and further, quite different consistency
concepts are needed depending on the development context. Before we move on
to our methodology, we will first discuss characteristics of consistency problems.
In the following section, we present an approach to consistency management
based on the idea of partially formalizing the model for enabling consistency
checks. As a consequence, our approach can be regarded as a combination of the
approaches in the first and the second category. As our approach also comprises
the idea of consistency management within a development process, it is also
related to the fourth category although the idea of tolerating inconsistencies is
not in focus.
Consistency Concept
Submodel m
Type Semantic
Domain
a b
Consistency Conditions …
c1 ck
Consistency Concept
Submodel m1
Type 1
Semantic
Submodel m2
Domain
a Type 2
b
Consistency Conditions c1 … cl
Consistency
Management
Consistency Management Approach
Consistency
Management
Methodology Consistency Management Process
defines
Consistency Checks
Activities
Consistency Concept
Techniques
Consistency Properties
p1 <<connector>> p2
con
caps1 caps2
SC1_p1 SC2_p2
Simple
collaboration SC2
SC1
s1 s4
s4 s1
/send b /send d
d b SCProt
/send c s2 s3
s3 s2 s1 c
SC2_p2.b
s2
SC1_p1.c
s4 s3
SC2_p2.d
4 Application
In this section, we sketch the application of our methodology to a sample con-
sistency problem type.
In Figure 6, two structured objects caps1 and caps2 are shown, joined by a
connector via two ports p1 and p2 . Attached to this connector is a collabora-
tion with its behavior modeled in the protocol statechart SCP rot . The behavior
of the structured objects is specified in two statecharts, named SC1 and SC2 .
Intuitively, the interaction arising from executing the statecharts of the struc-
tured objects should conform to the protocol specified in the protocol statechart.
Activity 1 of the methodology will yield as outcome that there exists a consis-
tency problem type in this case (called protocol consistency), together with the
informal consistency condition formulated above.
Activity 2 aims at constructing a formal consistency concept. In this case, we
will choose CSP [21] as a semantic domain. The formal method CSP is supported
by the model checker FDR [14] for evaluating consistency conditions formulated
in CSP. We then have to define partial mappings of the statecharts and the
protocol statechart into the semantic domain of CSP. In other words, the consis-
tency concept consists of the submodel types protocol statechart, the statechart
of structured objects and the collaboration, mappings of these submodel types
170 J.M. Küster and G. Engels
LS LT ::= RT
:StateMachine +top
ε::= <SMName>(state,static) =
name = <SMName> act_<SMName> →
:CompositeState
if (state == <SName_1>) then
p1 +subvertex State(<SName_1>,static)
else …
if (state == final) then
:SimpleState FinalState(<SMName>)
name = {<SName_1>,…,<SName_n>} else STOP
State(<SName>,static)::=
:State
<Event_1>?x_<Event_1> →
name = {<Target_1>, ..., <Target_n>} ..
<Event_n>?x_<Event_n> →
+target
+outgoing
if (x_<Event_1> == 1) then
p2 :SimpleState ExitAction(<SName>) →
name = <SName> :Transition
:Transition
Transition(<SName>, <Target_1>)
else ..
if (x_<Event_n> == 1) then
ExitAction(<SName>) →
+trigger
Transition(<SName>, <Target_n>)
:Event
else
StaticReaction(<SName>)
name = {<Event_1>, ..., <Event_n>}
into CSP and a set of consistency conditions formalizing the informally noted
form of consistency.
For the consistency problem of protocol consistency, we can define two dif-
ferent consistency conditions: For weak protocol consistency we require that all
traces of the interaction of the structured object statecharts must be contained
in the set of traces of the protocol statechart. For strong protocol consistency
we additionally assume that all the traces of the protocol statechart must occur
in the system. Extending the statechart SC1 by introducing another transition
sending another event will violate the condition of weak protocol consistency.
Removing the last transition of SC2 will violate the condition of strong protocol
consistency. In previous work (e.g. [22]), we have reported on the details of such
a consistency concept which are beyond the scope of this work.
Activity 3 aims at making the consistency concept operational. In our case,
the partial translations of the submodel types must be defined in such a way that
they are executable automatically. We have recently explored a graph transfor-
mation approach [19] [8] [23] which allows the translation to be specified by a set
of compound graph transformation rules. In our case, such a compound graph
transformation rule consists of two parts, a source production rule specified by a
UML metamodel extract and a target production rule in the semantic formalism,
here CSP. As we do not want to change the source model, the source production
is the identical production, with equal left and right side. In Figure 7, two com-
Consistency Management Within Development of Components 171
pound graph transformation rules are shown for translating statecharts to CSP,
inspired by existing work of Hiemer [20].
Graph transformation rules of this form can then be used to specify a model
transformation from a given source UML model to a target CSP model. The
semantics of rule applications is briefly described as follows: Given a concrete
UML model, a match for the UML metamodel extract is searched for in the
concrete UML model. Once such a match is found, a match of the left side of
the target production is searched for in the CSP model. Once the two matches
have been found, the match of the CSP model is replaced by the right side of
the target production. Note that using these kind of graph transformation rules,
no additional specification language for describing the transformation is needed:
Each rule is basically expressed in terms of the source and target language, in
our case in UML and CSP, enriched with mechanisms for c3ommon variables and
placeholders. A detailed explanation of this model transformation approach can
be found in [19] and [8]. The problem of ensuring termination and confluence of
such rule-based transformations is treated in [23]. For this activity, also related
model transformation approaches such as the one by Whittle [30] or Varro et al.
[29] could be used.
In Activity 4, the consistency check must be defined, on the basis of the
previously developed transformation units. Typically, such a consistency check
can be specified by using activity diagram for modeling the overall workflow.
Such an activity diagram will define for example that given a situation like in
Figure 6, first the statecharts of the structured objects are translated to CSP
and then the protocol statechart. The overall result will then be fed into a model
checker and the result will be interpreted.
On the basis of such consistency checks, an overall development process can
be modified, by introducing consistency checks. For that, the order of consistency
checks must be determined and also how inconsistency handling influences the
overall consistency of a model. The details of these tasks are defined in Activity
5. In our sample application we have not described a development process but
concentrated on one consistency problem. For a more detailed example of this
activity, the reader is referred to [22].
6 Conclusion
In this paper, we have presented our approach to consistency management of
object-oriented models. Motivated by the situation that currently a general ap-
174 J.M. Küster and G. Engels
proach for consistency management is not provided by the UML, we have first
introduced the concepts for consistency management such as consistency condi-
tion, consistency concept, consistency check and consistency management. Using
this thorough investigation of consistency, we have explained how our general
methodology builds a consistency management approach, depending on the mod-
eling language, application domain and development process. Activities of this
methodology have been discussed. The overall methodology has been demon-
strated by applying it to an example consistency problem type and sketching
the outcome of each activity. Finally, we have reported on the tool Consistency
Workbench which is a research prototype designed for supporting the software
engineer in the complex task of consistency management. Due to the nature of
this paper being a summary and overview paper, we have not been able to pro-
vide the full details of all activities. For that the reader is referred to the existing
publications.
Future work can be performed into several directions: With regards to our
general methodology, by applying it to real-world development processes, it can
be validated and refined. Furthermore, more consistency problems occuring in
UML-based development will be discovered and treated which will lead to a
number of predefined model transformations. Further, also suitable abstraction
mechanisms must be developed. In the context of our work, it has turned out
that this issue is vital for being able to perform consistency checking on larger,
real-world models. This is due to the underlying approach of model checking
which suffers from the well-known state explosion problem. With regards to tool
support, we envisage that our consistency workbench could be integrated into
an existing CASE tool.
References
1. M. Boger, T. Sturm, E. Schildhauer, and E. Graham. Poseidon for UML Users
Guide. Gentleware AG, 2003. Available under http://www.gentleware.com.
2. E. Boiten, H. Bowman, J. Derrick, P. Linington, and M. Steen. Viewpoint Consis-
tency in ODP. Computer Networks, 34(3):503–537, August 2000.
3. E. Boiten, H. Bowman, J. Derrick, and M. Steen. Viewpoint consistency in Z
and LOTOS: A case study. In J. Fitzgerald, C. B. Jones, and P. Lucas, editors,
FME’97: Industrial Applications and Strengthened Foundations of Formal Methods
(Proc. 4th Intl. Symposium of Formal Methods Europe, Graz, Austria, September
1997), volume 1313 of Lecture Notes in Computer Science, pages 644–664. Springer-
Verlag, Heidelberg, September 1997.
4. B. Cheng, L. Campbell, and E. Wang. Enabling Automated Analysis Through
the Formalization of Object-Oriented Modeling Diagrams. In Proceedings of IEEE
International Conference on Dependable Systems and Networks, pages 433–442.
IEEE Computer Society, 2000.
5. E. M. Clarke, O. Grumberg, and D. A. Peled. Model Checking. The MIT Press,
Cambridge, MA, 1999.
6. A. Egyed. Heterogenous View Integration and its Automation. Dissertation, Uni-
versity of Southern California, 2000.
Consistency Management Within Development of Components 175
1 2
José Luiz Fiadeiro and Antónia Lopes
1
Department of Computer Science, University of Leicester
University Road, Leicester LE1 7RH, UK
jose@fiadeiro.org
2
Department of Informatics, Faculty of Sciences, University of Lisbon
Campo Grande, 1749-016 Lisboa, PORTUGAL
mal@di.fc.ul.pt
1 Introduction
F.S. de Boer et al. (Eds.): FMCO 2003, LNCS 3188, pp. 177–196, 2004.
© Springer-Verlag Berlin Heidelberg 2004
178 J.L. Fiadeiro and A. Lopes
CommUnity is a parallel program design language that is similar to Unity [6] and IP
[10] in its computational model but adopts a different coordination model. More
concretely, whereas, in Unity, the interaction between a program and its environment
relies on the sharing of memory, CommUnity relies on the sharing (synchronisation)
of actions and exchange of data through input and output channels.
To illustrate the way components can be designed in CommUnity, and provide a
fair idea of the range of situations that our approach can address, we use a variation of
a problem that we previously developed in [3,19] – a typical airport luggage delivery
system in which carts move along a track and stop at designated stations for handling
luggage.
In order to illustrate how incremental development is supported in CommUnity, we
start with a very high-level design of a cart:
design Cart is
prv busy:bool
do move[]: ¬busy, false → true
dock[busy]: ¬busy, false → busy’
undock[busy]: busy, false → ¬busy’
This design caters for the very basic description that we gave of a cart’s behaviour:
the fact that it can move and stop at stations to handle luggage. In CommUnity, com-
ponents are designed having in mind the interactions that they can establish with other
components in terms of exchanging data through communication channels and syn-
chronising to perform joint actions. The design above does not mention any public
channels because, at this stage, we have not identified any need for the cart to ex-
change data with its environment. However, the cart needs to keep some internal data
to know when it is parked at a station; this is modelled by the private channel busy.
We call it channel because it can be used to exchange information between different
components inside the cart, but we make it private to hide it from the environment.
The actions that a component can perform are declared under “do” and their speci-
fication takes the general form:
g[D(g)]: L(g), U(g) → R(g)
where
• D(g) consists of the local channels into which executions of the action can place
values. This is normally called the write frame of g. We omit this set when it can
be inferred from the assignments in R(g). Given a private or output channel v, we
will also denote by D(v) the set of actions g such that v僆D(g). Hence, above,
180 J.L. Fiadeiro and A. Lopes
move has an empty write frame and busy is in the write frames of dock and un-
dock.
• L(g) and U(g) are two conditions that establish the interval in which the enabling
condition of any guarded command that implements g must lie: the lower bound
L(g) is implied by the enabling condition, and the upper bound U(g) implies the
enabling condition. Hence, the enabling condition of g is fully determined only if
L(g) and U(g) are equivalent, in which case we write only one condition. From a
specification point of view, U(g) allows us to place requirements on the states in
which the action should be enabled (progress) and L(g) allows us to restrict the
occurrence of the action to given sets of states (safety). By setting U to false, as
in the examples above, we are not making any requirements as to when we want
the actions to be enabled; this is useful for being able to add requirements in an
incremental way as illustrate below. For instance, restrictions on how a cart can
move will certainly arise when taking into consideration other aspects of the sys-
tem. On the other hand, each of the three actions was given a safety guard, basi-
cally ensuring that carts do not move while docked at a station for handling lug-
gage.
• R(g) is a condition that uses primed channels to account for references to the val-
ues that the channels take after the execution of the action. This is usually a con-
junction of implications of the form pre ⊃ pos where pre does not involve primed
channels. Each such implication corresponds to a pre/post-condition specification
in the sense of Hoare. When R(g) is such that the primed channels are fully de-
termined, we obtain a conditional multiple assignment, in which case we can use
the notation that is normally found in programming languages (||v僆D(g) v:=F(g,v)).
Hence, we could have used busy:=true for R(dock) and busy:=false for
R(undock). When the write frame D(g) is empty, R(g) is tautological. This is the
case of move.
A CommUnity design is called a program when, for every g僆Γ, L(g) and U(g) co-
incide, and the relation R(g) defines a conditional multiple assignment. The behav-
iour of a program is as follows. At each execution step, any of the actions whose
enabling condition holds can be executed if requested, in which case its assignments
are performed atomically.
Actions can also be declared to be private, a situation not illustrated above, mean-
ing that they cannot be shared with the environment of the component. Private ac-
tions that are infinitely often enabled are guaranteed to be selected for execution infi-
nitely often. A model-theoretic semantics of CommUnity can be found in [15].
The design that we gave above does not take into account the fact that the cart can
only dock when it reaches the station to which it has been sent, nor does it model the
way a cart comes to know about its destination. The design below refines the previ-
ous one with this kind of information:
CommUnity on the Move: Architectures for Distribution and Mobility 181
This design uses new primitives, some of which relate to the way we handle the
notions of location, distribution and mobility. In CommUnity, the underlying “space
of mobility” is constituted by the set of possible values of a special data type with a
designated sort Loc and whatever operations are necessary to characterise locations,
for instance hierarchies or taxonomies. The only requirement that we make is for a
special position –⊥– to be distinguished; its role will be discussed further below.
By not adopting a fixed notion of location, CommUnity can remain independent of
any specific notion of space and, hence, be used for designing systems with different
kinds of mobility. For instance, for physical mobility, the space is, typically, the
surface of the earth, represented through a set of GPS coordinates, but it may also be a
portion of a train track represented through an interval of integers. In other kinds of
logical mobility, space is formed by IP addresses. Other notions of space can be
modelled, namely multidimensional spaces, allowing us to accommodate richer per-
spectives on mobility. For instance, in order to combine logical mobility with secu-
rity concerns, it is useful to consider locations that incorporate information about
administrative domains.
CommUnity designs are made location-aware by associating their “constituents”
— code and data — with “containers” that can move to different positions. Designs
are not located: they can address components that are distributed across different
locations. Hence, the unit of mobility, i.e., the smallest constituent of a system that is
allowed to move, is fine-grained and different from the unit of execution.
More precisely, location-awareness comes about in CommUnity designs as fol-
lows:
• Location variables, or locations for short, can be declared as “containers” that can
be moved to different positions. Locations can be input or output. Input locations,
declared under inloc, are controlled by the environment and cannot be modified by
the component. Hence, the movement of any constituent located at an input loca-
tion is operated by the environment. Output locations, declared under outloc, can
only be modified locally through assignments performed within actions and,
hence, the movement of any constituent located at an output location is under
the control of the component. In the case above, we declared only one location
– pos – because the cart is not a distributed component. This location is declared
as input because we want other components to be able to control the movement of
the cart.
• Each local channel x is associated with a location variable l. We make this as-
signment explicit by simply writing x@l in the declaration of x. The intuition is
that the value of l indicates the current position of the space where the values of x
are made available. A modification in the value of l entails the movement of x as
182 J.L. Fiadeiro and A. Lopes
well as of the other channels and actions located at l. Because the cart is not dis-
tributed, busy has no choice but to be located at pos.
• Every action g is associated with a set of location variables Λ(g) meaning that the
execution of action g is distributed over those locations. In other words, the exe-
cution of g consists of the synchronous execution of a guarded command in each
of these locations: given l僆Λ(g), g@l is the guarded command that g executes at l.
Again, because carts are not distributed, all the actions are located at pos.
Notice that guarded commands may now include assignments involving the read-
ing or writing of location variables. This is the case of the actions of the cart: they
were refined in order to make use of locations. More precisely, we have now re-
stricted the enabling of move to the situation in which the cart has not reached its
destination, and dock and undock to when the cart is at its destination.
The destination of the cart is kept in a private channel dest and updated before
leaving the station by reading it from an input channel next. Input channels are used
for reading data from the environment; the component has no control on the values
that are made available in such channels. Notice that reading a value at a channel
does not consume it: the value will remain available until it is changed by the envi-
ronment.
Input channels are assigned a distinguished output location – λ – usually omitted in
designs. This location has the special value ⊥ that is used whenever one wants to
make no commitment as to the location of a channel or action. For instance, input
channels are always located at λ because the values that they carry are provided by
the environment in a way that is location-transparent; their location is determined at
configuration time when they are connected to output channels of other components.
Actions uniquely located at λ model activities for which no commitments with re-
spect to location-awareness have been mad. The reference to λ in these cases is usu-
ally omitted. This is what happened with our first design: all its constituents were
assumed to be located at λ. In later stages of the development process, the execution
of such actions can be distributed over several locations, i.e. the guarded command
associated with g@λ can be split in several guarded commands associated with lo-
cated actions of the form g@l, where l is a proper location. Whenever the command
associated with g@λ has been fully distributed over a given set of locations in the
sense that all its guards and effects have been accounted for, the reference to g@λ is
usually omitted. In the second design, we made location-awareness more explicit and
introduced references to specific location variables. However, distribution was not
illustrated. This will be done below.
In order to illustrate how CommUnity can handle distribution, consider the situation
in which a cart can move in two different modes: slow and fast. More specifically, by
default, a cart will move in fast mode. However, control points may be placed dy-
namically along the track to slow down the cart: when the cart comes in the proximity
CommUnity on the Move: Architectures for Distribution and Mobility 183
of a control point, it changes to slow mode and, before it leaves the restricted area, it
goes back to fast mode.
design Controlled Located Cart is
outloc pos:Loc
inloc cpoint:Loc
in next:Loc
prv busy@pos, in@cpoint:bool, dest@pos:Loc, mode@pos:[slow,fast]
do move[pos]@pos:
¬busy∧pos≠dest, false → pos:=controlled(mode,pos)
prv enter[mode,in]
@pos: true → mode:=slow
@cpoint: ¬in → in:=true
prv leave[mode,in]
@pos: true → mode:=fast
@cpoint: in → in:=false
dock[busy]@pos: ¬busy∧pos=dest, false → busy:=true
undock[busy,dest]@pos:
busy∧pos=dest, false → busy:=false || dest:=next
This design introduces a new location cpoint accounting for a control point; this
location is declared to be input because we are leaving to the environment to
(re)distribute the control points along the track. However, the position pos of the cart
has now become output because it became under the control of the extended compo-
nent (subsystem).
A private channel in is located at the control point to indicate when a cart enters its
proximity, which is controlled by the action enter. This action is distributed between
the control point, where it updates in, and the cart, where it changes the mode to slow.
The action leave operates the other way around. Both actions are declared to be pri-
vate and their components are designed with a fully determined enabling condition
because their execution is completely under the control of the component.
The execution of a distributed action requires that the locations involved be “in-
touch” so that one can ensure that they are executed as a single transaction. For in-
stance, the physical links that support communication between the positions of the
space of mobility (e.g. wired networks, or wireless communications through infrared
or radio links) may be subject to failures or interruptions, making communication
temporarily impossible. Formally, we rely on a set bt(l) for every location l that, at
any given moment of time, consists of the locations that are “in touch” with l. Hence,
for any action g and any locations l1,l2 to which it is distributed, g can only be exe-
cuted if l1僆bt(l2) and l2僆bt(l1). In the case of the cart, this means that enter and
leave actions can only take place when the cart is in the proximity of the control point.
Notice that the action move is now making explicit that the next position is calcu-
lated from the current one taking the mode into account. The function controlled that
is being used will need to be defined, at specification time, on the representation cho-
sen for the tracks. However, because move implies calculating a new position, an
important condition applies: it can only be executed if the new position can be
reached from the current one.
Typically, the space of mobility has some structure, which can be given by walls
and doors, barriers erected in communication networks by system administrators, or
the simple fact that not every position of the space has a host where code can be exe-
184 J.L. Fiadeiro and A. Lopes
cuted. This structure can change over time. Hence, it is not realistic to imagine that
entities can migrate from any point to any point at any time without restrictions.
Formally, we rely, for every location l, on a set reach(l) consisting, at any given in-
stant of time, of the locations that can be reached from l. Hence, for any located ac-
tion g@l, if a location l1 can be affected by the execution of g@l, then the new value
of l1 must be a position reachable from l. In the case of the cart, this means that move
can only be executed if controlled returns a position that is reachable from the current
one – e.g. no other cart is in between.
Simpler modes of the movement of the cart could be envisioned, for instance
design Step Located Cart is
outloc pos:Loc
in next:Loc
prv busy@pos:bool, dest@pos:Loc
do move[pos]@pos: ¬busy∧pos≠dest, false → pos:=inc(pos)
dock[busy]@pos: ¬busy∧pos=dest, false → busy:=true
undock[busy,dest]@pos:
busy∧pos=dest, false → busy:=false || dest:=next
In this case, we are relying on a simpler increment function on locations that leads
the cart step by step through a path of a pre-established graph. The function itself can
define the graph. For instance, by defining Loc as nat5, two different alternative
graphs are:
0 1
1
0 2
3
4 3
4 2
Loc
and reach:2 – to be distinguished.
Σ
The purpose of rssv:nat×2 is to represent the resources and services that are avail-
able for computation. The first component of rssv quantifies the resources available.
It may be defined as a function of more specific observables in Cxt, for instance, the
remaining lifetime of a battery or the amount of memory available. In this way, it is
186 J.L. Fiadeiro and A. Lopes
possible to model the fact that the same resources may affect different applications in
different ways. The second component of rssv represents the services available and it
is taken as a part of the data signature Σ. This is because, as we have seen in the pre-
vious sections, the services that perform the computations are abstracted as operations
on data elements. In this paper, we will not illustrate this particular aspect of Com-
mUnity; see [13] instead.
Loc Loc
The intuition behind bt:2 and reach:2 is even simpler: both represent the set of
locations that are accessible. The former represents the locations that can be reached
through communication while the latter concerns reachability through movement. We
have already motivated the use of these relations in section 2.3.
We consider that such models are Cxt-indexed sets {Mobs:type}obs:type僆Cxt of infinite
sequences of functions over ULoc. Each Mobs:type is an infinite sequence of functions
that provide the value of the observable obs at every position of the space, at a par-
ticular instant of time. For the special observables rssv:nat×2 , bt:2 and reach:2 ,
Σ Loc Loc
involves the synchronisation of its local actions and, hence, their positions have
to be mutually in touch.
2. For every l僆Λ(g), g@l can be executed, i.e.,
i. If Mrssv([l] )=(n,Σ’) then, for every operation symbol f used in the guarded
i
command associated with g@l requires that every channel in its frame can be
accessed from its current position and, hence, l has to be in touch with the lo-
cations of each of these channels.
CommUnity on the Move: Architectures for Distribution and Mobility 187
iii. For every location l1僆D(g), [F(g@l,l1)] 僆Mreach ([l1] ): if a location l1 can be
i i i
effected by the execution of g@l, then the new value of l1 must be a position
reachable from the current one.
iv. The local guard L(g@l)(=U(g@l)) evaluates to true.
i
By [e] we denote the value of the expression e at time i. It is important to notice
that, because observables can be used in programs as terms, the evaluation of an ex-
pression e at time i may also depend on the model of Cxt.
Given this, the execution of the action consists of the transactional execution of its
guarded commands at their locations, which requires the atomic execution of the
multiple assignments. Private actions are subject to a fairness requirement: if infi-
nitely often enabled, they are guaranteed to be selected infinitely often.
Section 2 illustrated several of the primitives provided in CommUnity for the design
of distributed and mobile components. It did so through an incremental process of
addition of detail to an initial, abstract account of the behaviour of a cart. CommmU-
nity does not prescribe any specific method of incremental development. Instead, it
provides the ability for different concerns to be modelled independently and super-
posed dynamically over the configuration of a system to account for new design deci-
sions.
For instance, if we consider the addition of the distribution/mobility aspects in sec-
tion 2.3, it is clear that the behaviour of the cart at the stations is not concerned.
Moreover, it should be possible to capture these aspects as an architectural element
(connector) that is being plugged to control the movement of cart. Changing from the
fast/slow control to the step-by-step mode should be just a matter of unplugging a
connector and plugging a new one; it should not require the cart to be re-designed or
re-implemented.
Another example can be given as follows. Consider that we now need to monitor
the number of times a cart docks at a station. It seems clear that we should be able
to:
• Address this issue independently of the way the movement of the cart is being
controlled, i.e. regardless of whether we are monitoring a step or a controlled lo-
cated cart.
• Separate the “logic” of monitoring from the location in which the data that is
required is provided, i.e. address interaction separately from the location as-
pects.
In this section, we address these issues in two steps. First, we illustrate how con-
nectors can be externalised from components. Then, we address the separate model-
ling of coordination and distribution.
188 J.L. Fiadeiro and A. Lopes
Consider again the controlled located cart and the way it was obtained from the lo-
cated cart. The following design attempts at externalising the extension that was
performed.
design Mode controller is
inloc mine:Loc
outloc theirs:Loc
prv in@mine:bool, mode@theirs:[slow,fast]
do control[theirs]@theirs: true → theirs:=controlled(mode,theirs)
prv enter[mode,in]
@theirs: true → mode:=slow
@mine: ¬in → in:=true
prv leave[mode,in]
@theirs: true → mode:=fast
@mine: in → in:=false
This design contains more than just what was added to the located cart; it repeats
the elements that are necessary for this extension to be autonomous as a design. This
is why it includes both the location of the cart and the action of the cart that is being
controlled. Notice, however, that the action control is always enabled; the idea, as
detailed below, is that restrictions on its occurrence are left to the component being
controlled.
We deliberately changed the names of some of the design elements to highlight the
fact that we want this mode controller to exist, as a design, independently of the lo-
cated cart. However, this renaming is not necessary because it is automatically en-
forced in Category Theory [8], which is the mathematical framework in which we
give semantics to our interconnection mechanisms. As far as we are concerned, this
mode controller could even pre-exist the located cart as part of a library of connectors
that a software architect uses for designing a system. What we need to say is how it
can be applied to a component like a located car.
CommUnity supports the design of interactions through configurations; these are
diagrams that exhibit interconnections between designs. For instance, a located cart
under the control of a mode controller is specified by the following configuration:
dock undock
Mode
Located cart controller
next mine
pos theirs
move control
superposition that are typical in parallel program design [6,10,12]. The semantics of
such a diagram is given by its colimit [8], which can be informally explained as the
design of the system viewed as a single, distributed component:
• Connected locations are amalgamated; input locations can be connected with in-
put connections, in which case their amalgamation is an input location, our with
output locations, in which case their amalgamation is an output location; output
locations cannot be connected with output locations.
• The same rule applies to channels; only channels carrying the same type of data
can be connected.
• Connected actions give rise to joint distributed actions; every set {g1,…,gn} of ac-
tions that are synchronised is represented by a single action g1||…||gn whose occur-
rence captures the joint execution of the actions in the set. The transformations
performed by the joint action are distributed over the locations of the synchro-
nised actions. Each located action g1||…||gn@l is specified by the conjunction of
the specifications of the local effects of each of the synchronised actions gi that is
distributed over l, and the guards of joint actions are also obtained through the
conjunction of the guards specified by the components.
We must call attention to the fact that elements (locations, channels and actions)
that have the same name in different designs but are not connected need to be re-
named. This is because there can be no implicit interconnection between designs
resulting from accidental naming of locations, channels or actions. Any name binding
needs to be made explicit through a line as illustrated.
The design that we have just described is itself obtained only up to renaming; the
actual choice of names for locations, channels, and actions does not really matter as
long as all the interconnections are respected and no additional interconnections are
introduced. Hence, in the case of the cart, what we obtain from the configuration
above is a specification of the controlled located cart as given in section 2.3. Notice
in particular that the result of synchronising the action
move[pos]@pos: ¬busy∧pos≠dest, false → true
This is because the semantics of the composition is given by the conjunction of the
guards and of the effects of the component actions.
Summarising, we have expressed the behaviour of the controlled located cart as re-
sulting from a configuration in which the located cart is connected to a component
that controls its movement. The advantage of this representation is that, in order to
change to a step-by-step control, we just need to replace the mode controller by an-
other connector, namely
190 J.L. Fiadeiro and A. Lopes
dock undock
Step
Located cart controller
next
pos theirs
move control
σlc: L1→L2 that maps the designated location of P1 to that of P2, satisfying:
1. for every x僆X1:
(a) sort2(σch(x))=sort1(x);
(b) if x僆out(X1) then σch(x)僆out(X2);
(c) if x僆prv(X1) then σch(x)僆prv(X2);
(d) if x僆in(X1) then σch(x)僆out(X2)傼in(X2).
2. for every g僆Γ2 s.t. σac(g) is defined:
(a) if g僆sh(Γ2) then σac(g)僆sh(Γ1);
(b) if g僆prv(Γ2) then σac(g)僆prv(Γ1).
3. for every x僆X1and l僆L1
(e) σlc (λ2)={λ1}
-1
Configuration diagrams define diagrams in this category, i.e. graphs whose nodes
are labelled with CommUnity designs as defined in section 2.4, and arrows are la-
belled with morphisms as defined above. Colimits of such diagrams define the se-
mantics of configurations.
Consider now the situation described at the beginning of this section: assume that we
want to monitor how many times a cart has docked at a station. Intuitively, we should
be able to start by putting in place just the mechanisms that coordinate the interaction
between the cart and the monitor, which should not depend on the location and mobil-
ity aspects of the cart.
The interaction aspects of the monitor can be resumed to a counting function and
designed as follows:
design Counter is
out count:nat
do inc[count]: true → count:=count+1
reset[count]: true → count:=0
The counter can be connected to the original design of the cart because their inter-
action does not involve mobility explicitly:
Counter Cart
count
reset move
Notice that the synchronisations of reset with move and undock are automatically
added! This is because there is no reason to prevent the counter from being reset
while the cart is moving or undocking. Should such synchronisations be undesirable,
one would have to configure the system in a way that prevents them; the default se-
mantics is of maximum parallelism. It is important to stress that this complex design
is just providing the semantics of the configuration; it is the configuration that one
should use to develop and evolve the system, not its semantics! In order to simplify
192 J.L. Fiadeiro and A. Lopes
the presentation, we shall omit these synchronisations in the examples below and
replace them by ‘…’.
This interconnection can be extended to the located cart because the designs Cart
and Located Cart are related by a morphism as defined in 3.2. Indeed, because mor-
phisms preserve locations, channels and actions, the interconnection propagates from
the source to the target of the morphism:
Decisions on the location of the counter can now be made independently of those
made for the cart. A “minimal” decision is to consider that the location and mobility
of the counter is left to the environment:
design Counter* is
inloc where:Loc
out count@where:nat
do inc[count]@where: true → count:=count+1
reset[count]@where: true → count:=0
If one wants to place the counter in the cart, then the following configuration
should be used:
reset move
CommUnity on the Move: Architectures for Distribution and Mobility 193
Notice that the dock action is no longer distributed and combines the actions of the
cart and the counter.
If one wants to place the counter at some fixed location, the following connector
can be used:
design Fixed is
outloc stay:Loc
Notice that, because no actions are provided for changing the location of Fixed, it
cannot be moved!
reset move
We can now put together our system by combining these different connectors, for
instance a cart monitored by a fixed counter and step controller:
194 J.L. Fiadeiro and A. Lopes
reset move
control
theirs
Step
controller
This paper presented, around a typical example – a luggage handling system, how
CommUnity is being extended with primitives that support the modelling of distribu-
tion and mobility aspects at an architectural level. This extension is being pursued
within the IST-2001-32747 Project AGILE – Architectures for Mobility with two main
goals in mind:
• To provide support for the description of the mobility aspects of systems in a way
that is completely separated from the computational and coordination concerns.
• To be based on proper abstractions for modelling the part of the run-time envi-
ronment that may affect their behaviour, what is often referred as context.
This paper focused essentially on the first goal. We showed how a new class of ar-
chitectural connectors can be defined that externalise patterns and policies related to
the locations in which components perform computations and the network topology
that supports coordination. Such connectors can be superposed over location-
transparent models of components and connectors as a means of addressing the mo-
bility-based aspects that reflect the properties of the operational and communication
infrastructure without having to redesign the other dimensions.
In this respect, our work goes one step beyond what can be found in the literature
that addresses the formalisation of software architectures, e.g. [1]. In all the ap-
CommUnity on the Move: Architectures for Distribution and Mobility 195
proaches that we know, including those around Mobile Unity [17,18], the mobility
dimension is not taken as a separate and first-class aspect.
Further work is in progress in several directions.
On the one hand, we are using these results on CommUnity to make available this
level of architectural support in modelling languages like the UML. The aim is to
extend the set of coordination-based semantic primitives that we developed in the past
[2] with similar ones for distribution and mobility [4]. At the same time, we are relat-
ing architectural design in CommUnity with extensions of process languages like
KLAIM [5] that can handle distribution and mobility at a lower level of abstraction.
On the other hand, and towards the second goal mentioned above, we are further
exploring the notion of context that we only briefly mentioned in section 2.4. Con-
texts usually model these different types of resources as well as other kinds of exter-
nal factors, from the screen size of a device to the power left on a battery. Given that
different kinds of applications typically require different notions of context, it is im-
portant that formalisms for designing mobile systems consider contexts as first-class
design entities and support their explicit modelling. If a specific notion of context is
assumed as, for instance, in Ambients [7], the encoding of a different notion of con-
text can be cumbersome and entangled with other aspects, if at all possible. By ex-
tending CommUnity with the explicit modelling of a notion of context, we hope to
make it possible for such aspects to be progressively refined through the addition of
detail, without interfering with the parts of the system already designed.
Acknowledgements
This work was partially supported through the IST-2001-32747 Project AGILE –
Architectures for Mobility. We wish to thank our partners for much useful feedback.
References
1. R.Allen and D.Garlan, “A Formal Basis for Architectural Connectors”, ACM TOSEM 6(3),
213-249, 1997.
2. L.F.Andrade and J.L.Fiadeiro, “Architecture Based Evolution of Software Systems”, in
M.Bernardo and P.Inverardi (eds), Formal Methods for Software Architectures, LNCS
2804, 148-181, Springer Verlag 2003.
3. L.F.Andrade, J.L.Fiadeiro, A.Lopes and M.Wermelinger, “Architectural Techniques for
Evolving Control Systems”, in G.Tarnai and E.Schnieder (eds), Formal Methods for Rail-
way Operation and Control Systems, 61-70, L’Harmattan Press 2003
4. N.Aoumeur, J.L.Fiadeiro and C.Oliveira, “Towards an Architectural Approach to Loca-
tion-Aware Business Processes”, in Proc. 13th IEEE International Workshops on Enabling
Technologies: Infrastructures for Collaborative Enterprises (WETICE-2004), IEEE Com-
puter Society Press 2004.
5. L. Bettini, M. Loreti, and R. Pugliese “An Infrastructure Language for Open Nets”, in
Proceedings of the 2002 ACM Symposium on Applied Computing, 373-377, ACM 2002
6. K.Chandy and J.Misra, Parallel Program Design - A Foundation, Addison-Wesley 1988.
196 J.L. Fiadeiro and A. Lopes
7. L.Cardelli and A.Gordon, “Mobile Ambients”, in Nivat (ed), FOSSACS’98, LNCS 1378,
140-155, Springer-Verlag 1998.
8. J.L.Fiadeiro, Categories for Software Engineering, Springer-Verlag 2004.
9. J.L.Fiadeiro, A.Lopes and M.Wermelinger, “A Mathematical Semantics for Architectural
Connectors”, in R.Backhouse and J.Gibbons (eds), Generic Programming, LNCS 2793,
190-234, Springer-Verlag 2003.
10. N.Francez and I.Forman, Interacting Processes, Addison-Wesley 1996.
11. D.Gelernter and N.Carriero, “Coordination Languages and their Significance”,
Communications ACM 35(2), 97-107, 1992.
12. S.Katz, “A Superimposition Control Construct for Distributed Systems”, ACM TOPLAS
15(2), 337-356, 1993.
13. A.Lopes and J.L.Fiadeiro, “Adding Mobility to Software Architectures”, in A.Brogi and
J.-M.Jacquet (eds), FOCLASA 2003 – Foundations of Coordination Languages and Soft-
ware Architecture, Electronic Notes in Theoretical Computer Science. Elsevier Science, in
print.
14. A.Lopes, J.L.Fiadeiro and M.Wermelinger, “Architectural Primitives for Distribution and
Mobility”, in Proc. SIGSOFT 2002/FSE-10, 41-50, ACM Press 2002.
15. A.Lopes and J. L. Fiadeiro, “Using Explicit State to Describe Architectures”, in
E.Astesiano (ed), FASE’99, LNCS 1577, 144–160, Springer-Verlag 1999.
16. D.Perry and A.Wolf, “Foundations for the Study of Software Architectures”, ACM SIG-
SOFT Software Engineering Notes 17(4), 40-52, 1992.
17. G.Picco, G.-C.Roman and P.McCann, “Expressing Code Mobility in Mobile Unity”, in
M.Jazayeri and H.Schauer (eds), Proc. 6th ESEC, LNCS 1301, 500-518, Springer-Verlag
1998.
18. G.-C.Roman, A.L.Murphy and G.P.Picco, “Coordination and Mobility”, in A.Omicini et al
(eds), Coordination of Internet Designs: Models, Techniques, and Applications, 253-273,
Springer-Verlag 2001.
19. M.Wermelinger and J.Fiadeiro, “Connectors for Mobile Programs”, IEEE Transactions on
Software Engineering 24(5), 331-341, 1998.
TulaFale: A Security Tool for Web Services
F.S. de Boer et al. (Eds.): FMCO 2003, LNCS 3188, pp. 197–222, 2004.
c Springer-Verlag Berlin Heidelberg 2004
198 K. Bhargavan et al.
all communication paths, and thus can alter or copy parts of messages, replay
messages, or emit false material” [NS78]. XML rewriting attacks are included
in the WS–I threat model [DHK+ 04]. We have found a variety of replay and
impersonation attacks in practice.
The begin- and end-events define our authentication and correlation goals: for
every end-event with a particular label, there is a preceding begin-event with the
same label in any run of the system, even in the presence of an active attacker.
Such goals are known as one-to-many correspondences [WL93] or non-injective
agreements [Low97]. The C1 events specify authentication of the request, while
the C2 events specify authentication of the response. By including data from the
request, C2 events also specify correlation of the request and response.
Like most message sequence notations, Fig. 2 simply illustrates a typical
protocol run, and is not in itself an adequate specification. In Sections 4 and 6 we
present a formal specification in TulaFale: we define the principals Client(kr,U)
and Server(sx,cert,S) as parametric processes, and we define the checks isMsg1
and isMsg2 as predicates on our model of XML with symbolic cryptography. The
formal model clarifies the following points, which are left implicit in the figure:
TulaFale: A Security Tool for Web Services 203
– The client can arbitrarily choose which service S to call, and which data
t1 and b1 to send. (In the formal model, we typically make such arbitrary
choices by inputting the data from the opponent.) Conversely, the client
must generate a fresh identifier id1 for each request, or else it is impossible to
correlate the responses from two simultaneous requests to the same service.
– Similarly, the server can arbitrarily choose the response data id2, t2, and b2.
On the other hand, our formal model does not directly address replay pro-
tection. To rule out direct replays of correctly signed messages, we would need
to specify that for each end-event there is a unique preceding begin-event with
the same label. This is known as a one-to-one correspondence or injective agree-
ment. In practice, we can protect against direct replays using a cache of recently
received message identifiers and timestamps to ensure that no two messages are
accepted with the same identifier and timestamp. Hence, if we can prove that
the protocol establishes non-injective agreement on data including the identifiers
and timestamps, then, given such replay protection, the protocol implementation
also establishes injective agreement.
We end this section by discussing some flawed variations of the protocol,
corresponding to actual flaws we have encountered in user code for web services.
– Suppose that the check isMsg1(−,U,S,id1,t1,b1) only requires that S, id1, and
b1, are signed by U, but not the timestamp t1. Replay protection based on
the timestamp is now ineffective: the opponent can record a message with
timestamp t1, wait until some time t2 when the timestamp has expired,
and the message identifier id1 is no longer being cached, rewrite the original
204 K. Bhargavan et al.
message with timestamp t2, and then replay the message. The resulting
message satisfies isMsg1(−,U,S,id1,t2,b1), since t2 does not need to be signed,
and hence is accepted by the server. Fig. 3 shows the attack, and the resulting
failure of correspondence C1.
– Suppose that a client re-uses the same message identifier in two different
calls to a web service; the opponent can manipulate messages so that the
client treats the response to the first call as if it were the response to the
second call. Fig. 4 shows the attack. The client sends a first request with
body b1 and identifier id1. The opponent intercepts the response with body
b2, and sends a SOAP fault back to the client. Subsequently, the client sends
a second request with the same identifier id1 as the first, and body b1’. The
opponent can delete this request to prevent it reaching the service, and then
replay the original response. The client now considers that b2 is the response
to b1’, when in fact it is the response to b1, perhaps completely different.
Formally, this is a failure of correspondence C2.
– Suppose that the server does not include the request identifier id1 in the
signature on the response message. Then the opponent can mount a similar
correlation attack, breaking C2—we omit the details.
We can easily adapt our TulaFale script to model these variations in the
protocol. Our tool automatically and swiftly detects the errors, and returns
descriptions of the messages sent during the attacks. These flaws in web services
code are typical of errors in cryptographic protocols historically. The practical
impact of these flaws is hard to assess, as they were found in preliminary code,
before deployment. Still, it is prudent to eliminate these vulnerabilities, and tools
such as TulaFale can systematically rule them out.
TulaFale: A Security Tool for Web Services 205
For example, encryption functions are constructors, and decryption functions are
destructors. This approach, the basis of the Dolev-Yao model [DY83], assumes
that the underlying cryptography is perfect, and can be faithfully reflected by ab-
stract equational properties of the functions. It also abstracts some details, such
as the lengths of strings and byte arrays. The TulaFale syntax for introducing
constructors and destructors is based on the syntax used by ProVerif.
For instance, we declare function symbols for RSA key generation, public-key
encryption, and private-key decryption using the following TulaFale declarations:
constructor pk(bytes):bytes.
constructor rsa(bytes,bytes):bytes.
destructor decrsa(bytes,bytes):bytes with
decrsa(s,rsa(pk(s),b)) = b.
The constructor pk represents the relationship between private and public
keys (both byte arrays, of sort bytes); it takes a private key and returns the
corresponding public key. There is no inverse or destructor, as we intend to
represent a one-way function: given only pk(s) it is impossible to extract s.
The constructor rsa(k,x) encrypts the data x:bytes under the public key k,
producing an encrypted byte array. The destructor decrsa(s,e) uses the corre-
sponding private key s to decrypt a byte array generated by rsa(pk(s),x). The
destructor definition expresses the decryption operation as a rewrite rule: when
an application of decrsa in a term matches the left-hand side of the rule, it may
be replaced by the corresponding right-hand side.
To declare RSA public-key signatures, we introduce another constructor
rsasha1(s,x) that produces a RSA signature of a cryptographic hash of data
x under the private key s:
constructor rsasha1(bytes,bytes):bytes.
destructor checkrsasha1(bytes,bytes,bytes):bytes with
checkrsasha1(pk(s),x,rsasha1(s,x))=pk(s).
To check the validity of a signature sig on x using a public key k, one can
form the term checkrsasha1(k,x,sig) and compare it to k. If k is a public key of
the form pk(s) and sig is the result of signing x under the corresponding private
key s, then this term rewrites to k.
For the purposes of this paper, an X.509 certificate binds a key to a subject
name by embedding a digital signature generated from the private key of some
certifying authority (CA). We declare X.509 certificates as follows:
constructor x509(bytes,string,string,bytes):bytes.
destructor x509key(bytes):bytes with
x509key(x509(s,u,a,k))=k.
destructor x509user(bytes):string with
x509user(x509(s,u,a,k))=u.
destructor x509alg(bytes):string with
x509alg(x509(s,u,a,k))=a.
destructor checkx509(bytes,bytes):bytes with
checkx509(x509(sr,u,a,k),pk(sr))=pk(sr).
TulaFale: A Security Tool for Web Services 207
The term x509(sr,u,a,k) represents a certificate that binds the subject name u
to the public key k, for use with the signature algorithm a (typically rsasha1).
This certificate is signed by the CA with private key sr. Given such a certifi-
cate, the destructors x509key, x509user, and x509alg extract the three public
fields of the certificate. Much like checkrsasha1 for ordinary digital signatures,
an additional destructor checkx509 can be used to check the authenticity of the
embedded signature.
The first line parses U to extract the username u and password pwd. The
second line parses tok to extract n and t, implicitly checking that the user-
name u is the same. In TulaFale, lists of terms are written as tm1 . . .tmm @ tm
with m ≥ 0, where the terms tm1 , . . ., tmm are the first m members of the list,
and the optional term tm is the rest of the list. Here, the wildcard @ \ of the
<UsernameToken> element matches the entire list of attributes. The last line
computes the key k by applying the cryptographic hash function psha1 to pwd,
n, and t (converted to bytes). (This formula for k is a slight simplification of the
actual key derivation algorithm used by WSE.) The concat function returns the
concatenation of two byte arrays.
predicate mkRef(t:item,r:item) :−
r = <Reference>
<Other></> <Other></>
<DigestValue> base64(sha1(c14n(t))) </> </>.
predicate isRef(t:item,r:item) :−
r = <Reference>
(The XML constructed by mkRef abstracts some of the detail that is included in
actual signatures, but that tends not to vary in practice; in particular, we include
<Other> elements instead of the standard <Transforms> and <DigestMethod>
elements. On the other hand, the <DigestValue> element is the part that de-
pends on the subject of the signature, and that is crucial for security, and we
model this element in detail.)
More generally, the predicate mkRefs(ts,rs) constructs a list ts and from a
list rs, such that their members are pairwise related by mkRef. Similarly, the
predicate mkRefs(ts,rs) checks that two given lists are pairwise related by mkRef.
We omit their definitions.
A <SignedInfo> element is constructed from <Reference> elements for every
signed element. A <Signature> element consists of a <SignedInfo> element si
and a <SignatureValue> element containing sv. Finally, the following predicates
define how signatures are constructed and checked.
predicate mkSigInfo (si:item,a:string,ts:item) :−
mkRefs(ts,rs),
rs = <list>@ refs</>,
si = <SignedInfo>
<Other></> <SignatureMethod Algorithm=a> </>
@ refs </>.
<Body>b1</>
<To>uri</>
<Action>ac</>
<MessageId>id1</>
<Created>t1</>
eutok</>),
env1(msg1,uri,ac,id1,t1,eutok,sig1,b1).
On the server side, with server certificate cert, associated private key sx, and
expected user U, we use a predicate isMsg1 to check the input msg1 and produce
S, id1, t1, and b1 as outputs:
predicate isMsg1(msg1:item,U:item,sx:bytes,cert:bytes,S:item,
id1:string,t1:string,b1:item) :−
env1(msg1,uri,ac,id1,t1,eutok,sig1,b1),
isService(S,uri,ac,subj),
isEncryptedData(eutok,utok,sx),
isUserTokenKey(utok,U,n,t1,sk),
isSignature(sig1,"hmacsha1",sk,
<list>
<Body>b1</>
<To>uri</>
<Action>ac</>
<MessageId>id1</>
<Created>t1</>
eutok</>).
predicate env2(msg2:item,uri:item,id1:string,id2:string,
t2:string,cert:bytes,sig2:item,b2:item) :−
msg2 =
<Envelope>
<Header>
<From>uri</>
<RelatesTo>id1</>
<MessageId>id2</>
<Security>
<Timestamp><Created>t2</></>
<BinarySecurityToken>base64(cert)</>
sig2</></>
<Body>b2</></>.
predicate mkMsg2(msg2:item,sx:bytes,cert:bytes,S:item,
id1:string,id2:string,t2:string,b2:item):−
isService(S,uri,ac,subj),
mkSignature(sig2,"rsasha1",sx,
<list>
<Body>b2</>
<RelatesTo>id1</>
<MessageId>id2</>
<Created>t2</></>),
env2(msg2,uri,id1,id2,t2,cert,sig2,b2).
A client, given the CA’s public key kr, and awaiting a response from S to a
message with unique identifier id1, uses the predicate isMsg2 to check its input
msg2, and produce data id2, t2, and b2 as outputs.
predicate isMsg2(msg2:item,S:item,kr:bytes,
id1:string,id2:string,t2:string,b2:item) :−
env2(msg2,uri,id1,id2,t2,cert,sig2,b2),
isService(S,uri,ac,subj),
isX509Cert(cert,kr,subj,"rsasha1",k),
isSignature(sig2,"rsasha1",k,
<list>
<Body>b2</>
<RelatesTo>id1</>
<MessageId>id2</>
<Created>t2</></>).
TulaFale: A Security Tool for Web Services 215
to a previous begin-event logged by the system, also labelled ide, and with the
same tuple of data. We name this property robust safety, following Gordon and
Jeffrey [GJ03]. The implication of robust safety is that two compliant processes
have reached agreement on the data, which typically include the contents of a
sequence of one or more messages.
A declaration process ide(ide1 :sort1 , . . ., iden :sortn ) = proc defines a para-
metric process, with body the process proc, named ide, whose parameters ide1 ,
. . ., iden have sorts sort1 , . . ., sortn , respectively.
Next, we describe the various kinds of TulaFale process.
– A process out ide(tm1 , . . ., tmn ); proc sends the tuple (tm1 , . . ., tmn ) on the
ide channel, then runs proc.
– A process in ide(ide1 , . . ., iden ); proc blocks awaiting a tuple (tm1 , . . ., tmn )
on the ide channel; if one arrives, the process behaves as proc, with its pa-
rameters ide1 , . . ., iden bound to tm1 , . . ., tmn , respectively.
– A process new ide:bytes; proc binds the variable ide to a fresh byte array, to
model cryptographic key or nonce generation, for instance, then runs proc.
Similarly, a process new ide:string; proc binds the variable ide to a fresh
string, to model password generation, for instance, then runs as proc.
– A process proc1 |proc2 is a parallel composition of subprocesses proc1 and
proc2 ; they run in parallel, and may communicate on shared channels.
– A process !proc is a parallel composition of an unbounded array of replicas
of the process proc.
– The process 0 does nothing.
– A process let ide = tm; proc binds the term tm to the variable ide, then runs
proc.
– A process filter form → ide1 , . . ., iden ; proc binds terms tm1 , . . ., tmn to the
variables ide1 , . . ., iden such that the formula form holds, then runs proc.
(The terms tm1 , . . ., tmn are computed by pattern-matching, as described
in a previous paper [BFG04a].)
– A process ide(tm1 , . . ., tmn ), where ide corresponds to a declaration process
ide(ide1 :sort1 , . . ., iden :sortn ) = proc binds the terms tm1 , . . ., tmn to the
variables ide1 , . . ., iden , then runs proc.
– A process begin ide(tm1 , . . ., tmn ); proc logs a begin-event labelled with ide
and the tuple (tm1 , . . ., tmn ), then runs proc.
– A process end ide(tm1 , . . ., tmn ); proc logs an end-event labelled with ide
and the tuple (tm1 , . . ., tmn ), then runs proc.
– Finally, the process done logs a done-event. (We typically mark the successful
completion of the whole protocol with done. Checking for the reachability
of the done-event is then a basic check of the functionality of the protocol,
that it may run to completion.)
The main goal of the TulaFale tool is to prove or refute robust safety for all the
correspondences declared in a script. Robust safety may be proved by a range of
techniques; the first paper on TulaFale [BFG04a] uses manually developed proofs
of behavioural equivalence. Instead, our TulaFale tool translates scripts into the
applied pi calculus, and then runs Blanchet’s resolution-based protocol verifier;
TulaFale: A Security Tool for Web Services 217
Relying on the predicates given in Section 4, we now define the processes mod-
elling our sample system.
between all clients and servers. The second and third allow the opponent to
generate fresh services with subject names "BobsPetShop" and "ChasMarket",
respectively. The fourth acts as an arbitrary client U, and the fifth acts as an
arbitrary service S.
The process MkUser inputs the name of a user from the environment on
channel genUser, then creates a new password and records the username/pass-
word combination U as a message on private channel anyUser, representing the
database of authorized users.
channel genUser(string).
private channel anyUser(item).
process MkUser(kr:bytes) =
in genUser(u);
new pwd:string;
let U = <User><Username>u</><Password>pwd</></>;
!out anyUser (U).
The process MkService allows the attacker to create services with the subject
name of the certificate cert.
predicate isServiceData(S:item,sx:bytes,cert:bytes) :−
isService(S,uri,ac,x509user(cert)),
pk(sx) = x509key(cert).
channel genService(item).
private channel anyService(bytes,bytes,item).
process MkService(sx:bytes,cert:bytes) =
in genService(S);
filter isServiceData(S,sx,cert) → ;
!out anyService(sx,cert,S).
Finally, we present the processes representing clients and servers. Our desired
authentication and correlation properties are correspondence assertions embed-
ded within these processes. We declare the sorts of data to be agreed by the
clients and servers as follows.
correspondence C1(item,item,string,string,item).
correspondence C2(item,item,string,string,item,string,string,item).
The process Client(kr:bytes,U:item) acts as a client for the user U, assuming
that kr is the CA’s public key.
channel init(item,bytes,bytes,string,item).
process Client(kr:bytes,U:item) =
in init (S,certA,n,t1,b1);
new id1:string;
begin C1 (U,S,id1,t1,b1);
filter mkMsg1(msg1,U,S,kr,certA,n,id1,t1,b1) → msg1;
TulaFale: A Security Tool for Web Services 219
out soap(msg1);
in soap(msg2);
filter isMsg2(msg2,S,kr,id1,id2,t2,b2) → id2,t2,b2;
end C2 (U,S,id1,t1,b1,id2,t2,b2);
done.
The process generates a globally fresh, unpredictable identifier id1 for Mes-
sage 1, to allow correlation of Message 2 as discussed above. It then allows the
attacker to control the rest of the data to be sent by receiving it off the public
init channel. Next, the TulaFale filter operator evaluates the predicate mkMsg1
to bind variable msg1 to Message 1. At this point, the client marks its intention
to communicate data to the server by logging an end-event, labelled C1, and
then outputs the message msg1. The process then awaits a reply, msg2, checks
the reply with the predicate isMsg2, and if this check succeeds, ends the C2 cor-
respondence. Finally, to mark the end of a run of the protocol, it becomes the
done process—an inactive process, that does nothing, but whose reachability
can be checked, as a basic test of the protocol description.
The process Server(sx:bytes,cert:bytes,S:item) represents a service S, with
private key sx, and certificate cert.
channel accept(string,string,item).
process Server(sx:bytes,cert:bytes,S:item) =
in soap(msg1);
in anyUser(U);
filter isMsg1(msg1,U,sx,cert,S,id1,t1,b1) → id1,t1,b1;
end C1 (U,S,id1,t1,b1);
in accept (id2,t2,b2);
filter mkMsg2(msg2,sx,cert,S,id1,id2,t2,b2) → msg2;
begin C2 (U,S,id1,t1,b1,id2,t2,b2);
out soap(msg2).
The process begins by selecting a SOAP message msg1 and a user U off the
public soap and the private anyUser channels, respectively. It filters this data
with the isMsg1 predicate, which checks that msg1 is from U, and binds the
variables S, id1, t1, and b1. At this point, it asserts an end-event, labelled C1, to
signify apparent agreement on this data with a client. Next, the process inputs
data from the opponent on channel accept, to determine the response message.
The server process completes by using the predicate mkMsg2 to construct the
response msg2, asserting a begin-event for the C2 correspondence, and finally
sending the message.
6.2 Analysis
The TulaFale script for this example protocol consists of 200 lines specific to
the protocol, and 200 lines of library predicates. (We have embedded essentially
the whole script in this paper.) Given the applied pi calculus translation of this
script, ProVerif shows that our two correspondences C1 and C2 are robustly
220 K. Bhargavan et al.
safe. Failure of robust safety for C1 or C2 would reveal that the server or the
client has failed to authenticate Message 1, or to authenticate Message 2 and
correlate it with Message 1, respectively. Processing is swift enough—around 25s
on a 2.4GHz 1GB P4—to support easy experimentation with variations in the
protocol, specification, and threat model.
7 Conclusions
TulaFale is a high-level language based on XML with symbolic cryptography,
clausally-defined predicates, pi calculus processes, and correspondence asser-
tions. Previous work [BFG04a] introduces a preliminary version of TulaFale,
defines its semantics via translation into the applied pi calculus [AF01], illus-
trates TulaFale via several single-message protocols, and describes hand-crafted
correctness proofs.
The original reasons for choosing to model WS-Security protocols using the
the pi calculus, rather than some other formal method, include the generality
of the threat model (the attacker is an unbounded, arbitrary process), the ease
of simulating executable specifications written in the pi calculus, and the exis-
tence of a sophisticated range of techniques for reasoning about cryptographic
protocols.
Blanchet’s ProVerif [Bla01, Bla02] turns out to be a further reason for using
the pi calculus to study SOAP security. Our TulaFale tool directly implements
the translation into the applied pi calculus and then invokes Blanchet’s verifier,
to obtain fully automatic checking of SOAP security protocols. This checking
shows no attacker expressible as a formal process can violate particular SOAP-
level authentication or secrecy properties. Hence, we expect TulaFale will be
useful for describing and checking security aspects of web services specifica-
tions. We have several times been surprised by vulnerabilities discovered by the
TulaFale tool and the underlying verifier. Of course, every validation method,
formal or informal, abstracts some details of the underlying implementation, so
checking with TulaFale only partially rules out attacks on actual implementa-
tions. Still, ongoing work is exploring how to detect vulnerabilities in web ser-
vices deployments, by extracting TulaFale scripts from XML-based configuration
data [BFG04b].
The request/response protocol presented here is comparable to the abstract
RPC protocols proposed in earlier work on securing web services [GP03], but
here we accurately model the SOAP and WS-Security syntax used on the wire.
Compared with the SOAP-based protocols in the article introducing the TulaFale
semantics [BFG04a], the novelties are the need for the client to correlate the
request with the reply, and the use of encryption to protect weak user passwords
from dictionary attacks. In future work, we intend to analyse more complex
SOAP protocols, such as WS-SecureConversation [KN+ 04], for securing client-
server sessions.
Although some other process calculi manipulate XML [BS03, GM03], they are
not intended for security applications. We are beginning to see formal methods
TulaFale: A Security Tool for Web Services 221
References
[AF01] M. Abadi and C. Fournet. Mobile values, new names, and secure com-
munication. In 28th ACM Symposium on Principles of Programming
Languages (POPL’01), pages 104–115, 2001.
[AG99] M. Abadi and A. D. Gordon. A calculus for cryptographic protocols:
The spi calculus. Information and Computation, 148:1–70, 1999.
[BEK+ 00] D. Box, D. Ehnebuske, G. Kakivaya, A. Layman, N. Mendelsohn,
H. Nielsen, S. Thatte, and D. Winer. Simple Object Access Proto-
col (SOAP) 1.1, 2000. W3C Note, at http://www.w3.org/TR/2000/
NOTE-SOAP-20000508/.
[BFG04a] K. Bhargavan, C. Fournet, and A. D. Gordon. A semantics for web
services authentication. In 31st ACM Symposium on Principles of Pro-
gramming Languages (POPL’04), pages 198–209, 2004.
[BFG04b] K. Bhargavan, C. Fournet, and A. D. Gordon. Verifying policy-based
security for web services. Submitted for publicaton, 2004.
[Bla01] B. Blanchet. An Efficient Cryptographic Protocol Verifier Based on
Prolog Rules. In 14th IEEE Computer Security Foundations Workshop
(CSFW-14), pages 82–96. IEEE Computer Society, 2001.
[Bla02] B. Blanchet. From Secrecy to Authenticity in Security Protocols. In
9th International Static Analysis Symposium (SAS’02), volume 2477 of
Lecture Notes on Computer Science, pages 342–359. Springer, 2002.
[Box01] D. Box. A brief history of SOAP. At http://webservices.xml.com/
pub/a/ws/2001/04/04/soap.html, 2001.
[BS03] G. Bierman and P. Sewell. Iota: a concurrent XML scripting language
with application to Home Area Networks. Technical Report 557, Uni-
versity of Cambridge Computer Laboratory, 2003.
[DHK+ 04] M. Davis, B. Hartman, C. Kaler, A. Nadalin, and J. Schwarz.
WS–I Security Scenarios, February 2004. Working Group Draft
Version 0.15, at http://www.ws-i.org/Profiles/BasicSecurity/
2004-02/SecurityScenarios-0.15-WGD.pdf.
[DY83] D. Dolev and A.C. Yao. On the security of public key protocols. IEEE
Transactions on Information Theory, IT–29(2):198–208, 1983.
[GJ03] A. D. Gordon and A. Jeffrey. Authenticity by typing for security pro-
tocols. Journal of Computer Security, 11(4):451–521, 2003.
[GM03] P. Gardner and S. Maffeis. Modeling dynamic web data. In DBPL’03,
LNCS. Springer, 2003.
222 K. Bhargavan et al.
1 Introduction
Model checking has come about as one of the major advances in automated ver-
ification of systems in the last decade. It has earned its medals in many applica-
tion areas (e.g. communications protocols, timed systems and hybrid systems),
originating from both academic and industrial environments.
However, the class of systems to which model checking techniques are ap-
plicable, is restricted to systems in which dependencies on infinite datatypes
are absent, or can be abstracted from. The models for such systems therefore
do not always represent these systems best. In particular, for some systems the
most vital properties are sensitive to data. There, the model checking technique
breaks down. This clearly calls for an extension of model checking techniques for
systems that are data-dependent.
In this paper, we explore a possibility for extending model checking techniques
to deal with processes which can depend on data. We describe a procedure, for
which we have also implemented a prototype, that verifies a given property
on a given data-dependent process. The problem in general is easily shown to
be undecidable, so, while we can guarantee soundness of our procedure, we
cannot guarantee its termination. However, as several examples suggest, many
interesting systems with infinite state spaces can be verified using our procedure.
F.S. de Boer et al. (Eds.): FMCO 2003, LNCS 3188, pp. 223–239, 2004.
c Springer-Verlag Berlin Heidelberg 2004
224 J.F. Groote and T.A.C. Willemse
Naturally, our technique also applies to systems with finite (but extremely large)
state-spaces.
The framework we use for describing the behaviour of a system is process
algebraic. We use the process algebraic language μCRL [10, 11], which is an ex-
tension of ACP [2]; this language includes a formal treatment of data, as well as
an operational and axiomatic semantics of process terms. Compared to CCS or
ACP, the language μCRL is more expressive [17]. For our model checking pro-
cedure, we assume that the processes are written in a special format, the Linear
Process Equation (LPE) format, which is discussed in e.g. [23]. Note that this
does not pose a restriction on the set of processes that can be modelled using
μCRL, as all sensible process descriptions can be transformed to this format [23].
When dealing with datatypes, an explicit representation of the entire state space
is often not possible, since it can very well be infinite. Using the LPE format has
the advantage of working with a finite representation of the (possibly infinite)
state space.
The language we use to denote our properties in is an extension of the modal
μ-calculus [16]. In particular, we allow first order logic predicates and param-
eterised fixpoint variables in our properties. These extensions, which are also
described in e.g. [9], are needed to express properties about data.
The approach we follow is very much inspired by the work of e.g. Mader [18],
and uses (in our case, first order) boolean equation systems as an intermediate
formalism. We present a translation of first order modal μ-calculus expressions
to first order boolean equation systems in the presence of a fixed Linear Process
Equation. The procedure for solving the first order boolean equation systems is
based on the Gauß elimination algorithm described in, e.g. [18].
This paper is structured as follows: Section 2 briefly introduces the language
μCRL and the Linear Process Equations format that is used in all subsequent
sections. In Section 3, we describe the first order modal μ-calculus. Section 4
discusses first order boolean equation systems and describes the translation of
first order modal μ-calculus formulae, given a Linear Process Equation, to a
sequence of first order boolean equations. A procedure for solving the first order
boolean equations is then described in Section 5; its implementation is discussed
in Section 6, and a sample verification is described in Section 7. Section 8 is
reserved for concluding remarks.
2 Preliminaries
Our main focus in this paper is on processes with data. As a framework, we use
the process algebra μCRL [10]. Its basic constructs are along the lines of ACP [2]
and CCS [20], though its syntax is influenced mainly by ACP. In the process
algebra μCRL, data is an integral part of the language. For the exhibition of
the remainder of the theory, we assume we work in the context of a data alge-
bra without explicitly mentioning its constituent components. As a convention,
we assume the data algebra contains all the required data types; in particular,
A Checker for Modal Formulae for Processes with Data 225
we always have the domain B of booleans with functions ,:→B and ⊥:→B,
representing true and false at our disposal.
The language μCRL has only a small number of carefully chosen operators
and primitives. Processes are the main objects in the language. A set of param-
eterised actions Act is assumed. Actions represent atomic events; for an action
a∈Act, taking a number of data arguments d, a(d) is a process. The process
representing no behaviour, i.e. the process that cannot perform any actions is
denoted δ. This constant is often referred to as deadlock or inaction. All actions
a terminate successfully immediately after execution; δ cannot be executed.
Processes are constructed using several operators. The main operators are
alternative composition (p + q for some processes p and q) and sequential com-
position (p · q for some processes p and q). Conditional behaviour is denoted
using a ternary operator (we write p b q when we mean process p if b holds
and else process q). The process [b]:→p serves as a shorthand for the process
p b δ, which represents the process p under the premise that b holds. Recursive
behaviour is specified using equations. Process variables are typed; they should
be considered as functions from a data domain to processes.
Example 1. The behaviour, denoted by process X(n) is the increasing and de-
creasing of an internal counter n or showing its current value.
For the formal exposition, it can be more convenient to assume that actions
and processes have a single parameter. This assumption is easily justified, as we
can assume the existence of an appropriate data domain, together with adequate
pairing and projection functions.
A more complex notion of process composition consists of the parallel com-
position of processes (we write pq to denote the process p parallel to the process
q). Synchronisation is achieved using a separate partial communication function
γ, prescribing the result of a communication of two actions (e.g. γ(a, b) = c de-
notes the communication between actions a and b, resulting in action c). Two
parameterised actions a(n) and b(n ) can communicate to action c(n ) only if
the communication between actions a and b results in action c (i.e. γ(a, b) = c)
and n = n = n.
The communication function is used to specify when communication is pos-
sible; this, however, does not mean communication is enforced. To this end, we
must encapsulate the individual occurrences of the actions that participate in
the communication. This is achieved using the encapsulation operator (we write
∂H (p) to specify that all actions in the set of actions H are to be encapsulated
in process p).
The last operator considered here is data-dependent alternative quantification
(we write d:D p to denote the alternatives of process p, dependent on some
arbitrary
datum d selected from the (possibly infinite) data domain D). The
-operator is best compared to e.g. input prefixing, but is more expressive (see
e.g. [17]).
226 J.F. Groote and T.A.C. Willemse
where I is a finite index set; D and Di are data domains; d and ei are data
variables; ai ∈Act are actions with parameters of sort Dai ; fi :D × Di → Dai ,
gi :D × Di → D and ci :D × Di → B are functions. The function fi yields, on the
basis of the current state d and the bound variable ei , the parameter for action
ai ; the “next-state” is encoded in the function gi . The function ci describes when
action ai can be executed.
[[,]]ε =Σ
[[a(e)]]ε = {a(ε(e))}
[[¬α]]ε = Σ \ [[α]]ε
[[α1 ∧ α2 ]]ε =
[[α1 ]]ε ∩ [[α2 ]]ε
[[∀d:D.α]]ε = v∈D [[α]]ε[v/d]
def def
We use the abbreviations as usual: (ϕ1 ∨ ϕ2 ) = ¬(¬ϕ1 ∧ ¬ϕ2 ), (α)ϕ = ¬[α]¬ϕ,
def
(∃d:D.ϕ) = (¬∀d:D.¬ϕ) and (μZ(d:D).ϕ)(e) = (¬νZ(d:D).¬ϕ[¬Z/Z])(e). We
write σ for an arbitrary fixpoint, i.e. σ ∈ {ν, μ}.
We only consider state formulae in which all variables are bound exactly
once by a fixpoint operator or quantifier. State formulae are interpreted over a
labelled transition system M , induced by an LPE, according to Def. 2.
Definition 6. The interpretation of a state formula ϕ in the context of data
environment ε:D→D and propositional environment ρ:P→(D→2S ), denoted by
[[ϕ]]ρε, is defined inductively as:
S if [[b]]ε
[[b]]ρε =
∅ otherwise
[[Z(e)]]ρε = ρ(Z)(ε(e))
[[¬ϕ]]ρε = S \ [[ϕ]]ρε
[[ϕ1 ∧ ϕ2 ]]ρε = [[ϕ1 ]]ρε ∩ [[ϕ2 ]]ρε
[[[α]ϕ]]ρε = {X(v)∈S | ∀v ∈D ∀a∈Act ∀va ∈Da
a(va )
(X(v) −→ X(v ) ∧ a(va )∈[[α]]ε) ⇒ X(v )∈[[ϕ]]ρε}
[[∀d:D.ϕ]]ρε = v ∈D [[ϕ]]ρ(ε[v /d])
[[(νZ(d:D).ϕ)(e)]]ρε = (νΦρε )(ε(e))
def
where we have Φρε = λF :D → 2S .λv:D.[[ϕ]](ρ[F/Z])(ε[v/d]). For states X(d) ∈ S
of the transition system induced by an LPE X, and a formula ϕ, we write d |=X ϕ
for X(d) ∈ [[ϕ]]ρε.
Example 4. Consider a process with at least the states s0 , s1 and s2 , the labels
a(,) and a(⊥) and the state formula ϕ. We write s |= ϕ to denote that ϕ is
satisfied in state s, and, likewise, we write s |= ϕ to denote that ϕ is not satisfied
in state s.
A Checker for Modal Formulae for Processes with Data 229
Property 1. Let ϕ be a state formula, such that d does not occur in ϕ, and let
α be an action formula. Then, we have the following identities:
1. (∃d:D.α)ϕ ⇔ ∃d:D.(α)ϕ, and [∃d:D.α]ϕ ⇔ ∀d:D.[α]ϕ,
2. ∃d:D.[α]ϕ ⇒ [∀d:D.α]ϕ, and (∀d:D.α)ϕ ⇒ ∀d:D.(α)ϕ
Note: here we use implication as an abbreviation for ⊆ and bi-implication as an
abbreviation for = on the interpretations of the state formulae.
These properties state a weak relation between quantifiers in state formulae
and quantifiers in action formulae. Note that the converse of the second item
does not hold, see e.g. [14, 24] for a counterexample. Thus, compared to the frag-
ment of the first order modal μ-calculus that disallows quantifiers inside action
formulae, the quantifiers inside action formulae indeed increase the expressive
power of the whole first order modal μ-calculus.
Remark 3. Note that negation in combination with universal quantifiers in ac-
tion formulae can yield more exciting sets than the empty set.
4 Equation Systems
Following [9], we use an extension of the formalism of boolean equation systems
(see e.g. [18]) as an intermediate formalism that allows us to combine an LPE
with a first order modal μ-calculus expression.
Definition 7. A first order boolean expression is a formula ϕ in positive form,
defined by the following grammar:
We denote the set of functions of type D→B by [D→B]. The set of first order
boolean expressions ([D→B], ⇒),˙ where ϕ⇒ψ ˙ iff for all d:D ϕ(d)⇒ψ(d), forms a
complete lattice and is isomorphic to (2D , ⊆). The propositional variables Z∈P,
occurring as free variables in first order boolean expressions are bound in first
order boolean equation systems (also known as parameterised boolean equation
systems [15] or equation systems for short), used in the sequel.
Definition 8. The interpretation of a first order boolean expression ϕ in the
context of propositional environment θ:P→(D→B) and data environment
η:D→D, written as [[ϕ]]θη is either true or false, determined by the following
induction:
[[b]]θη = [[b]]η
[[ϕ1 ∧ ϕ2 ]]θη = [[ϕ1 ]]θη ∧ [[ϕ2 ]]θη
[[ϕ1 ∨ ϕ2 ]]θη = [[ϕ1 ]]θη ∨ [[ϕ2 ]]θη
[[Z(e)]]θη = θ(Z)([[e]]η)
[[∀d:D.ϕ]]θη = true, if for all v:D it holds that [[ϕ]]θ(η[v/d]) else false
[[∃d:D.ϕ]]θη = true, if there exists a v:D such that [[ϕ]]θ(η[v/d]) else false
Lemma 1. First order boolean expressions are monotone over ([D→B], ⇒),
˙
see [14, 24].
Definition 11. Let ϕ = (σZ(df :D).Φ)(e) be a first order modal μ-calculus for-
mula ϕ. Let X(dp :D) be an LPE (see Def. 1). The equation system E that corre-
sponds to the expression ϕ for LPE X is given by E(ϕ). The translation function
E is defined by structural induction in Table 1.
Theorem 1. Let X be an LPE with initial state X(d0 ) and parameter space
D. For each environment ρ:P→(D →2S ) the environment θρ :P→(D×D →B)
def
is defined as θρ (Z̃) = λ(d, d ):D×D .(X(d)∈ρ(Z)(d )). Let ϕ = (σZ(d:D ).Φ)(e).
Then, we have
d0 |=X ϕ iff ([E(ϕ)]θρ )(Z̃(e, d0 ))
Proof. See [9].
The translation function E splits nested fixpoint expressions into equations
for which the right-hand side is determined by the function RHS. This latter
function takes care of the logical connectives, such as ∧ and ∨, and the modalities
[α]ϕ and (α)ϕ.
Example 5. Consider a coffee-vending machine that produces either cappuccino
or espresso on the insertion of a special coin. It accepts coins as long as there
is at least one type of coffee that can still be dispensed. If the machine has run
out of a type of coffee, it can be filled again with C fillings of cappuccino or E
fillings of espresso.
proc X(b:B, c, e:N) = [b ∧ c > 0]:→ cappuccino · X(¬b, c − 1, e)
+[b ∧ e > 0]:→ espresso · X(¬b, c, e − 1)
+[¬b ∧ c + e > 0]:→ coin · X(¬b, c, e)
+[¬b ∧ c = 0]:→ refillcappuccino · X(b, C, e)
+[¬b ∧ e = 0]:→ refillespresso · X(b, c, E)
Boolean b indicates whether a coin has been inserted or not and parameters
c and e register the number of servings of cappuccino, resp. espresso that are
left in the coffee-vending machine. Consider the (first order) modal μ-calculus
expression μZ.((coin ∨ cappuccino)Z ∨ (refillcappuccino ),), expressing that there
exists a path where cappuccino can be refilled when it is the only thing that has
been ordered. We briefly illustrate how we can obtain an equation system by
combining process X and the above modal formula using Def. 11:
E(μZ.((coin ∨ cappuccino)Z ∨ (refillcappuccino ),))
= (μZ̃(b:B, c, e:N) = RHS(((coin ∨ cappuccino)Z ∨ (refillcappuccino ),))
= (μZ̃(b:B, c, e:N) = RHS((coin ∨ cappuccino)Z) ∨ RHS((refillcappuccino ),))
= (μZ̃(b:B, c, e:N) = (¬b ∧ c + e > 0 ∧ RHS(Z)[(¬b, c, e)/(b, c, e)])
∨(b ∧ c > 0 ∧ RHS(Z)[(¬b, c − 1, e)/(b, c, e)])
∨(¬b ∧ c = 0 ∧ RHS(,)[(b, C, e)/(b, c, e)]))
= (μZ̃(b:B, c, e:N) = (¬b ∧ (c = 0 ∨ (c + e > 0 ∧ Z̃(¬b, c, e))))
∨(b ∧ c > 0 ∧ Z̃(¬b, c − 1, e))
Notice that this equation carries the parameters of the LPE, even though the
first order modal μ-calculus expression was not parameterised.
232 J.F. Groote and T.A.C. Willemse
Table 1. Translation of first order μ-calculus formula ϕ and LPE X(dp :D) to an
equation system E(ϕ). Note that Z̃ is a fresh propositional variable, associated to the
propositional variable Z. Function E determines the number and order of equations for
E(ϕ), whereas function RHS breaks down ϕ to obtain first order boolean expressions
that form the right-hand side of each equation in E(ϕ). The satisfaction relation |= and
the function Par are listed in Table 2. The function ParX (ϕ) yields a list of parameters
with types that must be bound by the parameterised propositional variable X. Here,
we have abused the notation ParX (ϕ) to also denote the list of parameters without
typing information. Note that ParX (ϕ) is always calculated for the entire formula ϕ,
and not for subformulae
def
E(b) =
def
E(Z(df )) =
def
E(Φ1 ∧ Φ2 ) = E(Φ1 )E(Φ2 )
def
E(Φ1 ∨ Φ2 ) = E(Φ1 )E(Φ2 )
def
E([α]Φ) = E(Φ)
def
E((α)Φ) = E(Φ)
def
E(∀d:D.Φ) = E(Φ)
def
E(∃d:D.Φ) = E(Φ)
def
E((σZ(df :Df ).Φ)(e)) = (σ Z̃(df :Df , dp :Dp , ParZ (ϕ)) = RHS(Φ) ) E(Φ)
def
RHS(b) = b
def
RHS(Z(e)) = Z̃(e, dp , ParZ (ϕ))
def
RHS(Φ1 ∧ Φ2 ) = RHS(Φ1 ) ∧ RHS(Φ2 )
def
RHS(Φ1 ∨ Φ2 ) = RHS(Φ1 ) ∨ RHS(Φ2 )
def
RHS([α]Φ) = i:I ∀ei :Di (ai (fi (dp , ei )) |= α ∧ ci (dp , ei )) ⇒
RHS(Φ)[gi (dp , ei )/dp ]
def
RHS((α)Φ) = i:I ∃ei :Di (ai (fi (dp , ei )) |= α ∧ ci (dp , ei )∧
RHS(Φ)[gi (dp , ei )/dp ])
def
RHS(∀d:D.Φ) = ∀d:D.RHS(Φ)
def
RHS(∃d:D.Φ) = ∃d:D.RHS(Φ)
def
RHS((σZ(df :Df ).Φ)(e)) = Z̃(e, dp , ParZ (ϕ))
5 Model-Checking
Mader [18] describes an algorithm for solving boolean equation systems. The
method she uses resembles the well-known Gauß elimination algorithm for solv-
ing linear equation systems, and is therefore also referred to as Gauß elimination.
The semi-decision procedure we use (see Fig. 1) is an extension of the Gauß elim-
ination algorithm of [18]. Basically, all lines (except for line 3) are part of the
algorithm of [18]. The essential difference is in the addition of line 3, where an
A Checker for Modal Formulae for Processes with Data 233
Table 2. Auxiliary functions used in the translation of Table 1. Here, + + denotes list
concatenation. The satisfaction relation |= checks whether a symbolic action a(d) is
part of an action formula α. The function ParX (ϕ) yields a list of parameters together
with their types that have to be bound by the equation for X
def
a(d) |= a (d ) = a = a ∧ d = d
def
a(d) |= , = true
def
a(d) |= ¬α = ¬(a(d) |= α)
def
a(d) |= α1 ∧ α2 = (a(d) |= α1 ) ∧ (a(d) |= α2 )
def
a(d) |= α1 ∨ α2 = (a(d) |= α1 ) ∨ (a(d) |= α2 )
def
a(d) |= ∃d :D.α = ∃d :D.(a(d) |= α)
def
a(d) |= ∀d :D.α = ∀d :D.(a(d) |= α)
def
ParX (b) = []
def
ParX (Z(df )) = [] for all Z ∈ P
def
ParX (Φ1 ∧ Φ2 ) = ParX (Φ1 ) ++ParX (Φ2 )
def
ParX (Φ1 ∨ Φ2 ) = ParX (Φ1 ) ++ParX (Φ2 )
def
ParX ([α]Φ) = ParX (Φ)
def
ParX ((α)Φ) = ParX (Φ)
def
ParX (∀d:D.Φ) = [d:D] ++ParX (Φ)
def
ParX (∃d:D.Φ) = [d:D] ++ParX (Φ)
def
ParX ((σZ(df :Df ).Φ)(e)) = ParX (Φ) for all Z ∈ P such that Z = X
def
ParX ((σX(df :Df ).Φ)(e)) = []
extra loop for calculating a stable point in the (transfinite) approximation for
each equation is given.
The reduction of an equation system proceeds in two separate steps. First,
a stabilisation step is issued, in which an equation σi Xi (d:D) = ϕi is reduced
to a stable equation σi Xi (d:D) = ϕi , where ϕi is an expression containing no
occurrences of Xi . Second, we substitute each occurrence of Xi by ϕi in the
rest of the equations of the first order boolean equation system. This does not
change the solution of the equation system (see [14, 24, 15]). Since there are no
more occurrences of Xi in the right-hand side of the equations, it suffices to
reduce a smaller equation system. The semi-decision procedure terminates iff
the stabilisation step terminates for each equation.
Theorem 2. On termination of the semi-decision procedure in Fig. 1, the so-
lution of the given equation system has been computed [14, 24].
1. for i = n downto 1 do
2. j := 0; ψ0 := ( if σbi = ν then , else ⊥);
3. repeat ψj+1 := ϕi [Xi := ψj ]; j := j + 1 until (ψj ≡ ψj−1 )
4. for k = 1 to i do ϕk := ϕk [Xi := ψj ] od ;
5. od
terminate. However, there are a number of cases for which termination is guar-
anteed, e.g. if all considered datatypes are finite.
Example 6. Consider the infinite-state system C(0) that counts from zero to
infinity, and reports its current state via an action current. Even though
this process is not very complex, it cannot be represented by a finite labelled
transition system, which is why most current tools cannot handle such
processes.
proc C(n:N) = current(n) · C(n+1)
6 Implementation
Based on our semi-decision procedure, described in the previous section, we
have implemented a prototype of a tool1 . The prototype implementation of our
algorithm employs Equational Binary Decision Diagrams (EQ-BDDs) [13] for
representing first order boolean expressions. These EQ-BDDs extend on standard
BDDs [6] by explicitly allowing equality on nodes. We first define the grammar
for EQ-BDDs.
The constants 0 and 1 represent false and true. An expression of the form
ITE(ϕ, ψ, ξ) must be read as an if-then-else construct, i.e. (ϕ ∧ ψ) ∨ (¬ϕ ∧ ξ), or,
alternatively, (ϕ ⇒ ψ) ∧ (¬ϕ ⇒ ξ). For data variables d and e, and ϕ of the form
d = e, the extension to EQ-BDDs is used, i.e. we explicitly use ITE(d = e, ψ, ξ)
in such cases. Using the standard BDD and EQ-BDD encodings [6, 13], we can
then represent all quantifier-free first order boolean expressions.
Representing expressions that contain quantifiers over finite domains is done
in a straightforward manner, i.e. we construct explicit encodings for each distinct
element in the domain. Expressions containing quantifiers over infinite domains
are in general problematic, when it comes to representation and calculation. The
following theorem, however, identifies a number of cases in which we can deal
with these.
7 Example Verification
We have successfully used the prototype on several applications, including many
communications protocols, such as the IEEE-1394 firewire, sliding window proto-
cols, the bounded retransmission protocol, etc. As an example of its capabilities,
we here report on our findings for Lamport’s Bakery Protocol [21]. A μCRL
specification of the Bakery Protocol is given in Fig. 2. The bakery protocol we
consider is restricted to two processes. Each process, waiting to enter its critical
section, can choose a number, larger than any other number already chosen.
Then, the process with the lower number is allowed to enter the critical section
before the process with the larger number. Due to the unbounded growth of
the numbers that can be chosen, the protocol has an infinite state-space. How-
ever, our techniques are immediately applicable. Below, we list a number of key
properties we verify for the bakery protocol.
1. No deadlocks, i.e.
νZ.([,]Z ∧ (,),),
2. Two processes can never be in the critical section at the same time, i.e.
νZ.([T ]Z ∧ ∀b:B.([enter(b)]νZ .([enter(¬b)]F ∧ [¬leave(b)]Z ))),
3. All processes requesting a number eventually enter the critical section, i.e.
νZ.([,]Z ∧ ∀b:B.([request(b)]μZ .(([,]Z ∧ (,),) ∨ (enter(b)),)))
The first two properties are satisfied. Using our prototype we were able to
produce these results in 1 and 2 seconds2 resp. The third property was proved
not to hold in 1 second.
8 Closing Remarks
Related Work. In a setting without data, the use of boolean equation systems for
the verification of modal μ-calculus formulae on finite and infinite state systems
2
These results were obtained using a 1.47Ghz AMD Athlon XP1700+ machine with
256Mb main memory, running Linux kernel 2.2.
A Checker for Modal Formulae for Processes with Data 237
was studied by Mader [18]. As observed by Mader, the use of boolean equation
systems is closely related to the tableau methods of Bradfield and Stirling [5],
but avoids certain redundancy of tableaux. It is therefore likely that in the case
with data our approach performs better than tableau methods if these would be
extended to deal with data.
Closely related to our work is the tool Evaluator 3.0 [19], which is an on-
the-fly model checker for the regular alternation-free μ-calculus. The machinery
of this tool is based on boolean equation systems. Although the alternation-
free μ-calculus allows for the specification of temporal logic properties involving
data, the current version of the tool does not support the data-based version
of this language. It is well imaginable that this tool can be extended with our
techniques.
A different approach altogether is undertaken by e.g. Bryant et al. [7]. Their
Counter arithmetic with Lambda expressions and Uninterpreted function (CLU)
can be used to model both data and control, and is shown to be decidable.
For this, CLU sacrifices expressiveness, as it is restricted to the quantifier-free
fragment of first order logic. Moreover, their tool (UCLID) is restricted to dealing
with safety properties only. We allow for safety, liveness and fairness properties to
be verified automatically. Nevertheless, CLU is interesting as it provides evidence
that there may be a fragment in our logic or in our specification language that
is decidable, even for infinite state systems.
Much work on symbolic reachability analysis of infinite state systems has
been undertaken, but most of it concentrates on safety properties only. Bouaj-
jani et al. (see e.g. [4]) describe how first-order arithmetical formulae, expressing
safety and liveness conditions, can be verified over Parametric Extended Au-
tomaton models, by specifying extra fairness conditions on the transitions of the
models. The main difference with our approach is that we do not require fairness
conditions on transitions of our models and that the first order modal μ-calculus
is in fact capable of specifying fairness properties.
The technique by Bultan et al. [8] seems to be able to produce results that
are comparable to ours. Their techniques, however, are entirely different from
ours. In fact, their approach is similar to the approach used by Alur et al. [1] for
hybrid systems. It uses affine constraints on integer variables, logical connectives
and quantifiers to symbolically encode transition relations and sets of states. The
logic, used to specify the properties is a CTL-style logic. In order to guarantee
termination, they introduce conservative approximation techniques that may
yield “false negatives”, which always converges. It is interesting to investigate
whether the same conservative approximation techniques can be adapted to our
techniques.
References
1. R. Alur, C. Courcoubetis, N. Halbwachs, T.A. Henzinger, P.-H. Ho, X. Nicollin,
A. Olivero, J. Sifakis, and S. Yovine. The algorithmic analysis of hybrid systems.
Theoretical Computer Science, 138:3–34, 1995.
2. J.C.M. Baeten and W.P. Weijland. Process Algebra. Cambridge Tracts in Theo-
retical Computer Science. Cambridge University Press, 1990.
3. S.C.C. Blom, W.J. Fokkink, J.F. Groote, I. Van Langevelde, B.Lisser, and J.C.
van de Pol. μCRL: A toolset for analysing algebraic specification. In CAV’01,
volume 2102 of LNCS, pages 250–254. Springer-Verlag, 2001.
4. A. Bouajjani, A. Collomb-Annichini, Y. Lacknech, and M. Sighireanu. Analysis of
fair extended automata. In P. Cousot, editor, Proceedings of SAS’01, volume 2126
of LNCS, pages 335–355. Springer-Verlag, 2001.
5. J.C. Bradfield and C. Stirling. Local model checking for infinite state spaces.
Theoretical Computer Science, 96(1):157–174, 1992.
6. R.E. Bryant. Graph-based algorithms for Boolean function manipulation. IEEE
Transactions on Computers, C-35(8):677–691, 1986.
7. R.E. Bryant, S.K. Lahiri, and S.A. Seshia. Modeling and verifying systems using a
logic of counter arithmetic with lambda expressions and uninterpreted functions.
In CAV 2002, volume 2404 of Lecture Notes in Computer Science, pages 78–92.
Springer-Verlag, 2002.
A Checker for Modal Formulae for Processes with Data 239
1 Introduction
For years, formal method advocates have criticized specification and documenta-
tion practices of the software industry. They point out that neither more rigorous
English nor semi-formal notation like UML protect us from unintended ambigu-
ity or missing important information. The more practical among them require
specifications to be linked to an executable code. Without such a linkage one can-
not debug the specification or impose it. Non-linked specifications tend quickly
to become obsolete.
We agree with the critique. We need specifications that are precise, readable
and executable. The group of Foundations of Software Engineering at Microsoft
Research [4] was not satisfied with existing solutions of the specification problem
(we address related work in the full paper [8]) and has worked out a new solution
based on the theory of abstract state machines [5, 6, 3, 9]. We think of specifica-
tions as executable models that exhibit the desired behavior on the appropriate
level of abstraction. Abstract State Machine Language, AsmL, is a language for
writing such models [1].
The FSE group has designed AsmL, implemented it and integrated it with
the Microsoft runtime and tool environment. Furthermore, the group has built
various tools on top of AsmL.
F.S. de Boer et al. (Eds.): FMCO 2003, LNCS 3188, pp. 240–259, 2004.
c Springer-Verlag Berlin Heidelberg 2004
Semantic Essence of AsmL 241
less, AsmL is primarily a specification language. Users familiar with the speci-
fication language literature will find familiar data structures and features, like
sets, sequences, maps, pattern matching, bounded quantification, and set com-
prehension.
But the crucial features of AsmL, intrinsic to ASMs, are massive synchronous
parallelism and finite choice. These features give rise to a cleaner programming
style than is possible with standard imperative programming languages. Syn-
chronous parallelism means that AsmL has transactional semantics. (A single
step of AsmL can be viewed as a transaction. This transaction may involve mas-
sive parallelism.) This provides for a clean separation between the generation
of new values and the committal of those values into the persistent state. For
instance, when an exception is thrown, the state is automatically rolled back
rather than being left in an unknown and possibly inconsistent state. Finite
choice allows the specification of a range of behaviors permissible for an (even-
tual) implementation.
Acknowledgments. Without the support from the FSE group this work would
not be possible; particular thanks go to Wolfgang Grieskamp and Nikolai Till-
mann for developing the runtime mechanism of AsmL. Thanks to Robert Stärk
for his comments on the draft of this extended abstract.
2.1 Expressions
In AsmL-S, expressions are the only syntactic means for writing executable spec-
ifications. Binding and function application are call-by-value. (The necessity of
.NET integration is a good reason all by itself not to use lazy evaluation.)
Literal is the set of literals, like 1, true, null or void . We write the value
denoted by a literal as the literal itself. Literals are typed; for instance, 1 is of
type Int and true is of type Bool . AsmL-S has various operations on Literal , like
addition over integers or conjunction, i.e. and , over Bool .
Exception is an infinite set of exceptions, that is disjoint from Literal . For
now, think of exceptions as values representing different kinds of errors. We will
discuss exceptions further in Section 2.8.
If e is a closed expression, i.e. an expression without free variables, and v is a
v
literal or an exception, then e −→ v means that e evaluates to v. The “v” above
the arrow alludes to “value”.
Examples 1–5 show how to evaluate simple AsmL-S expressions.
field name drawn from a set FieldId . A content map is a partial function from
Location to Nvalue. It records the initial bindings for all locations.
The default constructor in AsmL-S takes one parameter for each field in
the order of their declaration. The constructor extends the type map, extends
the field map using the corresponding arguments, and returns a fresh object
identifier.
v
class A {i as Int} : new A(1).i −→ 1 (8)
If the receiver of a field or method selection is null , evaluation fails and throws
a null pointer exception.
v
class A {}, class B extends A {} : new B() is A −→ true (12)
Casting checks that an instance is a subtype of the given type, and if so then
yields the instance without changing the dynamic type of the instance.
v
class A {}, class B extends A {} : new A() as B −→ castX (14)
2.3 Maps
Maps are finite partial functions. A map display is essentially the graph of the
partial function. For example, a map display m = {1 → 2, 3 → 4} represents the
partial function that maps 1 to 2 and 3 to 4. The map m consists of two maplets
1 → 2 and 3 → 4 mapping keys (or indices) 1, 3 to values 2, 4 respectively.
Remark 2. In AsmL, maps can be also described by means of comprehension
expressions. For example, {x → 2 ∗ x | x ∈ {1, 2, 3}} denotes {1 → 2, 2 →
4, 3 → 6}. In AsmL-S map comprehension should be programmed.
The maps of AsmL-S are similar to associative arrays of AWK or Perl. Maps
have identities and each key gives rise to a location. Arbitrary normal values can
serve as keys. We extend the notion of a location accordingly.
Maps may be modified (see Section 2.4). Maps are often used in forall and
choose expressions (see Sections 2.5 and 2.7). Examples 15–19 exhibit the use of
maps in AsmL-S.
A map constructor takes the map type and the initial map as arguments.
v
new Int → Bool {1 → true, 1 → false} −→ argconsistencyX (16)
v
new Int → Int {1 → 7} [2] −→ mapkeyX (19)
However, if the receiver of the index expression is null or if the index is not in
the domain of the map, then the evaluation throws a null exception or a map-key
exception, respectively.
Remark 3. AsmL-S treats maps differently than the full AsmL. The full AsmL
is more sophisticated; it treats maps as values which requires partial updates [7].
In AsmL-S, maps are objects. An example illustrating this difference is given in
Section 2.10.
2.4 Assignments
One of AsmL’s unique features is its handling of state. In sequential languages,
like C# or Java, assignments trigger immediate state changes. In ASMs, and
therefore also in AsmL, an assignment creates an update. An update is a pair:
the first component describes the location to update, the second the value to
which it should be updated. An update set is a set of updates. A triple that
consists of a type map, a content map and an update set will be called a store.
Note that we extended V alue with a special symbol DEL which is used only
with locations given by map keys and which marks keys to be removed from the
map.
s,v
If e is a closed expression, then e −−→ s, v means that evaluation of e pro-
duces the store s and the value v. Examples 20–23 show the three ways to create
updates. Note that in AsmL-S, but not in AsmL, all fields and keys can be up-
dated. AsmL distinguishes between constants and variables and allows updates
only to the latter.
A map-value assignment behaves similarly. Note that the update set is created
irrespective of whether the location exists or not.
remove new Int → Bool {1 → true} [1] (22)
s,v
−−→ {o → Int → Bool }, {((o, 1) → true}, {(o, 1), DEL)} , void
The remove instruction deletes an entry from the map by generating an
update that contains the placeholder DEL in the location to delete.
class A {F (map as Int → A, val as A) as Void do map[0] := val },
class B extends A {} : (23)
v
let a = new A() do a.F (new Int → B {}, a) −→ mapvalueX
Since Int → B is a subtype of Int → A, it is reasonable that this piece of
code type-checks successfully at compile time. However, the assignment fails at
runtime and throws a map-assignment exception. Thus, map assignments must
be type-checked at runtime. (The same reason forces runtime type-checks of
array assignments in C# or Java.)
If the range of a forall expression is empty, it simply returns the literal void .
let x = new Int → Int {2 → 4} do let y = x[2] do (x[2] := 8) y (27)
s,v
−−→ {o → Int → Int}, {(o, 2) → 4}, {((o, 2), 8)} , 4
Parallel expressions can return values. In full AsmL, the return value is distin-
guished syntactically by writing return. In AsmL-S, the value of the second
expression is returned, whereas forall-expressions return void .
If the choice domain is empty, a choice exception is thrown. (The full AsmL
distinguishes between choose-expressions and choose-statements. The choose-
expression throws an exception if the choice domain is empty, but the choose-
statement with the empty choice domain is equivalent to void .)
v
[2] −→{ → o}, ({o → Int→Bool},{(o,2) → false},∅) false (43)
s,v
A more general notation e −−→ b,r s, v means that a computation of e in
evaluation context (b, r) produces new store s and value v.
In this example, the first assignment a.g := a.f is responsible for the update
((o1 , g), o2 ); the second assignment gives rise to the update ((o2 , 2), false). Thus,
a.g[2] has value false after all updates are executed.
This same program has a different semantics in the full AsmL, where maps
are treated as values rather than objects. In AsmL, the assignment a.g := a.f has
the effect of updating a.g to the value of a.f , i.e., the map {1 → true, 2 → false}.
The second assignment, a.f [2] := false, has no bearing on a.g. Thus, a.g[2] has
value true after all updates are executed.
In treating maps as objects in AsmL-S, we avoid having to introduce the
machinery of partial updates [7], which is necessary for the treatment of maps
as values in AsmL. This causes a discrepancy between the semantics of AsmL-S
and of AsmL. Fortunately, there is an easy AsmL-S expression that updates the
value of a map m1 to the value of another map m2 (without assigning m2 to
m1 ):
The first forall expression erases m1 ; the second forall expression copies m2
to m1 at all keys i in the domain of m2 .
Semantic Essence of AsmL 251
uate either e1 or e2 . The related semantical issues will be addressed later. The
while, forall and choose expressions generalize the two-component sequential,
parallel and nondeterministic compositions, respectively.
AsmL-S supports exception handling. In full AsmL, exceptions are instances
of special exception classes. In AsmL-S, exceptions are atomic values of type
Thrown. (Alternatively, we could have introduced a whole hierarchy of exception
types.) There are a handful of built-in exceptions, like argX ; all of them end with
“X”. A user may use additional exception names. There is no need to declare
new exception names; just use them. Instead of prescribing a particular syntactic
form to new exception names, we just presume that they are taken from a special
infinite pool of potential exception names that is disjoint from other semantical
domains of relevance.
Semantic Essence of AsmL 253
t ≤ t t ≤ t
• t ≤ t, ≤ is a reflexive partial order
t ≤ t
c c
• ≤ extends the parent relation over classes
c ≤ c
t≤τ t ≤ τ
• maps types are covariant in argument and result types
(t → t ) ≤ (τ → τ )
t ≤ Object
• Null lies beneath all object types
Null ≤ t
Call two types comparable if one of them is a subtype of the other; otherwise
call them incomparable. Primitive types compare the least. If t is a primitive
type, then t ≤ t and Thrown ≤ t are the only subtype relations involving t.
The following proposition is easy to check.
Proposition 1. Every two types t1 , t2 have a greatest lower bound t1 ' t2 . Every
two subtypes of Object have a least upper bound t1 t2 . '
Remark 5. One may argue that map types should be contravariant in the argu-
ment, like function types [13]. In the full paper, we discuss pros and cons of such
a decision.
If c is a class different from Object, then addf (c) is the sequence of distinct
field names given by the declaration of c. These are the new fields of c, acquired
254 Y. Gurevich, B. Rossman, and W. Schulte
fldseq(Object) =
fldseq(c) = addf (c) · fldseq(parent(c))
We assume that addf (c) is disjoint from fldseq(parent(c)) for all classes c. If
f is a field of c of type t, then fldtype(f, c) = t. If fldseq(c) = (f1 , . . . , fn ) and
fldtype(fi , c) = ti , then
fldinfo(c) = f¯ as t̄ = (f1 as t1 , . . . , fn as tn ).
mthset(Object) = ∅
mthset(c) = addm(c) ∪ mthset(parent(c))
m(1 as τ1 , . . . , n as τn ) as t do e
3.4 Well-Formedness
We now make an additional assumption about the underlying class table: for
each class c and each method m ∈ mthset(c), m is well-formed relative to c
(symbolically: m ok in c).
The definition of m ok in c is inductive. Suppose dclr (m, c) = m(1 as τ1 ,
. . . , n as τn ) as t do e and c c . Let T denote the type context {me →
c} ∪ {1 → τ1 , . . . , n → τn }.
m ∈ mthset(c) − addm(c) m ok in c
•
m ok in c
256 Y. Gurevich, B. Rossman, and W. Schulte
4 Analysis
The effect operator is monotone with respect to stores: if Eb,r (e) = (s, v) then
r is a substore of s. Furthermore, if v is an exception then r = s, meaning that
the store is rolled back whenever an exception occurs.
In addition to these properties, the static-type and effect operators satisfy
the usual notions of type soundness and semantic refinement. See the full paper
for precise statements and proofs of the theorems mentioned in this section.
The type of an effect (s, v), where s = (θ, ω, u), is defined as follows:
⎧
⎪
⎨θ(v) if v ∈ dom(θ)
type(s, v) = littype(v) if v ∈ Literal
⎪
⎩
Thrown if v ∈ Exception.
Theorem 2 (Type Soundness). For every evaluation context (b, r) and every
(b, r)-typed expression e, we have
type(Eb,r (e)) ≤ T[b,r] (e)
for any converging computation of Eb,r (e).
Semantic Essence of AsmL 257
Roughly speaking, the “core” of an effect (s, v) is the subeffect (s , v ) that
remains after a process of garbage-collection relative to the binding b: we remove
all but the objects reachable from values in rng(b).
The refinement relation has the following property.
258 Y. Gurevich, B. Rossman, and W. Schulte
Proposition 4
e1 e1 =⇒ choose in e1 do e2 choose in e1 do e2
c.d.
References
1. The AsmL webpage, http://research.microsoft.com/foundations/AsmL/.
2. Dines Bjoerner and Cliff B. Jones (Editors), “Formal Specification and Software
Development”, Prentice-Hall International, 1982.
3. Egon Boerger and Robert Staerk, “Abstract State Machines: A Method for High-
Level System Design and Analysis”, Springer, Berlin Heidelberg 2003.
4. Foundations of Software Engineering group, Microsoft Research,
http://research.microsoft.com/fse/
5. Yuri Gurevich, “Evolving Algebra 1993: Lipari Guide”, in “Specification and Val-
idation Methods”, Ed. E. Boerger, Oxford University Press, 1995, 9–36.
6. Yuri Gurevich, “For every Sequential Algorithm there is an Equivalent Sequential
Abstract State Machine”, ACM Transactions on Computational Logic 1:1 (2000),
pages 77–111.
7. Yuri Gurevich and Nikolai Tillmann, “Partial Updates: Exploration”, Springer J.
of Universal Computer Science, vol. 7, no. 11 (2001), pages 918-952.
8. Yuri Gurevich, Benjamin Rossman and Wolfram Schulte, “Semantic Essence of
AsmL”, submitted for publication. A preliminary version appeared as Microsoft
Research Technical Report MSR-TR-2004-27, March 2004.
9. James K. Huggins, ASM Michigan web page, http://www.eecs.umich.edu/gasm.
10. Atsushi Igarashi, Benjamin C. Pierce and Philip Wadler, “Featherweight Java:
a minimal core calculus for Java and GJ”, ACM Transactions on Programming
Languages and Systems (TOPLAS) 23:3 (May 2001), 396–450.
11. Gilles Kahn, “Natural semantics”, In Proc. of the Symposium on Theoretical As-
pects of Computer Science, Lecture Notes in Computer Science 247 (1987), 22–
39.
12. Robin Milner, Mads Tofte, Robert Harper, and David MacQueen, “The Definition
of Standard ML (Revised)”, MIT Press, 1997.
13. Benjamin C. Pierce, “Types and Programming Languages”, MIT Press, Cam-
bridge, Massachusetts, 2002
Semantic Essence of AsmL 259
Abstract. The aim of this paper is to show how the Model Driven Architecture
(MDA) can be used in relation with component based software engineering. A
software component only exhibits its provided or required interfaces, hence de-
fining basic contracts between components allowing one to properly wire them.
These contractually specified interfaces should go well beyond mere syntactic
aspects: they should also involve functional, synchronization and Quality of
Service (QoS) aspects. In large, mission-critical component based systems, it is
also particularly important to be able to explicitly relate the QoS contracts at-
tached to provided interfaces with the QoS contracts obtained from required in-
terfaces. We thus introduce a QoS contract model (called QoSCL for QoS Con-
straint Language), allowing QoS contracts and their dependencies to be mod-
eled in a UML2.0 modeling environment. Building on Model Driven Engineer-
ing techniques, we then show how the very same QoSCL contracts can be ex-
ploited for (1) validation of individual components, by automatically weaving
contract monitoring code into the components; and (2) validation of a compo-
nent assembly, including getting end-to-end QoS information inferred from in-
dividual component contracts, by automatic translation to a Constraint Logic
Programming language. We illustrate our approach with the example of a GPS
(Global Positioning System) software component, from its functional and con-
tractual specifications to its implementation in a .Net framework.
1 Introduction
Szyperski [22] remarked that while objects were good units for modular composition
at development time, they were not so good for deployment time composition, and he
formulated the now widely accepted definition of a software component: “a software
component is a unit of composition with contractually specified interfaces and explicit
context dependencies only. A software component can be deployed independently and
is subject to composition by third-party”. In this vision, any composite application is
viewed as a particular configuration of components, selected at build-time and con-
figured or re-configured at run-time, as in CORBA [15], or .NET [20].
A software component only exhibits its provided or required interfaces, hence de-
fining basic contracts between components allowing one to properly wire them.
F.S. de Boer et al. (Eds.): FMCO 2003, LNCS 3188, pp. 260–275, 2004.
© Springer-Verlag Berlin Heidelberg 2004
An MDA Approach to Tame Component Based Software Development 261
These contractually specified interfaces should go well beyond mere syntactic as-
pects: they should also involve functional, synchronization and Quality of Service
(QoS) aspects. In large, mission-critical component based systems, it is also particu-
larly important to be able to explicitly relate the QoS contracts attached to provided
interfaces with the QoS contracts obtained from required interfaces.
It is then natural that people resorted to modelling to try to master this complexity.
According to Jeff Rothenberg, “Modeling, in the broadest sense, is the cost-effective
use of something in place of something else for some cognitive purpose. It allows us
to use something that is simpler, safer or cheaper than reality instead of reality for
some purpose. A model represents reality for the given purpose; the model is an ab-
straction of reality in the sense that it cannot represent all aspects of reality. This
allows us to deal with the world in a simplified manner, avoiding the complexity,
danger and irreversibility of reality.” Usually in science, a model has a different na-
ture that the thing it models. Only in software and in linguistics a model has the same
nature as the thing it models. In software at least, this opens the possibility to auto-
matically derive software from its model. This property is well known from any com-
piler writer (and others), but it was recently be made quite popular with an OMG
initiative called the Model Driven Architecture (MDA).
The aim of this paper is to show how MDA can be used in relation with compo-
nent based software engineering. We introduce a QoS contract model (called QoSCL
for QoS Constraint Language), allowing QoS contracts and their dependencies to be
modeled in a UML2.0 [13] modeling environment. Building on Model Driven Engi-
neering techniques, we then show how the very same QoSCL contracts can be ex-
ploited for (1) validation of individual components, by automatically weaving con-
tract monitoring code into the components; and (2) validation of a component assem-
bly, including getting end-to-end QoS information inferred from individual compo-
nent contracts, by automatic translation to a Constraint Logic Programming.
The rest of the paper is organized as follows. Using the example of a GPS (Global
Positioning System) software component, Section 2 introduces the interest of model-
ling components, their contracts and their dependencies, and describes the QoS Con-
straint Language (QoSCL). Section 3 discusses the problem of validating individual
components against their contracts, and proposes a solution based on automatically
weaving reusable contract monitoring code into the components. Section 4 discusses
the problem of validating a component assembly, including getting end-to-end QoS
information inferred from individual component contracts by automatic translation to
a Constraint Logic Programming. This is applied to the GPS system example, and
experimental results are presented. Finally, Section 5 presents related works.
the required and provided services implemented by the modelled artifact. The rela-
tionship between the required and provided services within one component must be
explicitly stated. The knowledge of this relationship is of utmost importance to the
component-based application designer. In the rest of this section, we address this
relationship using the example of a GPS device.
A GPS device computes its current location from satellite signals. Each signal con-
tains data which specifies the identity of the emiting satellite, the time of its emission,
the orbital position of the satellite and so on. In the illustrating example, each satellite
emits a new data stream every fifteen seconds.
In order to compute its current location, the GPS device needs at least three signals
from three different satellites. The number of received signals is unknown a priori,
because obstacles might block the signal propagation.
Our GPS device is modeled as a component which provides a getLocation() ser-
vice, and requires a getSignal() service from Satellites components. The GPS compo-
nent is made up of four components:
− the decoder which contains twelve satellite receivers (only three are shown on
Fig. 1). This element receives the satellite streams and demutiplexes it in order to
extract the data for each satellite. The number of effective data obtained via the
getData() service depends not only on the number of powered receivers, but also
on the number of received signals. Indeed, this number may change at any time.
− The computer which computes the current location (getLocation()) from the data
(getData()) and the current time (getTime()).
− The battery which provides the power (getPower()) to the computer and the de-
coder.
− The clock component which provides the current time (getTime()).
GPS
decoder
computer getSignal()
getLocation() getData()
receiver satellite
receiver satellite
getTime() getPower()
receiver satellite
clock battery
havior is specified by using Boolean assertions for each service offered, called pre and
post-conditions, as well as class invariants [14]. The third level adds synchronization
constraints and the fourth level provides extra-functional constraints. To be more pre-
cise, we can build on the well-known idea of design-by-contract [12] negotiable con-
tracts for components. These contracts ensure that a service will perform correctly.
In the previous section 2.1, we have said that a dependency relationship always ex-
ists inside one component between its provided and required services. A component
provides its services inasmuch as its environment provides the services that it re-
quires. All components always support this implicit contract. The extra-functional
properties, which are intrinsic features of services, inherit this dependency relation-
ship. The quality of a provided service depends on the quality of required services
that it depends on. This fact is illustrated in our example.
The GPS application contains several time out constraints. For instance, the pro-
vided getLocation() service must ensure that it is completed in a delay less than 30s,
whereas the getData() service must be completed in less than 25 s for example.
However, it is obvious that the time spent to acquire data from the decoder, de-
noted TethaD, has a direct impact on the global cost in time of the getLocation()
service, denoted ThetaC. Not only ThetaC depends on ThetaD, but also on the num-
ber of active receivers, denoted Nbr, because of the interpolation algorithm imple-
mented by the Computer component. ThetaD and Nbr are two extra-functional prop-
erties associated to the getData() service provided by the Decoder component. The
relation that binds these three quantities is:
ThetaC = ThetaD + Nbr * log ( Nbr ) . (1)
Each receiver demultiplexes a signal, in order to extract the data. This operation
has a fixed time cost: nearly 2 seconds. In addition, the demultiplexed signals must be
transformed into a single data vector. This operation takes 3 s. If ThetaR (resp.
ThetaS) denotes the time spent by the receiver to complete the getDatal() service
(resp. the satellite to complete its getSignal() service), then we have the two follow-
ing formulae:
ThetaR = ThetaS + 2 , (2)
ThetaD = max ( ThetaR ) + 3 . (3)
There exist many QoS contracts languages which allow the designer to specify the
extra-functional properties and their constraints on the provided interfaces only (see
section 5). However, none of them allow specifying dependency relationships be-
tween the provided and required services of a component. To overcome this limita-
tion we introduce the QoS Constraint Language (QoSCL). This language includes the
fundamental QoS concepts defined in the well-known precursor QML [5]. It is the
cornerstone to implement in a second time a QoS prediction tool.
Our own contract model for extra-functional contracts extends the UML2.0 compo-
nents metamodel. We designed the QoSCL notation with the following objectives in
mind.
264 J.-M. Jézéquel, O. Defour, and N. Plouzeau
UML2.0 QoSCL
Component QoSComponent
formalParameter type
Parameter Type
body, pre, post
Constraint
With the QoSCL metamodel, it is possible to specify contracts, such as the Time-
Out contract useful for our GPS, as an Interface in any UML case tool:
« interface »
TimeOutContract
+timeOut():bool +dimension
+start():bool
« operation »
+onTimeE vent(source:object, e:ElapsedEventArgs)
delay
+return:double
TimeOutC
-delay:double
+delay():double
+timeOut():bool
+start():bool
+isValid():bool
+onTimeE vent(source:object, e:ElapsedEventArgs)
Level 3 contracts (i.e. contracts that include protocols) are more difficult to test be-
cause of non-deterministic behaviours of parallel and distributed implementations.
One of the most difficult problems is the consistent capture of data on the behaviour
of the system's elements. Level 4 contracts (i.e. extra-functional properties) are also
difficult to test for quite similar reasons. Our approach for testing level 4 contracts
relies on the following features:
− existence of probes and extra-functional data collection mechanisms (monitors);
− test cases;
− oracles on extra-functional properties.
In order to be testable, a component must provide probe points where basic extra-
functional data must be available. There are several techniques to implement such
probe points and make performance data available to the test environment.
1. The component runtime may include facilities to record performance data on
various kinds of resources or events (e.g. disk operations, RPC calls, etc). Mod-
ern operating systems and component frameworks now provide performance
counters that can be “tuned” to monitor runtime activity and therefore deduce
performance data on the component’s service.
2. The implementation of the component may perform extra computation to monitor
its own performance. This kind of “self monitoring” is often found in compo-
nents that are designed as level 4 component from scratch (e.g. components pro-
viding multimedia services).
3. A component can be augmented with monitoring facilities by weaving a specific
monitor piece of model or of code. Aspect-oriented design (AOD) or aspect-
oriented programming can help in automating this extension.
We have chosen this latter approach as our main technique for designing monitors.
This choice was motivated mainly by the existence of “legacy” components from
industrial partners [17]. From a software design process point of view, we consider
that designing monitors is a specialist’s task. Monitors rely on low level mechanisms
and/or on mechanisms that are highly platform dependant. By using aspect-oriented
design (AOD), we separate the component implementation model into two main
models: the service part that provides the component’s functional services under
extra-functional contracts, and the monitor part that supervises performance issues. A
designer in charge of the “service design model” does not need to master monitor
design. A specific tool1 (a model transformer) [24] is used to merge the monitor part
of the component with its service part.
More precisely, a contract monitor designer provides component designers with a
reusable implementation of a monitor. This implementation contains two items: a
monitor design model and a script for the model transformer tool (a weaver). The
goal of this aspect weaver is to modify a platform specific component model by inte-
grating new QoSCL classes and modifying existing class and their relationships.
1 The Kase tool is developed by TU-Berlin with the support of the European Project “Quality
Control of Component-based Software” (QCCS) [17].
An MDA Approach to Tame Component Based Software Development 267
As we have said in the last paragraph of section 2, QoSCL allows us to model the
structural, behavioral and contractual components features. These three aspects can be
specified using the dedicated UML2.0 diagrams. The QoS aspect weaver is a mecha-
nism integrated into Kase, which:
− modifies the UML diagram (add new classes and associations)
− modifies the behavior of the targeted service
Thanks to QoSCL, it is possible to specify into Kase the contract types and their
implementation such as TimeOut and TimeOutC (Fig. 4). According to our vision,
detailed in the QoSCL section (§2.3), the TimeOut contract is an interface, which has
a special operation denoting the “delay” dimension. The TimeOutC is a .Net class that
implements the TimeOut interface. The value of the “delay” dimension is imple-
mented like a private attribute (-delay:double) and its related access/evaluation
method (delay():double).
A QoS aspect not only specifies how the structural diagram will be modified, but
also how the monitored part and the monitor cooperate: when does the timer start,
when does it stop, who handles timeout, etc… This part of the aspect is specified
using the Hierarchical Message Sequence Charts (HMSC) notation in the UML 2.0.
Fig. 5 shows the behavior of a contractual service, called op(), as a HMSC diagram.
The op() operation is the service which must verify a TimeOut contract. The op_c()
operation is a new operation, which realizes the op() service and evaluates the Time-
Out contract below (Fig. 5). This service has two possible behaviors, depending on
whether the op() service finishes before or after the timer.
Contract
« delegate » « interface »
MyDelegate
ContractType
ContractType
+myDelegate():bool +isValid():bool
Dimension
TimeOut
System
« interface »
TimeOut Contract ComponentModel
+timeOut():bool Component
+start():bool
« operation »
+onTimeEvent(source:object, e:ElapsedE ventArgs)
delay
+return:double
Timer
TimeOut C Timer
-delay:double
+delay():double
ElapsedEventArgs
+timeOut():bool
+start():bool ContractQoSCL
+isValid():bool
+onTimeEvent(source:object, e:ElapsedE ventArgs)
In addition of its structural (Fig. 4) and behavioral (Fig. 5) parts, a contractual QoS
aspect has pre-conditions that must be met at weaving time. For example, a :Cl class
abides a TimeOut contract under the condition that it implements the op() service of
course. In our tool, the aspect is concretely weaved in the UML diagram by a Python
script, which:
− checks the aspect pre-conditions;
− weaves the aspect if these preconditions are satisfied, and this weaving adds new
classes, modifies constructors and operations, etc).
The QoS aspect weaver implemented in the Käse tool allows us to:
− specify a QoS aspect;
− implement an evaluation of this aspect for a targeted service.
According to the QoSCL point of view, contracts can be specified at design time as
specialized interfaces. Therefore, connecting two components at binding time is easy,
using their respectively compliant required and provided interfaces. The QoS aspect
weaver implemented in Käse allows to implement in C# any contract type.
In case of failure, an extra-functional contract can be renegotiated. For instance, a
time out contract that fails too often obviously needs to be adjusted (alternatively the
service bound to that contract has to be shut down).
The QoSCL notation and the monitor integration technique help the component
designer to define and check extra-functional properties. However, application
designers rely on component assemblies to build applications. These designers
need to estimate at design time the overall extra-functional properties of a given
assembly. Using the techniques presented above, they can perform a kind of inte-
gration testing. The tests aim at validating the extra-functional behavior of the
assembly with respect to the global specification of the application. However, the
application designers often have trouble to select and configure the components,
make the assembly and match the global application behavior. Conversely, some
applications are built with preconfigured components and the application designer
needs to build a reasonable specification of the overall extra-functional behavior of
the application.
provided
« QoSComponent »
required
Computer
service service
getLocation() getData()
provided required
thetaC( thetaD, nbr, P) thetaD()
qualities eps( thetaD, nbr, P) nbr() qualities
required required
getPower() P()
service qualities
In this section we present the set of constraints for the GPS component-based model
(Fig. 1). A first subset of constraints defines possible or impossible values for a QoS
property. These admissible value sets come on the one hand from implementation or
technological constraints and on the other hand from designers’ and users’ require-
ments about a service. The fact that the Nbr value is 3, 5 or 12 (2), or ThetaC and
ThetaD values must be real positive values (3-4) belongs to the first category of con-
An MDA Approach to Tame Component Based Software Development 271
straints. Conversely, the facts that Eps is at least medium (5) and P is less or equal
than 15mW (6) are designers or users requirements.
Nbr ∈ {3, 5, 12}, (2)
ThetaC ≥ 0, (3)
ThetaD ≥ 0, (4)
Eps ∈ {medium, high}, (5)
P ≤ 15. (6)
Secondly, constraints can also explain the dependency relationships that bind the
QoS properties of a component. For instance, the active power level P is linearly
dependent on the Nbr number of receivers according to the formula:
P = 3 * Nbr. (7)
Moreover, the time spent by the getLocation() service (ThetaC) depends on the
time spend by the getData() service (ThetaD) and the number of data received (Nbr),
according the equation (1). Lastly, a rule binds the precision Eps, the time spent to
compute the current position ThetaC and the number of received data (Nbr). The
following diagram (Fig. 7) presents this rule:
Fig. 7. The rule that binds the Eps, Nbr and ThetaC dimensions
All these constraints, expressed in OCL syntax, can be translated into a specific
CLP-compliant language, using a Model Transfomation [24]. For instance, we pre-
sent below the result of a such transformation applied to the computer QoSCompo-
nent (Fig. 6) and its OCL conditions (using the Eclipse™ syntax):
01- computer( [ ThetaC, Eps, P, ThetaD, Nbr ] ) :-
02- ThetaC $>= 0, Eps = high, P $>= 0,
03- ThetaD $>= 0, member( Nbr, [3,5,12]),
04- ThetaC $>= 0, ThetaD $>= 0,
05- ThetaC $= ThetaD + Nbr * log(Nbr),
06- P $= Nbr * 3,
07- rule( Eps, ThetaC, Nbr).
08-
09- rule( medium, ThetaC, 3) :- ThetaC $=< 25.
10- rule( low, ThetaC, 3) :- ThetaC $> 25.
11- rule( high, ThetaC, 5) :- ThetaC $=< 24.
12- rule( medium, ThetaC, 5) :- ThetaC $>24,
272 J.-M. Jézéquel, O. Defour, and N. Plouzeau
The requirement about the estimated position (Eps = high) implies that:
− the number of data channels must be either 5 or 12,
− consequently, the active power is either 15 or 36mW,
− and the response times of the getLocation() ands getData() services are respec-
tively in the [3.49; 32.0] and [0.0; 20.51] real intervals.
At this time, the designer knows the qualitative behavior of all of its components.
It is also possible to know the qualitative behavior of an assembly, by conjunction of
the constraints systems and unification of their QoS properties.
The following constraint program shows the example of the GPS component:
19- satellite( [ ThetaS ] ) :-
20- ThetaS $>= 15, ThetaS $=< 30.
21-
22- battery( [ P ] ) :-
23- P $>= 0,
24- P $=< 15.
25-
26- receiver( [ ThetaR, ThetaS ] ) :-
27- ThetaR $>= 0, ThetaS $>= 0,
28- ThetaR $= ThetaS + 2.
29-
30- decoder( [ ThetaD, ThetaS, Nbr ] ) :-
31- ThetaD $>= 0, ThetaS $>= 0,
32- member( Nbr, [3,5,12]),
33- receiver( [ ThetaR, ThetaS ] ),
34- ThetaD $= ThetaR + 3.
35-
36- gps( [ ThetaC, Eps, ThetaS ] ) :-
37- ThetaC $>= 0, Eps = high, ThetaS $>= 0,
An MDA Approach to Tame Component Based Software Development 273
The strong requirement on the precision of the computed location implies that the
satellite signals have to be received by the GPS component with a delay less than
15.5 s. In this case, the location will be computed in less than 24 s.
5 Related Work
References
1. Aagedal J.O.: “Quality of service support in development of distributed systems”. Ph.D
thesis report, University of Oslo, Dept. Informatics, March 2001.
An MDA Approach to Tame Component Based Software Development 275
2. Beugnard A., Jézéquel J.M., Plouzeau N. and Watkins D.: “Making components contract
aware” in Computer, pp. 38–45, IEEE Computer Society, July 1999.
3. Cheung R.C.: “A user-oriented software reliability model” in IEEE Transactions on Soft-
ware Engineering vol. 6 (2), pp. 118–125, 1980.
4. de Roever W.P.: “The need for compositional proof systems: a survey” in Proceedings of
the Int. Symp. COMPOS’97, Bad Malente, Germany, Sept. 8–12, 1997.
5. Frolund S. and Koistinen J.: “QoS specification in distributed object systems” in Distrib-
uted Systems Engineering, vol. 5, July 1998, The British Computer Society.
6. Gotlieb A., Botella B. and Rueher M.: “Automatic test data generation using constraint
solving techniques” in ACM Int. Symp. on Software Testing and Analysis (ISSTA'98),
also in Software Engineering Notes, 23(2):53–62, 1998.
7. Halbwachs N., Caspi P., Raymond P. and Pillaud D.: “The synchronous data flow pro-
gramming language LUSTRE” in Proc. of IEEE, vol. 79, pp.1305–1320, Sept. 1991.
8. McHale C.: “Synchronization in concurrent object-oriented languages: expressive power,
genericity and inheritance”. Doctoral dissertation, Trinity College, Dept. of computer sci-
ence, Dublin, 1994.
9. Marre B. and Arnould A.: “Test sequences generation from luster descriptions: Gatel” in
th
15 IEEE Int. Conf. On Automated Software Engineering (ASE), pp. 229–237, Sept.
2000, Grenoble, France.
10. Meudec C.: “Automatic generation of software test cases from formal specifications”. PhD
thesis, Queen’s University of Belfast, 1998.
nd
11. Meyer B.: “Object oriented software construction”, 2 ed., Prentice Hall, 1997.
12. Meyer B.: “Applying design by contract” in IEEE Computer vol. 25 (10), pp. 40–51, 1992.
13. Object Management Group: “UML Superstructure 2.0”, OMG, August 2003.
14. Object Management Group: “UML2.0 Object Constraint Language RfP”, OMG, July 2003.
15. Object Management Group: “CORBA Components, v3.0”, adopted specification of the
OMG, June 2002.
16. Object Management Group: “UML profile for schedulability, performance and time speci-
fication”. OMG adopted specification no ptc/02-03-02, March 2002.
17. http://www.qccs.org, Quality Control of Component-based Software (QCCS) European
project home page.
18. Reussner R.H.: “The use of parameterized contracts for architecting systems with software
th
components” in Proc. of the 6 Int. Workshop on Component-Oriented Programming
(WCOP’01), June 2001.
19. Reusnerr R.H., Schmidt H.W. and Poernomo I.H.: “Reliability prediction for component-
based software architecture” in the Journal of Systems and Software, vol. 66, pp.
241–252, 2003.
20. Richter, J.: “Applied Microsoft .Net framework programming”. Microsoft Press, January
23, 2002.
21. Stafford J. and Scott H.: “The Software Engineering Institute’s Second Workshop on
Predictable Assembly: Landscape of compositional predictability”. SEI report no
CMU/SEI-2003-TN-029, 2003
nd
22. Szyperski, C.: “Component software, beyond object-oriented programming”, 2 ed.,
Addison-Wesley, 2002
23. Wallnau K.: “Volume III: A technology for predictable assembly from certifiable compo-
nents”. SEI report no CMU/SEI-2003-TR-009.
24. Weis T. and al.: “Model metamorphosis” in IEEE Software, September 2003, p. 46–51.
25. Whittaker J.A. and Thomason M.G.: “A Markov chain model for statistical software test-
ing” in IEEE Transactions on Software Engineering vol.20 (10), pp.812–824, 1994.
An Application of Stream Calculus to
Signal Flow Graphs
J.J.M.M. Rutten
CWI and VUA, P.O. Box 94079, 1090 GB Amsterdam, The Netherlands
1 Summary
The present paper can be seen as an exercise in the author’s stream calculus
[Rut01] and gives a new proof for an existing result about stream circuits. Such
circuits are also known under the name of signal flow graphs, and are built from
(scalar) multipliers, copiers (fan-out), adders (element-wise sum), and registers
(here: one-element memory cells, aka delays). Because of the presence of mem-
ory, the input-output behaviour of these circuits is best described in terms of
functions from streams to streams (of real numbers). The main statement of
this paper (Theorem 6), gives a characterization of the input-output behaviour
of finite stream circuits in terms of so-called rational streams. It is well-known
in the world of signal processing, where it is formulated and proved in terms
of the Z-transform (a discrete version of the Laplace transform) and transfer
functions (see for instance [Lah98, p.694]). These transforms are used as repre-
sentations of streams of (real or complex) numbers. As a consequence, one has
to deal with two different worlds, and some care is required when moving from
the one to the other. In contrast, we use stream calculus to formulate and obtain
essentially the same result. What is somewhat different and new here is that we
use only streams and nothing else. In particular, expressions for streams such as
1
(1−X)2 = (1, 2, 3, . . .), are not mere representations but should be read as formal
identities. Technically, the formalism of stream calculus is simple, because it uses
the constant stream X = (0, 1, 0, 0, 0, . . .) as were it a formal variable (cf. work
on formal power series such as [BR88]).
We find it worthwhile to present this elementary treatment of signal flow
graphs for a number of reasons:
F.S. de Boer et al. (Eds.): FMCO 2003, LNCS 3188, pp. 276–291, 2004.
c Springer-Verlag Berlin Heidelberg 2004
An Application of Stream Calculus to Signal Flow Graphs 277
Stream calculus has been mainly developed as a playground for the use of
coinduction definition and proof principles (see [Rut01]). In particular, streams
and stream functions can be elegantly defined by so-called stream differential
equations. For the elemenary operations on streams that are used in this paper
(sum, convolution product and its inverse), the more traditional definitions of
the necessary operations on streams suffice and therefore, coinduction is not
discussed here.
Acknowledgements. Thanks are due to the referees for their critical yet con-
structive remarks.
to view real numbers as streams in the following manner. We define for every
r ∈ IR a stream [r] ∈ IRω by
[r] = (r, 0, 0, 0, . . .)
[ ] : IR → IRω , r → [r]
which embeds the set of real numbers into the set of streams. This definition
allows us to add and multiply real numbers r with streams σ, yielding:
[r] + σ = (r, 0, 0, 0, . . .) + σ
= (r + σ0 , σ1 , σ2 , σ3 . . .)
[r] × σ = (r, 0, 0, 0, . . .) × σ
= (r · σ0 , r · σ1 , r · σ2 , . . .)
−σ ≡ [−1] × σ
= (−σ0 , −σ1 , −σ2 , . . .)
[r] + [s] = [r + s]
σ+0=σ
σ+τ =τ +σ
σ + (τ + ρ) = (σ + τ ) + ρ
[r] × [s] = [r · s]
0×σ =0
1×σ =σ
σ×τ =τ ×σ
σ × (τ + ρ) = (σ × τ ) + (σ × ρ)
σ × (τ × ρ) = (σ × τ ) × ρ
Particularly simple are those streams that from a certain point onwards are
constant zero:
σ = (r0 , r1 , r2 , . . . , rn , 0, 0, 0, . . .)
An Application of Stream Calculus to Signal Flow Graphs 279
for n ≥ 0 and r0 , . . . , rn ∈ IR. Using the following constant, we shall see that
there is a very convenient way of denoting such streams: we define
X = (0, 1, 0, 0, 0, . . .)
It satisfies, for all r ∈ IR, σ ∈ IRω , and n ≥ 0:
r × X = (0, r, 0, 0, 0, . . .)
X × σ = (0, σ0 , σ1 , σ2 , . . .)
X n = (0, . . . , 0, 1, 0, 0, 0, . . .)
n times
For instance, 2+3X −8X 3 = (2, 3, 0, −8, 0, 0, 0, . . .). More generally, we have,
for all n ≥ 0 and all r0 , . . . , rn ∈ IR:
r0 + r1 X + r2 X 2 + · · · + rn X n = (r0 , r1 , r2 , . . . , rn , 0, 0, 0, . . .)
Such streams are called polynomial streams. Note that although a polynomial
stream such as 2 + 3X − 8X 3 looks like a (polynomial) function f (x) = 2 + 3x −
8x3 , for which x is a variable, it really is a stream, built from constant streams
(2, 3, 8, and X), and the operations of sum and product. At the same time, it
is true that we can calculate with polynomial streams in precisely the same way
as we are used to compute with (polynomial) functions, as is illustrated by the
following example (here we use the basic properties of sum and product listed in
Proposition 1): (2−X)+(1+3X) = 3+2X and (2−X)×(1+3X) = 2+5X −3X 2 .
We shall need to solve linear equations in one unknown τ , such as
τ = 1 + (X × τ ) (1)
(where, recall, 1 = (1, 0, 0, 0, . . .)). Ideally, we would like to solve (1) by reasoning
as follows:
τ = 1 + (X × τ )
⇒ τ − (X × τ ) = 1
⇒ (1 − X) × τ = 1
1
⇒τ =
1−X
Recall that we are not dealing with functions but with streams. Therefore it
is not immediately obvious what we mean by the ‘inverse’ of a stream 1 − X =
(1, −1, 0, 0, 0, . . .). There is however the following fact: for any stream σ such
that σ0 = 0, there exists a unique stream τ such that σ × τ = 1. A proof of this
fact can be given in various ways:
(a) Using the definition of convolution product, one can easily derive the follow-
ing recurrence relation
1
n−1
τn = · σn−k · τk
σ0
k=0
(b) Alternatively and equivalently, one can use the algorithm of long division to
obtain τ out of σ.
(c) Our personal favourite is a method described in [Rut01], where we have
introduced the operation of inverse by means of so-called stream differ-
ential equations, formulated in terms of the notions of stream derivative
σ = (σ1 , σ2 , σ3 , . . .) and initial value σ0 for σ ∈ IRω . (In fact, all the opera-
tions on IRω are there introduced by means of such equations.)
Now we can simply define the inverse σ1 of a stream σ with σ0 = 0 as the
unique stream τ such that σ × τ = 1. Here are a few examples that can be easily
computed using any of the methods (a)-(c) above:
1
= (1, 1, 1, . . .)
1−X
1
= (1, 0, 1, 0, 1, 0, . . .)
1 − X2
1
= (1, 2, 3, . . .)
(1 − X)2
As with sum and product, we can calculate with the operation of inverse in
the same way as we compute with functions: For all σ, τ ∈ IRω with σ0 = 0 = τ0 ,
1
σ× =1
σ
1 1 1
× =
σ τ σ×τ
1
1 =σ
σ
Using the various properties of our operators, it is straightforward to see that
in the calculus of streams, we can solve linear equations as usual. Consider for
instance the following system of equations:
σ = 1 + (X × τ )
τ =X ×σ
In order to find σ and τ , we compute as follows: σ = 1 + (X × τ ) = 1 + (X ×
X × σ) = 1 + (X 2 × σ). This implies σ − (X 2 × σ) = 1 and (1 − X 2 ) × σ = 1.
1 X
Thus σ = 1−X 2 and τ = 1−X 2 .
r0 + r 1 X + r 2 X 2 + · · · + r n X n
σ=
s0 + s1 X + s2 X 2 + · · · + sm X m
'
An Application of Stream Calculus to Signal Flow Graphs 281
3 Stream Circuits
Certain functions from IRω to IRω can be represented by means of graphical
networks that are built from a small number of basic ingredients. Such networks
can be viewed as implementations of stream functions. We call them stream
circuits; in the literature, they are also referred to as (signal) flow graphs. Using
the basic stream calculus from Section 2, we shall give a formal but simple answer
to the question precisely which stream functions can be implemented by such
stream circuits.
The input end is denoted by the arrow shaft and the output end is
denoted by the arrow head / . For streams σ, τ ∈ IRω , we shall write
σ /τ
and say that the circuit inputs the stream σ and outputs the stream τ . Writing
the elements of these streams explicitly, this notation is equivalent to
/ (τ0 , τ1 , τ2 , . . .)
(σ0 , σ1 , σ2 , . . .)
which better expresses the intended operational behaviour of the circuit: It con-
sists of an infinite sequence of actions, at time moments 0, 1, 2, . . .. At each
moment n ≥ 0, the circuit simultaneously inputs the value σn ∈ IR at its input
end and outputs the value τn ∈ IR at its output end. In general, this value τn
depends both on the value σn and on the values σi that have been taken as
inputs at earlier time moments i < n. Note that this implies that circuits have
memory.
Next we present the four basic types of circuits, out of which all other circuits
in this section will be constructed.
(a) For every a ∈ IR, we define a circuit with one input and one output end,
called an a-multiplier , for all σ, τ ∈ IRω , by
σ a / τ ⇐⇒ τn = a · σn , all n ≥ 0
⇐⇒ τ = a × σ
This circuit takes, at any moment n ≥ 0, a value σn at its input end, multi-
plies it with the constant a, and outputs the result τn = a · σn at its output
end. It defines, in other words, a function that assigns to an input stream σ
the output stream τ = a × σ.
282 J.J.M.M. Rutten
(b) The adder circuit has two input and one output ends, and is defined, for all
σ, τ, ρ ∈ IRω by
σ
+ /ρ ⇐⇒ ρn = σn + τn , all n ≥ 0
$ ⇐⇒ ρ = σ + τ
τ
At moment n ≥ 0, the adder simultaneously inputs the values σn and τn at
its input ends, and outputs their sum ρn = σn + τn at its output end.
(c) The copier circuit has one input and two output ends and is defined, for all
σ, τ, ρ ∈ IRω , by
1τ
σ c ⇐⇒ τn = σn = ρn , all n ≥ 0
-ρ ⇐⇒ τ = σ = ρ
At any moment n ≥ 0, the copier inputs the value σn at its input end, and
outputs two identical copies τn and ρn at its output ends.
(d) A register circuit has one input and one output end and is defined, for all
σ, τ ∈ IRω , by
σ R / τ ⇐⇒ τ0 = 0 and τn = σn−1 , all n ≥ 1
⇐⇒ τ = (0, σ0 , σ1 , σ2 , . . .)
The register circuit can be viewed as consisting of a one-place memory cell
that initially contains the value 0. The register starts its activity, at time
moment 0, by outputting its value τ0 = 0 at its output end, while it simulta-
neously inputs the value σ0 at its input end, which is stored in the memory
cell. At any future time moment n ≥ 1, the value τn = σn−1 is output and
the value σn is input and stored. (For obvious resaons, the register circuit is
sometimes also called a unit delay.) Recalling that for the constant stream
X = (0, 1, 0, 0, 0, . . .), we have X × σ = (0, σ0 , σ1 , σ2 , . . .), it follows that for
all σ, τ ∈ IRω ,
σ R / τ ⇐⇒ τ = X × σ
⇐⇒ ∃ρ ∈ IRω : σ 2 / ρ and ρ 3 /τ
Note that the stream ρ is uniquely determined by the stream σ. The motiva-
tion for our notation “∃ρ” is not so much to suggest that there might be more
possible candidate streams for ρ, but rather to emphasise the fact that in order
to express the output stream τ in terms of σ, we have to compute the value of
the stream ρ in the middle.
We can compose circuits, more generally, with several output ends with cir-
cuits having a corresponding number of input ends, as in the following example:
0◦
c + /
.◦!
In this example, the behaviour of the resulting circuit is defined, for all σ, τ ∈
IRω , by
0◦
σ c + /τ
.◦!
⇐⇒ 2 ∃γ
σ c + /τ
, ∃δ $
284 J.J.M.M. Rutten
⇐⇒ 0γ γ
/τ
∃γ, δ ∈ IRω : σ c and +
"
.δ δ
⇐⇒ ∃γ, δ ∈ IRω : σ = γ = δ and τ = γ + δ
⇐⇒ τ = 2 × σ
It will be convenient to have adders with more than two inputs and, sim-
ilarly, copiers with more than two outputs. We define a ternary adder as the
composition of two binary adders as follows:
! !
+ / ≡ /◦
+
! ! /
+
For input streams σ, τ, ρ ∈ IRω , it produces the output stream σ + τ + ρ. We
define a ternary copier by the following composition:
/ .
c /≡ c /
. .◦ c /
It takes one input stream and produces three identical copies as output
streams. Adders and copiers with four or more inputs and outputs can be con-
structed in a similar fashion.
The following circuit combines (various instances of) all four basic circuit
types:
0◦ 2 /◦
c /◦ 3 /◦ R /◦ + /
.◦ /◦ R /◦ R /◦
−7
In order to express the output stream τ for a given input stream σ, we have
to compute one intermediate stream for each of the (nine) internal nodes ◦ in
the circuit above. Using the definitions of the basic circuits, and computing from
left to right, we find:
0σ 2 / 2σ
σ c /σ 3 / 3σ R / 3Xσ + /τ
(To save space, we have omitted the symbol × for multiplication.) We can
now express the output stream τ in terms of the input stream σ as follows:
τ = (2 × σ) + (3X × σ) + (−7X 2 × σ)
= (2 + 3X − 7X 2 ) × σ
The circuit above computes — we shall also say implements — the following
function on streams:
f : IRω → IRω , f (σ) = (2 + 3X − 7X 2 ) × σ
If we supply the circuit with the input stream σ = 1 (= (1, 0, 0, 0, . . .)) then
the output stream is τ = f (1) = 2 + 3X − 7X 2 . We call this the stream generated
by the circuit.
Convention 3. In order to reduce the size of the diagrams with which we depict
stream circuits, it will often be convenient to leave the operations of copying and
addition implicit. In this manner, we can, for instance, draw the circuit above
as follows:
2
0 &
σu 3 /◦ R / τ
D
,◦ /◦&
R
−7 R
The (respective elements of the) stream σ gets copied along each of the three
outgoing arrows. Similarly, the stream τ will be equal to the sum of the output
streams of the three incoming arrows. This convention saves a lot of writing.
Moreover, if we want to express τ in terms of σ, we now have only three internal
streams to compute. If a node has both incoming and outgoing arrows, such as
1
L
F◦r
$ -
then first the values of the output streams of the incoming arrows have to be
added; then the resulting sum is copied and given as an input stream to each of
the outgoing arrows. Consider for instance the circuit below. It has input streams
σ and τ , an intermediate stream γ, and output streams δ and in IRω :
σ 4δ
2 R
L
E γs
' R 5
+
τ
286 J.J.M.M. Rutten
satisfying
γ = 2σ + (X × τ )
δ =X ×γ
= (2X × σ) + (X 2 × τ )
= 5γ
= 10σ + (5X × τ )
'
As an example, we compute the stream function implemented by the following
circuit, with input stream σ, output stream τ , and intermediate streams γ and δ:
3γ
R
_ 5
H
σv R Dτ
,δ&
3 R
We have:
γ =X ×σ
δ = (3 × σ) + (X 2 × σ)
τ = (5 × γ) + (X × δ)
= (8X + X 3 ) × σ
Thus the stream function implemented by this circuit is f : IRω → IRω with
f (σ) = (8X + X 3 ) × σ, for all σ ∈ IRω . An equivalent circuit, implementing the
same stream stream function, is given by:
The following proposition, of which we have omitted the easy proof, charac-
terizes which stream functions can be implemented by the type of circuits that
we have been considering so far.
Proposition 4. For all n ≥ 0 and r0 , . . . , rn ∈ IR, each of the following two
circuits:
3◦ r0 /◦
and
implements the stream function f : IRω → IRω given, for all σ ∈ IRω , by
f (σ) = ρ × σ
ρ = r0 + r1 X + r2 X 2 + · · · + rn−1 X n−1 + rn X n
'
◦ o ◦
_ R O
+ /◦ c /
τ = (σ0 , σ0 + σ1 , σ0 + σ1 + σ2 , . . .)
Next we show how the same answer can be obtained, more formally and
more systematically, by applying a bit of basic stream calculus. As before, we
try to express the output stream τ in terms of the input stream σ by computing
288 J.J.M.M. Rutten
ρ_1 o ρ
R
O2
σ + / ρ3 c /τ
ρ 1 = X × ρ2
ρ3 = σ + ρ1
ρ2 = ρ3
τ = ρ3
We have seen in the previous section how to solve such systems of equations.
The right way to start, which will work in general, is to compute first the output
stream of the register:
ρ1 = X × ρ 2
= X × ρ3
= X × (σ + ρ1 )
= (X × σ) + (X × ρ1 )
the stream function f : IRω → IRω that is implemented by the feedback circuit
is given, for all σ ∈ IRω , by
1
f (σ) = ×σ
1−X
We see that this function consists again of the convolution product of the
1
argument σ and a constant stream 1−X . The main difference with the exam-
ples in the previous subsections is that now this constant stream is no longer
polynomial but rational.
We still have to check that the first informal and the second formal compu-
tation of the function implemented by the feedback circuit coincide. But this
follows from the fact that, for all σ ∈ IRω ,
1
× σ = (σ0 , σ0 + σ1 , σ0 + σ1 + σ2 , . . .)
1−X
An Application of Stream Calculus to Signal Flow Graphs 289
ρ_1 o ρ
1
O2
σ + / ρ3 c /τ
In this circuit, we have replaced the register feedback loop of the example
above by a 1-multiplier. If we try to compute the stream function of this circuit
as before, we find the following system of equations:
ρ1 = 1 × ρ2
ρ 3 = σ + ρ1
ρ2 = ρ3
τ = ρ3
Assumption 5. From now on, we shall consider only circuits in which every
feedback loop passes through at least one register. '
Note that this condition is equivalent to requiring that the circuit has no
infinite paths passing through only multipliers, adders, and copiers.
Next we present the main result of the present paper. It is a characterization
of which stream functions can be implemented by finite stream circuits. We
formulate it for finite circuits that have one input and one output end, but it
can be easily generalised to circuits with many inputs and outputs.
Theorem 6. (a) Let C be any finite stream circuit, possibly containing feedback
loops (that always pass through at least one register). The stream function
f : IRω → IRω implemented by C is always of the form:
f (σ) = ρ × σ
r0 + r 1 X + r 2 X 2 + · · · + r n X n
ρ=
s0 + s1 X + s2 X 2 + · · · + sm X m
(b) Let f : IRω → IRω be a stream function of the form, for all σ ∈ IRω :
f (σ) = ρ × σ
for some fixed rational stream ρ. Then there exists a finite stream circuit C
that implements f .
Proof. (a) Consider a finite circuit C containing k ≥ 1 registers. We associate
with the input end of C a stream σ and with the output end of C a stream τ .
With the output end of each register Ri , we associate a stream αi . For the input
end of each register Ri , we look at all incoming paths that: (i) start in either
an output end of any of the registers or the input end of C, (ii) lead via adders,
copiers, and multipliers, (iii) to the input end of Ri . Because of Assumption 5,
there are only finitely many of such paths. This leads to an equation of the form
αi = (a1i × X × α1 ) + · · · + (aki × X × αk ) + (ai × X × σ)
for some ai , aji ∈ IR. We have one such equation for each 1 ≤ i ≤ k. Solving this
system of k equations in stream calculus as before, yields for each register an
expression αi = ρi × σ, for some rational stream ρi . Finally, we play the same
game for τ , at the output end of C, as we did for each of the registers. This will
yield the following type of expression for τ :
τ = (b1 × α1 ) + · · · + (bk × αk ) + (b × σ)
= ((b1 × ρ1 ) + · · · + (bk × ρk ) + b) × σ
for some b, bi ∈ IR, which proves (a). For (b), we treat only the special case that
r0 + r 1 X + r 2 X 2 + r 3 X 3
ρ=
1 + s1 X + s2 X 2 + s3 X 3
where we have taken n = m = 3 and s0 = 1. The general case is not more
difficult, just more writing. We claim that the following circuit implements the
function f (σ) = ρ × σ (all σ ∈ IRω ):
r0 r1
r2
. / *
σ / ρ0 2/ ρ1 3/ ρ2 3/ ρ3
/( τ
1 e R R R r3
−s1
−s2
−s3
where we have denoted input and output streams by σ and τ , and intermediate
streams by ρ0 , ρ1 , ρ2 , ρ3 . They satisfy the following equations:
ρ0 = σ − (s1 × ρ1 ) − (s2 × ρ2 ) − (s3 × ρ3 )
ρ1 = X × ρ0
ρ2 = X × ρ1
ρ3 = X × ρ2
τ = (r0 × ρ0 ) + (r1 × ρ1 ) + (r2 × ρ2 ) + (r3 × ρ3 )
An Application of Stream Calculus to Signal Flow Graphs 291
It follows that
Xi
ρi = ×σ
1 + s1 X + s2 X 2 + s3 X 3
This implies
r 0 + r 1 X + r2 X 2 + r 3 X 3
τ= ×σ
1 + s1 X + s2 X 2 + s3 X 3
whereby the claim above is proved. '
References
[AR03] F. Arbab and J.J.M.M. Rutten. A coinductive calculus of component con-
nectors. In M. Wirsing, D. Pattinson, and R. Hennicker, editors, Proceedings
of WADT 2002, volume 2755 of LNCS, pages 35–56. Springer, 2003.
[BR88] J. Berstel and C. Reutenauer. Rational series and their languages, volume 12
of EATCS Monographs on Theoretical Computer Science. Springer-Verlag,
1988.
[Lah98] B.P. Lahti. Signal Processing & Linear Systems. Oxford University Press,
1998.
[Rut01] J.J.M.M. Rutten. Elements of stream calculus (an extensive exercise in coin-
duction). In S. Brooks and M. Mislove, editors, Proceedings of MFPS 2001,
volume 45 of ENTCS, pages 1–66. Elsevier Science Publishers, 2001. To ap-
pear in MSCS.
Synchronous Closing and Flow Analysis for
Model Checking Timed Systems
1 Introduction
Model checking [8] is well-accepted for the verification of reactive systems. To al-
leviate the notorious state-space explosion problem, a host of techniques has been
invented, including partial-order reduction [12, 32] and abstraction [23, 8, 10].
F.S. de Boer et al. (Eds.): FMCO 2003, LNCS 3188, pp. 292–313, 2004.
c Springer-Verlag Berlin Heidelberg 2004
Synchronous Closing and Flow Analysis 293
As standard model checkers, e.g., Spin [16], cannot handle open systems, one
has to construct a closed model, and a problem of practical importance is how
to close open systems. This is commonly done by adding an environment pro-
cess that must exhibit at least all the behavior of the real environment. In the
framework of the assume-guarantee paradigm, the environment should model the
behavior corresponding to the verified properties of the components forming the
environment. However, the way of closing should be well-considered to counter
the state-space explosion problem. This is especially true in the context of model
checking programs with an asynchronous message-passing communication model
—- sending arbitrary message streams to the unbounded input queues would im-
mediately lead to an infinite state space, unless some assumptions restricting the
environment behavior are incorporated in the closing process. Even so, adding
an environment process may result in a combinatorial explosion caused by all
combinations of messages in the input queues.
A desirable solution would be to construct an environment that communicates
to the system synchronously. In [29] such an approach is considered for the sim-
plest safe abstraction of the environment, the chaotically behaving environment:
the outside chaos is embedded into the system’s processes, which corresponds
to the synchronous communication scheme. Though useful at a first verification
phase, the chaotic environment may be too general. Here, we investigate for what
kind of processes, apart from the chaotic one, the asynchronous communication
can be safely replaced with the synchronous one. To make such a replacement
possible, the system should be not reactive — it should either only send or only
receive messages. However, when we restrict our attention to systems with the
discrete-time semantics like the ones of [15, 3], this requirement can be softened
in that the restrictions are imposed on time slices instead of whole runs: In every
time slice, the environmental process can either only receive messages, or it can
both send and receive messages under condition that inputs do not change the
state of the environment process.
Another problem the closing must address is that the data carried with the
messages are usually drawn from some infinite data domains. For data abstrac-
tion, we combine the approaches from [29] and [17]. The main idea is to condense
data exchanged with the environment into a single abstract value , , to deal with
the infinity of environmental data. We employ data-flow analysis to detect in-
stances of chaotically influenced variables and timers and remove them. Based
on the result of the data flow analysis, the system S is transformed into a closed
system S which shows more behavior in terms of traces than the original one.
For formulas of next-free LTL [26, 22], we thus get the desired property preser-
vation: if S |= ϕ then S |= ϕ.
The main target application are protocols specified in SDL (Specification and
Description Language) [28]. As verification tool, we use the well-known Spin
model checker. Our method is implemented as transformations of Promela-
programs, Spin’s input language. With this tool we show experiments on a
real-life protocol to estimate the effect of removing queues on the state space.
294 N. Ioustinova, N. Sidorova, and M. Steffen
2 Semantics
In this section we fix syntax and operational semantics we work with. Our model
is based on asynchronously communicating state machines with top-level con-
currency. The communication is done via channels and we assume a fixed set
Chan of channel names for each program, with c, c , . . . as typical elements. The
set of channel names is partitioned into input channels Chan i and output chan-
nels Chan o , and we write ci , co , . . . to denote membership of a channel to one of
n
these classes. A program Prog is given as the parallel composition Πi=1 Pi of a
finite number of processes.
A process P is described by a tuple (in, out, Var , Loc, Edg, σinit ), where in
and out are finite sets of input resp. output channel names of the process, Var
denotes a finite set of variables, Loc denotes a finite set of locations or control
states, and σinit is the initial state. We assume the sets of variables Var i of
n
processes Pi in a program Prog = Πi=1 Pi to be disjoint. An edge of the state
machine describes a change of state by performing an action from a set Act; the
set Edg ⊆ Loc × Act × Loc denotes the set of edges. For an edge (l, α, ˆl) ∈ Edg
of P , we write more suggestively l −→α ˆl.
A mapping from variables to values is called a valuation; we denote the set
of valuations by Val = Var → D. We assume standard data domains such as
N, Bool , etc., where we write D when leaving the data domain unspecified, and
we silently assume all expressions to be well-typed. A location together with
a valuation of process variables define a state of a process. The set of process
states is defined as Σ = Loc × Val , and each process has one designated initial
state σinit = (linit , ηinit ).
Processes communicate by exchanging signals (carrying values) over chan-
nels. Signals coming from the environment form the set of external signals Sig ext .
Signals that participate in the communication within the system belong to the
set Sig int of internal signals. Note that both signal sets are not necessarily dis-
joint.
As untimed actions, we distinguish (1) input over a channel c of a signal s
containing a value to be assigned to a local variable, (2) sending over a channel c
a signal s together with a value described by an expression, and (3) assignments.
We assume the inputs to be unguarded, while output and assignment are guarded
by a boolean expression g, its guard. The three classes of actions are written as
c?s(x), g c!s(e), and g x := e, respectively, and we use α, α . . . when leaving
an action unspecified.
Synchronous Closing and Flow Analysis 295
l −→c?s(x) ˆ
l ∈ Edg l ∈ Edg ⇒ s = s
l −→c?s(x) ˆ
Input Discard
(l, η) →ci ?(s,v) (ˆ
l, η [x → v]) (l, η) →ci ?(s ,v) (l, η)
l −→g c!(s,e) ˆl ∈ Edg [[g]]η = true [[e]]η = v
Output
(l, η) →co !(s,v) (ˆ
l, η)
l −→g x:=e ˆ
l ∈ Edg [[g]]η = true [[e]]η = v
Assign
(l, η) →τ (ˆ
l, η [x → v])
ˆ
l −→g set t:=e l ∈ Edg [[g]]η = true [[e]]η = v
Set
(l, η) →τ (ˆ
l, η [t → on(v)])
l −→g reset t ˆ
l ∈ Edg [[g]]η = true blocked (σ)
Reset TickP
(l, η) →τ (ˆ l, η [t → off ]) σ →tick σ [t →(t−1)]
ˆ
l −→gt reset t l ∈ Edg [[t]]η = on(0)
Timeout
(l, η) →τ (ˆ
l, η [t → off ])
(l −→α ˆ
l ∈ Edg ⇒ α = gt reset t) [[t]]η = on(0)
TDiscard
(l, η) →τ (l, η [t → off ])
92 [27]) is captured by rule Discard: If the input value cannot be reacted upon
at the current control state, i.e., if there is no input action originating from the
location treating this signal, then the message is just discarded, leaving control
state and valuation unchanged. The automaton is therefore input-enabled: it
cannot refuse to accept a message; it may throw it away, though.
Unlike inputs, outputs are guarded, so sending a message involves evaluat-
ing the guard and the expression according to the current valuation (cf. rule
Output). Assignment in Assign works analogously, except that the step is in-
ternal. We assume for the non-timer guards, that at least one of them evaluates
to true in each state. At the SDL source language, this assumption corresponds
to the natural requirement that each conditional construct must cover all cases,
for instance by having at least a default branch. The system should not block
because of a non-covered alternative in a decision-construct [25].
Concerning the temporal behavior, timers are treated in valuations as vari-
ables, distinguishing active and deactivated timer. We use off to represent in-
active timers. The value of an active timer shows the delay left until timer
expiration. The set-command activates a timer, setting its value to the specified
period until timer expiration, and reset deactivates the timer. Both actions are
guarded (cf. rules Set and Reset). A timeout may occur, if an active timer has
expired, i.e., reached zero (cf. rule Timeout).
Time elapses by counting down active timers till zero, which happens in case
no untimed actions are possible. In rule TickP , this is expressed by the predicate
blocked on states: blocked (σ) holds if no move is possible except either a tick -
step or a reception of a message, i.e., if σ →λ for some label λ, then λ = tick or
λ = c?(s, v). In other words, the time-elapsing steps are those with least priority.
The counting down of the timers is written η [t →(t−1)], by which we mean, all
currently active timers are decreased by one, i.e., on(n + 1) − 1 = on(n), non-
active timers are not affected. Note that the operation is undefined for on(0),
which is justified later by Lemma 1.
In SDL, timeouts are often considered as specific timeout messages kept in
a queue like any other message, and timer-expiration consequently is seen as
adding a timeout-message to the queue. We use an equivalent presentation of
this semantics, where timeouts are not put into the input queue, but are modelled
more directly by guards. The equivalence of timeouts-by-guards and timeouts-as-
messages in the presence of SDL’s asynchronous communication model is argued
for in [3]. The time semantics for SDL chosen here is not the only one conceivable
(see e.g. [6] for a broader discussion of the use of timers in SDL). The semantics
we use is the one described in [15, 3], and is also implemented in DTSpin [2, 11],
a discrete time extension of the Spin model checker.
In the asynchronous communication model, a process receives messages via
channels modelled as queues. We write for the empty queue; (s, v) :: q denotes
a queue with message (s, v) at the head of the queue, i.e., (s, v) is the message
to be input next; likewise the queue q ::(s, v) contains (s, v) most recently en-
tered; Q denotes the set of possible queues. We model the queues implementing
asynchronous channels explicitly as separate entities of the form (c, q), consist-
Synchronous Closing and Flow Analysis 297
ing of the channel name together with its queue content. We sometimes refer to
the channel process (c, q) just by its name c. We require for the input and the
output channel names of channel c to be in(c) = co and out(c) = ci resp. The
operational rules for queues are shown in Table 2.
In analogy to the tick -steps for processes, a queue can perform a tick -step iff
the only steps possible are input or tick-steps, as captured again by the blocked -
predicate (cf. rule Tick). Note that a queue is blocked and can therefore tick
only if it is empty, and that a queue does not contain any timers. Hence, the
counting down operation [t →(t−1)] has no effect and is therefore omitted in the
rule TickQ of Table 2.
In blocked (c, q)
(c, q) →co ?(s,v) (c, q ::(s, v)) TickQ
(c, q) →tick (c, q)
Out
(c, (s, v) :: q) →ci !(s,v) (c, q)
state σi being part of σ; analogously, we use the notation [[e]]σ for the value of
e in σ. The initial state of a parallel composition is given by the array of initial
process states together with (c, ) for channels in Chan. We call a sequence
σinit = σ0 →λ σ1 →λ . . . starting from an initial state a run.
Communication between two processes is done by exchanging a common sig-
nal and a value over a channel. According to the syntactic restriction on the use
of communication labels, only synchronisation between a process and a chan-
nel may happen. Sending of a signal over the channel means synchronising an
output step of the process with an input step of the queue, i.e. a co !(s, v) step
of the process is synchronised with a co ?(s, v) step of the channel c. Receiving
is accomplished by synchronising an output step, which removes first element
from the channel queue, with an input step of the process. As defined by the
rule Comm of Table 3, systems perform common steps synchronously. The result
of communication is relabelled to τ .
Communication steps of two partners may synchronize, if they use the same
channel name.Communication steps may be interleaved as in rules Interleavein
and Interleaveout provided the channel name belongs to the set of external
channel names ext(S) of the system. As far as τ steps are concerned, each system
can act on its own according to rule Interleaveτ .
Proof. For part (1), if [[t]]η = on(0) for a timer t in a process P , then a τ -step is
allowed due to either Timeout or TDiscard of Table 1. Hence, the system is
not blocked and therefore cannot do a tick -step.
Part (2) follows from the fact that a channel can only perform a tick -step
exactly when it is empty. '
1
A more general definition would require that the process actions satisfy a confluence
condition as far as the input and output actions are concerned, i.e., doing an input
action does not invalidate the possibility of an output action, and vice versa. Also
in this case, the process is not reactive, since there is no feed-back from input to
output actions.
2
A time slice of a run is a maximal subsequence of the run without tick -steps.
300 N. Ioustinova, N. Sidorova, and M. Steffen
Proof. We are given a sequence γa = γ0a →λ0 γ1a . . . →λn−1 γna = γa , with the
queues of γ0a and γna empty. According to the definition of tick -separation, we
distinguish the following two cases:
Case 1: λi ∈
/ {tick , c!(s, v)}, for all 1 ≤ i ≤ n − 1
To get a matching reduction sequence of the synchronous system starting at
γ0s , we apply the following renaming scheme. Input actions γa →c?(s,v) γa into the
queue are just omitted (which means, they are postponed for the synchronous
process). τ -steps γa →τ γa , inputting a value from the queue into the process,
i.e., τ -steps justified by rule Comm where the process does a step σ →c?(s,v) σ
by rule Input and the queue the corresponding output step by rule Out, are
replaced by a direct input steps γs →c?(s,v) γs . Process internal τ -steps of the
Synchronous Closing and Flow Analysis 301
Note that γa γs means that γs is blocked whenever γa is blocked.
We write [[P ]]wtrace to denote the set of all weak traces of process P . To prove
that for tick -separated processes [[Ps ]]wtrace = [[Pa ]]wtrace , we introduce a notion
of tick -simulation that captures the ability to simulate any sequence of steps up
to a tick step, i.e. the chosen granularity level are time slices and only the states
immediately before and after tick are of importance there. (Remember that we
assume the absence of zero-time cycles.)
Proof. There are two directions to show. [[Ps ]]wtrace ⊆ [[Pa ]]wtrace is immediate:
each communication step of the synchronous process Ps can be mimicked by
the buffered Pa with adding an internal τ -step for the communication with the
buffer.
302 N. Ioustinova, N. Sidorova, and M. Steffen
For the reverse direction [[Pa ]]wtrace ⊆ [[Ps ]]wtrace we show that Pa is simulated
by Ps according to the definition of tick -simulation, which considers as basic steps
only tick -steps or else the sequence of steps within one time slice.
We define the relation R ⊆ Γa × Γs as (σa , ((c0 , q0 ), . . . , (cm , qm )))Rσs iff
σa = σs and qi = for all queues modelling the channels. To show that R is
indeed a tick -simulation, assume γa = (σa , ((c0 , ), . . . , (cm , ))) and γs = σs
with γa Rγs . There are two cases to consider.
Case: γa →tick γa
where γa = γa [t →(t−1)]. By the definition of the tick -step, blocked (γa ) must hold,
i.e., there are no steps enabled except input from the outside or tick -steps. Since
immediately blocked (γs ), also γs →tick γs [t →(t−1)], which concludes the case.
Case: γa ⇒λ γa
where blocked (γa ) and "λ does not contain a tick -label. The case follows directly
from Lemma 4 and the fact that γa γs where γa is blocked implies that also
γs is blocked.
Since clearly the initial states are in relation R as defined above, this gives
Pa tick Ps . Since Pa tick Ps and each tick -step of Pa can be mimicked by the
tick step of Ps and each weak step ⇒λ of Pa can also be mimicked by Ps . That
implies [[Pa ]]wtrace ⊆ [[Ps ]]wtrace , as required. '
4 Abstracting Data
Originating from an unknown or underspecified environment, signals from out-
side can carry any value, which renders the system infinite state. Assuming
nothing about the data means one can conceptually abstract values from out-
side into one abstract “chaotic” value, which basically means to ignore these
data and focus on the control structure. Data not coming from outside is left
untouched, though chaotic data from the environment influence internal data
of the system. In this section, we present a straightforward dataflow analysis
marking variable and timer instances that may be influenced by the environ-
ment, namely we establish for each process- and timer-variable in each location
whether
1. the variable is guaranteed to be non-chaotic, or
2. the variable is guaranteed to be influenced by the outside, or
3. whether its status depends on the actual run.
The analysis is a combination of the ones from [29] and [17].
symbol η α for the valuation per node, i.e., for functions of type node → Val α .
The abstract valuation [[e]]ηα for an expression e equals ⊥ iff all variables in e
are evaluated to ⊥, [[e]]ηα is , iff the abstract valuation of at least one of the
variables in e is ,.
Depending on whether we are interested in an answer to point (1) or point (2)
from above, , is interpreted as a variable potentially influenced from outside,
and, dually for the second case, , stands for variables guaranteed to be influenced
from outside. Here we present may and must analysis for the first and the second
case respectively.
May Analysis. First we consider may analysis that marks variables potentially
influenced by data from outside. Each node n of the flow graph has associated
an abstract transfer function fn : Val α → Val α , describing the change of the
abstract valuations depending on the kind of action at the node. The functions
are given in Table 5. The equations are mostly straightforward; the only case de-
serving mention is the one for c?s(x), whose equation captures the inter-process
data-flow from a sending to a receiving action. It is easy to see that the transfer
functions are monotone.
Upon start of the analysis, at each node the variables’ values are assumed to
α
be defined, i.e., the initial valuation is the least one: ηinit (n) = η⊥ . This choice
rests on the assumption that all local variables of each process are properly
initialized. We are interested in the least solution to the data-flow problem given
by the following constraint set:
α
ηpost (n) ≥ fn (ηpre
α
(n))
(1)
α
ηpre (n) ≥ {ηpost
α
(n ) | (n , n) in flow relation}
α η α [x → ] s ∈ Sig ext
f (c?s(x))η =
η α [x → {[[e]]ηα |n =g c!s(e)}] s ∈ Sig ext
f (g c!s(e))η α = ηα
f (g x := e)η α = η α [x →[[e]]ηα ]
f (g set t := e)η α = η α [t → on([[e]]ηα )]
f (g reset t)η α = η α [t → off ]
f (gt reset t)η α = η α [t → off ]
304 N. Ioustinova, N. Sidorova, and M. Steffen
For each node n of the flow graph, the data-flow problem is specified by two
α
inequations or constraints. The first one relates the abstract valuation ηpre before
α
entering the node with the valuation ηpost afterwards via the abstract effects of
Table 5. The least fixpoint of the constraint set can be found iteratively in a fairly
standard way by a worklist algorithm (see e.g., [19, 14, 24]), where the worklist
steers the iterative loop until the least fixpoint is reached (cf. Figure 1).
η α (n) = ηinit
α
(n) ;
WL = {n | αn =?s(x), s ∈ Sig ext } ;
repeat
p i c k n ∈ WL ;
if n = g c!s(e) then
l e t S = {n | n = c?s(x) and [[e]]ηα (n) ≤ [[x]]ηα (n ) }
in
f o r a l l n ∈ S : η α (n ) := fn (η α (n )) ;
l e t S = {n ∈ succ(n) | fn (η α (n)) ≤ η α (n )}
in
f o r a l l n ∈ S : η α (n ) := fn (η α (n)) ;
WL := WL\{n} ∪ S ∪ S ;
u n t i l WL = ∅ ;
α
ηpre (n) = η α (n) ;
ηpost (n) = fn (η α (n))
α
Must Analysis. The must analysis is almost dual to may analysis. A transfer
function that describes the change of the abstract valuation depending on the
action at the node is defined in Table 6. For inputs, c?s(x) in process P assigns
⊥ to x if the signal is sent to P with reliable data, only. This means the values
after reception correspond to the greatest lower bound over all expressions which
can occur in a matching send-action.
η α [x → ] s ∈ Sig int
f (c?s(x))η α =
η α [x → {[[e]]ηα |n =g c!s(e)}] s ∈ Sig int
f (g c!s(e))η α = ηα
f (g x := e)η α = η α [x →[[e]]ηα ]
f (g set t := e)η α = η α [t → on([[e]]ηα )]
f (g reset t)η α = η α [t → off ]
f (gt reset t)η α = η α [t → off ]
As that is done for may analysis, the data-flow problem is specified for each
node n of the flow graph by two inequations (2) (see Table 6). Analogously,
the greatest fixpoint of the constraint set can be found iteratively by a worklist
algorithm (cf. Figure 2). Upon start of the analysis, at each node the variables’
values are assumed to be defined, i.e., the initial valuation is the greatest one:
α
ηinit (n) = η .
α
ηpost (n) ≤ fn (ηpre
α
(n))
(2)
α
ηpre (n) ≤ {ηpost
α
(n ) | (n , n) in flow relation}
Like the may-analysis case, the termination of the algorithm follows from the
finiteness of the set of variables.
η α (n) = ηinit
α
(n) ;
WL = {n | αn = g x := e} ;
repeat
p i c k n ∈ WL ;
i f n = g c!s(e) then
l e t S = {n | n = c?s(x) and [[e]]ηα (n) [[x]]ηα (n ) }
in
f o r a l l n ∈ S : η α (n ) := fn (η α (n )) ;
l e t S = {n ∈ succ(n) | fn (η α (n)) η α (n )}
in
f o r a l l n ∈ S : η α (n ) := fn (η α (n)) ;
WL := WL\{n} ∪ S ∪ S ;
u n t i l WL = ∅ ;
α
ηpre (n) = η α (n) ;
ηpost (n) = fn (η α (n))
α
In either case we must ensure that the abstraction of timer values is treated
adequately (see below). Here we describe the transformation for the combination
of may and must analysis, only, since the alternative is simpler.
Overloading the symbols , and ⊥ we mean for the rest of the paper: the value
of , for a variable at a location refers to the result of the must analysis, i.e., the
definite knowledge that the data is chaotic for all runs. Dually, ⊥ stands for the
definite knowledge of the may analysis, i.e., for data which is never influenced
from outside. Additionally, we write ⊥ , in case neither analysis gave a definite
answer.
We extend the data domains each by an additional value , ,, representing
unknown, chaotic, data, i.e., we assume now domains such as N
= N ∪˙ {,,},
Bool = Bool ∪˙ {, ,}, . . . , where we do not distinguish notationally the various
types of chaotic values. These values , , are considered as the largest values, i.e.,
we introduce ≤ as the smallest reflexive relation with v ≤ , , for all elements v
(separately for each domain). The strict lifting of a valuation η
to expressions
is denoted by [[.]]η .
The transformation is straightforward: guards influenced by the environment
are taken non-deterministically, i.e., a guard g at a location l is replaced by true,
if [[g]]ηlα = ,. A guard g whose value at a location l is ⊥
, is treated dynamically on
the extended data domain. For assignments, we distinguish between the variables
that carry the value ⊥ , in at least one location and the rest. Assignments of ,, to
variables that take ⊥ , at no location are omitted. Assignments of concrete values
are left untouched and the assignments to the variables that are marked by ⊥ ,
in at least one location are performed on the extended data domain.
The interpretation of timer variables on the extended domain requires spe-
cial attention. Chaos can influence timers only via the set-operation by setting
Table 7. Transformation
l −→c?s(x) ˆ
l ∈ Edg x ∈ Var ⊥
[[x]]ηlα =
T-Inputext
l −→c?s( ) ˆ
l ∈ Edg
l −→g c!(s,e) ˆ
l ∈ Edg [[e]]ηlα =
T-Output
l −→g c!(s, ˆ
) l ∈ Edg
l −→g x:=e ˆ
l ∈ Edg x ∈ Var ⊥
[[x]]ηlα =
T-Assign1
l −→g skip ˆ
l ∈ Edg
l −→g x:=e ˆ
l ∈ Edg x ∈ Var ⊥
[[e]]ηlα =
T-Assign2
l −→g x:=
ˆ
l ∈ Edg
ˆ
l −→g set t:=e l ∈ Edg [[e]]ηlα =
T-Set
l −→g set t:= ˆ
l ∈ Edg
308 N. Ioustinova, N. Sidorova, and M. Steffen
it to a chaotic value. Therefore, the domain of timer values contains the addi-
tional chaotic value on(, ,). Since we need the transformed system to show at
least the behavior of the original one, we must provide proper treatment of the
rules involving on(,,), i.e., the Timeout-, the TDiscard-, and the Tick-rule.
As on(, ,) stands for any value of active timers, it must cover the cases where
timeouts and timer-discards are enabled (because of the concrete value on(0))
as well as disabled (because of on(n) with n ≥ 1). The second one is necessary,
since the enabledness of the tick steps depends on the disabledness of timeouts
and timer discards via the blocked-condition.
To distinguish the two cases, we introduce a refined abstract value on(, ,+ )
for chaotic timers, representing all on-settings larger than or equal to 1. The
order on the domain of timer values is given as smallest reflexive order relation
such that on(0) ≤ on(, ,) and on(n) ≤ on(, ,+ ) ≤ on(,,), for all n ≥ 1. To treat
the case where the abstract timer value on(, ,) denotes absence of immediate
timeout, we add edges of the form
T-NoTimeout
l −→t=on( + l ∈ Edg
) set t:=
Table 8. Model checking MCL with chaos as a process and embedded chaos
Table 8 gives the results for the model checking of MCL with chaos as external
process on the left and embedded on the right. The first column gives the buffer
size for process queues. The other columns give the number of states, transitions,
memory and time consumption, respectively. As one can see, the state space
as well as the time and the memory consumption are significantly larger for
the model with the environment as a process, and they grow with the buffer
size much faster than for the model with embedded chaos. The model with the
embedded environment has a relatively stable state-space size.
6 Conclusion
In this paper, we integrated earlier works from [29, 18, 31, 17] into a general
framework describing how to close an open, asynchronous system by a timed
environment while avoiding the combinatorial state-explosion in the external
buffers. The generalization presented here goes a step beyond complete arbitrary
environmental behavior, using the timed semantics of the language. We facilitate
the model checking of the system by using the information obtained with may
and must analyses: We substitute the chaotic value , , for expressions influenced
by chaotic data from outside and then optimize the system by removing variables
and actions that became redundant.
In the context of software-testing, [9] describes an a dataflow algorithm to
close program fragments given in the C-language with the most general envi-
ronment. The algorithm is incorporated into the VeriSoft tool. As in our paper,
the assume an asynchronous communicating model and abstract away external
data, but do not consider timed systems and their abstraction. As for model-
checking and analyzing SDL-programs, much work has been done, for instance
in the context of the Vires-project, leading to the IF-toolset [5]
A fundamental approach to model checking open systems is known as module
checking [21][20]. Instead of transforming the system into a closed one, the un-
derlying computational model is generalized to distinguish between transitions
under control of the module and those driven by the environment. Mocha [1]
is a model checker for reactive modules, which uses alternating-time temporal
logic as specification language.
For practical applications, we are currently extending the larger case study
[30] using the chaotic closure to this more general setting. We proceed in the fol-
lowing way: after splitting an SDL system into subsystems following the system
structure, properties of the subsystems are verified being closed with an embed-
ded chaotic environment. Afterwards, the verified properties are encoded into
Synchronous Closing and Flow Analysis 311
References
1. R. Alur, T. A. Henzinger, F. Mang, S. Qadeer, S. K. Rajamani, and S. Tasiran.
Mocha: Modularity in model checking. In A. J. Hu and M. Y. Vardi, editors,
Proceedings of CAV ’98, volume 1427 of Lecture Notes in Computer Science, pages
521–525. Springer-Verlag, 1998.
2. D. Bošnački and D. Dams. Integrating real time into Spin: A prototype imple-
mentation. In S. Budkowski, A. Cavalli, and E. Najm, editors, Proceedings of
Formal Description Techniques and Protocol Specification, Testing, and Verifica-
tion (FORTE/PSTV’98). Kluwer Academic Publishers, 1998.
3. D. Bošnački, D. Dams, L. Holenderski, and N. Sidorova. Verifying SDL in Spin.
In S. Graf and M. Schwartzbach, editors, TACAS 2000, volume 1785 of Lecture
Notes in Computer Science. Springer-Verlag, 2000.
4. M. Bozga, J. C. Fernandez, and L. Ghirvu. State space reduction based on Live.
In A. Cortesi and G. Filé, editors, Proceedings of SAS ’99, volume 1694 of Lecture
Notes in Computer Science. Springer-Verlag, 1999.
5. M. Bozga, J.-C. Fernandez, L. Ghirvu, S. Graf, J.-P. Krimm, and L. Mounier. IF:
An intermediate representation and validation environment for timed asynchronous
systems. In J. Wing, J. Woodcock, and J. Davies, editors, Proceedings of Sympo-
sium on Formal Methods (FM 99), volume 1708 of Lecture Notes in Computer
Science. Springer-Verlag, Sept. 1999.
6. M. Bozga, S. Graf, A. Kerbrat, L. Mounier, I. Ober, and D. Vincent. SDL for
real-time: What is missing? In Y. Lahav, S. Graf, and C. Jard, editors, Electronic
Proceedings of SAM’00, 2000.
7. J. Brock and W. Ackerman. An anomaly in the specifications of nondeterministic
packet systems. Technical Report Computation Structures Group Note CSG-33,
MIT Lab. for Computer Science, Nov. 1977.
8. E. Clarke, O. Grumberg, and D. Long. Model checking and abstraction. ACM
Transactions on Programming Languages and Systems, 16(5):1512–1542, 1994. A
preliminary version appeared in the Proceedings of POPL 92.
9. C. Colby, P. Godefroid, and L. J. Jagadeesan. Automatically closing of open reac-
tive systems. In Proceedings of 1998 ACM SIGPLAN Conference on Programming
Language Design and Implementation. ACM Press, 1998.
10. D. Dams, R. Gerth, and O. Grumberg. Abstract interpretation of reactive sys-
tems: Abstraction preserving ∀CTL∗ ,∃CTL∗ , and CTL∗ . In E.-R. Olderog, editor,
Proceedings of PROCOMET ’94. IFIP, North-Holland, June 1994.
11. Discrete-time Spin. http://www.win.tue.nl/~dragan/DTSpin.html, 2000.
12. P. Godefroid. Using partial orders to improve automatic verification methods.
In E. M. Clarke and R. P. Kurshan, editors, Computer Aided Verification 1990,
volume 531 of Lecture Notes in Computer Science, pages 176–449. Springer-Verlag,
1991. an extended Version appeared in ACM/AMS DIMACS Series, volume 3,
pages 321–340, 1991.
312 N. Ioustinova, N. Sidorova, and M. Steffen
31. N. Sidorova and M. Steffen. Synchronous closing of timed SDL systems for model
checking. In A. Cortesi, editor, Proceedings of the Third International Workshop on
Verification, Model Checking, and Abstract Interpretation (VMCAI) 2002, volume
2294 of Lecture Notes in Computer Science, pages 79–93. Springer-Verlag, 2002.
32. A. Valmari. A stubborn attack on state explosion. Formal Methods in System De-
sign, 1992. Earlier version in the proceeding of CAV ’90 Lecture Notes in Computer
Science 531, Springer-Verlag 1991, pp. 156–165 and in Computer-Aided Verification
’90, DIMACS Series in Discrete Mathematics and Theoretical Computer Science
Vol. 3, AMS & ACM 1991, pp. 25–41.
33. A wireless ATM network demonstrator (WAND), ACTS project AC085.
http://www.tik.ee.ethz.ch/~wand/, 1998.
Priority Systems
1 Introduction
A common idea for avoiding a posteriori verification and testing, is to use system
design techniques that guarantee correctness by construction. Such techniques
should allow to construct progressively from a given system S and a set of re-
quirements R1 , . . . , Rn , a sequence of systems S1 , . . . , Sn , such that system Si
meets all the requirements Rj for j ≤ i. That is, to allow incremental construc-
tion, requirements should be composable [2,6] along the design process. In spite
of their increasing importance, there is currently a tremendous lack of theory
and methods, especially for requirements including progress properties which
are essential for reactive systems. Most of the existing methodologies deal with
construction of systems such that a set of state properties always hold. They are
founded on the combined use of invariants and refinement relations. Compos-
ability is ensured by the fact that refinement relations preserve trace inclusion.
We present a framework allowing to consider jointly state property invariance
and deadlock-freedom.
Practice for building correct systems is often based on the idea of adding
enforcement mechanisms to a given system S in order to obtain a system S
meeting a given requirement. These mechanisms can be implemented by instru-
menting the code of S or by composing S with systems such as controllers or
monitors that modify adequately the overall behavior.
An application of this principle is the enforcement of security policies which
are safety properties described by automata [14]. A main requirement for the
enforced system is that it safely terminates when it detects a deviation from
F.S. de Boer et al. (Eds.): FMCO 2003, LNCS 3188, pp. 314–329, 2004.
c Springer-Verlag Berlin Heidelberg 2004
Priority Systems 315
some nominal secure behavior. A more difficult problem is also to ensure system
availability and preserve continuity of service [3,10].
Another application of this principle is aspect oriented programming [8] used
to build programs meeting (usually simple) requirements. Aspects can be con-
sidered as requirements from which code is generated and woven into a program
intended to meet the requirements. In aspect oriented programming, aspect com-
position is identified as a central problem as it may cause unintentional interfer-
ence and inconsistency [15].
Practice for building correct systems by using enforcement mechanisms raises
some hard theoretical problems. For a sufficiently fine granularity of observation,
it is relatively easy to enforce safety requirements (as non violations of given state
properties) by stopping system progress. It is much harder to devise mechanisms
that also guarantee system availability and avoid service interruption. Further-
more, composability of requirements e.g. security policies, aspects, is identified
as a main obstacle to rigorous incremental system construction.
We propose a design framework for both safety and deadlock-freedom re-
quirements. The framework consists of a model, priority systems and results
concerning its basic properties including composability. A priority system is a
transition system with a (dynamic) priority relation on its actions. A priority re-
lation ≺ is a set of predicates of the form ai ≺ Cij .aj meaning that action ai has
lower priority than action aj at all states satisfying Cij . At a given state of the
transition system, only enabled actions with maximal priority can be executed.
That is, in a priority system, a priority relation restricts the behavior of its tran-
sition system exactly as a scheduler restricts the behavior of a set of tasks. The
remarkably nice property of priority systems is that they are deadlock-free if
they are built from deadlock-free transition systems and from priority relations
satisfying some easy-to-check consistency condition.
The proposed framework considers design as a controller synthesis [12] prob-
lem: from a given system S and requirement R, find a system S meeting R.
S is the composition of S with a controller which monitors the state of S and
restricts its behavior by adequately switching off a subset of controllable actions
of S. The controller is usually specified as a solution of a fixpoint equation.
The simple case where R means that S is deadlock-free and does not violate
a state predicate U has been studied in various contexts e.g., in [11,1]. The
corresponding controller is specified as a deadlock-free control invariant which is
a state predicate U , U ⇒ U , such that
– it is preserved by the non controllable actions of S, that is if U holds at
some state then it remains true forever if only non controllable actions are
executed;
– U is false for all deadlock states of S.
Given U , the controlled (designed) system S is obtained from S by con-
juncting the guard of any controllable action a by the weakest precondition of
U under a.
In Section 2, we formalize the relationship between S and S , by introducing
restriction operators. These are specified as tuples of state predicates in bijection
316 G. Gössler and J. Sifakis
G(B).
– U is a control invariant of B if U ⇒ a∈Au ¬pre a (¬U ). A control invariant
U , U = false, is called deadlock-free if U ⇒ a∈A prea (U ).
We write inv[B](U ) to express the fact that U is an invariant of B. Notice
that invariants are control invariants of systems that have only uncontrollable
actions.
Proposition 1. If U is a control invariant of B = (X, A, {Ga }a∈A , {F a }a∈A )
then U is an invariant of B = (X, A, {(Ga ) }a∈A , {F a }a∈A ) where (Ga ) =
Ga ∧ U [F a (X)/X] for a ∈ Ac and (Ga ) = Ga otherwise. Furthermore, if U is a
deadlock-free control invariant of B then it is a deadlock-free invariant of B .
This result allows to build from a given system B and a safety requirement
of the form ”always U0 ” a deadlock-free system B meeting this requirement,
provided there exists a deadlock-free control invariant U of B such that U ⇒ U0 .
The following simple example illustrates this fact.
Example 1. In a Readers/Writers system, we use two counters, non negative
integers, r and w to represent respectively, the number of readers and writers
using a common resource. The counters are modified by actions of a transition
system B specified as a set of guarded commands:
a1 : true → r := r + 1 a2 : r > 0 → r := r − 1
b1 : true → w := w + 1 b2 : w > 0 → w := w − 1
318 G. Gössler and J. Sifakis
where a1 and b1 are respectively, the actions of granting the resource to a reader
and a writer and a2 and b2 are respectively, the actions of releasing the resource
by a reader and a writer.
We assume that the actions a1 and b1 are controllable and we want to enforce
the requirement ”always U” for U = (w ≤ 1) ∧ (w = 0 ∨ r = 0). This prevents
concurrent access among writers, as well as between readers and writers. It is
easy to check that U is a deadlock-free control invariant. In fact, it is easy to
check that U is preserved by the uncontrollable actions a2 and b2 :
(r > 0) ∧ U ⇒ U [r − 1/r] and (w > 0) ∧ U ⇒ U [w − 1/w].
Furthermore, it is easy to check that U ⇒ prea1 ∨ prea2 ∨ preb1 ∨ preb2 .
As prea1 (U ) ≡ w = 0 and preb1 (U ) ≡ (w = 0) ∧ (r = 0), we have inv[B ](U )
where B is the controlled transition system:
a1 : w = 0 → r := r + 1 a2 : r > 0 → r := r − 1
b1 : (r = 0) ∧ (w = 0) → w := w + 1 b2 : w > 0 → w := w − 1
The notion of restriction defined below allows a formalization of the relation-
ship between the initial and the controlled system.
Definition 5 (Restriction). Given a transition system B = (X, A, {Ga }a∈A ,
{F a }a∈A ), a restriction is a tuple of predicates V = (U a )a∈A . B/V denotes the
transition system B restricted by V , B/V = (X, A, {Ga ∧ U a }a∈A , {F a }a∈A ).
V = (U a )a∈A is a control restriction for B if a∈Au (¬G a∨ U a) =
a a
true.
V = (U )a∈A is a deadlock-free restriction for B if a∈A G ∧U = a∈A Ga .
a
3 Priority Systems
We define priority systems which are transition systems restricted with priorities.
Priorities provide a general mechanism for generating deadlock-free restrictions.
Static Priorities
Definition 11 (Static Priority). A static priority is a priority≺={Cij }ai ,aj ∈A
such that the predicates Cij are positive boolean expressions on guards. We call
static restrictions the corresponding restrictions V (B, ≺) = (U a )a∈A , that is
restrictions which are tuples of negative boolean expressions on guards.
It is easy to check that any static restriction defines a static priority. Notice
that in a priority system with static priorities, the choice of the action to be
executed at some state depends only on the set of the actions enabled at this
state. For example, a restriction with U a1 = ¬Ga2 ∧(¬Ga3 ∨¬Ga4 ) means that in
the restricted system the action a1 can be executed only if a2 is disabled and a3
or a4 is disabled. The corresponding the priority relation is: a1 ≺ true.a2 , a1 ≺
Ga3 .a4 , a1 ≺ Ga4 .a3
Notation: For a static priorities the notation can be drastically simplified.
If (U ai )ai ∈A is a static restriction then it is of the form, U ai = k∈Ki ¬Mik
where Mik is a monomial on guards Mik = kw ∈W Gakw . Each monomial Mik ,
Priority Systems 321
corresponds to the set of priorities {ai ≺ kw ∈W {j} Gakw .aj }j∈W . This set can
be canonically represented by simply writing ai ≺ kw ∈W akw .
For example if Mik = Ga1 ∧ Ga2 ∧ Ga3 instead of writing ai ≺ (Ga1 ∧ Ga2 ).a3 ,
ai ≺ (Ga1 ∧ Ga3 ).a2 , ai ≺ (Ga2 ∧ Ga3 ).a1 , we write ai ≺ a1 a2 a3 . We propose the
following definition for static priorities.
Definition 12 (Static Priority – Simplified Definition). A monomial m
on a vocabulary of actions A is any term m = aj1 . . . ajn obtained by using
an associative, commutative and idempotent product operation. Let 1 denote its
neutral element, and m(A) the set of the monomials on A.
A static priority ≺ on A is a relation ≺⊆ A × m(A).
Lemma 2. Let ≺=≺∓ be an irreflexive closed static priority. Then, any non
maximal action a is dominated by some monomial m on maximal actions.
Proof. Omitted.
Proof. Let Ga , (Ga ) , (Ga ) , and (Ga ) be the guards of action a in B, B/ ≺1 ,
(B/ ≺1 )/ ≺2 , and B/(≺1 ⊕ ¯ ≺2 ), respectively. For some state x, let A0 =
{a ∈ A | G (x)}, A1 = {a ∈ A | (Ga ) (x)}, A2 = {a ∈ A | (Ga ) (x)}, and
a
Proof. We have from B/V (U1 ) 0U1 (B, ≺U1 ) and B/V (U2 ) 0U2 (B, ≺U2 ),
(B, ≺U1 ⊕ ≺U2 ) U1 (B, ≺U1 ∪ ≺U2 ) U1 B/V (U1 ) and (B, ≺U1 ⊕ ≺U2 ) U2
(B, ≺U1 ∪ ≺U2 ) U2 B/V (U2 ). This gives, (B, ≺U1 ⊕ ≺U2 ) U1 ∧U2 B/V (U1 ) ∧
V (U2 ) 0 B/V (U1 ∧ U2 ). From the previous proposition we get the result.
4 Example
We consider a robotic system controlled by the following processes:
We consider for each process P predicates P.halted and P.running such that
P.halted ≡ ¬P.running. Each process P can leave states of P.halted (resp.
P.running) by action P.start (resp. P.stop), as in figure 1. The robotic system
must satisfy forever the following constraints:
start
halted running
stop
where I, Ji and Ji are index sets such that any conjunct has at least two atoms
that are predicates on two different processes (this is always possible for any
predicate U if we have at least two processes).
Invariance invariance of all of its conjuncts Di . Consider
of U is equivalent to
the conjunct l∈Ji Bl .running ∨ l∈J Bl .halted. As in the previous example,
i
consider a critical configuration, that is, a configuration where only one literal
is true. We distinguish two cases:
5 Discussion
We present a framework for the incremental construction of deadlock-free sys-
tems meeting given safety properties. The framework borrows concepts and
basic results from the controller synthesis paradigm by considering a step in
the construction process as a controller synthesis problem. Nevertheless, it does
not directly address controller synthesis and other related computationally hard
problems. Instead, it is based on the abstraction that the effect of the controller
corresponding to a deadlock-free control invariant can be modeled by deadlock-
free control restrictions.
Priorities play a central role in our framework. They can represent any
deadlock-free control restriction. They can be naturally used to model mutual
exclusion constraints and scheduling policies [4,2]. They are equipped with very
simple and natural composition operations and criteria for composability. We
provide an equational characterization of priorities and a sufficient condition for
representing deadlock-free restrictions. Static priorities are solutions expressed
as boolean expressions on guards for which a necessary and sufficient condition
for deadlock-freedom is provided.
The use of priority systems instead of simple transition systems is a key idea
in our approach. Of course, any priority system is, by its semantics, equivalent
to a transition system. Nevertheless, using such layered models offers numerous
advantages of composability and compositionality:
retical framework can be a basis for the various approaches and practices using
enforcement mechanisms in a more or less ad-hoc manner.
References
1. K. Altisen, G. Gössler, A. Pnueli, J. Sifakis, S. Tripakis, and S. Yovine. A frame-
work for scheduler synthesis. In Proc. RTSS’99, pages 154–163. IEEE Computer
Society Press, 1999.
2. K. Altisen, G. Gössler, and J. Sifakis. Scheduler modeling based on the controller
synthesis paradigm. Journal of Real-Time Systems, special issue on ”control-
theoretical approaches to real-time computing”, 23(1/2):55–84, 2002.
3. L. Bauer, J. Ligatti, and D. Walker. A calculus for composing security policies.
Technical Report TR-655-02, Princeton University, 2002.
4. S. Bornot, G. Gössler, and J. Sifakis. On the construction of live timed systems.
In S. Graf and M. Schwartzbach, editors, Proc. TACAS’00, volume 1785 of LNCS,
pages 109–126. Springer-Verlag, 2000.
5. G. Gössler and J. Sifakis. Component-based construction of deadlock-free systems
(extended abstract). In proc. FSTTCS’03, volume 2914 of LNCS. Springer-Verlag,
2003.
6. G. Gössler and J. Sifakis. Composition for component-based modeling. In proc.
FMCO’02, volume 2852 of LNCS. Springer-Verlag, 2003.
7. S. Graf, I. Ober, and I. Ober. Model checking of uml models via a mapping to
communicating extended timed automata. In S. Graf and L. Mounier, editors,
Proc. SPIN’04, volume 2989 of LNCS. Springer-Verlag, 2004.
8. G. Kiczales, J. Lamping, A. Mendhekar, C. Maeda, C. Videira Lopes, J.-M. Lo-
ingtier, and J. Irwin. Aspect-oriented programming. In Proc. ECOOP ’97, volume
1241 of LNCS, page 220ff. Springer-Verlag, 1997.
9. C. Kloukinas, C. Nakhli, and S. Yovine. A methodology and tool support for
generating scheduled native code for real-time java applications. In R. Alur and
I. Lee, editors, Proc. EMSOFT’03, volume 2855 of LNCS, pages 274–289, 2003.
10. J. Ligatti, L. Bauer, and D. Walker. Edit automata: Enforcement mechanisms
for run-time security policies. Technical Report TR-681-03, Princeton University,
2003.
11. O. Maler, A. Pnueli, and J. Sifakis. On the synthesis of discrete controllers for
timed systems. In E.W. Mayr and C. Puech, editors, STACS’95, volume 900 of
LNCS, pages 229–242. Springer-Verlag, 1995.
12. P.J. Ramadge and W.M. Wonham. Supervisory control of a class of discrete event
processes. SIAM J. Control and Optimization, 25(1), 1987.
13. E. Rutten and H. Marchand. Task-level programming for control systems using
discrete control synthesis. Technical Report 4389, INRIA, 2002.
14. F. Schneider. Enforceable security policies. ACM Transactions on Information
and System Security, 3(1):30–50, 2000.
15. P. Tarr, M. D’Hondt, L. Bergmans, and C. V. Lopes. Workshop on aspects and
dimensions of concern: Requirements on, challenge problems for, advanced separa-
tion of concerns. In ECOOP 2000 Workshop Proceedings, Springer Verlag, 2000.
Preserving Properties Under Change
Heike Wehrheim
Universität Oldenburg, Fachbereich Informatik,
26111 Oldenburg, Germany
wehrheim@informatik.uni-oldenburg.de
1 Introduction
With the advent of component-based software engineering systems are more
and more built from pre-fabricated components which are taken from libraries,
adapted to new needs and assembled into a system. Furthermore, for the design
of dependable systems formal methods are employed during the construction
process to improve the degree of correctness and reliability. The combination
of these two techniques — component-based design and formal methods — in
system construction poses a large number of new research challenges which are
currently very actively taken up.
This paper studies one aspect arising in this area, based on the following
scenario of a component-based construction. We assume that we have a library
of components which are formally specified and proven correct with respect to
certain requirements. During system construction components are taken from the
library and (since they might not fully comply to their new use) are modified
or even extended with new features. The question is then whether the proven
properties are preserved under this specialisation and thus whether we can also
get a re-use of verification results and not just of components. More specifically,
given a component A (which will be a single class here) and its modification or
extension C we are interested in knowing whether a property P holding for A
still holds for C (see the following figure).
F.S. de Boer et al. (Eds.): FMCO 2003, LNCS 3188, pp. 330–343, 2004.
c Springer-Verlag Berlin Heidelberg 2004
Preserving Properties Under Change 331
A Property P
C Property P ?
Although the picture might suggest that the relationship between A and C
is that of inheritance (since we use the specialisation arrow of UML) we are
actually interested in a more general relationship: C may be any class which
is constructed out of A, may it be by inheritance or by a simple change of the
existing specification.
As a first observation, it can be remarked that even a restriction to inheri-
tance cannot ensure that properties are preserved: a subclass may differ from its
superclass in any aspect and thus none of the properties holding for A might be
preserved in C . Still, preservation of properties to subclasses is an important and
intensively studied topic. Within the area of program verification, especially of
Java programs, this question has already been tackled by a number of researchers
[6,10,5]. In these approaches correctness properties are mainly formulated in
Hoare logic, and the aim is to find proof rules which help to deduce subclass
properties from superclass properties. In order to get correctness of these rules
it is required that the subclass is a behavioural subtype [7] of the superclass. This
assumption is also the basis of [14] which studies preservation of properties in an
event-based setting with correctness requirements formulated as CSP processes.
In this paper we lift this assumption (although also looking at subtypes as a
special case) and consider arbitrary classes constructed out of existing classes.
For convenience we will, however, often call the class C the subclass and A
its superclass. Instead of employing restrictions on the subclass (in order to
preserve properties) we will compute whether a property is preserved or not. This
computation does not involve re-verification of the property but can be carried
out on a special representation of the classes called program dependence graphs.
Program dependence graphs carry all information about the dependencies within
programs (or in our case, specifications) and thus can be used to determine
the influence of a change or extension on proven properties. This technique
is originally coming from program analysis where slicing techniques operating
on program dependence graphs are used to reduce a program with respect to
certain variables of interest. Slicing techniques (and a similar technique called
cone-of-influence reduction) are also being applied in software and hardware
model checking for reducing programs [4,9,1].
In our framework classes are not written in a programming language but are
defined in a state-based object-oriented formal method (Object-Z [11,2]). Cor-
rectness requirements on classes are formalised in a temporal logic (LTL [8]).
As changes (specialisation) we allow the addition of attributes, the modification
of existing methods and the extension with new methods. A comparable study
332 H. Wehrheim
2 Background
This section describes the background necessary for understanding the results:
the definition of classes in Object-Z, the temporal logic LTL and a result showing
that LTL-X properties are preserved under stuttering equivalence. Stuttering
equivalence will be used to compare super- and subclasses.
Account0
balance : Z
Init
balance = 0
1
In fact, it is the Object-Z part of CSP-OZ specifications [3] (a formalism which inte-
grates CSP with Object-Z). We use this formalism since we are ultimately interested
in answering the question of property preservation for CSP-OZ.
Preserving Properties Under Change 333
2
This assumption is not essential but more convenient.
334 H. Wehrheim
– v = d , v ∈ V , d ∈ D and
– enabled (m), m ∈ M .
Since the atomic propositions do not refer to inputs and outputs of methods,
they are not reflected in the semantics. However, inputs and outputs can be
embedded in the state and thus can be made part of the atomic propositions
(see e.g. [12]).
Figure 1 shows the Kripke structure (without L) of class Account0 . The num-
bers indicate the values of attribute balance. All states satisfying balance < 0 are
unreachable. The upper arrows correspond to executions of Deposit, the lower
to those of Withdraw .
... ...
−1 0 1
Definition 4. The set of LTL formulae over AP is defined as the smallest set
of formulae satisfying the following conditions:
– p ∈ AP is a formula,
– if ϕ1 , ϕ2 are formulae, so are ¬ϕ1 and ϕ1 ∨ ϕ2 ,
– if ϕ is a formula, so are X ϕ (Next), 2ϕ (Always), 3ϕ (Eventually),
– if ϕ1 , ϕ2 are formulae, so is ϕ1 U ϕ2 (Until).
Preserving Properties Under Change 335
Usually, paths are assumed to be always infinite (and LTL formulae inter-
preted on infinite paths). We deviate from that because objects may also exhibit
finite behaviour: if no methods are called from the outside anymore, the object
just stops. This has, however, consequences on the holding of liveness properties:
since for instance s0 alone is also a path, a liveness property can only hold if
it already holds in the initial state. Thus we essentially treat safety here. Live-
ness can be treated if we additionally make some fairness assumptions on the
environment of an object (see conclusion for a discussion).
– π |= p iff p ∈ L(π[0]),
– π |= ¬ϕ iff not π |= ϕ,
– π |= ϕ1 ∨ ϕ2 iff π |= ϕ1 or π |= ϕ2 ,
– π |= X ϕ iff #π > 1 ∧ π 1 |= ϕ,
– π |= 2ϕ iff ∀ i , 0 ≤ i ≤ #π : π i |= ϕ,
– π |= 3ϕ iff ∃ i , 0 ≤ i ≤ #π : π i |= ϕ,
– π |= ϕ1 U ϕ2 iff ∃ k , 0 ≤ k ≤ #π : π k |= ϕ2 and ∀ j , 0 ≤ j < k : π j |= ϕ1 .
For our bank example we for instance have the following properties. The
Kripke structure KAccount0 of Account0 fulfills
KAccount0 |= 2(balance ≥ 0) ,
KAccount0 |= 2(enabled (Deposit)) .
Intuitively, the sequences are equivalent if they can be divided into blocks in
which atomic propositions stay stable and the i -th block in π has the same set
of propositions from AP as the i -th block in ρ (illustrated in Figure 2).
p, q p, q p, ¬q p, ¬q ¬p, ¬q p, ¬q ...
p, q p, ¬q p, ¬q p, ¬q ¬p, ¬q p, ¬q ...
L1 (s0,1 ) ∩ AP = L2 (s0,2 ) ∩ AP ,
– for each path π in K1 starting from s0,1 there exists a path π starting from
s0,2 such that π ≈AP π ,
– and vice versa, for each path π in K2 starting from s0,2 there exists a path
π starting from s0,1 such that π ≈AP π .
Stuttering equivalent Kripke structures satisfy the same set of LTL-X prop-
erties [1]. The Next operator has to be omitted since stuttering may introduce
additional steps in one structure which have no counterpart in the other.
K1 |= ϕ iff K2 |= ϕ .
Preserving Properties Under Change 337
3 Property Preservation
Now that we have set the ground, we have another look at our example and
make two changes to the class. The first is an extension of the class, we add one
new method for balance checking. Here, we use inheritance to avoid having to
write the whole specification again.
Account1
inherit Account0
enable CheckBalance
true
effect CheckBalance
bal ! : Z
bal ! = balance
Account2
inherit Account0
modifies Withdraw
Init
overdraft : N overdraft = 1000
The question is then which of our properties are preserved, i.e. which of the
following questions can be answered with yes.
For this simple example, the answers are easy. What we aim at is, however,
a general technique which answers such questions. In general, these two changes
338 H. Wehrheim
are of two different types. The changed class can be a subtype of the original class
(and then all properties are preserved) or it is not (and then a more sophisticated
technique has to be applied to find out whether a property is preserved).
In this section, we deal with the first, more simple case. The second case is
dealt with in the next section. A subtype can be seen as a conservative extension
of a class: new methods may read but may not modify old variables.
Subtypes inherit all properties as long as they are only talking about propo-
sitions over the old attributes and methods.
A |= ϕ =⇒ C |= ϕ .
In fact, the implication also holds in the reverse direction. The proof proceeds
by showing that C and A are stuttering equivalent. The stuttering steps in C
are those belonging to executions of the new methods: they do not change old
attributes and thus do not affect AP . The proof can be found in an extended
version of this paper.
Coming back to our example, Account1 is a subtype of Account0 : CheckBalance
only references balance but does not modify it. Hence both properties are pre-
served:
KAccount1 |= 2(balance ≥ 0)
KAccount1 |= 2(enabled (Deposit))
4 Slicing
In this section we look at the more general case, where the modifications do not
lead to subtypes. For this case, we cannot get one general result but have to
specifically look at the changes made and the properties under interest.
The technique we use for computing whether a property is preserved under a
specific change is the slicing technique of program analysis [13]. In program ana-
lysis slicing is originally used for debugging and testing, and answers questions
like the following: ”given a variable v and a program point p, which part of
the program may influence the value of v at p?”. Here, we like to extract a
similar kind of information about our changes: ”given some propositions and
Preserving Properties Under Change 339
Init
DO
effect m1 effect mn
The program dependence graph is obtained from this graph by erasing all
arrows and adding new ones corresponding to the control and data dependencies
of the class. Formally,
l: n0 → Init
nDO → DO
nen m → enable m
neff m → effect m
Here, we take Set(DO) = Ref (DO) = ∅. For class Account0 this gives rise
to the graph shown in Figure 4.
340 H. Wehrheim
Init
DO
= data dependency
= control dependency
The forward slice of N is the part of the class which is directly or indirectly
influenced by the changes. The atomic propositions appearing in this part might
be changed. We let APN denote the atomic propositions over variables or meth-
ods in the forward slice of N .
A |= ϕ =⇒ C |= ϕ .
Init
DO
The proof again proceeds by showing that KA and KC are stuttering equiv-
alent wrt. AP \ APN and is included in an extended version. Since they are
stuttering equivalent the implication in the theorem holds in the reverse direc-
tion as well.
For our example, the PDG for Account0 , Account2 is depicted in Figure 5.
The set of changed methods N is {Withdraw }. Nodes not in the forward slice
of Withdraw are {Init, DO, enable Deposit}. The variable balance is set by a
method in the forward slice, but enable Deposit is not in the forward slice.
Hence, concerning our properties, we know that one of them is preserved:
but for the question KAccount2 |= 2(balance ≥ 0)? we get no answer (and in fact
this property does not hold anymore).
The case of changes leading to subtypes can be seen as one particular instance
of this more general result: for subtypes we know by definition that the forward
slice (of the new methods) will only contain new methods and thus affects only
new variables. Hence, the proof of Theorem 3 can be seen as an alternative way
of proving Theorem 2.
The PDG of Account0 , Account1 is depicted in Figure 6. As can be seen, in
the forward slice of CheckBalance there is only CheckBalance.
5 Conclusion
This work is concerned with the re-use of verification results of classes. Given
a verified class the technique presented in this paper can be used to determine
342 H. Wehrheim
Init
DO
whether some specific property is preserved under a change made to the class.
The technique relies on the representation of the dependencies of a class specifi-
cation in a program dependence graph. On this graph it is possible to determine
the effect of changes on the behaviour of a class. As a special case we looked
at changes inducing subtypes in which all properties (talking about the original
class) are preserved.
So far, this technique considers a single class only. It could be extended to
larger systems either by combining it with compositional verification techniques
(e.g. for Object-Z [16]), or by constructing a program dependence graph of the
whole system. The latter could be achieved by combining program dependence
graphs of the individual objects through a special new dependency arc reflect-
ing the call structure between objects (possibly following approaches for slicing
programs with procedures).
Another limitation of the work presented here concerns the treatment of
liveness properties. The inclusion of finite paths of a Kripke structure into the
interpretation of LTL formulae lead to a restriction to safety properties. There
are a number of ways of avoiding this limitation. One way would be to make
certain assumptions about the environment of an object in that it infinitely often
calls certain methods. These set of methods can be used as a fairness constraint
on the behaviour of an object. The interpretation of LTL formulae can then be
restricted to fair paths. If the fairness constraint for the subclass is the same as
that for the superclass preservation of properties can be achieved.
As future work, we like to extend the technique presented here to integrated
specification formalisms which allow for the modelling of different viewpoints in
different formal methods, as for instance CSP-OZ [3].
References
1. E. Clarke, O. Grumberg, and D. Peled. Model checking. MIT Press, 1999.
2. R. Duke, G. Rose, and G. Smith. Object-Z: A specification language advocated for
the description of standards. Computer Standards and Interfaces, 17:511–533, 1995.
Preserving Properties Under Change 343
Abstract. Attack graphs depict ways in which an adversary exploits system vul-
nerabilities to achieve a desired state. System administrators use attack graphs
to determine how vulnerable their systems are and to determine what security
measures to deploy to defend their systems. In this paper, we present details of
an example to illustrate how we specify and analyze network attack models. We
take these models as input to our attack graph tools to generate attack graphs au-
tomatically and to analyze system vulnerabilities. While we have published our
generation and analysis algorithms in earlier work, the presentation of our example
and toolkit is novel to this paper.
1 Introduction
As networks of hosts continue to grow, it becomes increasingly more important to auto-
mate the process of evaluating their vulnerability to attack. When evaluating the security
of a network, it is rarely enough to consider the presence or absence of isolated vulnera-
bilities. Large networks typically contain multiple platforms and software packages and
employ several modes of connectivity. Inevitably, such networks have security holes that
escape notice of even the most diligent system administrator.
F.S. de Boer et al. (Eds.): FMCO 2003, LNCS 3188, pp. 344–371, 2004.
c Springer-Verlag Berlin Heidelberg 2004
Tools for Generating and Analyzing Attack Graphs 345
host vulnerability
scanning information
tools per host
Red Team Attack Graph
network information
network
box in the graph designates a single intruder action. A path from one of the boxes at the
top of the graph to one of the boxes at the bottom is a sequence of actions corresponding
to an attack scenario. At the end of any such scenario, the intruder has broken the network
security in some way. The graph is included here for illustrative purposes only, so we
omit the description of specific details.
Attack graphs can serve as a useful tool in several areas of network security, including
intrusion detection, defense, and forensic analysis. System administrators use attack
graphs for the following reasons:
– To gather information: Attack graphs can answer questions like “What attacks is
my system vulnerable to?” and “From an initial configuration, how many different
ways can an attacker reach a final state to achieve his goal?”
– To make decisions: Attack graphs can answer questions like “Which set of actions
should I prevent to ensure the attacker cannot achieve his goal?” or “Which set of
security measures should I deploy to ensure the attacker cannot achieve his goal?”
In this paper, we present the complete details of an example. We use this example to
illustrate:
– How we specify network attack models;
– The results of our automatic attack graph generation algorithms;
– The results of our minimization analyses;
– How to use our attack graph toolkit, including how we integrated tools from external
sources with ours.
The presentation of this example and our toolkit is novel to this paper.
In Sect. 2 we give general definitions for attack models and attack graphs. Section 3
narrows the definitions specifically to the domain of network security. Section 4 illus-
trates the definitions with a small example network. Section 5 focuses on the practical
aspects of building a usable attack graph tool. We discuss several approaches to collect-
ing the data necessary to build the network model. Finally, we review related work in
Sect. 6.
defender D represents both the system administrator(s) and security software installed on
the network. A state transition in a network attack model corresponds to a single action
by the intruder, a defensive action by the system administrator, or a routine network
action.
Real networks consist of a large variety of hardware and software pieces, most of
which are not involved in cyber attacks. We have chosen six network components relevant
to constructing network attack models. The components were chosen to include enough
information to represent a wide variety of networks and attack scenarios, yet keep the
model reasonably simple and small. The following is a list of the components:
Agent i ∈ I Si Ai
E I A
D Ids {alarm}
N H ×C ×T
It remains to make explicit the transition relation of the attack model M . Each
transition (s1 , s2 ) ∈ τ is either an action by the intruder, or an alarm action by the
system administrator. An alarm action happens whenever the intrusion detection system
is able to flag an intruder action. An action a ∈ A requires that the preconditions of
a hold in state s1 and the effects of a hold in s2 . Action preconditions and effects are
explained in Sect. 3.2.
scenario will target a host in some way. Typically, an action takes advantage of vulnerable
or misconfigured software to gain information or access privileges for the attacker.
The main goal in modeling hosts is to capture as much information as possible about
components that may contribute to creating an exploitable vulnerability.
A host h ∈ H is a tuple (id, svcs, sw, vuls), where
Actions. Each action is a triple (r, hs , ht ), where hs ∈ H is the host from which the
action is launched, ht ∈ H is the host targeted by the action, and r is the rule that
describes how the intruder can change the network or add to his knowledge about it. A
specification of an action rule has four components: intruder preconditions, network pre-
conditions, intruder effects, and network effects. The intruder preconditions component
places conditions on the intruder’s store of knowledge and the privilege level required
to launch the action. The network preconditions specifies conditions on target host state,
network connectivity, trust, services, and vulnerabilities that must hold before launching
the action. Finally, the intruder and network effects components list the action’s effects
on the intruder and on the network, respectively.
Intruder. The intruder has a store of knowledge about the target network and its users.
The intruder’s store of knowledge includes host addresses, known vulnerabilities, user
passwords, information gathered with port scans, etc. Also associated with the intruder
is the function plvl: Hosts → {none, user, root}, which gives the level of privilege that
the intruder has on each host. For simplicity, we model only three privilege levels. There
is a strict total order on the privilege levels: none ≤ user ≤ root.
Omitted Complications. Although we do not model actions taken by user services for
the sake of simplicity, doing so in the future would let us ask questions about effects of
intrusions on service quality. A more complex model could include services provided
by the network to its regular users and other routine network traffic. These details would
reflect more realistically the interaction between intruder actions and regular network
activity at the expense of additional complexity.
Another activity worth modeling explicitly is administrative steps taken either to
hinder an attack in progress or to repair the damage after an attack has occurred. The
former corresponds to transitioning to states of the model that offer less opportunity for
further penetration; the latter means “undoing” some of the damage caused by successful
attacks.
4 Example Network
Figure 3 shows an example network. There are two target hosts, Windows and Linux,
on an internal company network, and a Web server on an isolated “demilitarized zone”
(DMZ) network. One firewall separates the internal network from the DMZ and another
firewall separates the DMZ from the rest of the Internet. An intrusion detection system
(IDS) watches the network traffic between the internal network and the outside world.
The Linux host on the internal network is running several services—Linux “I Seek
You” (LICQ) chat software, Squid web proxy, and a Database. The LICQ client lets
Linux users exchange text messages over the Internet. The Squid web proxy is a caching
server. It stores requested Internet objects on a system closer to the requesting site than
to the source. Web browsers can then use the local Squid cache as a proxy, reducing
access time as well as bandwidth consumption. The host inside the DMZ is running
Microsoft’s Internet Information Services (IIS) on a Windows platform.
The intruder launches his attack starting from a single computer, which lies on the
outside network. To be concrete, let us assume that his eventual goal is to disrupt the
functioning of the database. To achieve this goal, the intruder needs root access on the
database host Linux. The five actions at his disposal are summarized in Table 2.
Each of the five actions corresponds to a real-world vulnerability and has an entry in
the Common Vulnerabilities and Exposures (CVE) database. CVE [22] is a standard list
of names for vulnerabilities and other information security exposures. A CVE identifier
is an eight-digit string prefixed with the letters “CVE” (for accepted vulnerabilities) or
“CAN” (for candidate vulnerabilities).
The IIS buffer overflow action exploits a buffer overflow vulnerability in the Mi-
crosoft IIS Web Server to gain administrative privileges remotely.
The Squid action lets the attacker scan network ports on machines that would other-
wise be inaccessible to him, taking advantage of a misconfigured access control list in
the Squid web proxy.
The LICQ action exploits a problem in the URL parsing function of the LICQ software
for Unix-flavor systems. An attacker can send a specially-crafted URL to the LICQ client
to execute arbitrary commands on the client’s computer, with the same access privileges
as the user of the LICQ client.
The scripting action lets the intruder gain user privileges on Windows machines.
Microsoft Internet Explorer 5.01 and 6.0 allow remote attackers to execute arbitrary
code via malformed Content-Disposition and Content-Type header fields that cause the
application for the spoofed file type to pass the file back to the operating system for
handling rather than raise an error message. This vulnerability may also be exploited
through HTML formatted email. The action requires some social engineering to entice
a user to visit a specially-formatted Web page. However, the action can work against
Tools for Generating and Analyzing Attack Graphs 353
firewalled networks, since it requires only that internal users be able to browse the Web
through the firewall.
Finally, the local buffer overflow action can exploit a multitude of existing vulner-
abilities to let a user without administrative privileges gain them illegitimately. For the
CVE number referenced in the table, the action exploits a buffer overflow flaw in the
at program. The at program is a Linux utility for queueing shell commands for later
execution.
Some of the actions that we model have multiple instantiations in the CVE database.
For example, the local buffer overflow action exploits a common coding error that occurs
in many Linux programs. Each program vulnerable to local buffer overflow has a separate
CVE entry, and all such entries correspond to the same action rule. The table lists only
one example CVE identifier for each rule.
variable meaning
w3svch IIS web service running on host h
squidh Squid proxy running on host h
licqh LICQ running on host h
scriptingh HTML scripting is enabled on host h
vul-ath at executable vulnerable to overflow on host h
The model of the target network includes connectivity information among the four
hosts. The initial value of the connectivity relation R is shown the following table. An
entry in the table corresponds to a pair of hosts (h1 , h2 ). IIS and Squid listen on port 80
and the LICQ client listens on port 5190, and the connectivity relation specifies which
of these services can be reached remotely from other hosts. Each entry consists of three
boolean values. The first value is ‘y’ if h1 and h2 are connected by a physical link, the
second value is ‘y’ if h1 can connect to h2 on port 80, and the third value is ‘y’ if h1 can
connect to h2 on port 5190.
We use the connectivity relation to reflect the settings of the firewall as well as the
existence of physical links. In the example, the intruder machine initially can reach only
the Web server on port 80 due to a strict security policy on the external firewall. The
internal firewall is initially used to restrict internal user activity by disallowing most
outgoing connections. An important exception is that internal users are permitted to
contact the Web server on port 80.
In this example the connectivity relation stays unchanged throughout an attack. In
general, the connectivity relation can change as a result of intruder actions. For example,
354 O. Sheyner and J. Wing
an action may enable the intruder to compromise a firewall host and relax the firewall
rules.
Intruder. The intruder’s store of knowledge consists of a single boolean variable ’scan’.
The variable indicates whether the intruder has successfully performed a port scan on
the target network. For simplicity, we do not keep track of specific information gathered
by the scan. It would not be difficult to do so, at the cost of increasing the size of the
state space.
Initially, the intruder has root access on his own machine Intruder, but no access
to the other hosts. The ’scan’ variable is set to false.
Actions. There are five action rules corresponding to the five actions in the intruder’s
arsenal. Throughout the description, S is used to designate the source host and T the target
host. R(S, T, p) says that host T is reachable from host S on port p. The abbreviation
plvl(X) refers to the intruder’s current privilege level on host X.
Recall that a specification of an action rule has four components: intruder precondi-
tions, network preconditions, intruder effects, and network effects. The intruder precon-
ditions component places conditions on the intruder’s store of knowledge and the privi-
lege level required to launch the action. The network preconditions component specifies
conditions on target host state, network connectivity, trust, services, and vulnerabilities
that must hold before launching the action. Finally, the intruder and network effects
components list the effects of the action on the intruder’s state and on the network,
respectively.
Sometimes the intruder has no logical reason to execute a specific action, even if all
technical preconditions for the action have been met. For instance, if the intruder’s current
privileges include root access on the Web Server, the intruder would not need to execute
the IIS buffer overflow action against the Web Server host. We have chosen to augment
each action’s preconditions with a clause that disables the action in instances when
the primary purpose of the action has been achieved by other means. This change is not
strictly conservative, as it prevents the intruder from using an action for its secondary side
effects. However, we feel that this is a reasonable price to pay for removing unnecessary
transitions from the attack graphs.
IIS Buffer Overflow. This remote-to-root action immediately gives a remote user a root
shell on the target machine.
action IIS-buffer-overflow is
intruder preconditions
plvl(S) ≥ user User-level privileges on host S
plvl(T ) < root No root-level privileges on host T
network preconditions
w3svcT Host T is running vulnerable IIS server
R(S, T, 80) Host T is reachable from S on port 80
intruder effects
plvl(T ) := root Root-level privileges on host T
network effects
¬w3svcT Host T is not running IIS
end
Squid Port Scan. The Squid port scan action uses a misconfigured Squid web proxy to
conduct a port scan of neighboring machines and report the results to the intruder.
action squid-port-scan is
intruder preconditions
plvl(S) = user User-level privileges on host S
¬scan We have not yet performed a port scan
network preconditions
squidT Host T is running vulnerable Squid proxy
R(S, T, 80) Host T is reachable from S on port 80
intruder effects
scan We have performed a port scan on the network
network effects
3 No changes to the network component
end
356 O. Sheyner and J. Wing
LICQ Remote to User. This remote-to-user action immediately gives a remote user a
user shell on the target machine. The action rule assumes that a port scan has been
performed previously, modeling the fact that such actions typically become apparent to
the intruder only after a scan reveals the possibility of exploiting software listening on
lesser-known ports.
action LICQ-remote-to-user is
intruder preconditions
plvl(S) ≥ user User-level privileges on host S
plvl(T ) = none No user-level privileges on host T
scan We have performed a port scan on the network
network preconditions
licqT Host T is running vulnerable LICQ software
R(S, T, 5190) Host T is reachable from S on port 5190
intruder effects
plvl(T ) := user User-level privileges on host T
network effects
3 No changes to the network component
end
Scripting Action. This remote-to-user action immediately gives a remote user a user shell
on the target machine. The action rule does not model the social engineering required to
get a user to download a specially-created Web page.
action client-scripting is
intruder preconditions
plvl(S) ≥ user User-level privileges on host S
plvl(T ) = none No user-level privileges on host T
network preconditions
scriptingT HTML scripting is enabled on host T
R(T, S, 80) Host S is reachable from T on port 80
intruder effects
plvl(T ) := user User-level privileges on host T
network effects
3 No changes to the network component
end
Local Buffer Overflow. If the intruder has acquired a user shell on the target machine,
this action exploits a buffer overflow vulnerability on a setuid root file (in this case, the
at executable) to gain root access.
action local-setuid-buffer-overflow is
intruder preconditions
plvl(T ) = user User-level privileges on host T
Tools for Generating and Analyzing Attack Graphs 357
network preconditions
vul-atT There is a vulnerable at executable
intruder effects
plvl(T ) := root Root-level privileges on host T
network effects
3 No changes to the network component
end
which states that the intruder will never attain root privileges on the Linux host. In
Figure 4, a sample attack scenario is highlighted with solid square nodes, with each
attack step identified by name and CVE number. Since the external firewall restricts
most network connections from the outside, the intruder has no choice with respect to
the initial step—it must be a buffer overflow action on the IIS Web server. Once the
intruder has access to the Web server machine, his options expand. The highlighted
scenario is the shortest route to success. The intruder uses the Web server machine to
launch a port scan via the vulnerable Squid proxy running on the Linux host. The scan
discovers that it is possible to obtain user privileges on the Linux host with the LICQ
exploit. After that, a simple local buffer overflow gives the intruder administrative control
over the Linux machine. The last transition in the action path is a bookkeeping step,
signifying the intruder’s success.
Any information explicitly represented in the model is available for inspection and
analysis in the attack graph. For instance, with a few clicks we are able to highlight
Begin
Done!
portions of the graph “covered” by the intrusion detection system. Figure 5 shades the
nodes where the IDS alarm has been sounded. These nodes lie on paths that use the
LICQ action along a network path monitored by the IDS. It is clear that while a sub-
stantial portion of the graph is covered by the IDS, the intruder can escape detection and
still succeed by taking one of the paths on the right side of the graph. One such attack
scenario is highlighted with square nodes in Figure 5. It is very similar to the attack
scenario discussed in the previous paragraph, except that the LICQ action is launched
from the internal Windows machine, where the intrusion detection system does not
see it. To prepare for launching the LICQ action from the Windows machine, an addi-
tional step is needed to obtain user privileges in the machine. For that, the intruder uses
the client scripting exploit on the Windows host immediately after taking over the Web
machine.
Begin
Highlighted scenario
IIS buffer
overflow Scripting remote-
Alarm has sounded to-user
CAN-2002-0364
CAN-2002-0193
Squid portscan
CVE-2001-1030
LICQ remote-
to-user
CVE-2001-0439
Local buffer
overflow
Done!
CVE-2002-0004
Single Action Removal. A simple kind of analysis determines the impact of removing
one action from the intruder’s arsenal. Recall from Sect. 3 that each action is a triple
(r, hs , ht ), where hs ∈ H is the host from which the attack is launched, ht ∈ H is
Tools for Generating and Analyzing Attack Graphs 359
the host targeted by the attack, and r is an action rule. The user specifies a set Arem of
action triples to be removed from the attack graph. The toolkit deletes the transitions
corresponding to each triple in the set Arem from the graph and then removes the nodes
that have become unreachable from the initial state.
As demonstrated in Figure 6, this procedure can be repeated several times, reducing
the size of the attack graph at each step. The full graph in Figure 6(a) has 362 states.
Removing one of two ways the intruder can sniff user W ’s login credentials produces
the graph in Figure 6(b), with 213 states. Removing one of the local buffer overflow
actions produces the graph in Figure 6(c), with 66 states. At each step, the user is able
to judge visually the impact of removing a single action from the intruder’s arsenal.
Critical Action Sets. Once an attack graph is generated, an approximation algorithm
can find an approximately-optimal critical set of actions that will completely disconnect
the initial state from states where the intruder has achieved his goals [16]. A related
algorithm can find an approximately-optimal set of security measures that accomplish the
same goal. With a single click, the user can invoke both of these exposure minimization
algorithms.
The effect of the critical action set algorithm on the modified example attack graph is
shown in Figure 7(a). The algorithm finds a critical action set of size 1, containing the port
scan action exploiting the Squid web proxy. The graph nodes and edges corresponding
to actions in the critical set computed by the algorithm are highlighted in the toolkit
by shading the relevant nodes. The shaded nodes are seen clearly when we zoom in to
inspect a part of the graph on a larger scale (Figure 7(b)).
Since the computed action set is always critical, removing every action triple in the
set from the intruder’s arsenal is guaranteed to result in an empty attack graph. In the
example, we might patch the Linux machine with a new version of the Squid proxy,
thereby removing every action triple that uses the Squid port scan rule on the Linux
machine from the intruder’s arsenal.
4HE SCENARIO GRAPH GENERATOR TAKES ANY lNITE MODEL AND CORRECTNESS SPECIlCATION
AND PRODUCES A GRAPH COMPOSED OF POSSIBLE EXECUTIONS OF THE MODEL THAT VIOLATE THE
CORRECTNESS SPECIlCATION 4HE MODEL BUILDER CONSTRUCTS THE INPUT TO THE GRAPH GENERATOR
SO THAT THE OUTPUT WILL BE THE DESIRED ATTACK GRAPH 4HE GRAPHICAL USER INTERFACE LETS THE
USER DISPLAY AND EXAMINE THE GRAPH
4HE MODEL BUILDERS RUNNING TIME IS LINEAR IN THE SIZE OF THE INPUT SPECIlCATION
TYPICALLY WRITTEN IN THE 8-, FORMAT SPECIlED IN 3ECT 4HE ALGORITHM IN THE SCENARIO
GRAPH GENERATOR IS LINEAR IN THE SIZE OF THE OUTPUT SCENARIO GRAPH ;= 4HE SLOWEST PART
OF THE TOOLKIT IS THE ALGORITHM THAT LAYS OUT THE ATTACK GRAPH ON SCREEN 4HE ALGORITHM
USES THE NETWORK SIMPLEX METHOD TO lND OPTIMAL X COORDINATES 4HE SIMPLEX METHOD
HAS EXPONENTIAL WORST CASE PERFORMANCE 4HE REST OF THE LAYOUT ALGORITHM HAS CUBIC
COMPLEXITY 4HUS FOR LARGE GRAPHS IT IS SOMETIMES NECESSARY TO RUN ANALYSIS ALGORITHMS
WITHOUT DISPLAYING THE FULL GRAPH ON SCREEN
The example description provides the host name and network identification (line
1), a list of active services with port numbers (lines 3-6), the part of the connectivity
relation that involves the host (lines 8-12), and names of CVE and CVE-candidate (CAN)
vulnerabilities known to be present on the host (lines 14-17). Connectivity is specified
as a list of services that the host can reach on each remote machine. Lines 9-11 each
specify one remote machine; e.g., typical-machine can reach machine1 on ports
assigned to the ftp and W3SVC (IIS Web Server) services.
It is unrealistic to expect the user to collect and specify all of the data by hand. In
Sections 5.3-5.5 we discuss three external data sources that supply some of the infor-
mation automatically: the Nessus vulnerability scanner, MITRE Corp.’s Outpost, and
Lockheed Martin’s ANGI. Whenever the model builder can get a specific piece of in-
formation from one of these sources, a special tag is placed in the XML file. If Nessus,
Outpost and ANGI are all available at the same time as sources of information, the above
host description may look as follows:
<host id="typical-machine" ip="|Outpost|">
<services source="|Outpost|"/>
<connectivity source="|ANGI|"/>
<cve source="|Nessus|"/>
</host>
The model builder gets the host network address and the list of running services from
Outpost, connectivity information from ANGI, and a list of existing vulnerabilities from
Nessus. Once all of the relevant information is gathered, the model builder creates a
finite model and encodes it in the input language of the scenario graph generator. The
scenario graph generator then builds the attack graph.
Outpost
Server Host
Network Configuration
of Data
Outpost Attack Graph
Clients Toolkit
SQL
database
toolkit. Until these deficiencies are fixed, the user must provide the missing information
manually.
In the future, the Outpost server will inform the attack graph toolkit whenever changes
are made to the database. The tighter integration with Outpost will enable attack graph
toolkit to re-generate attack graphs automatically every time something changes in the
network configuration.
Two distinguishing features of ANGI are the ability to discover network topology
changes dynamically and focus on technologies for pro-active, automated repair of net-
work problems. ANGI is capable of providing the attack graph model builder with
network topology information, which is not available in Outpost and is not gathered by
Nessus.
We tested our attack graph toolkit integrated with ANGI on a testbed of five hosts
with combinations of the five CVE vulnerabilities specified for the example model in
Chapter 4 (p. 352), and one adversary host. Figure 10 is a screenshot of the testbed
network schematic. The intruder resides on the host lindenwold. Hosts trenton
and mtholly run firewalls, which are initially disabled. We assume that the target of
the intruder is the host shamong, which contains some critical resource.
ANGI combines information about each host with data from firewall configuration
files into a single XML document. To convert firewall rules into a reachability relation C
accepted by the attack graph toolkit, ANGI uses a package developed at MITRE Corp.
that computes network reachability from packet filter data [14]. The XML file specifies
explicitly five attack rules corresponding to the CVE vulnerabilities present on the hosts.
ANGI then calls the model builder with the XML document and a security property as
inputs. The security property specifies a guarantee of protection for the critical resource
host shamong:
G(intruder.privilege[shamong] < root)
Tools for Generating and Analyzing Attack Graphs 367
The attack graph generator finds several potential attack scenarios. Figure 11 shows
the attack graph as it is displayed by the graphical user interface. The graph consists of
19 nodes with 28 edges.
Exploring the attack graph reveals that several successful attack scenarios exploit the
LICQ vulnerability on the host shamong. One such attack scenario is highlighted in
Figure 11. As indicated in the “Path Info” pane on the left of Figure 11, the second step
of the highlighted scenario exploits the LICQ vulnerability on shamong. This suggests
a possible strategy for reducing the size of the graph. Using the ANGI interface, we
enable the firewall on the host trenton, and add a rule that blocks all external traffic at
trenton from reaching shamong on the LICQ port. ANGI then generates a new XML
model file reflecting this change. The new graph demonstrates a significant reduction
in network exposure from this relatively small change in network configuration. The
modification reduces graph size to 7 nodes and 6 edges with only two possible paths.
(Contrast this new graph with the attack graph shown in Figure 11, which has 19 nodes,
28 edges, and 20 paths.)
368 O. Sheyner and J. Wing
Looking at the scenarios in this new graph, we discover that the attacker can still
reach shamong by first compromising the web server on cherryhill. Since we
do not want to disable the web server, we enable the firewall on mtholly and add
a rule specifically blocking cherryhill’s access to the LICQ client on shamong.
Yet another invocation of the attack graph generator on the modified model produces
an empty attack graph and confirms that we have successfully safeguarded shamong
while retaining the full functionality of the network.
6 Related Work
Many of the ideas that we propose to investigate have been suggested or considered in
existing work in the intrusion detection field. This section surveys recent related work.
Phillips and Swiler [13] propose the concept of attack graphs that is similar to the
one described here. However, they take an “attack-centric” view of the system. Since we
work with a general modeling language, we can express in our model both seemingly
benign system events (such as failure of a link) and malicious events (such as attacks).
Therefore, our attack graphs are more general than the one proposed by Phillips and
Swiler. Swiler et al. describe a tool [19] for generating attack graphs based on their
previous work. Their tool constructs the attack graph by forward exploration starting
from the initial state.
The advantage of using model checking instead of forward search is that the technique
can be expanded to include liveness properties, which can model service guarantees in
the face of malicious activity. For example, a model of a banking network could have a
liveness security property such as
G (CheckDeposited → (F CheckCleared))
which specifies that every check deposited at a bank branch must eventually clear.
Templeton and Levitt [20] propose a requires/provides model for attacks. The model
links atomic attacks into scenarios, with earlier atomic attacks supplying the prerequisites
for the later ones. Templeton and Levitt point out that relating seemingly innocuous sys-
tem behavior to known attack scenarios can help discover new atomic attacks. However,
they do not consider combining their attack scenarios into attack graphs.
Cuppens and Ortalo [6] propose a declarative language (LAMBDA) for specifying at-
tacks in terms of pre- and post-conditions. LAMBDA is a superset of the simple language
we used to model attacks in our work. The language is modular and hierarchical; higher-
level attacks can be described using lower-level attacks as components. LAMBDA also
includes intrusion detection elements. Attack specifications includes information about
the steps needed to detect the attack and the steps needed to verify that the attack has
already been carried out. Using a database of attacks specified in LAMBDA, Cuppens
and Miege [5] propose a method for alert correlation based on matching post-conditions
of some attacks with pre-conditions of other attacks that may follow. In effect, they
exploit the fact that alerts about attacks are more likely to be related if the corresponding
attacks can be a part of the same attack scenario.
Dacier [7] proposes the concept of privilege graphs. Each node in the privilege graph
represents a set of privileges owned by the user; edges represent vulnerabilities. Privi-
Tools for Generating and Analyzing Attack Graphs 369
lege graphs are then explored to construct attack state graphs, which represents different
ways in which an intruder can reach a certain goal, such as root access on a host. He
also defines a metric, called the mean effort to failure or METF, based on the attack
state graphs. Orlato et al. describe an experimental evaluation of a framework based on
these ideas [12]. At the surface, our notion of attack graphs seems similar to the one
proposed by Dacier. However, as is the case with Phillips and Swiler, Dacier takes an
“attack-centric” view of the world. As pointed out above, our attack graphs are more
general. From the experiments conducted by Orlato et al. it appears that even for small
examples the space required to construct attack state graphs becomes prohibitive. By
basing our algorithm on model checking we take advantage of advances in representing
large state spaces and can thus hope to represent large attack graphs.
Ritchey and Ammann [15] also use model checking for vulnerability analysis of
networks. They use the (unmodified) model checker SMV [18]. They can obtain only one
counter-example, i.e., only one attack corresponding to an unsafe state. In contrast, we
modified the model checker NuSMV to produce attack graphs, representing all possible
attacks. We also described post-facto analyzes that can be performed on these attack
graphs. These analysis techniques cannot be meaningfully performed on single attacks.
Graph-based data structures have also been used in network intrusion detection sys-
tems, such as NetSTAT [21]. There are two major components in NetSTAT, a set of
probes placed at different points in the network and an analyzer. The analyzer processes
events generated by the probes and generates alarms by consulting a network fact base
and a scenario database. The network fact base contains information (such as connec-
tivity) about the network being monitored. The scenario database has a directed graph
representation of various atomic attacks. For example, the graph corresponding to an IP
spoofing attack shows various steps that an intruder takes to mount that specific attack.
The authors state that “in the analysis process the most critical operation is the generation
of all possible instances of an attack scenario with respect to a given target network.”
Ammann et. al. present a scalable attack graph representation [1]. They encode attack
graphs as dependencies among exploits and security conditions, under the assumption
of monotonicity. Informally, monotonicity means that no action an intruder can take
interferes with the intruder’s ability to take any other actions. The authors treat vulnera-
bilities, intruder access privileges, and network connectivity as atomic boolean attributes.
Actions are treated as atomic transformations that, given a set of preconditions on the
attributes, establish a set of postconditions. In this model, monotonicity means that (1)
once a postcondition is satisfied, it can never become ’unsatisfied’, and (2) the negation
operator cannot be used in expressing action preconditions.
The authors show that under the monotonicity assumption it is possible to construct
an efficient (low-order polynomial) attack graph representation that scales well. They
present an efficient algorithm for extracting minimal attack scenarios from the represen-
tation, and suggest that a standard graph algorithm can produce a critical set of actions
that disconnects the goal state of the intruder from the initial state.
This approach is less general than our treatment of attack graphs. In addition to
the monotonicity requirement, it can handle only simple safety properties. Further, the
compact attack graph representation is less explicit, and therefore harder for a human to
370 O. Sheyner and J. Wing
read. The advantage of the approach is that it has a worst-case bound on the size of the
graph that is polynomial in the number of atomic attributes in the model, and therefore
can scale better than full-fledged model checking to large networks.
References
1. Paul Ammann, Duminda Wijesekera, and Saket Kaushik. Scalable, graph-based network
vulnerability analysis. In 9th ACM Conference on Computer and Communications Security,
pages 217–224, 2002.
2. G. Ausiello, A. D’Atri, and M. Protasi. Structure preserving reductions among convex opti-
mization problems. Journal of Computational System Sciences, 21:136–153, 1980.
3. T.H. Cormen, C.E. Leiserson, and R.L. Rivest. Introduction to Algorithms. MIT Press, 1985.
4. Cotse.net. Vulnerability Scanners. http://www.cotse.com/tools/vuln.htm.
5. Frederic Cuppens and Alexandre Miege. Alert correlation in a cooperative intrusion detection
framework. In 23rd IEEE Symposium on Security and Privacy, May 2002.
6. Frederic Cuppens and Rodolphe Ortalo. Lambda:A language to model a database for detection
of attacks. In Proceedings of the Third International Workshop on the Recent Advances in
Intrusion Detection (RAID), number 1907 in LNCS, pages 197–216. Springer-Verlag, 2000.
7. M. Dacier. Towards Quantitative Evaluation of Computer Security. PhD thesis, Institut
National Polytechnique de Toulouse, December 1994.
8. Renaud Deraison. Nessus Scanner. http://www.nessus.org.
9. Somesh Jha, Oleg Sheyner, and Jeannette M. Wing. Minimization and reliability analyses
of attack graphs. Technical Report CMU-CS-02-109, Carnegie Mellon University, February
2002.
Tools for Generating and Analyzing Attack Graphs 371
10. Somesh Jha, Oleg Sheyner, and Jeannette M. Wing. Two formal analyses of attack graphs. In
Proceedings of the15th IEEE Computer Security Foundations Workshop, pages 49–63, Nova
Scotia, Canada, June 2002.
11. Somesh Jha and Jeannette Wing. Survivability analysis of networked systems. In Proceedings
of the International Conference on Software Engineering, Toronto, Canada, May 2001.
12. R. Ortalo, Y. Dewarte, and M. Kaaniche. Experimenting with quantitative evaluation tools for
monitoring operational security. IEEE Transactions on Software Engineering, 25(5):633–650,
September/October 1999.
13. C.A. Phillips and L.P. Swiler. A graph-based system for network vulnerability analysis. In
New Security Paradigms Workshop, pages 71–79, 1998.
14. John Ramsdell. Frame propagation. MITRE Corp., 2001.
15. R.W. Ritchey and P. Ammann. Using model checking to analyze network vulnerabilities. In
Proceedings of the IEEE Symposium on Security and Privacy, pages 156–165, May 2001.
16. Oleg Sheyner. Scenario Graphs and Attack Graphs. PhD thesis, Carnegie Mellon University,
2004.
17. Oleg Sheyner, Joshua Haines, Somesh Jha, Richard Lippmann, and Jeannette Wing. Auto-
mated generation and analysis of attack graphs. In Proceedings of the IEEE Symposium on
Security and Privacy, 2002.
18. SMV. SMV:A Symbolic Model Checker. http://www.cs.cmu.edu/˜modelcheck/.
19. L.P. Swiler, C. Phillips, D. Ellis, and S. Chakerian. Computer-attack graph generation tool. In
Proceedings of the DARPA Information Survivability Conference and Exposition, June 2000.
20. Steven Templeton and Karl Levitt. A requires/provides model for computer attacks. In
Proceedings of the New Security Paradigms Workshop, Cork, Ireland, 2000.
21. G. Vigna and R.A. Kemmerer. Netstat: A network-based intrusion detection system. Journal
of Computer Security, 7(1), 1999.
22. Common Vulnerabilities and Exposures. http://www.cve.mitre.org.
Author Index