scispace - formally typeset
Open AccessJournal ArticleDOI

Communicating sequential processes

C. A. R. Hoare
- 01 Aug 1978 - 
- Vol. 21, Iss: 8, pp 666-677
Reads0
Chats0
TLDR
It is suggested that input and output are basic primitives of programming and that parallel composition of communicating sequential processes is a fundamental program structuring method.
Abstract
This paper suggests that input and output are basic primitives of programming and that parallel composition of communicating sequential processes is a fundamental program structuring method. When combined with a development of Dijkstra's guarded command, these concepts are surprisingly versatile. Their use is illustrated by sample solutions of a variety of a familiar programming exercises.

read more

Content maybe subject to copyright    Report

Programming
Teclmiques
S. L. Graham, R. L. Rivest
Editors
Communicating
Sequential Processes
C.A.R. Hoare
The Queen's University
Belfast, Northern Ireland
This paper suggests that input and output are basic
primitives of programming and that parallel
composition of communicating sequential processes is a
fundamental program structuring method. When
combined with a development of Dijkstra's guarded
command, these concepts are surprisingly versatile.
Their use is illustrated by sample solutions of a variety
of familiar programming exercises.
Key Words and Phrases: programming,
programming languages, programming primitives,
program structures, parallel programming, concurrency,
input, output, guarded commands, nondeterminacy,
coroutines, procedures, multiple entries, multiple exits,
classes, data representations, recursion, conditional
critical regions, monitors, iterative arrays
CR Categories: 4.20, 4.22, 4.32
1. Introduction
Among the primitive concepts of computer program-
ming, and of the high level languages in which programs
are expressed, the action of assignment is familiar and
well understood. In fact, any change of the internal state
of a machine executing a program can be modeled as an
assignment of a new value to some variable part of that
machine. However, the operations of input and output,
which affect the external environment of a machine, are
not nearly so well understood. They are often added to
a programming language only as an afterthought.
Among the structuring methods for computer pro-
General permission to make fair use in teaching or research of all
or
part of this material is granted to individual readers and to nonprofit
libraries acting for them provided that ACM's copyright notice is given
and that reference is made to the publication, to its date of issue, and
to the fact that reprinting privileges were granted by permission of the
Association for Computing Machinery. To otherwise reprint a figure,
table, other substantial excerpt, or the entire work requires specific
permission as does republication, or systematic or multiple reproduc-
tion.
This research was supported by a Senior Fellowship of the Science
Research Council.
Author's present address: Programming Research Group, 45, Ban-
bury Road, Oxford, England.
© 1978 ACM 0001-0782/78/0800-0666 $00.75
666
grams, three basic constructs have received widespread
recognition and use: A repetitive construct (e.g. the
while
loop), an alternative construct (e.g. the conditional
if..then..else), and normal sequential program composi-
tion (often denoted by a semicolon). Less agreement has
been reached about the design of other important pro-
gram structures, and many suggestions have been made:
Subroutines (Fortran), procedures (Algol 60 [15]), entries
(PL/I), coroutines (UNIX [171), classes (SIMULA 67 [5]),
processes and monitors (Concurrent Pascal [2]), clusters
(CLU [13]), forms (ALPHARD [19]), actors (Hewitt [1]).
The traditional stored program digital computer has
been designed primarily for deterministic execution of a
single sequential program. Where the desire for greater
speed has led to the introduction of parallelism, every
attempt has been made to disguise this fact from the
programmer, either by hardware itself (as in the multiple
function units of the CDC 6600) or by the software (as
in an I/O control package, or a multiprogrammed op-
erating system). However, developments of processor
technology suggest that a multiprocessor machine, con-
structed from a number of similar self-contained proc-
essors (each with its own store), may become more
powerful, capacious, reliable, and economical than a
machine which is disguised as a monoprocessor.
In order to use such a machine effectively on a single
task, the component processors must be able to com-
municate and to synchronize with each other. Many
methods of achieving this have been proposed. A widely
adopted method of communication is by inspection and
updating of a common store (as in Algol 68 [18], PL/I,
and many machine codes). However, this can create
severe problems in the construction of correct programs
and it may lead to expense (e.g. crossbar switches) and
unreliability (e.g. glitches) in some technologies of hard-
ware implementation. A greater variety of methods has
been proposed for synchronization: semaphores [6],
events (PL/I), conditional critical regions [10], monitors
and queues (Concurrent Pascal [2]), and path expressions
[3]. Most of these are demonstrably adequate for their
purpose, but there is no widely recognized criterion for
choosing between them.
This paper makes an ambitious attempt to find a
single simple solution to all these problems. The essential
proposals are:
(1) Dijkstra's guarded commands [8] are adopted (with
a slight change of notation) as sequential control struc-
tures, and as the sole means of introducing and control-
ling nondeterminism.
(2) A parallel command, based on Dijkstra's
parbegin
[6], specifies concurrent execution of its constituent se-
quential commands (processes). All the processes start
simultaneously, and the parallel command ends only
when they are all finished. They may not communicate
with each other by updating global variables.
(3) Simple forms of input and output command are
introduced. They are used for communication between
concurrent processes.
Communications August 1978
of Volume 21
the ACM Number 8

