4.3BSD/usr/contrib/B/doc/Description1

.\" Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984.
.Du START
.sp 1
.in 0
.ce 99
DESCRIPTION OF B

Lambert Meertens
Steven Pemberton

CWI
Amsterdam

April 1984
.ce 0
.Co
.ds Sn Contents
.bp
.in 15
.nf
.ps 8
.vs 10
CONTENTS

0.\0INTRODUCTION
1.\0VALUES IN B
2.\0SYNTAX DESCRIPTION METHOD
3.\0REPRESENTATIONS
4.\0UNITS
        4.1.\0HOW-TO-UNITS
        4.2.\0YIELD-UNITS
        4.3.\0TEST-UNITS
        4.4.\0REFINEMENTS
        4.5.\0COMMAND-SUITES
5.\0COMMANDS
        5.1.\0\0SIMPLE-COMMANDS
                5.1.1.\0\0CHECK-COMMANDS
                5.1.2.\0\0WRITE-COMMANDS
                5.1.3.\0\0READ-COMMANDS
                5.1.4.\0\0PUT-COMMANDS
                5.1.5.\0\0DRAW-COMMANDS
                5.1.6.\0\0CHOOSE-COMMANDS
                5.1.7.\0\0SET-RANDOM-COMMANDS
                5.1.8.\0\0REMOVE-COMMANDS
                5.1.9.\0\0INSERT-COMMANDS
                5.1.10.\0DELETE-COMMANDS
                5.1.11.\0QUIT-COMMAND
                5.1.12.\0RETURN-COMMANDS
                5.1.13.\0SUCCEED-COMMAND
                5.1.14.\0FAIL-COMMAND
                5.1.15.\0USER-DEFINED-COMMANDS
                5.1.16.\0REFINED-COMMANDS
        5.2.\0CONTROL-COMMANDS
                5.2.1.\0IF-COMMANDS
                5.2.2.\0SELECT-COMMANDS
                5.2.3.\0WHILE-COMMANDS
                5.2.4.\0FOR-COMMANDS
6.\0EXPRESSIONS, TARGETS AND TESTS
        6.1.\0EXPRESSIONS
                6.1.1.\0NUMERIC-CONSTANTS
                6.1.2.\0TARGET-CONTENTS
                6.1.3.\0TRIMMED-TEXTS
                6.1.4.\0TABLE-SELECTIONS
                6.1.5.\0DISPLAYS
                6.1.6.\0FORMULAS
                        Formulas with user-defined functions
                        Formulas with predefined functions
                6.1.7.\0REFINED-EXPRESSIONS
        6.2.\0TARGETS
                6.2.1.\0IDENTIFIERS
                6.2.2.\0TRIMMED-TEXT-TARGETS
                6.2.3.\0TABLE-SELECTION-TARGETS
        6.3.\0TESTS
                6.3.1.\0ORDER-TESTS
                6.3.2.\0PROPOSITIONS
                        Propositions with user-defined predicates
                        Propositions with predefined predicates
                6.3.3.\0REFINED-TESTS
                6.3.4.\0CONJUNCTIONS
                6.3.5.\0DISJUNCTIONS
                6.3.6.\0NEGATIONS
                6.3.7.\0QUANTIFICATIONS
