One nonstatic operand for a universal real relation AI-00405/06 1
86-12-01 ra WJ
!standard 04.10 (04) 86-12-01 AI-00405/06 |
!class ramification 86-05-13
!status approved by WG9/AJPO 86-11-26
!status approved by Director, AJPO 86-11-26
!status approved by WG9/Ada Board 86-11-18
!status panel/committee-approved 86-08-07 (reviewed)
!status committee-approved (9-0-0) 86-05-13 (pending editorial review)
!status work-item 86-01-24
!status received 85-12-04
!references AI-00103, 83-00659, 83-00665, 83-00736
!topic One nonstatic operand for a universal real relation
!summary 86-06-09
If the operands of a relational operator or membership test have the type
universal_real and one or more of the operands is nonstatic, the static
operands must be evaluated exactly. Doing so, however, does not impose a run
time overhead.
!question 86-03-24
4.10(4) says that "if a universal expression is a static expression, then the
evaluation must be exact." Consider a relational expression
NS = S
where NS is a nonstatic universal real expression and S is a static universal
real expression. 4.10(4) allows NS to be evaluated using the most accurate
floating point type supported by an implementation. Suppose the result of
evaluating NS lies in the model interval M1 .. M2 and suppose S lies just
outside this model interval. Since S has type universal_real, its exact
value is a model number, so the rules in 4.5.7(10) require that NS = S return
FALSE. To return the correct result for "=", S must, in general, be
represented with arbitrary precision at run time, but imposing such a
requirement on an implementation does not seem consistent with the idea that
NS can be evaluated inexactly.
Must a static operand of a such a relational expression be evaluated exactly
if the other operand is nonstatic? (A similar question can be posed for
membership tests.)
!response 86-06-09
There is both a trivial and a less trivial resolution of this problem.
Trivially 4.10(4) refers to "expressions," and in NS = S, for example, NS and
S are not expressions according to the Ada syntax, but rather are simple_
expressions, and possibly terms, factors, or primaries. Since the only
expression involved is NS = S, which is nonstatic, infinite precision is not
required anywhere, by this argument.
However, the intent of the Standard was that the word "expression" in these
contexts should not be interpreted in the strict syntactic sense, but should
be interpreted to refer also to simple_expressions, relations, terms,
factors, and primaries. Furthermore, in such constructs as
One nonstatic operand for a universal real relation AI-00405/06 2
86-12-01 ra WJ
2.0 * PI * X,
the phrase 2.0 * PI is also to be considered an expression for the purposes
of sections 4.9 and 4.10, even though it is not a term, but only a portion of
a term.
Given that established Ada usage does not support the trivial resolution,
there is also a non-trivial resolution that requires no compromise of the
semantics. Suppose NS is a nonstatic universal real expression, and S is a
static universal real expression. Consider the following relation.
NS relation S
The Standard (4.10(4)) indicates that S must be evaluated exactly. It also
indicates (4.5.7(10)) that because the values of S and NS, being of type
universal_real, are both model numbers, the relation itself must be evaluated
exactly using the computed values of S and NS. It might at first seem that
the expression S must be carried to full precision (i.e., as a ratio of
arbitrarily large integers) at run time. This is not, in fact, the case.
Let LONG be the base type for the highest precision floating point numbers
used by a given implementation. By abuse of notation, we shall also use it
to denote the set of all values of type LONG. Let CEIL(x,LONG) be the least
upper bound of the subset of LONG greater than or equal to x. Let
FLOOR(x,LONG) be the greatest lower bound of the subset of LONG less than or
equal to x. These may be undefined beyond the extrema of LONG. There are
two cases, and the one that applies can be determined at compilation time.
1) The value of S is a member of LONG. In this case, the
implementation is obvious.
2) S is not a member of LONG. Convert the relational
expression according to the following table.
---------------------------------------------------
| | |
| Expression | Transformed Expression |
| | |
|-------------------------------------------------|
| | |
| NS > S, NS >= S, | NS > FLOOR(S,LONG), if the |
| S < NS, S <= NS | latter is defined, or |
| | TRUE otherwise |
| | |
|-------------------------------------------------|
| | |
| NS < S, NS <= S | NS < CEIL(S,LONG), if the |
| S > NS, S >= NS | latter is defined, or |
| | TRUE otherwise |
| | |
---------------------------------------------------
One nonstatic operand for a universal real relation AI-00405/06 3
86-12-01 ra WJ
---------------------------------------------------
| | |
| NS = S, S = NS | FALSE |
| | |
|-------------------------------------------------|
| | |
| NS /= S, S /= NS | TRUE |
| | |
---------------------------------------------------
We thus reduce everything to at worst the case of comparing a static member
of LONG to a nonstatic member of LONG. As a consequence, it is possible to
maintain the convenient "semantic fiction" that S is carried to infinite
precision in the comparison without run time cost.