Annotated Ada Reference ManualLegal Information
Contents   Index   References   Search   Previous   Next 

 3.2.4 Subtype Predicates

{AI05-0153-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.
Aspect Description for Static_Predicate: Condition that must hold true for objects of a given subtype; the subtype may be static.
Aspect Description for Dynamic_Predicate: Condition that must hold true for objects of a given subtype; the subtype is not static.

Name Resolution Rules

{AI05-0153-3} The expected type for a predicate aspect expression is any boolean type.

Static Semantics

{AI05-0153-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: 
For a (first) subtype defined by a derived type declaration, the predicates of the parent subtype and the progenitor subtypes apply.
For a subtype created by a subtype_indication, the predicate of the subtype denoted by the subtype_mark applies. 
{AI05-0153-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)]. 

Legality Rules

{AI05-0153-3} The expression 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 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);
a case_expression whose selecting_expression is the current instance, and whose dependent_expressions are static expressions;
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 parenthesized predicate-static expression.
 {AI05-0262-1} A predicate shall not be specified for an incomplete subtype.
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. 
 {AI05-0153-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.
 {AI05-0153-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.
 {AI05-0153-3} {AI05-0262-1} The discrete_subtype_definition of a loop_parameter_specification shall not denote a subtype to which Dynamic_Predicate specifications apply.
 {AI05-0153-3} {AI05-0262-1} The discrete_choice of a named_array_aggregate shall not denote a non-static subtype to which predicate specifications apply.
Reason: {AI05-0262-1} 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. 
 {AI05-0262-1} 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

 {AI05-0153-3} If the assertion policy (see 11.4.2) in effect is Check, then: 
[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.
Ramification: Predicates are not evaluated at the point of the [sub]type declaration. 
Implementation Note: Static_Predicate checks can be removed even in the presence of potentially invalid values, just as constraint checks can be removed. 
 {AI05-0262-1} A value satisfies a predicate if the predicate is True for that value.
 {AI05-0153-3} If any of the above Legality Rules is violated in an instance of a generic unit, Program_Error is raised.
Discussion: This is the usual way around the contract model; this applies even in generic bodies. 
5  {AI05-0153-3} A predicate specification does not cause a subtype to be considered constrained.
6  {AI05-0153-3} 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

{AI05-0153-3} Predicate aspects are new in Ada 2012. 

Contents   Index   References   Search   Previous   Next 
Ada-Europe Ada 2005 and 2012 Editions sponsored in part by Ada-Europe