INDEX
.ps 10
.vs 12
.in 0
.ds Sn Introduction
.bp
.St 0 INTRODUCTION
.fi
.Tx
\*B is a simple but powerful new programming language, designed for use in
personal computing.
(Note: the name ``\*B'' is only a temporary working title,
and the new language bears no relation to the predecessor of
C.)\ 
The foremost aim in the design of \*B has been the ease of use for
programmers who want to produce working programs without having
to master a complex tool.
An implementation of \*B is available from the \*B group at
the CWI, currently only under UNIX* or its look-alikes, but soon
(scheduled early 1985) also for the IBM-PC under MS-DOS.
Remarks concerning the implementation appear in this description
between double braces {{ and }}.
.sp 0.6v
This description of \*B originated from a text, prepared by
the first author, for use in teaching \*B during the Fall
term of 1982 at New York University.
The aim is to provide a reference book for the users of \*B that is more
accessible than the somewhat formal ``Draft Proposal'' [2].
While it is not a text book, it should also be useful
to people who already have ample programming
experience and want to learn \*B.
A text book for beginners is also available from the CWI [1].
.sp 0.6v
In this description we have tried to remain close to the Draft Proposal
in order to facilitate cross-referencing. To this end, all section numbers
from section 4 onwards are the same as in the Draft Proposal.
However there are some changes in terminology.
Some minor differences are
.sp 0.6v
.ta 2m \w'mmTYPE-TYPES-expressionmm'u \w'mmTYPE-TYPES-expressionmm'u+\w'multiple-expressionmm'u
.nf
\&	Draft Proposal:	This description:
.sp 0.4v
\&	textual-display	text-display
\&	textual-body	text-body
\&	LIST-body	optional-list-body
\&	TABLE-body	optional-table-filler-series
.fi
.sp 0.6v
But the main difference is perhaps in the treatment of ``collateral'':
.sp 0.6v
.nf
\&	Draft Proposal:	This description:	Examples
.sp 0.4v
\&	collateral-expression	expression	\*(<:a   (a, b)   a, b\*(:>
\&	TYPE-expression	single-expression	\*(<:a   (a, b)\*(:>
\&	TYPE-TYPES-expression	multiple-expression	\*(<:             a, b\*(:>
.fi
.sp 0.6v
Whereas these are purely descriptional differences,
there are also a few differences in content.
Where the Draft Proposal has the keyword \*(<:ALLOW\*(:>,
\*B now has the keyword \*(<:SHARE\*(:>;
a command \*(<:READ\*(:>\ ...\ \*(<:RAW\*(:> has been added;
and approximate-constants may no longer consist of just an exponent-part:
\*(<:E-1\*(:> must now be written \*(<:1E-1\*(:>.
.sp 0.6v
References
.sp 0.5v
.in +\w'[1]\ 'u
.ti 0
[1]\ \fIComputer Programming for Beginners, Introducing the B Language,
Part 1\fP,
.br
Leo Geurts, CWI, Amsterdam, 1984
.sp 0.5v
.ti 0
[2]\ \fIDraft Proposal for the B Programming Language\fP,
.br
Lambert Meertens, CWI, Amsterdam, 1981
.sp 0.6v
.in 0
*\ \s-2Unix is a trademark of Bell Laboratories.\s0
.fi
.SN 1
.bp
.St 1 "VALUES IN \*B"
.de tY
.sp 1
.ne 5
.in \w'Compounds\0\0'u
.ta \w'Compounds\0\0'u
.ti 0
\\$1\t\c
..
.Xx number
.Xx exact number
.Xx approximate number
.Xx text
.Xx character
.Xx order
.Xx compound
.Xx field
.Xx list
.Xx entry
.Xx list entry
.Xx table
.Xx table entry
.Xx key
.Xx associate
.Tx
\*B has two basic types of values: numbers and texts, and three ways of making
new types of values from existing ones: compounds, lists and tables.
The built-in functions for operating on these values are described
in section 6.1.6 entitled ``Formulas with predefined functions''.
.tY Numbers
Numbers come in two kinds: exact and approximate.
Exact numbers are rational numbers.
For example, \*(<:1.25\*(:> = \*(<:5/4\*(:>, and \*(<:(1/3)*3\*(:> = \*(<:1\*(:>.
There is no restriction on the size of numerator and denominator.
Approximate numbers are implemented by whatever the hardware has to offer
for fast but approximate arithmetic (floating point).
.br
The arithmetic operations and many other functions give an exact result
when their operands are exact,
and an approximate result otherwise,
but the function \*(<:sin\*(:>, for example, always returns an approximate number.
.br
An exact number can be made approximate with the \*(<:~\*(:> function
(e.g. \*(<:~1.25\*(:>);
the functions \*(<:round\*(:>, \*(<:floor\*(:> and \*(<:ceiling\*(:> can be used to convert
an approximate number to an exact one.
.br
Exact and approximate numbers may be mixed in arithmetic, as in \*(<:4 * atan 1\*(:>.
.tY Texts
Texts (strings) are composed of printable ASCII characters.
They are variable length, and are ordered in the usual lexicographic way:
\&\*(<:'a' < 'aa' < 'b'\*(:>.
There is no type ``character'': a text of length one will do.
.br
The printable characters
are the 95 characters represented on the lines below,
where the blank space preceding `\*(<:!\*(:>' stands for the
(otherwise invisible) space character:
.Di 5
\*(<: !"#$%&'()*+,-./0123456789:;<=>?
@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_
`abcdefghijklmnopqrstuvwxyz{|}~\*(:>
.br
.Ed
The ordering
on the characters is the ASCII collating order, which is the order
in which the characters are displayed above.
.tY Compounds
A compound consists of a sequence of other values, its ``fields''.
For example,
the number \*(<:3\*(:> and the text \*(<:'xyz'\*(:> may be combined to give the
compound \*(<:3, 'xyz'\*(:>.
Compounds are also ordered lexicographically.
.br
For example, \*(<:(3, 'xyz') < (3, 'yz') < (pi, 'aaa')\*(:>.
For this to be meaningful, the compounds that are compared must
be of the same type.
This means that they have the
same number of fields, and that corresponding fields are of the same type.
.br
The only way to obtain the individual fields of a compound is to put it
in a multiple-target with the right number of components, as in
.Di 1
\*(<:PUT name IN last'name, first'name, middle'name\*(:>.
.Ed
.tY Lists
A list is a \fIsorted\fP sequence of values, its ``entries''.
All entries of a list must be of the same type, and this determines
the type of the list.
The length of a list may vary without influencing its type.
When an entry is inserted in a list (with an \*(<:INSERT\*(:> command), it is automatically
inserted in the list in the proper position in the sorting order.
A list may contain duplicates of the same entry.
Entries may be removed with the \*(<:REMOVE\*(:> command.
Again, lists themselves are ordered lexicographically.
.tY Tables
A table consists of a (sorted) sequence of ``table entries''.
Each table entry is a pair of two values: a \fIkey\fP and an \fIassociate\fP.
All keys of a table must be of the same type; similarly, all associates must
also be of the same type (but that type may be different to
that of the keys).
A table may not contain duplicate keys.
If \*(<:k\*(:> is a key of the table \*(<:t\*(:>, then \*(<:t[k]\*(:>
gives the associate corresponding to \*(<:k\*(:>.
New entries can be made, or existing entries modified, by putting the
associate value in the table after selecting with the key value, as
in \*(<:PUT a IN t[k]\*(:>.
Entries can be deleted with the \*(<:DELETE\*(:> command, as in \*(<:DELETE t[k]\*(:>.
The ordering is again lexicographic.
.St 2 "SYNTAX DESCRIPTION METHOD"
.Tx
The syntax of \*B is given in the following form:
each rule starts with the name of the thing being defined followed by a colon;
following this are one or more alternatives,
each marked with a \(bu in front.
Each alternative is composed of symbols that stand for
themselves, or the names of other rules.
These other rules are then defined elsewhere in the grammar,
or possibly in the same rule.
As an example, here is a simple grammar for a small part of English:
.Sy  4
.Pn  sentence 3
.Al
declarative
.Al
declarative \*(<:,\*(:> connective\0sentence
.Pn  declarative 3
.Al
collective-noun\0verb\0collective-noun
.Al
collective-noun \*(<:do not\*(:> verb\0collective-noun
.Pn collective-noun 2
.Al
\*(<:cats\*(:>
.Al
\*(<:dogs\*(:>
.Al
\*(<:people\*(:>
.Al
\*(<:the police\*(:>
.Pn verb 2
.Al
\*(<:love\*(:>
.Al
\*(<:hate\*(:>
.Al
\*(<:eat\*(:>
.Al
\*(<:hassle\*(:>
.Pn connective 2
.Al
\*(<:and\*(:>
.Al
\*(<:but\*(:>
.Al
\*(<:although\*(:>
.Al
\*(<:because\*(:>
.Al
\*(<:yet\*(:>
.Tx
This produces sentences like:
.Di 4
.in -6
\*(<:dogs do not love the police\*(:>
\*(<:the police hassle dogs\*(:>
\*(<:cats do not hate cats , but cats hate dogs , because dogs hate cats\*(:>
\*(<:people eat dogs , yet dogs love people\*(:>
.in +6
.Ed
.in 0
You will notice that the names of rules are in a different
typeface to words that stand for themselves.
In the grammar of \*B that follows, furthermore, rule names
are all in lower-case letters, while words that stand for themselves are all
in upper-case letters, so they are easily distinguished.
.sp
It often happens that a part of an alternative is optional.
There is a special rule for this:
.Sy  4
.Pr empty 2
.Al
.br
.Pr optional-ANYTHING 3
.Al
empty
.Al
ANYTHING
.Tx
The ``optional'' rule is included to save many rules in the definition.
For example, it stands for a rule
.Pn  optional-comment 3
.Al
empty
.Al
comment
.Tx
and similar rules.
(Empty produces an empty result.)
.St 3 REPRESENTATIONS
.Xx indentation
.Xx increase-indentation
.Xx decrease-indentation
.Xx new-line-proper
.Xx keyword
.Xx tag
.Pr new-line 2
.Sl
optional-comment\0new-line-proper\0indent
.Ps
A \*B program consists of indented lines.
A new-line-proper marks a transition to a new line.
An indent stands for the left margin blank offset.
Initially, the left margin has zero width.
The indentation is increased by an increase-indentation
and decreased again by a decrease-indentation.
These always come in pairs and serve for grouping, just as BEGIN-END pairs
do in other programming languages.
An increase-indentation is always preceded by a line ending with a colon
(possibly followed by comment).
.Pr comment 3
.Al
optional-new-line-proper\0optional-spaces
\*(<:\\\*(:> comment-body\0optional-further-comment
.Pr further-comment 3
.Al
new-line-proper\0optional-spaces
\*(<:\\\*(:> comment-body\0optional-further-comment
.Pr spaces 2
.Sl
space\0optional-spaces
.Ps
Comments may be placed at the end of a line or may stand alone
on a line.
No comment may precede the first line of a unit (see section 4).
.br
A comment-body may be any sequence of printable characters.
.Sx 2 comment:
\*(<:\\modified 6/4/84 to reject passwords of length < 6\*(:>
.Tx
Keywords are composed of CAPITAL letters (\*(<:A\*(:> to \*(<:Z\*(:>), digits,
and quotes (\*(<:'\*(:> and \*(<:"\*(:>).
A keyword must start with a letter.
For example, \*(<:A3'B"\*(:> is a keyword.
.Tx
Tags are composed of lower-case letters (\*(<:a\*(:> to \*(<:z\*(:>), digits, 
and quotes (\*(<:'\*(:> and \*(<:"\*(:>).
A tag must start with a letter.
For example, \*(<:a3'b"\*(:> is a tag.
.Tx
Some other signs are composite: \*(<:..\*(:>, \*(<:**\*(:>, \*(<:*/\*(:>, \*(<:/*\*(:>, \*(<:^^\*(:>,
\*(<:<<\*(:>, \*(<:><\*(:>, \*(<:>>\*(:>, \*(<:<=\*(:>, \*(<:<>\*(:> and \*(<:>=\*(:>.
Spaces are freely allowed between symbols, but not
within keywords, tags,  numeric-constants and composite signs.
Sometimes spaces are required to separate keywords and tags from following
symbols.
For example, \*(<:cos y\*(:> is not the same as \*(<:cosy\*(:>: the latter is
taken to be one tag.
.St 4 UNITS 
.Xx work-space
.Sy  4
.Pr unit 4
.Al
how-to-unit
.Al
yield-unit
.Al
test-unit
.Ps
Units are the building blocks of a \*B ``program''.
Users can define new commands, functions and predicates by writing a unit.
These units reside in a work-space.
.Pr refinement-suite 2
.Al
new-line\0refinement\0optional-refinement-suite
.Ps
When writing a unit, the specification of some parts
(commands, expressions and tests) may be deferred by
using a ``refinement''.
These refinements are then specified at the end of the unit.
.Se 3  4.1 HOW-TO-UNITS
.Xx keyword
.Xx user-defined-command
.Sy  3
.Pr how-to-unit 3
.Al
\*(<:HOW'TO\*(:> formal-user-defined-command\*(<::\*(:>
.br
command-suite
.br
optional-refinement-suite
.Pr formal-user-defined-command 2
.Sl
keyword\0optional-formal-tail
.Ps 
The first keyword of a formal-user-defined-command must be unique, i.e.,
different from the first keywords of all predefined and other
user-defined commands.
So it is impossible to redefine the built-in commands of \*B.
It may also not be \*(<:HOW'TO\*(:>, \*(<:YIELD\*(:>, \*(<:TEST\*(:>, \*(<:SHARE\*(:> or \*(<:ELSE\*(:>.
Otherwise, it may be chosen freely.
There are no restrictions on the second and further keywords.
.Pr formal-tail 3
.Al
formal-parameter\0optional-formal-trailer
.Al
formal-trailer
.Pr formal-trailer 2
.Sl
keyword\0optional-formal-tail
.Pr formal-parameter 1
.Sl
tag
.Ps
Note that, although actual-parameters (section 5.1.16)
and formal-operands (section 4.2) may be composite,
formal-parameters must be simple tags.
.Sx 5 \k1how-to-unit:
\*(<:HOW'TO PUSH value ON stack:
    PUT value IN stack[#stack+1]\*(:>
.Tx
A how-to-unit defines the meaning of a new command
(see ``user-defined-commands'', section 5.1.16).
The above unit defines a \*(<:PUSH\*(:>\ ...\ \*(<:ON\*(:>\ ... command.
Once the command has been defined, it may be used in the
same way as the built-in commands.
Other user-defined commands may be used in the body of a unit
even if they have not yet been defined,
though they must be defined by the time the unit is invoked.
.Xe
.Sa
quit-command (5.1.11),
share-heading (4.5),
user-defined-commands (5.1.16).
.Se 3  4.2 YIELD-UNITS
.Xx "overloading of functions and predicates"
.Xx user-defined functions
.Xx formula
.Xx function
.Xx predicate
.Xx zeroadic
.Xx monadic
.Xx dyadic
.Sy  3
.Pr yield-unit 3
.Al
\*(<:YIELD\*(:> formal-formula\*(<::\*(:>
.br
command-suite
.br
optional-refinement-suite
.Pr formal-formula 4
.Al
formal-zeroadic-formula
.Al
formal-monadic-formula
.Al
formal-dyadic-formula
.Pr formal-zeroadic-formula 2
.Sl
zeroadic-function
.Pr formal-monadic-formula 2
.Sl
monadic-function\0formal-operand
.Pr formal-dyadic-formula 2
.Al
formal-operand\0dyadic-function\0formal-operand
.Ps 
Functions must not be ``overloaded'' (multiply defined),
and a user-defined function must be represented by a tag.
However, a given tag may be used, at the same time, for
a dyadic-function and either a zeroadic- or a monadic-function or -predicate.
(In other words, you may not have a function that is both monadic
and zeroadic, for otherwise it would be impossible to decide what was meant
in cases such as \*(<:f + 1\*(:>,
where \*(<:f\*(:> could be either zeroadic or monadic, and the restrictions
also apply to combinations of functions and predicates.)
.Pr formal-operand 2
.Sl
single-identifier
.Sx 5 \k1yield-unit:
\*(<:YIELD (a, b) over (c, d):
    PUT c*c+d*d IN rr
    RETURN (a*c+b*d)/rr, (-a*d+b*c)/rr\*(:>
.Xe
.Tx
A yield-unit defines the meaning of a new function
(see ``Formulas with user-defined functions'', section 6.1.6).
The example given above defines complex division.
(Complex numbers are not a built-in type of \*B.)
.br
Functions may be zeroadic (no operands), monadic (one trailing operand)
or dyadic (two operands, one at the left and one at the right).
.Sa
return-commands (5.1.12),
share-headings (4.5),
formulas with user-defined functions (6.1.6).
.Se 3  4.3 TEST-UNITS
.Xx "overloading of functions and predicates"
.Xx user-defined-predicates
.Xx test
.Xx formula
.Xx function
.Xx predicate
.Xx proposition
.Xx zeroadic
.Xx monadic
.Xx dyadic
.Sy  3
.Pr test-unit 3
.Al
\*(<:TEST\*(:> formal-proposition\*(<::\*(:>
.br
command-suite
.br
optional-refinement-suite
.Pr formal-proposition 4
.Al
formal-zeroadic-proposition
.Al
formal-monadic-proposition
.Al
formal-dyadic-proposition
.Pr formal-zeroadic-proposition 2
.Sl
zeroadic-predicate
.Pr formal-monadic-proposition 2
.Al
monadic-predicate\0formal-operand
.Pr formal-dyadic-proposition 2
.Al
formal-operand\0dyadic-predicate\0formal-operand
.Ps 
Like functions, predicates must not be ``overloaded'',
though a given tag may be used, at the same time, for
a dyadic-predicate and either a zeroadic- or a monadic-function or -predicate.
.Sx 5 \k1test-unit:
\*(<:TEST a subset b:
    REPORT EACH x IN a HAS x in b\*(:>
.Xe
.Tx
A test-unit defines the meaning of a new predicate
(see ``Propositions with user-defined predicates'', section 6.3.2).
Like functions, predicates may be zeroadic, monadic or dyadic.
.br
Tests do not return a value, but succeed or fail via the \*(<:REPORT\*(:>,
\*(<:SUCCEED\*(:> and \*(<:FAIL\*(:> commands.
.Sa
report-commands (5.1.13),
succeed-command (5.1.14),
fail-command (5.1.15),
share-headings (4.5),
propositions with user-defined predicates (6.3.2).
.Se 4  4.4 REFINEMENTS
.Xx keyword
.Sy  4
.Pr refinement 4
.Al
command-refinement
.Al
expression-refinement
.Al
test-refinement
.Pr command-refinement 2
.Sl
keyword\*(<::\*(:> command-suite
.Ps
The keyword of a command-refinement must be different from the first keywords
of all predefined commands,
and it may also not be \*(<:HOW'TO\*(:>, \*(<:YIELD\*(:>, \*(<:TEST\*(:>, \*(<:SHARE\*(:> or \*(<:ELSE\*(:>.
It may, however, be the same as the first keyword of a user-defined-command.
.Sx 4 \k1command-refinement:
\*(<:SELECT'TASK:
    PUT min tasks IN task
    REMOVE task FROM tasks\*(:>
.Pr expression-refinement 2
.Sl
tag\*(<::\*(:> command-suite
.Sx 4 expression-refinement:
\*(<:stack'pointer:
    IF stack = {}: RETURN 0
    RETURN max keys stack\*(:>
.Pr test-refinement 2
.Sl
tag\*(<::\*(:> command-suite
.Sx 4 test-refinement:
\*(<:special'case:
    REPORT position+d = line'length\*(:>
.Xe
.Tx
Refinements support the method of ``top-down'' programming, also
known as programming by ``stepwise refinement''.
The body of a unit may be written using refined-commands, -expressions
and -tests that reflect the appropriate, coarse-grained, level of
abstraction for expressing the algorithmic intention.
In subsequent refinements, these may be refined to
the necessary detail, possibly in several steps.
As with units, there are three kinds of refinements.
The differences with units are:
.in (\w'\(em\ 'u+3m)u
.ti 3m
\(em\ refinements are bound to a unit and may not be invoked
from other units;
.ti 3m
\(em\ all tags known inside the unit are also known inside the
refinement;
.ti 3m
\(em\ no parameters or operands can be passed when the
refinement is invoked.
.in 0
{{Currently, refinements may only occur within unit bodies, and not
in ``immediate commands''.}}
.Sa
refined-commands (5.1.17),
refined-expressions (6.1.7),
refined-tests (6.3.3).
.Se 4  4.5 COMMAND-SUITES
.Xx target
.Xx local
.Xx global
.Xx work-space
.Xx permanent environment
.Xx yield-unit
.Xx expression-refinement
.Xx return-command
.Xx test-unit
.Xx test-refinement
.Xx report-command
.Xx succeed-command
.Xx fail-command
.Sy  4
.Pr command-suite 4
.Al
simple-command
.Al
increase-indentation\0optional-share-heading
optional-command-sequence\0decrease-indentation
.Ps
A command-suite may only follow the preceding colon on the same line
if it is a simple-command.
Otherwise, it starts on a new line, with
all lines of the command-suite indented.
.Sx 4 command-suite
\*(<:SHARE name'list, abbreviation'table
IF name in keys abbreviation'table:
    PUT abbreviation'table[name] IN name
IF name not'in name'list:
    INSERT name IN name'list\*(:>
.Xe
.Pr share-heading 3
.Al
new-line \*(<:SHARE\*(:> identifier\0optional-share-heading
.Ps 
Tags used as targets (variables) in a unit
(except those that are formal-parameters)
are by default local to the unit.
If a target should be shared between several units,
this can be indicated by listing the tag
in a share-heading at the start of the unit body.
It stands then for a global target of the work-space.
The global targets together with their contents are also called the ``permanent
environment'', because they survive on logging out.
.br
A share-heading may only occur in the command-suite of a unit (and not
of a refinement or compound-command).
.Sx 2 share-heading
\*(<:SHARE name'list, abbreviation'table\*(:>
.Xe
.Pr command-sequence 2
.Al
new-line\0command\0optional-command-sequence
.Ps 
The execution of the command-suite of a yield-unit or
expression-refinement must end in a return-command, and return-commands
may only occur within such command-suites.
.Ps 
The execution of the command-suite of a test-unit or
test-refinement must end in a report-, succeed- or fail-command, and these
may only occur within such command-suites.
.Sx 3 command-sequence
\*(<:IF name in keys abbreviation'table:
    PUT abbreviation'table[name] IN name
IF name not'in name'list:
    INSERT name IN name'list\*(:>
.Xe
.St 5 COMMANDS
.Xx immediate command
.Xx global
.Xx interrupt key
.Tx
Commands may be given as ``immediate commands'', directly from
the terminal, or may be part of a unit.
If commands are given as immediate commands, they are obeyed
directly.
Any targets in the command are then interpreted as global targets
from the permanent environment.
Within a unit, targets are local, unless they have been listed
in a share-heading (see above).
.br
If the user presses the interrupt key while a command is executing,
execution is aborted, and the user is prompted for another immediate command.
.Sy  3
.Pr command 3
.Al
simple-command
.Al
control-command
.Se 3  5.1 SIMPLE-COMMANDS
.Sy  3
.Pr simple-command 3
.Al
check-command
.Al
write-command
.Al
read-command
.Al
put-command
.Al
draw-command
.Al
choose-command
.Al
set-random-command
.Al
remove-command
.Al
insert-command
.Al
delete-command
.Al
terminating-command
.Al
user-defined-command
.Al
refined-command
.Pr terminating-command 3
.Al
quit-command
.Al
return-command
.Al
report-command
.Al
succeed-command
.Al
fail-command
.Se 2  5.1.1 CHECK-COMMANDS
.Sy  2
.Pr check-command 2
.Sl
\*(<:CHECK\*(:> test
.Sx 3 \k1check-command:
\*(<:CHECK i >= 0 AND j >= 0 AND i+j <= n\*(:>
.Xe
.Tx
When a check-command is executed, its test is tested.
If the test fails, an error is reported and execution halts.
Otherwise, no message is given and execution continues.
Check-commands may be used, for example, to check the requirements of
parameters or operands on entry to a unit.
The liberal use of check-commands helps to get programs correct quickly.
.Se 3  5.1.2 WRITE-COMMANDS
.Xx convert to a text
.Xx permanent environment
.Xx interrupt key
.Sy  3
.Pr write-command 3
.Al
\*(<:WRITE\*(:> new-liners
.Al
\*(<:WRITE\*(:> optional-new-liners\0expression\0optional-new-liners
.Pr new-liners 2
.Sl
\*(<:/\*(:> optional-new-liners
.Ex 3
\k1write-commands:
\h'|\n1u'\*(<:WRITE //\*(:>
\h'|\n1u'\*(<:WRITE // 'Give a value in the range 1 through `n`: '\*(:>
.Tx
The expression is converted to a text and written to the screen.
Each \*(<:/\*(:> gives a transition to a new line.
Note that you write no comma before or after the \*(<:/\*(:>s.
.br
With the exception of adjacent texts,
values that are adjacent are written separated by a space.
Compounds within other values (within lists, tables or other compounds)
are written with commas between their fields,
and where necessary, the whole surrounded by brackets.
Similarly, inner texts are written enclosed by quotes.
Compounds and texts not within other values are output without commas,
brackets and quotes.
Thus,
.Di 2
\*(<:WRITE 0, 1, ',', 2, '!', '!', 3
WRITE {1; 2}, {['a','b']:('b','a'); ['b','a']:('a','b')} /\*(:>
.Ed
gives
.Di 1
\*(<:0 1 , 2 !! 3 {1; 2} {['a', 'b']: ('b', 'a'); ['b', 'a']: ('a', 'b')}\*(:>
.Ed
For formatting purposes, see the operators \*(<:>>\*(:>, \*(<:<<\*(:>, and \*(<:><\*(:>
in section 6.1.6, ``Functions on Texts'',
and the conversions in text-displays in section 6.1.5, ``Displays''.
.Se 3  5.1.3 READ-COMMANDS
.Sy  3
.Pr read-command 4
.Al
\*(<:READ\*(:> target \*(<:EG\*(:> expression
.Al
\*(<:READ\*(:> target \*(<:RAW\*(:>
.Ex 3
read-commands:
\*(<:READ n, s EG 0, ''
READ line RAW\*(:>
.Xe
.Tx
The execution of a read-command prompts the user
to supply one input line.
.br
If an \*(<:EG\*(:> part is present, the input is interpreted as an
\fIexpression\fP of the same type as the expression following \*(<:EG\*(:>.
(Usually, the example expression will consist of constants,
but other expressions are also allowed.)
The input expression is evaluated in the permanent environment
(so local tags of units cannot be used) and put in the target.
To input a text-display (literal), text quotes are required.
.br
If \*(<:RAW\*(:> is specified, the target must be a text target.
The input line is put in the target literally.
No text quotes are needed.
.br
If the user presses the interrupt key instead of supplying a value,
the read-command, and in fact the whole program, is aborted.
This is useful for entering a sequence of data of unspecified length.
.Se 3  5.1.4 PUT-COMMANDS
.Xx target
.Xx location
.Xx type
.Sy  3
.Pr put-command 3
.Sl
\*(<:PUT\*(:> expression \*(<:IN\*(:> target
.Sx 3 \k1put-command:
\*(<:PUT a+1, ({}, {1..a}) IN a, b\*(:>
.Xe
.Tx
The value of the expression is put in the target.
This means that the value will be held in a location
for the target, until a different value is put in the target,
or the target is deleted.
If no such location exists already, it is created on
the spot.
Here, as in other cases, the types must agree.
{{This is currently not checked in general.}}
See also the sections on various kinds of targets below (section 6.2).
.Se 2  5.1.5 DRAW-COMMANDS
.Xx random
.Xx number
.Sy  2
.Pr draw-command 2
.Sl
\*(<:DRAW\*(:> target
.Sx 3 \k1draw-command:
\*(<:DRAW r\*(:>
.Xe
.Tx
A random approximate number
(from \*(<:~0\*(:> up to, but not including, \*(<:~1\*(:>)
is drawn and put in the target.
.Se 4  5.1.6 CHOOSE-COMMANDS
.Xx text, list or table
.Xx random
.Xx character
.Xx list entry
.Xx associate
.Sy  4
.Pr choose-command 4
.Sl
\*(<:CHOOSE\*(:> target \*(<:FROM\*(:> expression
.Sx 3 \k1choose-command:
\*(<:CHOOSE exit FROM exits[current'room]\*(:>
.Xe
.Tx
The expression must have a text, list or table as value.
This value must not be empty.
An item is drawn at random from the value
(characters from a text, entries from a list and associates
from a table)
and put in the target.
The item is not removed from the value.
.Se 2  5.1.7 SET-RANDOM-COMMANDS
.Xx random
.Sy  2
.Pr set-random-command 2
.Sl
\*(<:SET'RANDOM\*(:> expression
.Sx 3 \k1set-random-command:
\*(<:SET'RANDOM 'Monte Carlo', run\*(:>
.Xe
.Tx
The (pseudo-)random sequence
used for draw- and choose-commands
is reset to a point, depending on the
value of the expression.
.Se 3  5.1.8 REMOVE-COMMANDS
.Xx list entry
.Sy  3
.Pr remove-command 3
.Sl
\*(<:REMOVE\*(:> expression \*(<:FROM\*(:> target
.Sx 3 \k1remove-command:
\*(<:REMOVE task FROM tasks\*(:>
.Xe
.Tx
The target must hold a list, and the value of the expression must be
an entry of that list.
The entry is removed.
If it was present more than once, only one instance is removed.
.Se 3  5.1.9 INSERT-COMMANDS
.Xx list entry
.Sy  3
.Pr insert-command 3
.Sl
\*(<:INSERT\*(:> expression \*(<:IN\*(:> target
.Sx 3 \k1insert-command:
\*(<:INSERT new'task IN tasks\*(:>
.Xe
.Tx
The target must hold a list.
The value of the expression is inserted as a list entry.
If that entry was already present, one more instance will be present.
.Se 2  5.1.10 DELETE-COMMANDS
.Xx location
.Xx table entry
.Xx table-selection-target
.Sy  2
.Pr delete-command 2
.Sl
\*(<:DELETE\*(:> target
.Sx 3 \k1delete-command:
\*(<:DELETE t[i], u[i, j]\*(:>
.Xe
.Tx
The location for the target ceases to exist.
If a multiple-target is given, all its single-targets are deleted.
If a table-selection-target is given, the table must contain the key
that is used as selector.
The table entry with that key is then deleted from the table.
It is an error to delete a trimmed-text-target (e.g., \*(<:t@2\*(:>).
.Se 2  5.1.11 QUIT-COMMAND
.Xx how-to-unit
.Xx command-refinement
.Xx immediate-command
.Xx permanent environment
.Sy  2
.Pr quit-command 2
.Sl
\*(<:QUIT\*(:>
.Ps 
A quit-command may only occur in the command-suite of a
how-to-unit or command-refinement, or as an immediate command.
.Sx 3 \k1quit-command:
\*(<:QUIT\*(:>
.Xe
.Tx
The execution of a quit-command causes the termination of the execution
of the how-to-unit or command-refinement in whose command-suite
it occurs.
If it occurs in a command-refinement, the execution of
the invoking refined-command is thereby terminated and the further
execution continues as if the refined-command had terminated normally.
Otherwise, the execution of
the invoking user-defined-command is terminated and the further
execution continues similarly.
.br
Given as an immediate command, \*(<:QUIT\*(:> terminates the current
session.
All units and targets in the permanent environment
survive and can be used again at the next session.
.Se 2  5.1.12 RETURN-COMMANDS
.Xx expression-refinement
.Xx user-defined-function
.Xx refined-expression
.Xx yield-unit
.Sy  2
.Pr return-command 2
.Sl
\*(<:RETURN\*(:> expression
.Sx 3 \k1return-command:
\*(<:RETURN (a*c+b*d)/rr, (-a*d+b*c)/rr\*(:>
.Xe
.Tx
The execution of a return-command causes the termination of the execution
of the yield-unit or expression-refinement in whose command-suite
it occurs.
The value of the expression is returned as the value of the invoking
user-defined function or refined-expression.
Return-commands may only occur within the command-suite of a
yield-unit or expression-refinement.
.Se 2  5.1.13 REPORT-COMMANDS
.Xx test-unit
.Xx test-refinement
.Xx user-defined-predicate
.Xx refined-test
.Xx bound tags
.Pr report-command 2
.Sl
\*(<:REPORT\*(:> test
.Sx 3 \k1report-command:
\*(<:REPORT i in keys t\*(:>
.Xe
.Tx
The execution of a report-command causes the termination of the execution
of the test-unit or test-refinement in whose command-suite
it occurs.
The invoking user-defined predicate or refined-test
succeeds/fails if the test of the report-command succeeds/fails.
If the invoker is a test-refinement,
any bound tags set by a for-command (see section 5.2.4) or
a quantification (section 6.3.7) will temporarily survive,
as described under REFINED-TESTS (section 6.3.3).
.br
Report-commands may only occur within the command-suite of a
test-unit or test-refinement.
.br
The command ``\*(<:REPORT\*(:> test'' is equivalent to
.Di 3
\*(<:SELECT:
    \*(:>test\*(<:: SUCCEED
    ELSE: FAIL\*(:>
.Ed
.Se 2  5.1.14 SUCCEED-COMMAND
.Xx test-unit
.Xx test-refinement
.Xx user-defined-predicate
.Xx refined-test
.Xx bound tags
.Sy  2
.Pr succeed-command 2
.Sl
\*(<:SUCCEED\*(:>
.Sx 3 \k1succeed-command:
\*(<:SUCCEED\*(:>
.Xe
.Tx
The execution of a succeed-command causes the termination of the execution
of the test-unit or test-refinement in whose command-suite
it occurs.
The invoking user-defined predicate or refined-test succeeds.
As with report-commands, bound tags temporarily survive.
.br
Succeed-commands may only occur within the command-suite of a
test-unit or test-refinement.
.br
The command \*(<:SUCCEED\*(:> is equivalent to \*(<:REPORT 0 = 0\*(:>.
.Se 2  5.1.15 FAIL-COMMAND
.Xx test-unit
.Xx test-refinement
.Xx user-defined-predicate
.Xx refined-test
.Xx bound tags
.Sy  2
.Pr fail-command 2
.Sl
\*(<:FAIL\*(:>
.Sx 3 \k1fail-command:
\*(<:FAIL\*(:>
.Xe
.Tx
The execution of a fail-command causes the termination of the execution
of the test-unit or test-refinement in whose command-suite
it occurs.
The invoking user-defined predicate or refined-test fails.
As with report-commands, bound tags temporarily survive.
.br
Fail-commands may only occur within the command-suite of a
test-unit or test-refinement.
.br
The command \*(<:FAIL\*(:> is equivalent to \*(<:REPORT 0 = 1\*(:>.
.Se 2  5.1.16 USER-DEFINED-COMMANDS
.Xx keyword
.Xx how-to-unit
.Xx quit-command
.Sy  2
.Pr user-defined-command 2
.Sl
keyword\0optional-actual-parameter\0optional-trailer
.Pr trailer 2
.Sl
keyword\0optional-actual-parameter\0optional-trailer
.Pr actual-parameter 2
.Al
identifier
.Al
target
.Al
expression
.Ps 
The keywords and actual-parameters must correspond one to one to those
of the formal-user-defined-command of one unique how-to-unit.
.Ex 6
\k1user-defined-commands:
\h'|\n1u'\*(<:CLEAN'UP\*(:>
\h'|\n1u'\*(<:DRINK me\*(:>
\h'|\n1u'\*(<:TURN a UPSIDE DOWN\*(:>
\h'|\n1u'\*(<:PUSH v ON operand'stack\*(:>
.Xe
.Tx
A user-defined-command is executed in the following steps:
.in \w'2.\ 'u
.ti 0
1.\ Any local tags in the how-to-unit that might clash with tags currently
in use are systematically replaced by other tags that do not cause conflict.
.ti 0
2.\ Each actual-parameter is placed between parentheses \*(<:(\*(:> and \*(<:)\*(:>
and then
substituted throughout the unit for the corresponding formal-parameter.
.ti 0
3.\ The command-suite of the unit, thus modified, is executed.
.in 0
The execution of the user-defined-command is complete when the execution
of this command-suite terminates (normally, or because of the execution
of a quit-command).
After the execution is complete,
the local tags of the unit are no longer accessible.
.Se 2  5.1.17 REFINED-COMMANDS
.Xx keyword
.Xx command-refinement
.Xx quit-command
.Sy  2
.Pr refined-command 2
.Sl
keyword
.Ps 
The keyword of a refined-command must occur as the keyword of one
command-refinement in the unit
in which it occurs.
That command-refinement specifies the meaning of the refined-command.
.Sx 3 \k1refined-command:
\*(<:REMOVE'MULTIPLES\*(:>
.Xe
.Tx
A refined-command is executed by executing
the command-suite of the corresponding command-refinement.
The execution of the refined-command is complete when the execution
of this command-suite terminates
(normally, or because of the execution of a quit-command).
.Se 5  5.2 CONTROL-COMMANDS
.Sy  5
.Pr control-command 5
.Al
if-command
.Al
select-command
.Al
while-command
.Al
for-command
.Se 2  5.2.1 IF-COMMANDS
.Sy  2
.Pr if-command 2
.Sl
\*(<:IF\*(:> test\*(<::\*(:> command-suite
.Sx 3 \k1if-command:
\*(<:IF i < 0: PUT -i, -j IN i, j\*(:>
.Xe
.Tx
The test is tested.
If it succeeds, the command-suite is executed;
if it fails, the command-suite is not executed.
.br
(If something should be executed on failure too, or there are
more alternatives, you should use a select-command instead.)
.br
The command
``\*(<:IF\*(:> test\*(<::\*(:> command-suite''
is equivalent to:
.Di 3
\*(<:SELECT:
    \*(:>test\*(<:: \*(:>command-suite\*(<:
    ELSE: \\do nothing.\*(:>
.Ed
.Se 2  5.2.2 SELECT-COMMANDS
.Sy  2
.Pr select-command 2
.Sl
\*(<:SELECT:\*(:> alternative-suite
.Pr alternative-suite 3
.Al
increase-indentation\0new-line\0alternative-sequence\0decrease-indentation
.Pr alternative-sequence 4
.Al
single-alternative
.Al
else-alternative
.Al
single-alternative\0new-line\0alternative-sequence
.Pr single-alternative 2
.Sl
test\*(<::\*(:> command-suite
.Pr else-alternative 2
.Sl
\*(<:ELSE:\*(:> command-suite
.Eo 5 select-commands:\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\k2\":
\h'|\n1u'\*(<:SELECT:\*(:> \h'|\n2u'\*(<:SELECT:\*(:>
\h'|\n1u'\*(<:    a < 0: RETURN -a\*(:> \h'|\n2u'\*(<:    a < 0: RETURN -a\*(:>
\h'|\n1u'\*(<:    a >= 0: RETURN a\*(:> \h'|\n2u'\*(<:    ELSE: RETURN a\*(:>
.Xe
.Tx
The tests of the alternatives are tested one by one,
starting with the first and proceeding downwards, until one
is found that succeeds.
The corresponding command-suite is then executed.
\*(<:ELSE\*(:> may be used in the final alternative as a test that always succeeds.
If all the tests fail, an error is reported.
.Se 2  5.2.3 WHILE-COMMANDS
.Xx terminating command
.Sy  2
.Pr while-command 2
.Sl
\*(<:WHILE\*(:> test\*(<::\*(:> command-suite
.Sx 3 \k1while-command:
\*(<:WHILE x > 1: PUT x/10, c+1 IN x, c\*(:>
.Xe
.Tx
If the test succeeds, the command-suite is executed, and the
while-command is repeated, and so on, until the test fails,
or until an escape is forced by a terminating command.
If the test fails the very first time, the command-suite is
not executed at all.
.Se 3  5.2.4 FOR-COMMANDS
.Xx text, list or table
.Xx character
.Xx list entry
.Xx associate
.Xx target
.Xx bound tags
.Sy  3
.Pr for-command 3
.Sl
\*(<:FOR\*(:> in-ranger\*(<::\*(:> command-suite
.Pr in-ranger 2
.Sl
identifier \*(<:IN\*(:> expression
.Sx 3 \k1for-command:
\*(<:FOR i, j IN keys t: PUT t[i, j] IN t'[j, i]\*(:>
.Xe
.Tx
The value of the expression must be a text, list or table.
One by one, each item of that value
(characters for a text, list entries for a list and associates for a table)
is put in the identifier, and the command-suite executed.
For example,
.Di 1
\*(<:FOR c IN 'ABC': WRITE 'letter is', c /\*(:>
.Ed
is equivalent to
.Di 3
\*(<:WRITE 'letter is', 'A' /
WRITE 'letter is', 'B' /
WRITE 'letter is', 'C' /\*(:>
.Ed
If \*(<:t\*(:> is a table, then
``\*(<:FOR a IN t: TREAT a\*(:>''
treats the associates of \*(<:t\*(:> in the same way as
.Di 3
\*(<:FOR k IN keys t:
    PUT t[k] IN a
    TREAT a\*(:>
.Ed
The tags of the identifier of a for-command may not be used as targets
or target-contents
outside such a for-command.
They are ``bound tags'', and lose their meaning outside the
for-command.
There is one exception to this rule:
if a for-command is used in a test-refinement, and within
the for-command a report-, succeed- or fail-command is
executed, the currently bound tags will temporarily survive
as described under REFINED-TESTS (section 6.3.3).
.Sa
quantifications (6.3.7).