(4) Such communication occurs when one process
names another as destination for output
and
the second
process names the first as source for input. In this case,
the value to be output is copied from the first process to
the second. There is
no
automatic buffeting: In general,
an input or output command is delayed until the other
process is ready with the corresponding output or input.
Such delay is invisible to the delayed process.
(5) Input commands may appear in guards. A guarded
command with an input guard is selected for execution
only if and when the source named in the input com-
mand is ready to execute the corresponding output com-
mand. If several input guards of a set of alternatives
have ready destinations, only one is selected and the
others have
no
effect; but the choice between them is
arbitrary. In an efficient implementation, an output com-
mand which has been ready for a long time should be
favored; but the defmition of a language cannot specify
this since the relative speed of execution of the processes
is undefmed.
(6) A repetitive command may have input guards. If all
the sources named by them have terminated, then the
repetitive command also terminates.
(7) A simple pattern-matching feature, similar to that of
[16], is used to discriminate the structure of an input
message, and to access its components in a secure fash-
ion. This feature is used to inhibit input of messages that
do not match the specified pattern.
The programs expressed in the proposed language
are intended to be implementable.both by a conventional
machine with a single main store, and by a fixed network
of processors connected by input/output channels (al-
though very different optimizations are appropriate in
the different cases). It is consequently a rather static
language: The text of a program determines a fixed
upper bound on the number of processes operating
concurrently; there is no recursion and no facility for
process-valued variables. In other respects also, the lan-
guage has been stripped to the barest minimum necessary
for explanation of its more novel features.
The concept of a communicating sequential process
is shown in Sections 3-5 to provide a method of express-
ing solutions to many simple programming exercises
which have previously been employed to illustrate the
use of various proposed programming language features.
This suggests that the process may constitute a synthesis
of a number of familiar and new programming ideas.
The reader is invited to skip the examples which do not
interest him.
However, this paper also ignores many serious prob-
lems. The most serious is that it fails to suggest any proof
method to assist in the development and verification of
correct programs. Secondly, it pays no attention to the
problems of efficient implementation, which may be
particularly serious on a traditional sequential computer.
It is probable that a solution to these problems will
require (1) imposition of restrictions in the use of the
proposed features; (2) reintroduction of distinctive no-
tations for the most common and useful special cases;
(3) development of automatic optimization techniques;
and (4) the design of appropriate hardware.
Thus the concepts and notations introduced in this
paper (although described in the next section in the form
of a programming language fragment) should not be
regarded as suitable for use as a programming language,
either for abstract or for concrete programming. They
are at best only a partial solution to the problems tackled.
Further discussion of these and other points will be
found in Section 7.
2. Concepts and Notations
The style of the following description is borrowed
from Algol 60 [15]. Types, declarations, and expressions
have not been treated; in the examples, a Pascal-like
notation [20] has usually been adopted. The curly braces
{ } have been introduced into BNF to denote none or
more repetitions of the enclosed material. (Sentences in
parentheses refer to an implementation: they are not
strictly part of a language defmition.)
<command> :.--- <simple command>l<structured command>
<simple command> :.--- <null command>l<assignment command>
I<input command>l<output command>
<structured command> :.--- <alternative command>
I<repetitive command>l<parallel command>
<null command> :.--- skip
<command list> :.--- {<declaration>; I<command>;} <command>
A command specifies the behavior of a device exe-
cuting the command. It may succeed or fail. Execution
of a simple command, if successful, may have an effect
on the internal state of the executing device (in the case
of assignment), or on its external environment (in the
case of output), or on both (in the case of input). Exe-
cution of a structured command involves execution of
some or all of its constituent commands, and if any of
these fail, so does the structured command. (In this case,
whenever possible, an implementation should provide
some kind of comprehensible error diagnostic message.)
A null command has no effect and never fails.
A command list specifies sequential execution of its
constituent commands in the order written. Each decla-
ration introduces a fresh variable with a scope which
extends from its declaration to the end of the command
list.
2.1 Parallel Commands
<parallel command> :.--- [<process> {I I<process>} ]
<process> :.--- <process label> <command list>
<process label> :.--- <empty>l<identifier> ::
I<identifier>(<label subscript>{,<label subscript>}) ::
<label subscript> :.--- <integer constant>l<range>
<integer constant> :.--- <numeral>l<bound variable>
<bound variable> :.--- <identifier>
<range> :.~ <bound variable>:<lower bound>..<upper bound>
<lower bound> :.~ <integer constant>
<upper bound> :.~ <integer constant>
667
Communications August 1978
of Volume 21
the ACM Number 8

