3.2.4 Subtype Predicates
The language-defined
predicate aspects Static_Predicate
and Dynamic_Predicate may be used to define properties of subtypes. A
predicate specification is an
aspect_specification
for one of the two predicate aspects.
General rules for aspects and
aspect_specifications
are found in Clause
13 (
13.1
and
13.1.1 respectively).
Name Resolution Rules
The expected type for a predicate aspect
expression
is any boolean type.
Static Semantics
A predicate specification
may be given on a
type_declaration
or a
subtype_declaration,
and applies to the declared subtype. In addition, predicate specifications
apply to certain other subtypes:
For a (first) subtype defined by a derived type
declaration, the predicates of the parent subtype and the progenitor
subtypes apply.
The
predicate of a subtype consists of all
predicate specifications that apply, and-ed together; if no predicate
specifications apply, the predicate is True (in particular, the predicate
of a base subtype is True).
Predicate checks are
defined to be
enabled or
disabled for a given subtype as
follows:
if performing checks is required by the
Static_Predicate assertion policy (see
11.4.2)
and the declaration includes a Static_Predicate specification, then predicate
checks are enabled for the subtype;
if performing checks is required by the
Dynamic_Predicate assertion policy (see
11.4.2)
and the declaration includes a Dynamic_Predicate specification, then
predicate checks are enabled for the subtype;
otherwise, predicate checks are disabled
for the subtype, regardless of whether predicate checking is enabled
for any other subtypes mentioned in the declaration;
If a subtype is defined by a derived type declaration
that does not include a predicate specification, then predicate checks
are enabled for the subtype if and only if predicate checks are enabled
for at least one of the parent subtype and the progenitor subtypes;
If a subtype is created by a
subtype_indication
other than in one of the previous cases, then predicate checks are enabled
for the subtype if and only if predicate checks are enabled for the subtype
denoted by the
subtype_mark;
Otherwise, predicate checks are disabled for the
given subtype.
Legality Rules
The
expression
of a Static_Predicate specification shall be
predicate-static;
that is, one of the following:
a static expression;
a call to a predefined equality or ordering operator,
where one operand is the current instance, and the other is a static
expression;
a call to a predefined boolean logical operator,
where each operand is predicate-static;
a short-circuit control form where both operands
are predicate-static; or
A predicate shall not be specified for an incomplete
subtype.
If a predicate applies to a subtype, then that predicate
shall not mention any other subtype to which the same predicate applies.
In addition to the places where Legality Rules normally
apply (see
12.3), these rules apply also in
the private part of an instance of a generic unit.
Dynamic Semantics
If predicate checks
are enabled for a given subtype, then:
On every subtype conversion, the predicate of
the target subtype is evaluated, and a check is performed that the predicate
is True. This includes all parameter passing, except for certain parameters
passed by reference, which are covered by the following rule: After
normal completion and leaving of a subprogram, for each
in out
or
out parameter that is passed by reference, the predicate of
the subtype of the actual is evaluated, and a check is performed that
the predicate is True. For an object created by an
object_declaration
with no explicit initialization
expression,
or by an uninitialized
allocator,
if any subcomponents have
default_expressions,
the predicate of the nominal subtype of the created object is evaluated,
and a check is performed that the predicate is True. Assertions.Assertion_Error
is raised if any of these checks fail.
A value
satisfies a predicate if the predicate
is True for that value.
If any of the above Legality Rules is violated in
an instance of a generic unit, Program_Error is raised at the point of
the violation.
5 A predicate specification does not cause
a subtype to be considered constrained.
6 A Static_Predicate, like a constraint,
always remains True for all objects of the subtype, except in the case
of uninitialized variables and other invalid values. A Dynamic_Predicate,
on the other hand, is checked as specified above, but can become False
at other times. For example, the predicate of a record subtype is not
checked when a subcomponent is modified.
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe