Appears in The Computer Journal, Vol.40.1 (1997):59-61, ISSN 0010-4620.
B is a formal method in the same vein as Z and VDM. Such methods are often referred to as 'model oriented' since they describe system behaviour using an explicit model of the system state along with operations on the state. The B method was developed mostly by Jean-Raymond Abrial and was influenced by his work on the development of Z. Apart from some notational differences, what distinguishes B from Z is that B aims to cover a broader range of the development cycle from specification to coding, whereas Z is perhaps more suited to earlier stages of the development cycle. To quote from the introduction, 'B is a method for specifying, designing and coding software systems'. The method makes use of formal refinement to ensure that the properties of an initial specification are preserved by successive stages in the development of a system and thus that the final implementation is formally correct with respect to the specification.
Evolution of the B method started in the early 1980s and it has been applied successfully on several industrial projects, most notably on part of the control system for the Paris Metro. Commercial tools supporting the method are available in the form of the B-Toolkit from B-Core, UK, and Atelier B from Digilog, France. However, up until last year, there wasn't a single textbook available on the method. Around the same time that Abrial's book was published, two books on B were published separately by Kevin Lano of Imperial College and John Wordsworth of IBM UK Laboratories. Without denigrating either of the other two, it is fair to say that Abrial's book is by far the most comprehensive. It also has the advantage of having been written by the method's master. Prior to the publication of these books, the only source of information on B was the training material supplied with the B tools and a small number of conference papers. This material left a lot of important questions unanswered, relating to both the theory underlying the method and its practical application. Fortunately most of these questions are now answered by Abrial's book.
At just under 800 pages, the book is certainly not intended to be read straight through from cover to cover. Instead, Abrial provides several routes through the book to suit different readers depending on whether their interest is more practical or more theoretical. These suggested routes are especially important since the theoretical and practical sections are interspersed throughout the book. This mixing of theory and practice suits the presentation of the material as the practical material helps to motivate the theory. The book will also serve as the reference manual for B.
The presentation of the material is very clear and well structured. There is good use of typesetting, especially tables and boxes, to highlight important parts and to consolidate definitions, laws and examples. The mathematical notation is quite standard making it easy to switch backwards and forwards between chapters. However, a more comprehensive index would have been useful, especially if the book is to serve as a reference manual.
The book consists of four parts:
Part 1 could almost serve as a text book in discrete mathematics
on its own. It starts with a presentation of logic and proof. The logic
is an untyped first order logic while the proof style is natural deduction.
There are plenty of example proofs, as well as some good guidance on constructing
proofs. Use of an untyped logic is quite a pragmatic approach, resulting
in a straightforward proof system, though it is contrary to most modern
mechanical theorem provers such as PVS and HOL where typed logic is used.
Although the logic is untyped, the set theory is typed - a set can be
defined syntactically using a predicate, but this definition will only
represent a valid set if it satisfies some type-checking rules. There is
a detailed presentation of set theory, including relations, partial functions,
natural numbers, sequences and trees, with comprehensive lists of laws
for these structures and their operators. There is also a good treatment
of fixed points and induction which is deeper than is usually found in
formal methods books of this nature. Dealing with the application of partial
functions is notoriously difficult in proof systems. The approach Abrial
uses is to say that f(x) is defined by a 'choice' operator - but
only when x is in the domain of f. Thus he provides a partial
definition of function application at the meta level and avoids introducing
a three-valued logic to deal with undefinedness. While this approach works
quite well (the same approach is used in Z), Abrial could have elaborated
on its consequences.
I will consider Parts II, III and IV from a practical
point of view firstly, and then consider them from a theoretical point
of view.
Chapters 4 and 5 deal with abstract machines. An
abstract machine is the basic unit of specification in B and is essentially
a state machine with state variables and operations that act on the state
variables. The description of an abstract machine also contains some types,
constants and invariants. Continuing with the theme of an untyped logic,
the state variables of an abstract machine are declared without types,
but must then be constrained to be of some type by the invariant. Any of
the set-theoretic structures of Part I can be used to describe types. The
operations of an abstract machine are described using the so-called generalised-substitution
language. This is an extension of Dijkstra's guarded-command language
and includes specification constructs that allow an operation to be specified
by a predicate describing a before-after relation on the state variables
in the manner of VDM and Z. Those familiar with B will be interested to
note that Abrial has added two new clauses to abstract machines: abstract
constants and concrete variables. I refer readers to the book
for the significance of these additions and just say they lift some restrictions
in the earlier version of the language that had always seemed unnecessary.
Chapter 7 describes the ways in which abstract machines
may be combined to form larger specifications. This support for modular
specifications is an important feature of B, and is one that Z, for example,
lacks. B provides more than one way of combining machines and prior to
reading this book, I hadn't fully appreciated the need for some of them.
The book provides some good intuition on why the different ways are important
and in which situations they should be used.
Chapter 8 presents three medium-sized case studies in
specification using abstract machines. These examples nicely illustrate
the use of some of the different mechanisms for combining machines. The
third case study, involving a lift control system, contains an interesting
example of a 'liveness' argument. Here, in an analysis of the formal specification,
a variant argument is used to demonstrate that any request for lift by
a user is eventually met. This is not justified in terms of any formal
treatment of liveness, but the intuition appears to be sound. Perhaps researchers
interested in liveness might like to tackle this example more rigorously
using temporal logic.
Part III is concerned with implementation issues, in particular
loop correctness, while Part IV is concerned with moving from specifications
to designs. Although these parts may appear to be in the wrong order in
terms of the development cycle, there is a progression on terms of the
formal concepts covered. Chapter 9 develops the standard proof rule for
loops. It does this in a way that is more general than usual in textbooks
which I found attractive. Chapter 10 presents what is in effect a methodology
for developing loop-based algorithms. This involves the use of loop templates
which may be instantiated into more specific problems. This approach appears
to be very effective and practical since much of the proof effort is already
taken care of by the templates. I hadn't expected to see a chapter such
as this in the book and I think it would be of interest to anyone who cares
about the design of algorithms.
Chapter 11 introduces machine refinement both intuitively
and formally. An abstract machine is refined by making its operations more
algorithmic. The standard technique of data refinement may also be used.
This involves replacing abstract state variables with more concrete variables
that are closer to the data types provided by programming languages. While
the intuition behind refinement is well explained I felt that more guidance
is needed on how to 'invent' data refinements though I accept this could
be difficult to elucidate. The way in which the correctness of refinement
steps is checked in B is through the use of verification-style proof rules.
This contrasts with the approach used in the refinement calculus
developed by Back, Morgan, Morris and others where calculational rules
are used to gradually transform specifications into implementations. I
believe it would be quite feasible to combine these two styles in B.
Chapter 12 deals with the relationship between modularity
in specifications and modularity in implementations. Abrial shows how the
modular structure of a specification may be different to that of an implementation.
I found this chapter very illuminating and I feel that the issue receives
insufficient attention in the formal methods community. The structured-design
community could also learn from Abrial's treatment of the relationship
between modularity and machine refinement.
Curiously, Chapter 12 also introduces a construct for
general recursion to the generalised-substitution language. The previous
literature on B restricted iteration to 'while' loops. However, Abrial's
insistence that the use of loops and sequential composition (and now also
recursion) be restricted to implementations and not used in specifications
remains - a restriction that I don't fully agree with.
Chapter 13 presents two major case studies in specification
and design using B. The first deals with the development of a database
system and involves several stages of design including the introduction
of a file system for data storage. The case study provides a good illustration
of the relationship between refinement and modularity. The second major
case study deals with the specification and design of a pump controller
for a steam boiler. The requirements come from the nuclear power industry
and the system is surprisingly complex since it provides a degree of fault
tolerance. The case study very nicely illustrates how a formal specification
may be synthesised from informal requirements. The case study is also interesting
in that Abrial uses machine refinement not just as a design technique,
but also as a way of structuring and elaborating the initial specification
- another idea that I found attractive. Abrial also attempts to illustrate
how the specification can deal with changes to the requirements, but this
is not entirely convincing since the modifications in question are quite
trivial.
I now turn to some of the more theoretical aspects of
Parts II, III and IV. Abrial uses two levels of semantic definition to
model abstract machines. In Chapter 5, the language used to describe operations
is shown to be an be an extension of the logic. That is, statements in
the language are defined as substitutions that act on predicates, hence
the name 'generalised substitution'. If S is a statement and P
is a predicate, then S[P] represents the predicate that results
from applying substitution S to P. This approach corresponds
to Dijkstra's weakest-precondition formalism, that is, [S]P corresponds
to Dijkstra's wp(S,P).
Chapter 6 presents a set-theoretic semantics in which
predicates are modelled as sets of states and statements are modelled as
functions from sets to sets, so-called set transformers. The set-transformer
semantics is more rigorous than the substitution semantics since it can
deal with types and higher order concepts such as fixed points and refinement
(the logic is first order, so cannot be used to express 'for all predicates
P, T holds'). There is a degree of redundancy in having
the two levels of semantics and this decision is not fully justified by
Abrial. I suspect the reason for it is partly historical in that the substitution
semantics appears in previous literature by Abrial, but the set-transformer
model is newer. Also, the previously mentioned tools for B only work with
the substitution semantics so the set-transformer semantics can be seen
as providing a justification for the soundness of the tools. Abrial's two
level semantic approach may be compared with related work by Ralph Back,
for example, who also uses a weakest-precondition style semantics. Rather
than having a two level semantics, Back works with a single level semantics
that uses a typed higher order logic. An advantage of Back's approach is
that it uses a more uniform notation, and indeed, I would say more elegant
notation as I found the notation used in Abrial's set-transformer model
somewhat cumbersome. However, these issues are a matter of personal preference
and are only of concern to those who need to work with the semantics, such
as tool builders, not to those who wish to apply the B method in practice.
The definition of refinement is given in Chapter 11 in
terms of the set-transformer semantics. This is equivalent to the definition
used by others who work with a weakest-precondition semantics. The definition
is higher order but Abrial uses the neat trick of showing that it is equivalent
to a first order definition. This is important since he wants practitioners
of the method to only have to work with first order logic. I found that
Chapters 6 and 11 deal with a lot of previously unanswered questions about
the semantics of B.
So what about tool support? I was surprised to find that
Abrial doesn't cover the tool support available for B in this book (Atelier
B is briefly mentioned in the introduction but the B-Toolkit isn't mentioned
at all). Surely the availability of tool support is a major reason for
the industrial take up of B. Perhaps one reason for leaving it out is that
tool support is likely to evolve more rapidly than the definition of the
language and methodology presented in the book.
As I have already made clear, this book covers a broad
and coherent range of issues at more or less the right depth. I particularly
admire the emphasis it places on proof throughout the book. There is a
view that to gain from the use of formal methods, it is sufficient just
to use formal specification and not to use proof. But there is also the
view that it is ultimately unsatisfactory and wasteful to employ a tool
and not use it to its full potential. Abrial's book goes some way towards
showing how a formal method can be used to its full potential in a way
that is beneficial and practical. I would thoroughly recommend it to anyone
interested in the correct design of computer systems.
Michael Butler, University of Southampton, 1997.
The appendices (80 pages) contain a comprehensive listing
of the language syntax and the proof rules.