.\" Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984.
.St 6 "EXPRESSIONS, TARGETS AND TESTS"
.Se 3 6.1 EXPRESSIONS
.Xx scratch-pad copy
.Xx compound
.Tx
In \*B, the evaluation of an expression cannot alter the values of targets
that currently exist, nor can it create new targets that survive the expression.
If an expression appears to alter a target, it effectively modifies
a local ``scratch-pad''
\fIcopy\fP of that target, and the change is invisible outside the expression.
.Sy  3
.Pr expression 4
.Al
single-expression
.Al
multiple-expression
.Pr single-expression 3
.Al
basic-expression
.Al
\*(<:(\*(:> expression \*(<:)\*(:>
.Pr basic-expression 3
.Al
simple-expression
.Al
formula
.Pr simple-expression 7
.Al
constant
.Al
target-content
.Al
trimmed-text
.Al
table-selection
.Al
display
.Al
refined-expression
.Pr tight-expression 3
.Al
simple-expression
.Al
zeroadic-formula
.Al
\*(<:(\*(:> expression \*(<:)\*(:>
.Pr right-expression 3
.Al
tight-expression
.Al
monadic-formula
.Eo 6 basic-:\0\0\k2simple-:\0\k3tight-:\0\0\0\0\k4right-expressions:
\h'|\n1u'\*(<:a\*(:> \h'|\n2u'\*(<:a\*(:> \h'|\n3u'\*(<:a\*(:> \h'|\n4u'\*(<:a\*(:>
\h'|\n1u'\*(<:-a\*(:> \h'|\n4u'\*(<:-a\*(:>
\h'|\n1u'\*(<:a+b\*(:>
\h'|\n3u'\*(<:(a+b)\*(:> \h'|\n4u'\*(<:(a+b)\*(:>
.Xe
.Tx
The various kinds of expressions that are distinguished here
serve to define the syntax
in such a way that no parentheses are needed where the meaning is
sufficiently clear.
.Pr multiple-expression 1
.Al
single-expression\*(<:,\*(:> single-expression
.Al
single-expression\*(<:,\*(:> multiple-expression
.Ex 3
\k1multiple-expressions:
\h'|\n1u'\*(<:1, 'abc'\*(:>
\h'|\n1u'\*(<:(1, 0), (0, 1), (-1, 0), (0, -1)\*(:>
.Xe
.Tx
The value of a multiple-expression composed of single-expressions
separated by commas
is the compound whose fields are the values of the
successive single-expressions.
.Se 3  6.1.1 NUMERIC-CONSTANTS
.Sy  3
.Pr numeric-constant 3
.Al
exact-constant
.Al
approximate-constant
.Pr exact-constant 3
.Al
integral-part\0optional-fractional-part
.Al
integral-part \*(<:.\*(:>
.Al
fractional-part
.Pr integral-part 3
.Al
digit
.Al
integral-part\0digit
.Pr digit 2
.Al
\*(<:0\*(:>
.Al
\*(<:1\*(:>
.Al
\*(<:2\*(:>
.Al
\*(<:3\*(:>
.Al
\*(<:4\*(:>
.Al
\*(<:5\*(:>
.Al
\*(<:6\*(:>
.Al
\*(<:7\*(:>
.Al
\*(<:8\*(:>
.Al
\*(<:9\*(:>
.Pr fractional-part 3
.Al
\&\*(<:.\*(:> digit
.Al
fractional-part\0digit
.Pr approximate-constant 2
.Sl
exact-constant\0exponent-part
.Pr exponent-part 2
.Sl
\*(<:E\*(:> optional-plusminus\0integral-part
.Pr plusminus 2
.Al
\*(<:+\*(:>
.Al
\*(<:-\*(:>
.Eo 5 exact-constants:\0\0\0\0\0\0\k2approximate-constants:
\h'|\n1u'\*(<:666\*(:> \h'|\n2u'\*(<:2.99793E8\*(:>
\h'|\n1u'\*(<:666.\*(:> \h'|\n2u'\*(<:2.99793E+8\*(:>
\h'|\n1u'\*(<:3.14\*(:> \h'|\n2u'\*(<:1E-9\*(:>
.Xe
.Tx
The value of an exact-constant is an exact number.
For example, \*(<:1.25\*(:> stands for the exact number \*(<:5/4\*(:>.
The value of an approximate-constant is an approximate number.
The exponent-part gives the power of ten in floating-point notation.
For example, \*(<:1.2345E2\*(:> and \*(<:~123.45\*(:> are (approximately) the same,
because \*(<:123.45 = 1.2345*10**2\*(:>.
.Se 2  6.1.2 TARGET-CONTENTS
.Sy  2
.Pr target-content 2
.Sl
tag
.Tx
The value of a target-content is the value last put in the target whose
name is the given tag.
.Se 2  6.1.3 TRIMMED-TEXTS
.Xx integer
.Sy  2
.Pr trimmed-text 2
.Al
tight-expression \*(<:@\*(:> right-expression
.Al
tight-expression \*(<:|\*(:> right-expression
.Ps
.Ex 6
\k1trimmed-texts:
\h'|\n1u'\*(<:t@p\*(:>
\h'|\n1u'\*(<:t|1\*(:>
\h'|\n1u'\*(<:t|q@p\*(:>
\h'|\n1u'\*(<:t@p|(q-p+1)\*(:>
.Xe
.Tx
The value of the tight-expression must be a text T, and that
of the right-expression must be an integer N.
.br
If the sign between the expressions is \*(<:@\*(:>, then the value of
the trimmed-text is that of T after removing the first N\(mi1 characters.
For example, \*(<:'lamplight'@4 = 'plight'\*(:>.
N must be at least 1 and at most one more than the length of T.
.br
If the sign between the expressions is \*(<:|\*(:>, then the value of
the trimmed-text is the text consisting of the first N characters of T.
For example, \*(<:'scarface'|5 = 'scarf'\*(:>.
N must be at least 0 and at most equal to the length of T.
.br
Note that the tight-expression itself may be a trimmed-text
again.
For example, \*(<:'department'|6@3 = 'depart'@3 = 'part'\*(:>.
.Se 3  6.1.4 TABLE-SELECTIONS
.Xx key
.Xx associate
.Xx table entry
.Sy  3
.Pr table-selection 3
.Sl
tight-expression \*(<:[\*(:> expression \*(<:]\*(:>
.Sx 2 table-selection:
\*(<:t[i, j]\*(:>
.Xe
.Tx
The value of the tight-expression must be a table T, and
the value of the expression between the square brackets must
be a key K of T.
The value of the table-selection is then the associate of
the table entry in T whose key is K.
.Se 3  6.1.5 DISPLAYS
.Xx integer
.Xx character
.Xx quote
.Xx convert to a text
.Xx ambiguity
.Xx empty list
.Xx empty table
.Xx key
.Xx associate
.Sy  3
.Pr display 4
.Al
text-display
.Al
list-display
.Al
table-display
.Pr text-display 3
.Al
\&\*(<:'\*(:> optional-text-body \*(<:'\*(:>
.Al
\*(<:"\*(:> optional-text-body \*(<:"\*(:>
.Ps
The text-displays \*(<:''\*(:> and \*(<:""\*(:> stand for the empty text.
A text-body may be any sequence of printable characters
(see section 1 under `Texts')
and conversions
(see below).
However, in a text-display in the \*(<:'\*(:>\^...\^\*(<:'\*(:> style,
any single quote \*(<:'\*(:> in the text must be written twice to give \*(<:''\*(:>.
Otherwise, it will signal the end of the text-display.
Similarly, in a text-display in the \*(<:"\*(:>\^...\^\*(<:"\*(:> style,
any double quote \*(<:"\*(:> in the text must be written twice to give \*(<:""\*(:>.
Finally, the back-quote \*(<:`\*(:> must be written twice too, giving \*(<:``\*(:>.
Otherwise, it signals a conversion.
.Pr conversion 2
.Sl
\*(<:`\*(:> expression \*(<:`\*(:>
.Ps
The requirement that some signs be written twice does not hold
\fIinside\fP a conversion.
For example, \*(<:'`t['a']`'\*(:> is proper, whereas \*(<:'`t[''a'']`'\*(:> is not.
.Eo 6 text-displays:
\h'|\n1u'\*(<:''\*(:>
\h'|\n1u'\*(<:'He said: "Don''t!"'\*(:>
\h'|\n1u'\*(<:"He said: ""Don't!"""\*(:>
\h'|\n1u'\*(<:'altitude is `a/1E3` km'\*(:>
.Xe
.Tx
The value of a text-display is the text composed of the
characters given between the enclosing text quotes.
If the text-display contains conversions, the expressions of
these conversions are evaluated first and converted to a
text in the same way as for a write-command.
For example,
since
.Di 1
\*(<:WRITE 239*4649\*(:>
.Ed
causes the text \*(<:1111111\*(:> to be written,
the text-display
.Di 1
\&\*(<:'239 times 4649 gives `239*4649`'\*(:>
.Ed
is equivalent to
.Di 1
\&\*(<:'239 times 4649 gives 1111111'\*(:>.
.Ed
The quotes and conversion-signs that had to be written twice
according to the above rules correspond to one character of
the resulting text.
For example,  the number of characters in \*(<:'x''y""z'\*(:> is 6,
because it consists of one \*(<:x\*(:>, \fIone\fP \*(<:'\*(:> character,
one \*(<:y\*(:>, \fItwo\fP \*(<:"\*(:> characters, and finally one \*(<:z\*(:>.
Another way to specify the same text is \*(<:"x'y""""z"\*(:>.
.Pr list-display 2
.Sl
\*(<:{\*(:> optional-list-body \*(<:}\*(:>
.Pr list-body 5
.Al
list-filler-series
.Al
single-expression \*(<:..\*(:> single-expression
.Ps
The ambiguity in, e.g., \*(<:{1...9}\*(:>, is resolved by parsing it
as \*(<:{1. .. 9}\*(:>.
.Pr list-filler-series 2
.Al
list-filler
.Al
list-filler\*(<:;\*(:> list-filler-series
.Pr list-filler 2
.Sl
single-expression
.Eo 6 list-displays:
\h'|\n1u'\*(<:{}\*(:>
\h'|\n1u'\*(<:{x1; x2; x3}\*(:>
\h'|\n1u'\*(<:{1..n-1}\*(:>
\h'|\n1u'\*(<:{'a'..'z'}\*(:>
.Xe
.Tx
The value of \*(<:{}\*(:> is an empty list.
(It may also be an empty table; see below.)
.br
The value of a list-display containing list-fillers is the
list whose entries are the values of those list-fillers.
If values occur multiply, they give rise to multiple entries
in the list.
.br
For a list-display of the form \*(<:{\*(:>p\*(<:..\*(:>q\*(<:}\*(:>, p and q must both be
integers, or both be characters (texts of length one).
The resulting value is then the list of all integers
or characters x such that p\ \(<= x\ \(<=\ q.
For example, \*(<:{1..4} = {1; 2; 3; 4}\*(:> and \*(<:{'a'..'c'} = {'a'; 'b'; 'c'}\*(:>.
.br
If p\ >\ q, the list is empty, but this is only allowed if p
and q are adjacent.
If there is an intervening integer or character x (such that
p\ >\ x\ >\ q), an error is reported.
.Pr table-display 2
.Sl
\*(<:{\*(:> optional-table-filler-series \*(<:}\*(:>
.Pr table-filler-series 2
.Al
table-filler
.Al
table-filler\*(<:;\*(:> table-filler-series
.Pr table-filler 2
.Sl
\*(<:[\*(:> expression \*(<:] :\*(:> single-expression
.Eo 6 table-displays:
\h'|\n1u'\*(<:{}\*(:>
\h'|\n1u'\*(<:{[i, j]: 0}\*(:>
\h'|\n1u'\*(<:{[0]: {}; [1]: {0}}\*(:>
\h'|\n1u'\*(<:{[name]: (month, day, year)}\*(:>
.Xe
.Tx
The table-display \*(<:{}\*(:> stands for an empty table.
Otherwise, each table-filler gives a table entry with key K
and associate A, where K is the value of the expression
between square brackets, and A is the value of the
single-expression following the colon.
The result is then the table containing these table
entries.
.br
If there are \fIdifferent\fP table entries with the same
key, an error is reported.
Multiple occurrences of the \fIsame\fP table entry, however,
are allowed.
The extra occurrences are then simply discarded.
.Se 2  6.1.6 FORMULAS
.Xx formula
.Xx function
.Xx ambiguity
.Xx parentheses
.Xx brackets
.Xx priority
.Xx user-defined-function
.Xx yield-unit
.Xx target
.Xx scratch-pad copy
.Xx local
.Xx return-command
.Xx predefined functions
.Xx number
.Xx denominator
.Xx numerator
.Xx text
.Xx convert to a text
.Xx text, list and table
.Xx key
.Xx character
.Xx associate
.Xx list entry
.Xx integer
.Sy  2
.Pr zeroadic-formula 2
.Sl
zeroadic-function
.Pr monadic-formula 2
.Sl
monadic-function\0actual-operand
.Pr dyadic-formula 2
.Al
actual-operand\0dyadic-function\0actual-operand
.Ps 
The parsing ambiguities introduced by these rules 
are resolved by priority rules, as follows:
.in +\w'2.\ 'u
.ti -\w'2.\ 'u
1.\ If there is no parsing ambiguity (as in \*(<:1 + sin x\*(:>),
no parentheses are needed.
.ti -\w'2.\ 'u
2.\ If the order makes no difference (as in \*(<:a*b*c\*(:>, \*(<:a*b/c\*(:> or
\*(<:a^b^c\*(:>), no parentheses are needed.
.ti -\w'2.\ 'u
3.\ The five arithmetic functions
\*(<:**\*(:>, \*(<:*\*(:>, \*(<:/\*(:>, \*(<:+\*(:> and \*(<:-\*(:>
have their traditional priority rules:
.in +4
\*(<:**\*(:> comes before \*(<:*\*(:>, \*(<:/\*(:>, \*(<:+\*(:> and \*(<:-\*(:>;
.br
\*(<:*\*(:> and \*(<:/\*(:> come before \*(<:+\*(:> and \*(<:-\*(:>;
.br
combinations of \*(<:+\*(:> and \*(<:-\*(:> are computed from left to right.
.in -4
Note, however, that \*(<:a**b**c\*(:>, \*(<:a/b*c\*(:> and \*(<:a/b/c\*(:> are wrong.
.ti -\w'2.\ 'u
4.\ The function \*(<:#\*(:> has a high priority, higher than the
five arithmetic functions, and the function \*(<:~\*(:> has a
higher priority than all other functions.
.ti -\w'2.\ 'u
5.\ All other functions,
in particular \*(<:^\*(:>, \*(<:^^\*(:>, \*(<:<<\*(:>, \*(<:><\*(:>, \*(<:>>\*(:>
and all tags (like \*(<:sin\*(:> or \*(<:floor\*(:>) have no established priority and
may be used
.in +4
.ti -\w'\(em\ 'u
\(em\ having formulas as operands only if these operands
are parenthesized (except as in, e.g., \*(<:exp -x\*(:>, because of
point 1 above, or as in \*(<:~1>>20\*(:> because of point 4);
.ti -\w'\(em\ 'u
\(em\ in operands of other formulas only if these operands are
parenthesized (except as above).
.in -4
.in -\w'2.\ 'u
.Bl 3
None of
\*(<:a/b/c\*(:>, \*(<:a/b*c\*(:> and \*(<:sin x+y\*(:>
is a correct formula.
Each of these can be made correct by inserting parentheses,
depending on the intention:
either \*(<:(a/b)/c\*(:> or \*(<:a/(b/c)\*(:>,
either \*(<:(a/b)*c\*(:> or \*(<:a/(b*c)\*(:>,
and either \*(<:(sin x) + y\*(:> or \*(<:sin(x+y)\*(:>.
Note that because of point 5 above
\*(<:sin(x)+1\*(:> is just as wrong as \*(<:sin x + 1\*(:>,
in spite of what other programming languages might lead you to expect.
.br
The function \*(<:#\*(:> has been given
a high priority since expressions like \*(<:#t+1\*(:> are so common,
that it would be a nuisance to have to parenthesize these,
and more so since \*(<:#(t+1)\*(:> is meaningless anyway.
The reason for the high priority of the function \*(<:~\*(:> is
to make
\*(<:~0\*(:>, for example, for all practical purposes behave as a constant.
.Pr zeroadic-function 2
.Sl
tag
.Pr monadic-function 6
.Al
\*(<:~\*(:>
.Al
\*(<:+\*(:>
.Al
\*(<:-\*(:>
.Al
\*(<:*/\*(:>
.Al
\*(<:/*\*(:>
.Al
\*(<:#\*(:>
.Al
tag
.Pr dyadic-function 3
.Al
\*(<:+\*(:>
.Al
\*(<:-\*(:>
.Al
\*(<:*\*(:>
.Al
\*(<:/\*(:>
.Al
\*(<:**\*(:>
.Al
\*(<:^\*(:>
.Al
\*(<:^^\*(:>
.Al
\*(<:<<\*(:>
.Al
\*(<:><\*(:>
.Al
\*(<:>>\*(:>
.Al
\*(<:#\*(:>
.Al
tag
.Pr actual-operand 3
.Sl
single-expression
.Eo 3 zeroadic-formula:\0\0\0\k2monadic-formula:\0\0\0\k3dyadic-formula:
\h'|\n1u'\*(<:pi\*(:> \h'|\n2u'\*(<:atan(y/x)\*(:> \h'|\n3u'\*(<:x atan y\*(:>
.Xe
.Us 7 Formulas with user-defined functions
A formula whose function is defined by a yield-unit, is
evaluated in the following steps:
.in \w'2.\ 'u
.ti 0
1.\ A copy is made of the current environment (the value of
all targets), and all computations during the evaluation of
the formula will take place in this ``scratch-pad copy''.
.ti 0
2.\ Any local tags in the yield-unit that might clash with tags currently
in use are systematically replaced by other tags that do not cause conflict.
.ti 0
3.\ Each actual-operand is evaluated and put in the
corresponding formal-operand, used as a (new)
target.
.ti 0
4.\ The command-suite of the unit, thus modified, is executed.
.in 0
The evaluation of the formula is complete when the execution
of this command-suite terminates because of the execution of a return-command;
the value of the formula is the value returned.
.Us 7 Formulas with predefined functions
.de Qr
.sp 1
.in 0
.ne 3
..
.de Qe
.br
.sp -1
.in 7m
..
.Us 0 A. Functions on numbers
.Qr
\*(<:~x\*(:>
.Qe
returns an approximate number, as close as possible
in arithmetic magnitude to \*(<:x\*(:>.
.Qr
\*(<:x+y\*(:>
.Qe
returns the sum of \*(<:x\*(:> and \*(<:y\*(:>.
The result is exact if both operands are exact.
.Qr
\*(<:+x\*(:>
.Qe
returns the value of \*(<:x\*(:>.
.Qr
\*(<:x-y\*(:>
.Qe
returns the difference of \*(<:x\*(:> and \*(<:y\*(:>.
The result is exact if both operands are exact.
.Qr
\*(<:-x\*(:>
.Qe
returns minus the value of \*(<:x\*(:>.
The result is exact if the operand is exact.
.Qr
\*(<:x*y\*(:>
.Qe
returns the product of \*(<:x\*(:> and \*(<:y\*(:>.
The result is exact if both operands are exact.
.Qr
\*(<:x/y\*(:>
.Qe
returns the quotient of \*(<:x\*(:> and \*(<:y\*(:>.
The value of \*(<:y\*(:> must not be zero.
The result is exact if both operands are exact.
.Qr
\*(<:x**y\*(:>
.Qe
returns \*(<:x\*(:> to the power \*(<:y\*(:>.
The result is exact if \*(<:x\*(:> is exact and \*(<:y\*(:> is an integer.
If \*(<:x\*(:> is negative,
\*(<:y\*(:> must be an integer or an exact number with an odd denominator.
If \*(<:x\*(:> is zero,
\*(<:y\*(:> must not be negative.
If \*(<:y\*(:> is zero, the result is one (exact or approximate).
.Qr
\*(<:n root x\*(:>
.Qe
returns the same as \*(<:x**(1/n)\*(:>.
.Qr
\*(<:root x\*(:>
.Qe
returns the same as \*(<:2 root x\*(:>, the square root of \*(<:x\*(:>.
.Qr
\*(<:abs x\*(:>
.Qe
returns the absolute value of \*(<:x\*(:>.
The result is exact if the operand is exact.
.Qr
\*(<:sign x\*(:>
.Qe
returns \(mi1 if \*(<:x\*(:> is negative, 0 if \*(<:x\*(:> is zero, and 1 otherwise.
.Qr
\*(<:floor x\*(:>
.Qe
returns the largest integer not exceeding \*(<:x\*(:> in arithmetic
magnitude.
.Qr
\*(<:ceiling x\*(:>
.Qe
returns the same as \*(<:- floor -x\*(:>.
.Qr
\*(<:n round x\*(:>
.Qe
returns the same as \*(<:(10**-n)*floor(x*10**n+.5)\*(:>.
For example, \*(<:4 round pi = 3.1416\*(:>.
The value of \*(<:n\*(:> must be an integer.
It may be negative: \*(<:(-2) round 666 = 700\*(:>.
.Qr
\*(<:round x\*(:>
.Qe
returns the same as \*(<:0 round x\*(:>.
.Qr
\*(<:a mod n\*(:>
.Qe
returns the same as \*(<:a-n*floor(a/n)\*(:>,
that is, the remainder after dividing \*(<:a\*(:> by \*(<:n\*(:>.
(Both operands may be approximate, and \*(<:n\*(:> may be negative, but not zero.)
.Qr
\*(<:/*x\*(:>
.Qe
returns the ``denominator'' of \*(<:x\*(:>,
that is, regarding \*(<:x\*(:> as the fraction \*(<:p/q\*(:>,
the smallest positive integer \*(<:q\*(:> such that \*(<:q*x\*(:> is an integer.
The value of \*(<:x\*(:> must be an exact number.
.Qr
\*(<:*/x\*(:>
.Qe
returns the corresponding ``numerator'' with the same sign as \*(<:x\*(:>,
the same integer as \*(<:(/*x)*x\*(:>.
So, if \*(<:x\*(:> is exact, \*(<:x = (*/x)/(/*x)\*(:>.
.Qr
\*(<:pi\*(:>
.Qe
returns approximately \*(<:3.1415926535\*(:>...
.Qr
\*(<:sin x\*(:>
.Qe
returns an approximate number by applying the sine function to \*(<:x\*(:>,
with \*(<:x\*(:> in radians.
.Qr
\*(<:cos x\*(:>
.Qe
returns an approximate number by applying the cosine function to \*(<:x\*(:>,
with \*(<:x\*(:> in radians.
.Qr
\*(<:tan x\*(:>
.Qe
returns the same as \*(<:(sin x) / (cos x)\*(:>.
.Qr
\*(<:x atan y\*(:>
.Qe
returns an approximate number \*(<:phi\*(:>, in the range from (about)
\*(<:-pi\*(:> to \*(<:+pi\*(:>, such that
\*(<:x\*(:> is approximated by \*(<:r * cos phi\*(:>
and \*(<:y\*(:> by \*(<:r * sin phi\*(:>, where \*(<:r = root(x*x+y*y)\*(:>.
The operands must not both be zero.
.Qr
\*(<:atan x\*(:>
.Qe
returns the same as \*(<:1 atan x\*(:>.
.Qr
\*(<:e\*(:>
.Qe
returns approximately \*(<:2.7182818284\*(:>...
.Qr
\*(<:exp x\*(:>
.Qe
returns approximately the same as \*(<:e**x\*(:>.
.Qr
\*(<:log x\*(:>
.Qe
returns an approximate number by applying the natural logarithm function
(with base \*(<:e\*(:>)
to \*(<:x\*(:>.
The value of \*(<:x\*(:> must be positive.
.Qr
\*(<:b log x\*(:>
.Qe
returns the same as \*(<:(log x) / (log b)\*(:>,
that is, the logarithm with base \*(<:b\*(:> of \*(<:x\*(:>.
.Us 7 B. Functions on texts
.Qr
\*(<:t^u\*(:>
.Qe
returns the text consisting of \*(<:t\*(:> and \*(<:u\*(:> joined.
For example, \*(<:'now'^'here' = 'nowhere'\*(:>.
.Qr
\*(<:t^^n\*(:>
.Qe
returns the text consisting of \*(<:n\*(:> copies of \*(<:t\*(:> joined together.
For \pexample, \*(<:'Fi! '^^3 = 'Fi! Fi! Fi! '\*(:>.
The value of \*(<:n\*(:> must be an integer and not negative.
.Qr
\*(<:x<<n\*(:>
.Qe
converts \*(<:x\*(:> to a text and adds space characters to
the right until the length is \*(<:n\*(:>.
For example, \*(<:123<<6 = '123   '\*(:>.
In no case is the text truncated; if \*(<:n\*(:> is too small,
the resulting text is as long as necessary.
The value of \*(<:n\*(:> must be an integer, but \*(<:x\*(:> may be of any type.
See write-commands, section 5.1.2, for details about converting values to
texts.
.Qr
\*(<:x><n\*(:>
.Qe
converts \*(<:x\*(:> to a text and adds space characters to
the right and to the left, in turn, until the length is \*(<:n\*(:>.
For example, \*(<:123><6 = ' 123  '\*(:>.
In no case is the text truncated.
The value of \*(<:n\*(:> must be an integer, but \*(<:x\*(:> may be of any type.
.Qr
\*(<:x>>n\*(:>
.Qe
converts \*(<:x\*(:> to a text and adds space characters to
the left until the length is \*(<:n\*(:>.
For example, \*(<:123>>6 = '   123'\*(:>.
In no case is the text truncated.
The value of \*(<:n\*(:> must be an integer, but \*(<:x\*(:> may be of any type.
.Bl 7
.Us 7 C. Functions on texts, lists and tables
.Qr
\*(<:keys t\*(:>
.Qe
requires a table as operand, and returns a list of all keys
in the table.
For example, \*(<:keys {[1]: 1; [4]: 2; [9]: 3} = {1; 4; 9}\*(:>.
.Qr
\*(<:#t\*(:>
.Qe
accepts texts, lists and tables.
For a text operand, its length is returned, and
for a list or table operand, the number of
entries is returned (where duplicates in lists are counted).
.Qr
\*(<:e#t\*(:>
.Qe
accepts texts, lists and tables for the right operand.
.br
For a text operand, the first operand must
be a character, and the number of times the character
occurs in the text is returned.
For example, \*(<:'i'#'mississippi' = 4\*(:>.
.br
For a list operand, the number of entries is returned
that are equal to the first operand
(which must be of the same type as the list entries.)
.br
For example, \*(<:3#{1; 3; 3; 4} = 2\*(:>.
.br
.??
For a table operand, the number of \fIassociates\fP is returned
that are equal to the first operand
(which must be of the same type as the associates in the table.)
For example, \*(<:3#{[1]: 3; [2]: 4; [3]: 3} = 2\*(:>.
.Qr
\*(<:min t\*(:>
.Qe
accepts texts, lists and tables.
For a text operand, its smallest (in the ASCII order) character is returned,
for a list operand, its smallest
entry is returned, and
for a table operand, its smallest
\fIassociate\fP
.??
is returned.
For example, \*(<:min 'uscule' = 'c'\*(:>,
\*(<:min{1; 3; 3; 4} = 1\*(:>, and
\*(<:min{[1]: 3; [2]: 4; [3]: 3} = 3\*(:>.
The text, list or table must not be empty.
.br
To get the smallest \fIkey\fP of a table \*(<:t\*(:>,
use \*(<:min keys t\*(:>.
.Qr
\*(<:e min t\*(:>
.Qe
accepts texts, lists and tables for the right operand.
.br
For a text operand,
the first operand
must
be a character, and the smallest character in the text
\fIexceeding\fP
that character is returned.
For example, \*(<:'i' min 'mississippi' = 'm'\*(:>.
.br
For a list operand, the smallest
entry is returned exceeding the first operand
(which must be of the same type as the list entries.)
For example, \*(<:3 min {1; 3; 3; 4} = 4\*(:>.
.br
For a table operand, the smallest associate
is returned exceeding the first operand
(which must be of the same type as the associates in the table.)
For example, \*(<:3 min {[1]: 3; [2]: 4; [3]: 3} = 4\*(:>.
.br
There must be a character, list entry or table associate exceeding
the first operand.
.Qr
\*(<:max t\*(:> and
.br
\*(<:e max t\*(:>
.Qe
.Qe
are like \*(<:min\*(:>, except that they return the largest
element, and in the dyadic case the largest element
that is less than the first operand.
For example, \*(<:'m' max 'mississippi' = 'i'\*(:>.
.Qr
\*(<:n th'of t\*(:>
.Qe
requires an integer in \*(<:{1..#t}\*(:> for the left operand, and
accepts texts, lists and tables for the right operand.
It returns the \*(<:n\*(:>'th character, list entry or associate.
.br
In fact, \*(<:n th'of t\*(:>, for a text \*(<:t\*(:>, is written as easily
\*(<:t@n|1\*(:>.
For a table, it is the same as \*(<:t[n th'of (keys t)]\*(:>,
which is something different from \*(<:t[n]\*(:>, unless,
of course, \*(<:keys t = {1..#t}\*(:>.
For a list,
\*(<:1 th'of t\*(:> is \*(<:min t\*(:>.
.Se 2  6.1.7 REFINED-EXPRESSIONS
.Xx expression-refinement
.Xx scratch-pad copy
.Xx return-command
.Sy  2
.Pr refined-expression 2
.Sl
tag
.Ps 
The tag of a refined-expression must occur as
the tag of one
expression-refinement in the unit
in which it occurs.
.Sx 3 \k1refined-expression:
\*(<:stack'pointer\*(:>
.Xe
.Tx
A refined-expression is
evaluated in the following steps:
.in \w'2.\ 'u
.ti 0
1.\ A copy is made of the current environment (the value of
all targets), and all computations during the evaluation of
the expression will take place in this ``scratch-pad copy''.
.ti 0
2.\ The command-suite of the corresponding
expression-refinement is executed.
.in 0
The evaluation of the refined-expression is complete when the execution
of this command-suite terminates because of the execution of a return-command;
the value of the refined-expression is the value returned.
.Sa
expression-refinements (4.4).
.Se 4 6.2 TARGETS
.Xx compound
.Sy  4
.Pr target 4
.Al
single-target
.Al
multiple-target
.Pr single-target 3
.Al
basic-target
.Al
\*(<:(\*(:> target \*(<:)\*(:>
.Pr basic-target 4
.Al
tag
.Al
trimmed-text-target
.Al
table-selection-target
.Tx
For the use of a tag as target, see below under IDENTIFIERS.
For other kinds of targets, see below under the appropriate heading.
.Pr multiple-target 1
.Al
single-target\*(<:,\*(:> single-target
.Al
single-target\*(<:,\*(:> multiple-target
.Ex 3
\k1multiple-targets:
\h'|\n1u'\*(<:nn, t2\*(:>
\h'|\n1u'\*(<:(x0, y0), (x1, y1), (x2, y2), (x3, y3)\*(:>
.Xe
.Tx
If a value is put in a multiple-target, the value must be
a compound with as many fields as there are single-targets
separated by commas in the multiple-target.
The successive fields are then put in the
successive single-targets.
If it makes a difference in what order the fields are put in
the single-targets (as in \*(<:PUT 1, 2 IN x, x\*(:>
where the final value of \*(<:x\*(:> might be either \*(<:1\*(:> or \*(<:2\*(:>),
an error is reported {{but this is currently not checked}}.
.br
Note that the meaning of \*(<:PUT a, b IN b, a\*(:>
is well defined (provided that \*(<:a\*(:> and \*(<:b\*(:> are defined and have
values of the same type):
first the value of the expression \*(<:a, b\*(:> is determined,
and that value is next put in \*(<:b, a\*(:>.
Note also that the meaning of \*(<:PUT t[i], t[j] IN t[j], t[i]\*(:>
is well defined, even if \*(<:i\*(:> and \*(<:j\*(:> have the same value.
For although in this case a value is put twice in the same
target, that value is the same each time, so the order does not matter.
.Se 2  6.2.1 IDENTIFIERS
.Xx tag
.Xx target
.Xx location
.Xx local
.Sy  2
.Pr identifier 4
.Al
single-identifier
.Al
multiple-identifier
.Pr single-identifier 3
.Al
tag
.Al
\*(<:(\*(:> identifier \*(<:)\*(:>
.Pr multiple-identifier 1
.Al
single-identifier\*(<:,\*(:> single-identifier
.Al
single-identifier\*(<:,\*(:> multiple-identifier
.Eo 6 identifiers:\0\0\0\0\0\0\0\0\0\0\0\k2single-identifiers:
\h'|\n1u'\*(<:a\*(:>\h'|\n2u'\*(<:a\*(:>
\h'|\n1u'\*(<:(a)\*(:>\h'|\n2u'\*(<:(a)\*(:>
\h'|\n1u'\*(<:(a, b, (c, d))\*(:>\h'|\n2u'\*(<:(a, b, (c, d))\*(:>
\h'|\n1u'\*(<:a, b, (c, d)\*(:>
.Xe
.Tx
All identifiers can be used as targets, but the converse is
not true.
For example,
.Di 1
\*(<:FOR a[1] IN {1..3}: WRITE a\*(:>
.Ed
is wrong, because \*(<:a[1]\*(:>, although a target, is not an identifier.
If something is put in a target that is a tag, and no
location for that tag exists already, it is created first.
If the location is created locally (the tag did not occur in
an immediate command and was not listed in a share-heading),
the location will cease to exist when the current unit is exited.
For putting in multiple-identifiers, see multiple-targets in section 6.2.
.Se 2  6.2.2 TRIMMED-TEXT-TARGETS
.Sy  2
.Pr trimmed-text-target 3
.Al
target \*(<:@\*(:> right-expression
.Al
target \*(<:|\*(:> right-expression
.Ps\"(The \*(<:|\*(:> in the last line is not the BNF choice indicator, but should be takenliterally.)
.Ex 6
\k1trimmed-text-targets:
\h'|\n1u'\*(<:t@p\*(:>
\h'|\n1u'\*(<:t|1\*(:>
\h'|\n1u'\*(<:t|q@p\*(:>
\h'|\n1u'\*(<:t@p|(q-p+1)\*(:>
.Xe
.Tx
The target must hold a text T, and the value
of the right-expression must be an integer N.
.br
If the sign used is \*(<:@\*(:>, then the
trimmed-text-target indicates a location consisting of the
positions of T starting with the N'th position.
N must be at least 1 and at most one more than the length of T.
For example, after
.Di 2
\*(<:PUT 'computer' IN tt
PUT 'ass' IN tt@5\*(:>
.Ed
\*(<:tt\*(:> will contain the text \*(<:'compass'\*(:>.
.br
If the sign used is \*(<:|\*(:>, then the
trimmed-text-target indicates a location
consisting of the first N characters of T.
N must be at least 0 and at most equal to the length of T.
For example, after
.Di 2
\*(<:PUT 'computer' IN tt
PUT 'ne' IN tt|4\*(:>
.Ed
\*(<:tt\*(:> will contain the text \*(<:'neuter'\*(:>.
.Bl 1
Note that the target itself may be a trimmed-text-target
again.
For example, after
.Di 2
\*(<:PUT 'computer' IN tt
PUT 'm' IN tt@4|1\*(:>
.Ed
\*(<:tt\*(:> will contain the text \*(<:'commuter'\*(:>.
.br
Some useful special cases: \*(<:PUT '' IN t|1\*(:>
removes the first character of the text in \*(<:t\*(:>;
.br
\*(<:PUT '.' IN t@(#t+1)\*(:>
appends a period to the text in \*(<:t\*(:>.
.Se 2  6.2.3 TABLE-SELECTION-TARGETS
.Xx key
.Xx associate
.Xx table entry
.Xx location
.Xx type
.Sy  2
.Pr table-selection-target 2
.Sl
target \*(<:[\*(:> expression \*(<:]\*(:>
.Sx 3 \k1table-selection-target:
\*(<:t[i, j]\*(:>
.Xe
.Tx
The target must contain a table.
The value of the expression is a key K, to be used as selector.
For each key in the table, there is a location for the
corresponding associate.
If K is an existing key of the table, the location for the
table-selection-target is that of the associate corresponding to K.
If a value A is then put in the table-selection-target,
the original associate held in that location is superseded by A.
If K is not an existing key and a value A is to be put in the
table-selection-target, a new location is created, and the
(original) table is made to contain a new table entry
consisting of K and A.
K must be of the same type as the other keys of the
table, and A of the same type as the other associates.
.Se 5 6.3 TESTS
.Xx bound tags
.Xx scratch-pad copy
.Tx
Tests do not return a value, but succeed or fail when
tested.
In \*B, the testing of a test cannot alter the values of targets
that currently exist, nor can it create new targets that survive the test,
with the exception of the temporary survival of bound tags
as described under QUANTIFICATIONS (section 6.3.7) and
REFINED-TESTS (section 6.3.3).
.br
If a test appears to alter an existing target, it effectively modifies
a local, ``scratch-pad''
\fIcopy\fP of that target, and the change is invisible outside the test.
.Sy  6
.Pr test 6
.Al
tight-test
.Al
conjunction
.Al
disjunction
.Al
negation
.Al
quantification
.Pr tight-test 6
.Al
\*(<:(\*(:> test \*(<:)\*(:>
.Al
order-test
.Al
proposition
.Al
refined-test
.Pr right-test 4
.Al
tight-test
.Al
negation
.Al
quantification
.Tx
The various kinds of tests that are distinguished here
serve to define the syntax
in such a way that no parentheses are needed where the meaning is
sufficiently clear.
.Se 7  6.3.1 ORDER-TESTS
.Xx order
.Xx approximate
.Xx exact
.Xx equal
.Xx number
.Sy  7
.Pr order-test 3
.Al
single-expression\0order-sign\0single-expression
.Al
order-test\0order-sign\0single-expression
.Pr order-sign 7
.Al
\*(<:<\*(:>
.Al
\*(<:<=\*(:>
.Al
\*(<:=\*(:>
.Al
\*(<:<>\*(:>
.Al
\*(<:>=\*(:>
.Al
\*(<:>\*(:>
.Ps
(The order-sign \*(<:<>\*(:> stands for ``not equals''.)
.Ex 5
\k1order-tests:
\h'|\n1u'\*(<:(i', j') > (i, j)\*(:>
\&\h'|\n1u'\*(<:'0' <= d <= '9'\*(:>
\h'|\n1u'\*(<:fa <= f(x) >= fb\*(:>
.Xe
The single-expressions are evaluated one by one, from left to right,
and each adjacent pair is compared.
As soon as a comparison does not comply with the given order-sign,
the whole order-test fails and no further single-expressions are evaluated.
The order-test succeeds if all comparisons comply with the
specified order-signs.
.br
Note carefully that an approximate number is \fInever\fP equal to an exact
number, so, for instance, if you want to compare an approximate number \*(<:a\*(:>
for equality with an exact number \*(<:e\*(:>, you should write
.Di 1
\*(<:IF a = ~e:\*(:>\ ...
.Ed
.br
This also allows you to test if a number is exact or not:
.Di 3
\*(<:SELECT:
    x = ~x: WRITE 'Approximate'
    ELSE: WRITE 'Exact'\*(:>
.Ed
.Se 2  6.3.2 PROPOSITIONS
.Xx proposition
.Xx user-defined predicate
.Xx scratch-pad copy
.Xx test-unit
.Xx report-command
.Xx succeed-command
.Xx fail-command
.Xx text, list or table
.Sy  2
.Pr zeroadic-proposition 2
.Sl
zeroadic-predicate
.Pr monadic-proposition 2
.Sl
monadic-predicate\0actual-operand
.Pr dyadic-proposition 2
.Al
actual-operand\0dyadic-predicate\0actual-operand
.Pr zeroadic-predicate 2
.Sl
tag
.Pr monadic-predicate 2
.Sl
tag
.Pr dyadic-predicate 2
.Sl
tag
.Us 7 Propositions with user-defined predicates
A proposition whose predicate is defined by a test-unit, is
tested in the following steps:
.in \w'2.\ 'u
.ti 0
1.\ A copy is made of the current environment (the value of
all targets), and all computations during the testing of
the proposition will take place in this ``scratch-pad copy''.
.ti 0
2.\ Any local tags in the test-unit that might clash with tags currently
in use are systematically replaced by other tags that do not cause conflict.
.ti 0
3.\ Each actual-operand is evaluated and put in the
corresponding formal-operand, used as a (new)
target.
.ti 0
4.\ The command-suite of the unit, thus modified, is executed.
.in 0
The testing of the proposition is complete when the execution
of this command-suite terminates because of the execution
of a report-, succeed- or fail-command;
the proposition succeeds or fails accordingly.
.Us 7 Propositions with predefined predicates
.Qr
\*(<:e in t\*(:>
.Qe
accepts texts, lists and tables for the right operand.
It succeeds if \*(<:e#t > 0\*(:> succeeds,
in other words, if the value \*(<:e\*(:> occurs in \*(<:t\*(:>.
.Qr
\*(<:e not'in t\*(:>
.Qe
is the same as \*(<:(NOT e in t)\*(:>.
.Se 2  6.3.3 REFINED-TESTS
.Xx scratch-pad copy
.Xx report-command
.Xx succeed-command
.Xx fail-command
.Xx bound tags
.Sy  2
.Pr refined-test 2
.Sl
tag
.Sx 3 \k1refined-test:
\*(<:special'case\*(:>
.Xe
.Tx
A refined-test is
tested in the following steps:
.in \w'2.\ 'u
.ti 0
1.\ A copy is made of the current environment (the value of all targets),
and all computations during the testing of
the test will take place in this ``scratch-pad copy''.
.ti 0
2.\ The command-suite of the corresponding
test-refinement is executed.
.in 0
The testing of the refined-test is complete when the execution
of this command-suite terminates because of the execution
of a report-, succeed- or fail-command, and the refined-test
succeeds or fails accordingly.
.ne 3
.br
Any bound tags set by a for-command or
a quantification (see 6.3.7) at that time will temporarily survive
for those parts that are reachable only by virtue of the outcome of the test.
This is so that you can turn any test into a refined-test with the same effect.
.br
For example, in
.Di 3
\*(<:    IF divisible AND n > d**2: WRITE d
    \*(:>...\*(<:
divisible: REPORT SOME d IN {2..n-1} HAS n mod d = 0\*(:>,
.Ed
the bound tag \*(<:d\*(:> is set to a divisor of \*(<:n\*(:> if the
refined-test succeeds, and since the part \*(<:n > d**2\*(:>
is only reached after success, \*(<:d\*(:> may be used there.
The same is true for the write-command using \*(<:d\*(:>.
The line after (indicated with three dots), however, can be
reached if the divisibility test fails.
So there \*(<:d\*(:> has ceased to exist.
.Sa
test-refinements (4.4).
.Se 2  6.3.4 CONJUNCTIONS
.Sy  2
.Pr conjunction 3
.Al
tight-test \*(<:AND\*(:> right-test
.Al
tight-test \*(<:AND\*(:> conjunction
.Ex 4
\k1conjunctions:
\h'|\n1u'\*(<:a > 0 AND b > 0\*(:>
\h'|\n1u'\*(<:i in keys t AND t[i] in keys u AND u[t[i]] <> 'dummy'\*(:>
.Xe
.Tx
The tests of the conjunction, separated by \*(<:AND\*(:>, are tested
one by one, from left to right.
As soon as one of these tests fails,
the whole conjunction fails and no further parts
are tested.
The conjunction succeeds if all its tests succeed.
.Se 2  6.3.5 DISJUNCTIONS
.Sy  2
.Pr disjunction 3
.Al
tight-test \*(<:OR\*(:> right-test
.Al
tight-test \*(<:OR\*(:> disjunction
.Ex 4
\k1disjunctions:
\h'|\n1u'\*(<:a <= 0 OR b <= 0\*(:>
\h'|\n1u'\*(<:n = 0 OR s[1] = s[n] OR t[1] = t[n]\*(:>
.Xe
.Tx
The tests of the disjunction, separated by \*(<:OR\*(:>, are tested
one by one, from left to right.
As soon as one of these tests succeeds,
the whole disjunction succeeds and no further parts
are tested.
The disjunction fails if all its tests fail.
.Se 2  6.3.6 NEGATIONS
.Sy  2
.Pr negation 2
.Sl
\*(<:NOT\*(:> right-test
.Sx 3 \k1negation:
\*(<:NOT a subset b\*(:>
.Xe
.Tx
A negation succeeds if its right-test fails, and fails if
that test succeeds.
.Se 3  6.3.7 QUANTIFICATIONS
.Xx bound tags
.Xx text, list or table
.Xx character
.Xx list entry
.Xx associate
.Sy  3
.Pr quantification 2
.Sl
quantifier\0ranger \*(<:HAS\*(:> right-test
.Pr quantifier 4
.Al
\*(<:SOME\*(:>
.Al
\*(<:EACH\*(:>
.Al
\*(<:NO\*(:>
.Pr ranger 3
.Al
in-ranger
.Al
parsing-ranger
.Pr parsing-ranger 3
.Sl
multiple-identifier \*(<:PARSING\*(:> expression
.Ps
Note that the identifier of a parsing-ranger must be a multiple-identifier
(like \*(<:p, q, r\*(:>):
it may not be a single-identifier (like \*(<:pqr\*(:>).
Moreover, each of the single-identifiers (like \*(<:p\*(:>) must be
plain tags.
The reason is that this determines the number of parts
which the value of the expression must be split into (see below).
.Bl 1
(For in-rangers, see for-commands, section 5.2.4.)
.Ex 5
\k1quantifications:
\h'|\n1u'\*(<:SOME p, q, r PARSING line HAS q in {'. '; '? '; '! '}\*(:>
\h'|\n1u'\*(<:EACH i, j IN keys t HAS t[i, j] = t[j, i]\*(:>
\h'|\n1u'\*(<:NO d IN {2..n-1} HAS n mod d = 0\*(:>
.Xe
.Tx
The tags of the identifier of a quantifier may not be used as targets
or target-contents
outside such a quantifier.
They are ``bound tags'', and lose their meaning outside the
quantifier, except as described below.
.Bl 2
The meaning of quantifications will first be described for
the case of \*(<:SOME\*(:>\ ...\ \*(<:IN\*(:>\ ...
.br
The value of the expression must be a text, list or table.
The items (characters, list entries or associates) of that value are
assigned one by one to the identifier, and the right-test is
tested each time.
The quantification succeeds as soon as
the right-test succeeds once.
It fails only if the text, list or table is exhausted and the
right-test has failed each time.
.br
If the quantification succeeds,
the bound tags set at that moment
will temporarily survive and may be used
in those parts that are reachable only by virtue of the
outcome of the test.
.br
For example, in
.Di 3
\*(<: IF (SOME d IN {2..n-1} HAS n mod d = 0) AND n > d**2: WRITE d
\*(:>\ ...
.Ed
the bound tag \*(<:d\*(:> is set to a divisor of \*(<:n\*(:> if the
quantification succeeds, and since the part \*(<:n > d**2\*(:>
is only reached after success, \*(<:d\*(:> may be used there.
The same is true for the write-command using \*(<:d\*(:>.
So, if \*(<:n\*(:> has the value \*(<:77\*(:>, \*(<:7\*(:> will be written, since
the test \*(<:n mod d = 0\*(:> succeeds the first time when
\*(<:d\*(:> is set to \*(<:7\*(:> (and \*(<:77 > 7**2\*(:>).
The line after (indicated with three dots), however, can be
reached if the divisibility test fails.
So there \*(<:d\*(:> has ceased to exist and may not be used.
.sp
The meaning of a quantification \*(<:SOME id IN tlt HAS prop\*(:>
can also be described as the meaning of the refined-test
\*(<:test'if'some\*(:>, given
a test-refinement
.Di 4
\*(<:test'if'some:
    FOR id IN tlt:
        IF prop: SUCCEED
    FAIL\*(:>
.Ed
.Bl 3
The meaning of \*(<:EACH id IN tlt HAS prop\*(:>
is the same as that of \*(<:NOT SOME id IN tlt HAS NOT prop\*(:>.
In other words, an \*(<:EACH\*(:> quantification succeeds only if its
right-test succeeds each time.
.br
The meaning of \*(<:NO id IN tlt HAS prop\*(:>
is the same as that of \*(<:NOT SOME id IN tlt HAS prop\*(:>.
In other words, a \*(<:NO\*(:> quantification succeeds only if its
right-test fails each time.
.br
The rules for temporary survival are the same as for \*(<:SOME\*(:>.
So an \*(<:EACH\*(:> or \*(<:NO\*(:> quantification will only have set its
bound tags on failure.
Thus, in the following, the bound tag \*(<:d\*(:> survives into the \*(<:ELSE\*(:>:
.Di 4
\*(<:SELECT:
    NO d IN {2..n-1} HAS n mod d = 0:
        WRITE 'prime'
    ELSE: WRITE 'divisible by `d`'\*(:>
.Ed
.Bl 3
If \*(<:PARSING\*(:> is specified,
all \fIparsings\fP of the value of the given expression are
tried, instead of its items.
The value of the expression must be a text.
A ``parsing'' of a text is a way of splitting it in parts.
The text is split in all possible ways in as many parts as
there are tags in the multiple-identifier, and each split
is put in that identifier, whereupon the right-test is tested.
For example,
.Di 1
\*(<:SOME p, q, r PARSING 'abracadabra' HAS (p = r AND #p > 3)\*(:>
.Ed
will succeed with \*(<:p\*(:> and \*(<:r\*(:> set to \*(<:'abra'\*(:> and \*(<:q\*(:> set to \*(<:'cad'\*(:>.
If the test \*(<:#p > 3\*(:> is omitted, the quantification will
succeed with the uninteresting result that \*(<:p\*(:> and \*(<:r\*(:> are set
to \*(<:''\*(:> and \*(<:q\*(:> to \*(<:'abracadabra'\*(:>.
.br
To give another example,
.Di 3
\*(<:    PUT 'a man, a plan, a canal: panama!' IN palindrome
    WHILE SOME hd, x, tl PARSING palindrome HAS x'non'letter:
        PUT hd^tl IN palindrome
    WRITE palindrome /
x'non'letter: REPORT #x = 1 AND x not'in {'a'..'z'}\*(:>
.Ed
will successively find and remove all non-letters from the
text in \*(<:palindrome\*(:> finally leaving the text \*(<:'amanaplanacanalpanama'\*(:>.
(This is not a recommended way, because it will be very slow.
There are equally simple and much faster ways to achieve the same effect.
The example is only chosen to illustrate the possibilities of \*(<:PARSING\*(:>.)
Note that the test \*(<:#x = 1\*(:> here is essential.
If it is omitted, the program will go
into an endless loop ``removing'' empty texts \*(<:x\*(:> from \*(<:palindrome\*(:>.
.br
The meaning of \*(<:SOME p, q,\*(:>\ ...\ \*(<:PARSING whole HAS prop\*(:>
may more precisely be described as follows.
Let \*(<:parsings\*(:> stand for a list, containing
\fIall\fP compounds with the same number of fields as the
multiple-identifier \*(<:p, q,\*(:>\ ..., such that those fields
(which are texts) joined together give the text \*(<:whole\*(:>.
For example, in
.Di 1
\*(<:SOME p, q, r PARSING 'abracadabra' HAS (p = r AND #p > 3)\*(:>
.Ed
the list \*(<:parsings\*(:> will begin with
.Di 1
\*(<:{('', '', 'abracadabra'); ('', 'a', 'bracadabra');\*(:>\ ...\ ,
.Ed
contain somewhere in the middle
.Di 1
\&...\ \*(<:; ('abra', 'cad', 'abra');\*(:>\ ...\ ,
.Ed
and end with
.Di 1
\&...\ \*(<:; ('abracadabr', 'a', ''); ('abracadabra', '', '')}\*(:>.
.Ed
The effect of the quantification is then the same as that
of
.Di 1
\*(<:SOME p, q,\*(:>\ ...\ \*(<:IN parsings HAS prop\*(:>.
.Ed
The meaning of \*(<:EACH\*(:> or \*(<:NO\*(:> is accordingly defined.
.Sa
for-commands (5.2.4).
.ps 10
.vs 12
.de PH\"Page Header
.ie \\n+(cl<3 \{\
.po +\\n(TWu/3u
.rt
.ns \}
.el \{\
.po \\n(POu
.nr f1 \\n(.f\"	current font
.ft
.nr f2 \\n(.f\"	previous font
.ft R
.nr sp \\n(.s\"current point size
.ps \\n(ms-1   
'bp
.CM \" Cut Mark
'ie o 'tl ''\\*(TL'\\*(Sn'
'el   'tl '\\*(Sn'\\*(TL''
.ft \\n(f2\"	restore previous font
.ft \\n(f1\"	restore current font
.ps \\n(sp\"restore point size
'sp 2
.mk
'ns
'EH\"Extra Header
'nr cl 0 1 \}
'na
..
.ch PH
.wh -(\n(HFu-1v) PH
.de Fo\" Page footer
.nr f1 \\n(.f\"	current font
.ft
.nr f2 \\n(.f\"	previous font
.ft R
.nr sp \\n(.s\"current point size
.ps \\n(ms-1
.po \\n(POu
.if \\n%>2 .tl ''%''
.po
.ft \\n(f2\"	restore previous font
.ft \\n(f1\"	restore current font
.ps \\n(sp\"restore point size
..
.de XX
.br
.ti 0
..
.ds Sn Index
.nr cl 4 1
.ll \n(TWu/3u-2n
.na
.bp
.Us 3 INDEX
.mk
.in 2n
.XX
actual-operand 6.1.6
.XX
actual-parameter 5.1.16
.XX
alternative-sequence 5.2.2
.XX
alternative-suite 5.2.2
.XX
ambiguity 6.1.5, 6.1.6
.XX
approximate 6.3.1
.XX
approximate-constant 6.1.1
.XX
approximate number 1
.XX
associate 1, 5.1.6, 5.2.4, 6.1.4, 6.1.5, 6.1.6, 6.2.3, 6.3.7
.XX
basic-expression 6.1
.XX
basic-target 6.2
.XX
bound tags 5.1.13, 5.1.14, 5.1.15, 5.2.4, 6.3, 6.3.3, 6.3.7
.XX
brackets 6.1.6
.XX
character 1, 5.1.6, 5.2.4, 6.1.5, 6.1.6, 6.3.7
.XX
check-command 5.1.1
.XX
choose-command 5.1.6
.XX
command 5
.XX
command-refinement 4.4, 5.1.11, 5.1.17
.XX
command-sequence 4.5
.XX
command-suite 4.5
.XX
comment 3
.XX
compound 1, 6.1, 6.2
.XX
conjunction 6.3.4
.XX
control-command 5.2
.XX
conversion 6.1.5
.XX
convert to a text 5.1.2, 6.1.5, 6.1.6
.XX
decrease-indentation 3
.XX
delete-command 5.1.10
.XX
denominator 6.1.6
.XX
digit 6.1.1
.XX
disjunction 6.3.5
.XX
display 6.1.5
.XX
draw-command 5.1.5
.XX
dyadic 4.2, 4.3
.XX
dyadic-formula 6.1.6
.XX
dyadic-function 6.1.6
.XX
dyadic-predicate 6.3.2
.XX
dyadic-proposition 6.3.2
.XX
else-alternative 5.2.2
.XX
empty 2
.XX
empty list 6.1.5
.XX
empty table 6.1.5
.XX
entry 1
.XX
equal 6.3.1
.XX
exact 6.3.1
.XX
exact-constant 6.1.1
.XX
exact number 1
.XX
exponent-part 6.1.1
.XX
expression 6.1
.XX
expression-refinement 4.4, 4.5, 5.1.12, 6.1.7
.XX
fail-command 4.5, 5.1.15, 6.3.2, 6.3.3
.XX
field 1
.XX
for-command 5.2.4
.XX
formal-dyadic-formula 4.2
.XX
formal-dyadic-proposition 4.3
.XX
formal-formula 4.2
.XX
formal-monadic-formula 4.2
.XX
formal-monadic-proposition 4.3
.XX
formal-operand 4.2
.XX
formal-parameter 4.1
.XX
formal-proposition 4.3
.XX
formal-tail 4.1
.XX
formal-trailer 4.1
.XX
formal-user-defined-command 4.1
.XX
formal-zeroadic-formula 4.2
.XX
formal-zeroadic-proposition 4.3
.XX
formula 4.2, 4.3, 6.1.6
.XX
fractional-part 6.1.1
.XX
function 4.2, 4.3, 6.1.6
.XX
further-comment 3
.XX
global 4.5, 5
.XX
how-to-unit 4.1, 5.1.11, 5.1.16
.XX
identifier 6.2.1
.XX
if-command 5.2.1
.XX
immediate command 5, 5.1.11
.XX
in-ranger 5.2.4
.XX
increase-indentation 3
.XX
indentation 3
.XX
insert-command 5.1.9
.XX
integer 6.1.3, 6.1.5, 6.1.6
.XX
integral-part 6.1.1
.XX
interrupt key 5, 5.1.2
.XX
key 1, 6.1.4, 6.1.5, 6.1.6, 6.2.3
.XX
keyword 3, 4.1, 4.4, 5.1.16, 5.1.17
.XX
list 1
.XX
list-body 6.1.5
.XX
list-display 6.1.5
.XX
list entry 1, 5.1.6, 5.1.8, 5.1.9, 5.2.4, 6.1.6, 6.3.7
.XX
list-filler 6.1.5
.XX
list-filler-series 6.1.5
.XX
local 4.5, 6.1.6, 6.2.1
.XX
location 5.1.4, 5.1.10, 6.2.1, 6.2.3
.XX
monadic 4.2, 4.3
.XX
monadic-formula 6.1.6
.XX
monadic-function 6.1.6
.XX
monadic-predicate 6.3.2
.XX
monadic-proposition 6.3.2
.XX
multiple-expression 6.1
.XX
multiple-identifier 6.2.1
.XX
multiple-target 6.2
.XX
negation 6.3.6
.XX
new-line 3
.XX
new-line-proper 3
.XX
new-liners 5.1.2
.XX
number 1, 5.1.5, 6.1.6, 6.3.1
.XX
numerator 6.1.6
.XX
numeric-constant 6.1.1
.XX
optional-ANYTHING 2
.XX
order 1, 6.3.1
.XX
order-sign 6.3.1
.XX
order-test 6.3.1
.XX
overloading of functions and predicates 4.2, 4.3
.XX
parentheses 6.1.6
.XX
parsing-ranger 6.3.7
.XX
permanent environment 4.5, 5.1.2, 5.1.11
.XX
plusminus 6.1.1
.XX
predefined functions 6.1.6
.XX
predefined predicates 6.3.2
.XX
predicate 4.2, 4.3
.XX
priority 6.1.6
.XX
proposition 4.3, 6.3.2
.XX
put-command 5.1.4
.XX
quantification 6.3.7
.XX
quantifier 6.3.7
.XX
quit-command 5.1.11, 5.1.16, 5.1.17
.XX
quote 6.1.5
.XX
random 5.1.5, 5.1.6, 5.1.7
.XX
ranger 6.3.7
.XX
read-command 5.1.3
.XX
refined-command 5.1.17
.XX
refined-expression 5.1.12, 6.1.7
.XX
refined-test 5.1.13, 5.1.14, 5.1.15, 6.3.3
.XX
refinement 4.4
.XX
refinement-suite 4
.XX
remove-command 5.1.8
.XX
report-command 4.5, 5.1.13, 6.3.2, 6.3.3
.XX
return-command 4.5, 5.1.12, 6.1.6, 6.1.7
.XX
right-expression 6.1
.XX
right-test 6.3
.XX
scratch-pad copy 6.1, 6.1.6, 6.1.7, 6.3, 6.3.2, 6.3.3
.XX
select-command 5.2.2
.XX
set-random-command 5.1.7
.XX
share-heading 4.5
.XX
simple-command 5.1
.XX
simple-expression 6.1
.XX
single-alternative 5.2.2
.XX
single-expression 6.1
.XX
single-identifier 6.2.1
.XX
single-target 6.2
.XX
spaces 3
.XX
succeed-command 4.5, 5.1.14, 6.3.2, 6.3.3
.XX
table 1
.XX
table-display 6.1.5
.XX
table entry 1, 5.1.10, 6.1.4, 6.2.3
.XX
table-filler 6.1.5
.XX
table-filler-series 6.1.5
.XX
table-selection 6.1.4
.XX
table-selection-target 5.1.10, 6.2.3
.XX
tag 3, 6.2.1
.XX
target 4.5, 5.1.4, 5.2.4, 6.1.6, 6.2, 6.2.1
.XX
target-content 6.1.2
.XX
terminating-command 5.1, 5.2.3
.XX
test 4.3, 6.3
.XX
test-refinement 4.4, 4.5, 5.1.13, 5.1.14, 5.1.15
.XX
test-unit 4.3, 4.5, 5.1.13, 5.1.14, 5.1.15, 6.3.2
.XX
text 1, 6.1.6
.XX
text, list and table 5.1.6, 5.2.4, 6.1.6, 6.3.2, 6.3.7
.XX
text-display 6.1.5
.XX
tight-expression 6.1
.XX
tight-test 6.3
.XX
trailer 5.1.16
.XX
trimmed-text 6.1.3
.XX
trimmed-text-target 6.2.2
.XX
type 5.1.4, 6.2.3
.XX
unit 4
.XX
user-defined-command 4.1, 5.1.16
.XX
user-defined-function 4.2, 5.1.12, 6.1.6
.XX
user-defined-predicate 4.3, 5.1.13, 5.1.14, 5.1.15, 6.3.2
.XX
while-command 5.2.3
.XX
work-space 4, 4.5
.XX
write-command 5.1.2
.XX
yield-unit 4.2, 4.5, 5.1.12, 6.1.6
.XX
zeroadic 4.2, 4.3
.XX
zeroadic-formula 6.1.6
.XX
zeroadic-function 6.1.6
.XX
zeroadic-predicate 6.3.2
.XX
zeroadic-proposition 6.3.2
.rm PH
.wh -0 CM
.bp
