Book Review

The B-Book: Assigning Programs to Meanings

by J.-R. Abrial

Cambridge University Press 1996. ISBN 0-521-49619-5. 779pp. Hardbound.

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:

The appendices (80 pages) contain a comprehensive listing of the language syntax and the proof rules.

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.