CVS difference for ai12s/ai12-0054-2.txt

Differences between 1.3 and version 1.4
Log of other versions for file ai12s/ai12-0054-2.txt

--- ai12s/ai12-0054-2.txt	2013/07/06 00:01:21	1.3
+++ ai12s/ai12-0054-2.txt	2013/07/06 00:15:19	1.4
@@ -1,5 +1,5 @@
-!standard 3.2.4(14/3)                              13-06-14    AI12-0054-2/02
-!standard 3.2.4(30/3)
+!standard 3.2.4(14/3)                              13-06-15    AI12-0054-2/03
+!standard 3.2.4(31/3)
 !class binding interpretation 13-05-31
 !status work item 13-05-31
 !status received 13-05-02
@@ -17,13 +17,15 @@
 
 AI12-0022-1, "Raise expressions for specifying the exception raised for an
 assertion" added the ability to control which exception is raised by failure of
-various assertions. This is an important capability, because it allows to change
-interfaces to use assertions while preserving compatibility.
+various assertions. This is an important capability, because it allows one to
+change interfaces to use assertions while preserving compatibility.
 
-However, this feature doesn't work properly for predicates, because predicates
-are evaluated by membership tests, so we would get spurious failures. Should
-these spurious failures be removed from the language, so that there is a
-mechanism for specifying the exception raised by a predicate failure? (Yes.)
+However, this feature doesn't work properly for predicates, because
+predicates are evaluated by membership tests, so we would get spurious
+failures in such membership tests if the predicate expression included a
+raise expression. Should these spurious failures be removed from the
+language, so that there is a mechanism for specifying the exception
+raised by a predicate failure? (Yes.)
 
 !recommendation
 
@@ -33,29 +35,62 @@
 
 Add after 3.2.4(14/3):
 
-For a subtype, the following language-defined aspect may be specified with an
+For a subtype with a directly-specified predicate aspect, the following
+additional language-defined aspect may be specified with an
 aspect_specification (see 13.1.1):
 
 Predicate_Failure
-   This aspect specifies an expression that will be evaluated if a predicate
-   check for the subtype fails; it defines the Message associated to the
-   occurrence of Assertion_Error wich is raised by the failure of the condition.
+   This aspect shall be specified by a *string*_expression, which
+   determines the action to be performed when a predicate check fails because a
+   directly-specified predicate aspect of the subtype evaluates to
+   False, as explained below.
 
 Name Resolution Rules
 
-The expected type for a precondition or postcondition expression is String.
+The expected type for the Predicate_Failure expression is String.
 
-Change the end of 3.2.4(31/3) as follows:
-"Assertion_Error is raised {with the message defined by evaluating the
-aspect Predicate_Failure (or the empty string if not specified)} if
-any of these checks fail."
+Remove "Assertion_Error is raised if any of these checks fail." from
+3.2.4(31/3).
 
+Add after 3.2.4(31/3):
+
+If any of predicate checks fail, Assertion_Error is raised, unless the
+subtype whose directly-specified predicate aspect evaluated to False
+also has a directly-specified Predicate_Failure aspect.  In that case, the
+specified Predicate_Failure expression is evaluated; if the evaluation
+of the Predicate_Failure expression propagates an exception occurrence,
+then this occurrence is propagated for the failure of the predicate
+check; otherwise, Assertion_Error is raised, with an associated message
+string defined by the value of the Predicate_Failure expression.
+In the absence of such a Predicate_Failure aspect, an implementation-defined
+message string is associated with the Assertion_Error exception.
+
+NOTE: The example in AI12-0022-1 should be updated to not use a
+predicate expression as an example of where raise_expression should be
+used.
+
 !discussion
 
 Note that Predicate_Failure is not involved when a predicate is evaluated in a
 membership or Valid attribute. This is how we get our cake and eat it too in
 this case.
 
+Originally the Predicate_Failure was suggested as a way to be able to
+specify a different exception to be raised when failing a predicate
+check, without causing an exception to be raised when the predicate
+expression were evaluated as part of a membership test or Valid
+attribute reference. But then it was realized that the
+Predicate_Failure expression could be something other than simply a
+raise expression. In particular, it was suggested that it could specify
+the string to be associated with the predicate failure, even when still
+raising Assertion_Error. Here is a simple example, using
+Predicate_Failure to specify the message string to be associated with
+the Assertion_Error:
+
+   subtype Even_Integer is Integer
+     with Dynamic_Predicate => Even_Integer mod 2 = 0,
+          Predicate_Failure => "Even_Integer must be a multiple of 2";
+
 The expression of the Predicate_Failure aspect can be as simple as a
 string litteral if all that is desired is to change the message; note
 that the current instance of the subtype is visible in the
@@ -68,27 +103,27 @@
 thus achieving the effect of the predicate raising an expression
 different from Assertion_Error.
 
-If it is necessary to raise multiple exceptions for different failures, it is
-necessary to define multiple subtypes. For instance, Text_IO could define
-subtypes like:
+If it is necessary to raise multiple exceptions for different failures,
+or have distinct messages depending on which predicate fails, it is
+necessary to define multiple subtypes. For instance, Text_IO could
+define subtypes like:
 
    subtype Open_File_Type is File_Type
       with Dynamic_Predicate => Is_Open (Open_File_Type),
-           Predicate_Failure => raise Status_Error;
-   subtype Read_File_Type is Open_File_Type
-      with Dynamic_Predicate => Mode (Read_File_Type) = In_File;
-           Predicate_Failure => raise Mode_Error with "Can't read file: " & Name (Read_File_Type);
-
-One could imagine defining similar aspects for the other kinds of contract
-assertions. We didn't do that because those aspects generally aren't combinable,
-so such an aspect would be of limited utility and probably not be worth the
-implementation cost. Moreover, there is no counterpart to the membership that
-causes all of the trouble with predicates. But defining such an aspect would not
-be hard.
+           Predicate_Failure => raise Status_Error with "Already open";
+   subtype Input_File_Type is Open_File_Type
+      with Dynamic_Predicate => Mode (Input_File_Type) = In_File,
+           Predicate_Failure => raise Mode_Error with "Cannot read file: " &
+             Name (Input_File_Type);
+
+One could imagine defining similar aspects for the other kinds of
+contract assertions such as Pre and Post. However, there is no
+counterpart to the membership test or Valid attribute that causes
+the trouble with predicates. But defining such aspects would not be hard.
 
 A simpler alternative would be to simply have a Predicate_Failure_Exception
 aspect, which just specifies the exception. In that case, however, we've
-lost the ability to give an exception message. Thus we prefer the given
+lost the ability to specify an exception message. Thus we prefer the given
 solution.
 
 !ACATS Test

Questions? Ask the ACAA Technical Agent