Documente Academic
Documente Profesional
Documente Cultură
of
Control System Input/Output
Jonathan Jacky
Radiation Oncology Department RC-08
University of Washington
Seattle, WA 98195
jon@radonc.washington.edu
May, 1992
Abstract
This report presents a formal specication in the Z notation for computations that
calculate control system state variables from input/output device register contents (and
vice-versa). The specication is motivated by a particular medical device but is quite
generic and should be widely applicable. The specication is parameterized so that
an implementation can be adapted to dierent control systems by providing tables of
conguration data, rather than changing executable code. Specied behaviors include
detection of errors (where clients invoke operations with invalid parameters) and faults
(where input/output devices report invalid data). The specication is not merely de-
scriptive, but is also used in the formal development (or \renement") of a detailed
design. From an initial specication which naturally expresses the requirements, but
is abstract and non-constructive, we derive a functionally equivalent specication (also
in Z), which suggests a straightforward and ecient implementation in an imperative
programming language. Formal justication is provided for each step in the derivation.
Conjectures are posed that formalize claims such as \All inputs are handled properly."
Proving the conjectures could check for errors in the derivation, and provide condence
that the formal specication expresses the intended requirements.
c 1992 by Jonathan Jacky
This work may not be copied or reproduced in whole or part for any commercial purpose.
Permission to photocopy in whole or part without payment of fee is granted for nonprot
educational and research purposes provided that all such copies include the following notice:
a notice that such copying is by permission of the authors; an acknowledgment of the authors
of the work; and all applicable portions of this copyright notice. All rights reserved.
c 1992 by Jonathan Jacky
This work may not be copied or reproduced in whole or part for any commercial purpose.
Permission to photocopy in whole or part without payment of fee is granted for nonprot
educational and research purposes provided that all such copies include the following notice:
a notice that such copying is by permission of the authors; an acknowledgment of the authors
of the work; and all applicable portions of this copyright notice. All rights reserved.
1
1 Introduction
Safety-critical control systems are often advocated as ideal applications for formal software
development methods [2]. However, few published case studies apply formal methods to
a problem of central importance in these applications: low level input/output1. Control
systems often include large numbers of input and output signals, and devote much com-
putational eort to dealing with them. The system that motivates this study, a cyclotron
used for medical isotope production and radiation therapy for cancer, has more than one
thousand input and output signals [5, 7].
A vital activity in most control systems is the processing of unscaled, unencoded contents
of the input/output device registers that are attached to the transducers that sense and
control some physical process. Register contents must be translated to the values of the
state variables that occur in the control laws that the system is supposed to obey. For
example, analog quantities must be scaled and oset to match analog-to-digital converters
(ADC's) and DAC's and often must be adjusted according to calibration curves. Groups
of digital signals must be encoded as discrete variables. Obviously, the correctness of the
entire system depends critically upon such translations. Translations must be computed in
both directions: register contents are encoded into variables on input, and state variables
are decoded back to register contents on output.
It is also necessary to detect errors (where clients invoke operations with invalid parameters)
and faults (where operations fail despite valid invocation by the client). In most computing
applications, it is expected that programs should detect and report errors, but it is left to
the users to deal with faults. Control systems dier from other computing applications in
part because they are expected to handle some faults.
Our system is large, but most of its size derives from repetition of similar elements. We
hope to produce a manageable system by basing the implementation on tables that describe
the system conguration. For example, one table, the \wiring list," tells which signals are
connected to particular input/output device register addresses; another table, the \crate
diagram," tells which kind of device is present at each address. It should be possible to
accommodate most conguration changes simply by editing tables, rather than changing
executable code. Changing the routing between signals and devices, or adding additional
signals and devices similar to those already present, should only require changing tables.
Accommodating new kinds of signals and devices should only require adding the minimal
amount of code needed to deal with their specic characteristics.
The requirements are not dicult to understand, but a large control system provides many
opportunities for confusion and error. We decided it would be useful to conduct a formal
1
I could nd only [1] and [3], and these are not recent.
2 2 THE INITIAL SPECIFICATION
development. The purpose of the eort reported here was to determine what the tables
should contain and how the implementation should interpret their contents. The objective
was to produce a specication that was suciently detailed so that its implementation in
an imperative programming language would be a straightforward exercise, and it would
be clear how to construct and ll in the tables to describe any particular control system
conguration. We intended that the development should be suciently rigorous that we
could use proofs to support claims we would like to make, for example, \All possible inputs
will be handled properly," or \Every output will be valid."
We used the Z notation [8] for this work because it is a good match to our chosen table-
driven strategy. Global functions and relations in Z correspond to our conguration tables.
Z deals well with partial functions, providing a natural model for tables with gaps where
address spaces are not populated. Functional composition in Z can represent computations
where an entry found in one table is used as an index into another. Many Z textbooks
and case studies provide nice examples of error handling [6, 8]. Some of our preliminary
experiments with Z appear in [4]. The Z text in this report was found free of syntax and
type errors by the FUZZ type-checker [9].
Z does not provide built-in facilities for representing the passage of time, or synchronization
of concurrent processes. This report deals only with the functional aspects of input/output,
and defers other issues for treatment in a notation better suited for them.
This report is not a tutorial on Z, but the development is fully explained in the English text
and is intended to be meaningful to readers who are not familiar with Z. In fact, this essay
is intended to pursuade readers who are unfamiliar with formal methods that they can be
practical and eective in real projects.
Data converters contain registers. Every register is identied by a unique address, and holds
contents that encode the value of one signal in a form intelligible to the computer. In any
particular conguration, a xed set of addresses is populated with registers.
We distinguish register contents from control program state variables. While registers hold
contents, variables have values.
Expressed formally, we have:
[ADDR CONTENTS VAR VALUE ]
; ; ;
ioreg : ADDR
iovar : VAR
map : VAR # ADDR
map iovar ioreg
Sys
register : ADDR CONTENTS
variable : VAR VALUE
dom register = ioreg
dom variable \ dom map iovar
The sets ioreg and iovar , and the relation map model some of the tables that describe the
conguration. The set ioreg lists the populated register addresses, iovar lists the variables
that can be named as parameters in input or output operations, and map relates those vari-
ables to the registers from which they are derived. The predicate says that those variables
must be related to registers that are populated.
Here ioreg , iovar and map are global constants that model the features of the system that
do not change. We do not model any operations that change the conguration tables. We
have actually specied a whole family of control systems, where each assignment of values
to ioreg , iovar and map determines a particular control system that belongs to the family.
This is an example of what Spivey [8] calls a loose specication.
The schema Sys models the volatile part of the system that can change state. The registers
along with their contents are modeled as a function from addresses to contents, and the
variables with their values are modeled as another function. The rst predicate says that
there is a xed set of registers in the conguration; only their contents may change. There
is no predicate xing the domain of variable , because the set of variables may change as the
4 2 THE INITIAL SPECIFICATION
program executes, as dierent subroutines are invoked or dynamic data structures evolve.
It is possible that not all variables can be parameters of input/output operations; some may
only store intermediate values in computations. However, any variable that may be input
or output must be named in iovar .
Our choice of the words \register" and \address" does not mean this model is limited to
memory-mapped devices. A register could be any distinguishable item of data, including
a named element accessed through a \smart" controller, and an address might be a name
derived from an English word, instead of a number. Moreover, values need not be scalar;
variables might have complex internal structure.
These operations are called Encode and Decode , not Input and Output , because they are
only intended to model the translation between register contents and state variable values;
they do not necessarily include the transfer of data between the registers and the trans-
ducers connected to the controlled process. In some systems, those transfers are separate
operations.
We have not yet shown how the function encode is constructed. That is the subject of the
following sections.
5
3 Development strategy
In this and following sections we show how the function encode is constructed from cong-
uration tables, calibration formulas and other available information. A series of represen-
tations for encode are presented, where each successive version provides more detail that
suggests a more straightforward or ecient implementation in an imperative programming
language. This development process is often called renement. An important advantage of
a formal specication is that each development step can be calculated, inferred or otherwise
formally justied.
Our development strategy is based on several observations:
In the following sections we show how these observations are used, and introduce some
functions and other items that we will use to construct encode .
This representation makes it easy to change routing as needed, for example to bypass a
faulty data converter channel.
Register contents and variable values that do not lie within the ranges specied by these
two relations are considered faulty.
The relation mrange constrains the contents of each register, considered by itself. Registers
are sometimes collected together in groups, where the entire group encodes some variable.
The schema Combination associates each class with all of its members and all combinations
of their permitted values.
Combination
cclass : CLASS
contents : MEMBER CONTENTS
dom contents = classdef fcclass g
contents mrange
It is sometimes more ecient to replace functions with sequences. For many input/output
devices it is usual to transfer the contents of a long sequence of consecutive addresses in a
single operation (for example, in direct memory access (DMA) transfers). In such cases, we
do not need to associate addresses with items, because the source of each item is indicated
by its position in the sequence. Also, in most programming languages, parameters to
operations (procedure calls, function applications etc.) are distinguished by their position
in a sequence.
Therefore, for each class, we choose a particular sequence of the associated members. This
determines a sequence of addresses associated with each variable.
8 4 THE DEVELOPMENT STEPS
Using this predicate as a template, for any translate c we can use Combination to con-
struct the domain of the function, and then use our knowledge of the application to assign
4.1 Dene the translation tables 9
each corresponding VALUE . For analog quantities it is usually eective to represent this
assignment by a formula; for digital elements, a table is often preferred.
The predicate ensures that valid register contents are mapped into valid variable values (and
vice-versa). Consequently, analog quantities will not over
ow, saturate or clip when they are
transfered in either direction. This is particularly important for output, because converters
often provide quite limited resolution, but it is important to use as much resolution as
is available. Designers must be especially mindful of this consideration when substituting
converters during conguration changes.
Filling in translate c for each class is a central task in creating the detailed specication for
a particular control system. This report only describes generic aspects of the specication,
so this level of detail will not be described further. Our results are valid for any choice of
the translate c that satisfy the predicate given here. That is what we mean when we say
our system is table-driven.
The predicate does not require all possible patterns allowed by Combination to appear in
the domain of each translate c . It is usual for some patterns to be omitted because they
indicate faulty signal values or combinations. For example, it is good practice for binary
conditions to be indicated by two independent signals, rather than a single binary signal.
Thus, there would be independent signals to indicate valve open and valve closed , where
each signal might indicate set or clear . The pattern
is expected and would be included in the domain of translate valve , but the pattern
indicates at least one sensor is faulty and would be omitted. (Alternatively, a special element
of VALUE could be provided to indicate this and similar faults. This alternative would be
handled dierently by the fault-detection mechanism described in section 6.)
By rst limiting the permitted ranges in mrange and crange , and then choosing which
patterns of those dened by Combination belong to the domain of each translate c when
we congure a system, we can determine which patterns of register contents represent valid
encodings of any given set of variables. This is so important that we dene a schema to
describe it:
10 4 THE DEVELOPMENT STEPS
RegValid
vars ? : VAR
reg : ADDR CONTENTS
dom reg = map vars ?
8 v : vars ? 8 rs : reg j dom rs = map fv g
rmember rs 2 dom (translate (class v ))
4.2 Dene encode
Next, we propose a denition for encode . If we already know the class c that a variable
belongs to, and which registers reg determine the variable's value, encode can be derived
from translate by using rmember to adjust the type of reg :
encode reg v = translate c (rmember reg )
In fact v is related to c and reg through functions class and map , respectively, so:
encode register v = translate (class v ) (rmember (map fv g register ))
First, we must deal with amember , which is also dened non-constructively (section 3.4):
routing amember = member
Here amember is dened to be the function which, when composed with routing , yields
the function member . This denition is convenient because it makes sense for designers to
choose member and routing ; amember is determined by those choices. However, it does not
show how to construct amember . For that, we use a lemma about functional composition
and inverse:
f g = h ) g = f h
Since routing is an injective function, its inverse is also a function, which ensures amember
is functional. The denition of addr seq expands to:
(addr seq v ) routing member = (class member seq ) v
However, member is not functional because member is not injective; many signals have
the same membership. If we applied member to the expression on the right, we would
obtain a relation associating multiple signals where we just want one. Fortunately, it follows
from the denitions of class and classdef (section 3.2) that the signals that contribute to a
single variable do have dierent membership. Thus we can use domain restriction to obtain
a constructive denition of addr seq :
addr seq v = (class member seq ) v (signal fv g member ) routing
but this statement is much too vague to relate to our formal specication. Trying again,
we say,
\If the conguration tables are accurate, then valid input signals will be trans-
lated to the proper state variable values, and invalid input signals will be de-
tected."
Here the features of the formal specication begin to emerge, but we need still more detail.
Trying once again, we begin,
\If a group of signals are entered into the routing table, and the addresses to
which the signals are connected are populated, and the signals are found in the
tables to be members of recognized classes, and the value of each signal falls
within the permitted range for its class membership, and " :::
This is beginning to assume the prolix but shallow quality of most theorems in software
verication. Rather than press on in this vein, we resort to formal notation. We are trying
to state a hypotheses about signals:
SigValid
sigs : SIGNAL
scontents : SIGNAL CONTENTS
sigs = dom scontents
routing sigs ioreg
member sigs ran classdef
9 RegValid
sigs = signal vars ? ^
scontents = f a : dom reg routing a 7! reg a g
Here, we use the RegValid schema dened in section 4.1. We wish to relate the signals sigs
in these hypotheses to the vars ? parameter in the Encode operation schema, so we also
need:
SigMatchVar
sigs : SIGNAL
vars ? : VAR
sigs = signal vars ?
14 5 CHECKING THE DEVELOPMENT BY CALCULATION AND PROOF
Now we can state the entire conjecture, which formalizes the requirement, \All valid signals
will be handled properly".
SigValid ^ SigMatchVar ^ Encode `
8 v : vars ? 9 c : CLASS c = class v ^
variable 0 v = translate c fs : sigs member s 7! scontents s g
The conclusion says that the variables should have the values required for the signals'
contents by the tables and formulas for the signals' class membership.
This example demonstrates Z style for writing conjectures [6]. It means that, from the
declarations and predicates of the schema expression before the turnstile `, we can derive
(or prove) the conclusion after the turnstile4.
Proving this conjecture would provide condence that the formal specication expresses the
informally stated requirement5. It would also serve as a good check on the development
steps, since the hypothesis SigValid and the conclusion are expressed in terms of signals,
classes, members, and the function translate , while the schema that describes the operation,
Encode , is expressed in terms of registers, variables, and the function encode . The schema
SigMatchVar ties the two representations together.
Our development, and the conjecture posed to check it, are closely related to the formal de-
velopment method called renement described by Spivey [8] and taught (in slightly dierent
form) by Potter, et al. [6]. In this method, one rst proposes an abstract specication, then
renes it to a more concrete specication composed of items that are closer to the imple-
mentation language. The retrieve relation relates items in the abstract and concrete states.
To justify a renement, one should prove several conjectures that the method prescribes.
One of these, the correctness conjecture, has the form:
pre AOp ^ Retr ^ COp ^ Retr 0 ` AOp
Where AOp is the operation schema for the abstract state, Retr is the schema describing
the retrieve relation, and Cop is the operation schema for the concrete operation6 .
This is almost the same as our own conjecture; our hypotheses SigValid corresponds to
pre AOp , our SigMatchVar to Retr , our Encode to COp , and our conclusion to AOp . The
similarity is clear, except our development proceeded from the \concrete" to the \abstract"
4
This convention is not described in [8], and this conjecture was not type-checked.
5
I have not yet attempted to prove any of the conjectures posed in this report.
6
This is the form used in [6]. They call this the correctness theorem, not conjecture.
15
represention! We shouldn't feel obligated to follow the recommended sequence too dogmat-
ically, but instead should consider renement a useful collection of methods for checking
development steps, regardless of the order in which they are discovered.
The essential requirement expressed here turns out to be that the expression vars ?
encode register from Encode must be dened, so register must lie within the domain of
encode , and vars ? must lie within the domain of encode register . The expression on the
right can be expanded, simplied and expressed as a schema8 :
7
If a state fails to satisfy a precondition, but does not appear erroneous or faulty, the formal specication
may not express the intended requirements.
8
This is a guess. I haven't actually performed the calculation.
16 6 DETECTING ERRORS AND FAULTS
PreEncode
Sys
vars ? : VAR
vars ? iovar
9 reg : register RegValid
The rst line in the predicate deals with the input parameter vars ?; failure to satisfy this
predicate is an error. The second deals with the contents of register ; failure to satisfy
this predicate is a fault. The latter predicate is based on the schema RegValid dened in
section 4.1.
When an error or fault is detected, it should be reported, but the system state must not
otherwise change, for example:
BadReg
Sys
vars ? : VAR
status : STATUS
status = badreg
: (9 reg : register RegValid )
A similar schema BadVar describes the case where the input variables are not valid. Then
the Encode operation can be extended:
T Encode =b (Encode ^ Success ) _ BadVar _ BadReg
These three outcomes are supposed to exhaust all possibilities. Therefore, the operation
T Encode should be total; it should be dened in every possible state. This could be
conrmed by proving Pre T Encode ) Sys .
17
7 Inverse operations
Non-constructive notations make it easy to dene inverse operations. One example is the
denition of the Decode operation that translates state variable values to register contents
(section 2.2). It contains the predicate
variable = variable vars ? encode register 0
This is nonconstructive because register 0 is the item being dened. We can dene a con-
structive version of Decode by analogy with Encode :
decode : (VAR VALUE ) ADDR CONTENTS
Decode
Sys
vars ? : VAR
variable 0 = variable
register 0 = register map vars ? decode variable
It seems clear that decode should be the inverse of encode . If we already knew which variable
v was associated with a particular register address, we could derive decode from the inverse
of translate :
decode variable a = (translate (class v )) (variable v ) (amember a )
In fact v is related to a through the function map , so we can just use the preceding denition,
where it is understood that v 2 map fa g (any element will do)9 .
The function decode is expressed here in terms of previously-dened items. Thefore, we
do not need to dene any additional conguration tables. Where evaluating translate c is
implemented by table lookup, the implementation of (translate (class v )) can use the same
table, with the direction of lookup reversed.
This development could be checked by proving Encode Decode ` register 0 = register .
9
Hmnn :::
18 8 TOWARDS AN IMPLEMENTATION
8 Towards an implementation
In this section show how the nal development of our specication suggests an ecient and
straightforward implementation in an imperative programming language.
Given sets, global functions and relations can be implemented as tables that are loaded when
the control system is initialized; the predicates for these items suggest acceptance tests that
could be performed when the tables are produced, or run-time checks to be performed each
time the tables are loaded. Application of a higher-order function to its rst argument can
be implemented as code that dispatches to a handler for that particular case. Ordinary
function application can be implemented as table lookup or formula evaluation, whichever
is more ecient.
In section 4.3 we showed that the function encode can be represented:
9 Discussion
Critics charge that many formal developments are described in retrospect, merely casting
into formal notations work that has already been developed intuitively. Our own experience
refutes that cynical assessment.
Our results may seem obvious; in fact, we made several false starts that led to cumbersome
specications and unnished developments. The formal notation, by providing compact
descriptions that can be manipulated and checked algebraically, was quite helpful for identi-
fying problems, exploring alternatives, and expressing a detailed solution. The development
was easy to calculate, but might have been dicult to intuit or improvise. Had we plunged
on into implementation without the formal development, we might have begun building a
less satisfactory alternative.
The existing implementation provides some indication of the diculties we have avoided
(we are developing a replacement for the control system that was provided by the cyclotron
vendor when the facility was installed [7]). The code seems unnecessarily large and is
quite dicult to follow. There was some attempt to make the system table-driven, but
reconguring it to accommodate dierent converter hardware, or even to move a signal
from a failed converter, cannot be accomplished by changing table entries; it is necessary
to modify executable code. There is little error checking; it is not clear what errors are
checked. A manual startup sequence is necessary because the sytem can set outputs before
valid register contents are established.
The formally-developed replacement described in this report has not yet been implemented,
but we are condent that it will not be dicult, and will provide much improvement over
the present system.
References
[1] Kathryn Heninger Britton, R. Alan Parker, and David L. Parnas. A procedure for
designing abstract interfaces for device interface modules. In Proceedings, Fifth Inter-
national Conference on Software Engineering, pages 195{204. IEEE Computer Society
Press, 1981.
[2] Dan Craigen. FM89: Assessment of formal methods for trustworthy computer systems.
In 12th International Conference on Software Engineering Proceedings, pages 233{235.
IEEE Computer Society, 1990.
[3] K.L. Heninger. Specifying software requirements for complex systems: new techniques
and their application. IEEE Transactions on Software Engineering, SE-6(1):2{13, 1980.
20 A TWO USEFUL LEMMAS ABOUT COMPOSITION AND INVERSE
[4] Jonathan Jacky. Formal specications for a clinical cyclotron control system. In Mark
Moriconi, editor, Proceedings of the ACM SIGSOFT International Workshop on Formal
Methods in Software Development, pages 45{54, Napa, California, USA, May 9{11 1990.
(Also in ACM Software Engineering Notes, 15(4), Sept. 1990).
[5] Jonathan Jacky, Ruedi Risler, Ira Kalet, and Peter Wootton. Clinical neutron therapy
system, control system specication, Part I: System overview and hardware organization.
Technical Report 90-12-01, Radiation Oncology Department, University of Washington,
Seattle, WA, December 1990.
[6] Ben Potter, Jane Sinclair, and David Till. An Introduction to Formal Specication and
Z. Prentice Hall International (UK) Ltd, Hemel Hempstead, Hertfordshire, 1991.
[7] Ruedi Risler, Juri Eenmaa, Jonathan P. Jacky, Ira J. Kalet, Peter Wootton, and S. Lind-
baeck. Installation of the cyclotron based clinical neutron therapy system in Seattle. In
Proceedings of the Tenth International Conference on Cyclotrons and their Applications,
pages 428{430, East Lansing, Michigan, May 1984. IEEE.
[8] J. M. Spivey. The Z Notation: A Reference Manual. Prentice-Hall, New York, 1989.
[9] J. M. Spivey. The FUZZ Manual. J. M. Spivey Computing Science Consultancy, Oxford,
January 1991. Second Printing.
for any objects a and b , where f is any function with the appropriate signature.
First we prove f g = h ) g = f h . Page numbers refer to [8].
f g =h [premise]
21
f (f g ) = f h [Leibniz]
(f f ) g = f h [law about composition, p. 97]
id (ran f ) g = f h [law about id, ran, inverse and composition, p. 105]
g = f h [law about id and composition p. 97]