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.
for Static_Predicate: Condition
that must hold true for objects of a given subtype; the subtype may be
for Dynamic_Predicate: Condition
that must hold true for objects of a given subtype; the subtype is not
Name Resolution Rules
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)].
of a Static_Predicate specification shall be predicate-static;
that is, one of the following:
a static expression that
does not raise any exception;
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 both operands are predicate-static; or
A predicate shall not be specified for an incomplete
Reason: The expression
of such a predicate could not depend on the properties of the value of
the type (since it doesn't have any), so it is useless and we don't want
to require the added complexity needed to support it.
This rule prevents non-contiguous dynamically bounded
array aggregates, which could be expensive to check for. (Array aggregates
have rules to prevent problems with static subtypes.) We define this
rule here so that the runtime generic body check 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.
[On every subtype conversion,
the predicate of the target subtype is evaluated, and a check is made
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 made 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 made that the predicate is True. Assertions.Assertion_Error
is raised if any of these checks fail.
are not evaluated at the point of the [sub]type declaration.
Static_Predicate checks can be removed even in the presence of potentially
invalid values, just as constraint checks can be removed.
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.
is the usual way around the contract model; this applies even in generic
A predicate specification does not cause a subtype
to be considered constrained.
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.
Extensions to Ada 2005
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe