Subtype Predicates
Author: JTC1/SC22/WG9/ARG, by Randall Brukardt, ARG Editor

Ada Reference Manual — Legal Information

# 3.2.4 Subtype Predicates

1/3
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

2/3
The expected type for a predicate aspect expression is any boolean type.

#### Static Semantics

3/3
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:
4/3
For a (first) subtype defined by a derived type declaration, the predicates of the parent subtype and the progenitor subtypes apply.
5/3
For a subtype created by a subtype_indication, the predicate of the subtype denoted by the subtype_mark applies.
6/3
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).
7/3
Predicate checks are defined to be enabled or disabled for a given subtype as follows:
8/3
If a subtype is declared by a type_declaration or subtype_declaration that includes a predicate specification, then:
9/3
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;
10/3
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;
11/3
otherwise, predicate checks are disabled for the subtype, regardless of whether predicate checking is enabled for any other subtypes mentioned in the declaration;
12/3
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;
13/3
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;
14/3
Otherwise, predicate checks are disabled for the given subtype.

#### Legality Rules

15/3
The expression of a Static_Predicate specification shall be predicate-static; that is, one of the following:
16/3
a static expression;
17/3
a membership test whose simple_expression is the current instance, and whose membership_choice_list meets the requirements for a static membership test (see 4.9);
18/3
a case_expression whose selecting_ expression is the current instance, and whose dependent_ expressions are static expressions;
19/3
a call to a predefined equality or ordering operator, where one operand is the current instance, and the other is a static expression;
20/3
a call to a predefined boolean logical operator, where each operand is predicate-static;
21/3
a short-circuit control form where both operands are predicate-static; or
22/3
a parenthesized predicate-static expression.
23/3
A predicate shall not be specified for an incomplete subtype.
24/3
If a predicate applies to a subtype, then that predicate shall not mention any other subtype to which the same predicate applies.
25/3
An index subtype, discrete_range of an index_constraint or slice, or a discrete_subtype_definition of a constrained_array_definition, entry_declaration, or entry_index_specification shall not denote a subtype to which predicate specifications apply.
26/3
The prefix of an attribute_reference whose attribute_designator is First, Last, or Range shall not denote a scalar subtype to which predicate specifications apply.
27/3
The discrete_subtype_definition of a loop_parameter_specification shall not denote a nonstatic subtype to which predicate specifications apply or any subtype to which Dynamic_Predicate specifications apply.
28/3
The discrete_choice of a named_array_aggregate shall not denote a nonstatic subtype to which predicate specifications apply.
29/3
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

30/3
If predicate checks are enabled for a given subtype, then:
31/3
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.
32/3
A value satisfies a predicate if the predicate is True for that value.
33/3
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.
NOTES
34/3
5 A predicate specification does not cause a subtype to be considered constrained.
35/3
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