Each process of a parallel command must be
disjoint
from every other process of the command, in the sense
that it does not mention any variable which occurs as a
target variable (see Sections 2.2 and 2.3) in any other
process.
A process label without subscripts, or one whose label
subscripts are all integer constants, serves as a name for
the command list to which it is prefixed; its scope extends
over the whole of the parallel command. A process
whose label subscripts include one or more ranges stands
for a series of processes, each with the same label and
command list, except that each has a different combi-
nation of values substituted for the bound variables.
These values range between the lower bound and the
upper bound inclusive. For example,
X(i:l..n)
:: CL
stands for
X(l) :: CEll[X(2)::
CL211...[IX(n)
:: CL~
where each CLy is formed from CL by replacing every
occurrence of the bound variable i by the numeral j.
After all such expansions, each process label in a parallel
command must occur only once and the processes must
be well formed and disjoint.
A parallel command specifies concurrent execution
of its constituent processes. They all start simultaneously
and the parallel command terminates successfully only
if and when they have all successfully terminated. The
relative speed with which they are executed is arbitrary.
Examples:
(1) [cardreader?cardimage[ [lineprinter!lineimage]
Performs the two constituent commands in parallel,
and terminates only when both operations are complete.
The time taken may be as low as the longer of the times
taken by each constituent process, i.e. the sum of its
computing, waiting, and transfer times.
(2) [west :: DISASSEMBLEIlX :: SQUASH I [east :: ASSEMBLE]
The three processes have the names "west," "X," and
"east." The capitalized words stand for command lists
which will be defined in later examples.
(3) [room :: ROOM I Ifork(i:0..4) :: FORK I Iphil(i:0..4) :: PHIL]
There are eleven processes. The behavior of "room"
is specified by the command list ROOM. The behavior of
the five processes fork(0), fork(l), fork(2), fork(3),
fork(4), is specified by the command list FORK, within
which the bound variable i indicates the identity of the
particular fork. Similar remarks apply to the five proc-
esses PHIL.
2.2 Assignment Commands
<assignment command> :.--- <target variable> := <expression>
<expression> :.-= <simple expression>l<structured expression>
<structured expression> :~ <constructor>(<expression list>)
<constructor> :.--- <identifier>l<empty>
<expression list> :-- <empty>l<expression>{,<expression>}
<target variable> :.--- <simple variable>l<structured target>
<structured target> :.--- <constructor>(<target variable list>)
<target variable list> :~ <empty>[<target variable>
{,<target variable>}
668
An expression denotes a value which is computed by
an executing device by application of its constituent
operators to the specified operands. The value of an
expression is undefined if any of these operations are
undefined. The value denoted by a simple expression
may be simple or structured. The value denoted by a
structured expression is structured; its constructor is that
of the expression, and its components are the list of
values denoted by the constituent expressions of the
expression list.
An assignment command specifies evaluation of its
expression, and assignment of the denoted value to the
target variable. A simple target variable may have as-
signed to it a simple or a structured value. A structured
target variable may have assigned to it a structured value,
with the same constructor. The effect of such assignment
is to assign to each constituent simpler variable of the
structured target the value of the corresponding compo-
nent of the structured value. Consequently, the value
denoted by the target variable, if evaluated
after
a suc-
cessful assignment, is the same as the value denoted by
the expression, as evaluated
before
the assignment.
An assignment fails if the value of its expression is
undefined, or if that value does not
match
the target
variable, in the following sense: A
simple
target variable
matches any value of its type. A
structured
target variable
matches a structured value, provided that: (1) they have
the same constructor, (2) the target variable list is the
same length as the list of components of the value, (3)
each target variable of the list matches the corresponding
component of the value list. A structured value with no
components is known as a "signal."
Examples:
(1)
x.---x+ 1
(2) (x, y) -- (y, x)
(3) x .--- cons(left, right)
(4) cons(left, right) .--- x
(5) insert(n) ~ insert(2,x + 1)
(6) c .--- PO
(7).P0 .--- c
the value of x after the assignment
is the same as the value of x + 1
before.
exchanges the values of x and y.
constructs a structured value and
assigns it to x.
fails if x does not have the form
cons(y,
z); but if it does, then y is
assigned to left, and z is assigned
to right.
equivalent to n .--- 2*x + l.
assigns to c a "signal" with con-
structor P, and no components.
fails if the value of c is not P0;
otherwise has no effect.
(8) insert(n) .--- has(n) fails, due to mismatch.
Note: Successful execution of both (3) and (4) ensures
the truth of the postcondition x = cons(left, right); but
(3) does so by changing x and (4) does so by changing
left and right. Example (4) will fail if there is
no
value of
left and right which satisfies the postcondition.
2.3 Inimt and Output Commands
<input command> :.~ <source>?<target variable>
<output
command> :.--- <destination>!<expression>
<source> :.~ <process
name>
Communications August 1978
of Volume 2 l
the ACM Number 8

<destination> :.--- <process name>
<process name> :.= <identifier>[<identifier>(<subscripts>)
<subscripts> ::= <integer expression>{,<integer expression>}
Input and output commands specify communication
between two concurrently operating sequential processes.
Such a process may be implemented in hardware as a
special-purpose device (e.g. cardreader or lineprinter), or
its behavior may be specified by one of the constituent
processes of a parallel command. Communication occurs
between two processes of a parallel command whenever
(1) an input command in one process specifies as its
source the process name of the other process; (2) an
output command in the other process specifies as its
destination the process name of the first process; and (3)
the target variable of the input command matches the
value denoted by the expression of the output command.
On these conditions, the input and output commands are
said to
correspond.
Commands which correspond are
executed simultaneously, and their combined effect is to
assign the value of the expression of the output command
to the target variable of the input command.
An input command fails if its source is terminated.
An output command fails if its destination is terminated
or if its expression is undefined.
(The requirement of synchronization of input and
output commands means that an implementation will
have to delay whichever of the two commands happens
to be ready first. The delay is ended when the corre-
sponding command in the other process is also ready, or
when the other process terminates. In the latter case the
first command fails. It is also possible that the delay will
never be ended, for example, if a group of processes are
attempting communication but none of their input and
output commands correspond with each other. This form
of failure is known as a deadlock.)
Examples:
(1) cardreader?cardimage
(2) lineprinter!lineimage
(3) X?(x, y)
(4) DIV!(3.a + b, 13)
from cardreader, read a card and
assign its value (an array of char-
acters) to the variable cardimage
to lineprinter, send the value of
lineimage for printing
from process named X, input a pair
of values and assign them to x
andy
to process DIV, output the two
specified values.
Note: If a process named DIV issues command (3), and a process
named X issues command (4), these are executed simultaneously,
and have the same effect as the assignment:
(x,y) ~
(3*a + b, 13)
(mx~3*a+b;y~ 13).
(5) console(0?c
(6) console(./- I)!"A"
(7) x(o?v( )
(8) sem!P( )
from the/th element of an array of
consoles, input a value and assign
it to c
to the (j - l)th console, output
character "A"
from the/th of an array of processes
X, input a signal V( ); refuse to
input any other signal
to sem output a signal P( )
669
2.4
Alternative and
Repetitive Commands
<repetitive command> :.---,<alternative command>
<alternative command> :-- [<guarded command>
(13<gnarded command>} ]
<guarded command> :~ <guard> ----, <command list>
I(<range>{,<range>})<guard> --, <command list>
<guard> :.--- <guard list>l<guard list>;<input command>
I<input command>
<guard list> :~ <guard element>(;<gnard element>}
<guard element> :~ <boolean expression>l<declaration>
A guarded command with one or more ranges stands
for a series of guarded commands, each with the same
guard and command list, except that each has a different
combination of values substituted for the bound varia-
bles. The values range between the lower bound and
upper bound inclusive. For example, (i:l..n)G --~ CL
stands for
G1 ~ CLI[IG2 --> CL2n...[IGn ~ CLn
where each Gj --> CLj is formed from G --, CL by
replacing every occurrence of the bound variable i by the
numeralj.
A guarded command is executed only if and when
the execution of its guard does not fail. First its guard is
executed and then its command list. A guard is executed
by execution of its constituent elements from left to right.
A Boolean expression is evaluated: If it denotes false, the
guard fails; but an expression that denotes true has no
effect. A declaration introduces a fresh variable with a
scope that extends from the declaration to the end of the
guarded command. An input command at the end of a
guard is executed only if and when a corresponding
output command is executed. (An implementation may
test whether a guard fails simply by trying to execute it,
and discontinuing execution if and when it fails. This is
valid because such a discontinued execution has no effect
on the state of the executing device.)
An alternative command specifies execution of ex-
actly one of its constituent guarded commands. Conse-
quently, if all guards fail, the alternative command fails.
Otherwise an arbitrary one with successfully executable
guard is selected and executed. (An implementation
should take advantage of its freedom of selection to
ensure efficient execution and good response. For ex-
ample, when input commands appear as guards, the
command which corresponds to the earliest ready and
matching output command should in general be pre-
ferred; and certainly, no executable and ready output
command should be passed over unreasonably often.)
A repetitive command specifies as many iterations as
possible of its constituent alternative command. Conse-
quently, when all guards fail, the repetitive command
terminates with no effect. Otherwise, the alternative com-
mand is executed once and then the whole repetitive
command is executed again. (Consider a repetitive com-
mand when all its true guard lists end in an input guard.
Such a command may have to be delayed until either (1)
an output command corresponding to one of the input
Communications August 1978
of Volume 21
the ACM Number 8

guards becomes ready, or (2) all the sources named by
the input guards have terminated. In case (2), the repet-
itive command terminates. If neither event ever occurs,
the process fails (in deadlock.)
Examples:
(l) [x >_ y---~ m .--- xOy_> x--~ m ~ y]
If x _> y, assign x to m; ify >_ x assign y to m; if both
x _> y and y >_ x, either assignment can be executed.
(2) i .~ 0;*[i < size; content(/) # n ~ i .~ i + 1]
The repetitive command scans the elements con-
tent(i), for i = 0, 1 ..... until either i >_ size, or a value
equal to n is found.
(3) ,[c:character; west?c ~ east!c]
This reads all the characters output by west, and
outputs them one by one to east. The repetition termi-
nates when the process west terminates.
(4) ,[(i:l..10)continue(t); console(i)?c-:, X!(i, c); console(0!ack();
continue(i) := (c # sign off)]
This command inputs repeatedly from any of ten
consoles, provided that the corresponding element of the
Boolean array continue is true. The bound variable i
identifies the originating console. Its value, together with
the character just input, is output to X, and an acknowl-
edgment signal is sent back to the originating console. If
the character indicated "sign off," continue(i) is set false,
to prevent further input from that console. The repetitive
command terminates when all ten elements of continue
are false. (An implementation should ensure that no
console which is ready to provide input will be ignored
unreasonably often.)
(5) ,In:integer; X?insert(n) ---~ INSERT
On:integer; X?has(n) ~ SEARCH; X!(i < size)
]
(Here, and elsewhere, capitalized words INSERT and
SEARCH stand as abbreviations for program text defined
separately.)
On each iteration this command accepts from
X either
(a) a request to "insert(n)," (followed by INSERT)
or
(b)
a question "has(n)," to which it outputs an answer back
to X. The choice between (a) and (b) is made by the next
output command in X. The repetitive command termi-
nates when X does. If X sends a nonmatching message,
deadlock will result.
(6) *[X?V 0 ~ val := val + 1
0val > 0; Y?PO --~ val := val - 1
1
On each iteration, accept
either
a V 0 signal from X
and increment val,
or
a PO signal from Y, and decrement
val. But the second alternative cannot be selected unless
val is positive (after which val will remain invariantly
nonnegative). (When val > 0, the choice depends on the
relative speeds of X and Y, and is not determined.) The
repetitive command will terminate when both X and Y
are terminated, or when X is terminated and val <_ 0.
670
3. Coroutines
In parallel programming coroutines appear as a more
fundamental program structure than subroutines, which
can be regarded as a special case (treated in the next
section).
3.1 COPY
Problem: Write a process X to copy characters output by
process west to process, east.
Solution:
X :: ,[c:character; west?c ~ east!c]
Notes: (1) When west terminates, the input "west?e" will
fail, causing termination of the repetitive command, and
of process X. Any subsequent input command from east
will fail. (2) Process X acts as a single-character buffer
between west and east. It permits west to work on
production of the next character, before east is ready to
input the previous one.
3.2
SQUASH
Problem: Adapt the previous program to replace every
pair of consecutive asterisks "**" by an upward arrow
"~". Assume that the final character input is not an
asterisk.
Solution:
X :: ,[c:character; west?c --~
[c # asterisk --~ east!c
0c = asterisk ---~ wesOc;
[c # asterisk ~ east!asterisk; east!c
Dc = asterisk ~ east!upward arrow
11 ]
Notes: (l) Since west does not end with asterisk, the
second "west?c" will not fail. (2) As an exercise, adapt
this process to deal sensibly with input which ends with
an odd number of asterisks.
3.3 DISASSEMBLE
Problem: to read cards from a cardfile and output to
process X the stream of characters they contain. An extra
space should be inserted at the end of each card.
Solution:
[cardimage:(l..80)character; cardfile?cardimage
i:integer; i ~ 1;
[i _< 80 ~ X!cardimage(i); i .~ i + 1]
X!space
]
Notes: (1) "(1..80)character" declares an array of 80
characters, with subscripts ranging between 1 and 80. (2)
The repetitive command terminates when the cardfile
process terminates.
3.4 ASSEMBLE
Problem: To read a stream of characters from process X
and print them in lines of 125 characters on a lineprinter.
The last line should be completed with spaces if neces-
sary.
Communications August 1978
of Volume 21
the ACM Number 8

Citations
More filters
Journal ArticleDOI

Statecharts: A visual formalism for complex systems

TL;DR: It is intended to demonstrate here that statecharts counter many of the objections raised against conventional state diagrams, and thus appear to render specification by diagrams an attractive and plausible approach.
Journal ArticleDOI

A theory of timed automata

TL;DR: Alur et al. as discussed by the authors proposed timed automata to model the behavior of real-time systems over time, and showed that the universality problem and the language inclusion problem are solvable only for the deterministic automata: both problems are undecidable (II i-hard) in the non-deterministic case and PSPACE-complete in deterministic case.
Book

Principles of Model Checking

TL;DR: Principles of Model Checking offers a comprehensive introduction to model checking that is not only a text suitable for classroom use but also a valuable reference for researchers and practitioners in the field.
Proceedings ArticleDOI

Universally composable security: a new paradigm for cryptographic protocols

TL;DR: The notion of universally composable security was introduced in this paper for defining security of cryptographic protocols, which guarantees security even when a secure protocol is composed of an arbitrary set of protocols, or more generally when the protocol is used as a component of a system.
References
More filters
Proceedings Article

The Semantics of a Simple Language for Parallel Programming.

Gilles Kahn
TL;DR: A simple language for parallel programming is described and its mathematical properties are studied to make a case for more formal languages for systems programming and the design of operating systems.
Journal ArticleDOI

Guarded commands, nondeterminacy and formal derivation of programs

TL;DR: So-called “guarded commands” are introduced as a building block for alternative and repetitive constructs that allow nondeterministic program components for which at least the activity evoked, but possibly even the final state, is not necessarily uniquely determined by the initial state.
Journal ArticleDOI

Monitors: an operating system structuring concept

TL;DR: In this paper, the authors develop Brinch-Hansen's concept of a monitor as a method of structuring an operating system and describe a possible method of implementation in terms of semaphores and give a suitable proof rule.
Book

Notes on structured programming

TL;DR: The final author version and the galley proof are versions of the publication after peer review that features the final layout of the paper including the volume, issue and page numbers.