Chapter 12 ("The Use of OCL Expressions in UML Models") of the OCL spec
should be of some help. It defines the distinction between "contextual
classifier" (as the type of "self") and the constrained element, which may
be a classifier, operation, property, etc.

"self" always refers to the instance of the contextual classifier; OCL
expressions cannot be defined in the absence of a contextual classifier.
In operation and property constraints, the context declaration specifies an
operation context (which is important as a namespace for parameter
variables) or a property context (which is not a namespace). In both of
these cases, there is an explicit contextual classifier: the name before
the last "::".

Note that OCL allows, for example, an operation constraint to be specified
on a different contextual classifier than the classifier that defines the
operation. This is used to refine the constraints inherited by a
classifier along with the constrained operation. For example, consider

class A
public doit(s : String) : Integer

class B -> A

where B inherits the doit operation from A. You can define constraints on
this operation in both the A and B contexts:

In this example, B provides more guarantees about the operation result (as a
post-condition) than does A for the same operation. In the B context, the
type of "self" is B, not A (which actually defines the operation).

For OCL expressions in a UML model, in general, Chapter 12 indicates that
the element referenced by the Constraint::constrainedElement property is
the context, and its owner (or nearest owning classifier) is the contextual
classifier. The Constraint::context feature has no bearing on OCL.

So, for example, the context of a derivation constraint is the Property in
the constrainedElement collection and the contextual classifier is the
Classifier that owns the property. Transition guards are different; their
contextual classifier is the Classifier, if any, that owns the Statemachine
containing the transition.

In a UML model, the way to define additional constraints on an inherited
feature in some classifier context is to actually *redefine* the feature in
the subtype and constrain it.

HTH,

Christian

Andreas Maier wrote:

> The context defined for the "self" keyword in the OCL spec, and the
> context defined in an OCL "context" keyword does not always seem to be
> the same.
>
> For invariant constraints, it is the same.
>
> For all other kinds of constraints, it does not seem to be the same.
>
> For example, for precondition constraints, the OCL spec defines "self"
> as follows:
>
> > The name self can be used in the expression referring to the object
> > on which the operation was called.
>
> The keyword "context" however seems to specify the operation itself,
> rather than the object on which it is invoked:
>
> context Typename::operationName(param1 : Type1, ... ): ReturnType
> pre : param1 > ...
>
> So in a way, we have two different contexts.
>
> -> Am I missing anything ?
>
> -> Which of the two contexts does the "context" association end of the
> Constraint metaclass reference ? (Always the "self" context ?)
>
> Andy

I should have read chapter 12 earlier ... I did now, and for now it
answered my remaining questions in this area.

Andy

Christian W. Damus wrote:
> Hi, Andy,
>
> Chapter 12 ("The Use of OCL Expressions in UML Models") of the OCL spec
> should be of some help. It defines the distinction between "contextual
> classifier" (as the type of "self") and the constrained element, which may
> be a classifier, operation, property, etc.
>
> "self" always refers to the instance of the contextual classifier; OCL
> expressions cannot be defined in the absence of a contextual classifier.
> In operation and property constraints, the context declaration specifies an
> operation context (which is important as a namespace for parameter
> variables) or a property context (which is not a namespace). In both of
> these cases, there is an explicit contextual classifier: the name before
> the last "::".
>
> Note that OCL allows, for example, an operation constraint to be specified
> on a different contextual classifier than the classifier that defines the
> operation. This is used to refine the constraints inherited by a
> classifier along with the constrained operation. For example, consider
>
> class A
> public doit(s : String) : Integer
>
> class B -> A
>
> where B inherits the doit operation from A. You can define constraints on
> this operation in both the A and B contexts:
>
> context A::doit(s : String) : Integer
> pre: <...>
> pre: <...>
> post: <...>
> context B::doit(s : String) : Integer
> post: <...>
>
> In this example, B provides more guarantees about the operation result (as a
> post-condition) than does A for the same operation. In the B context, the
> type of "self" is B, not A (which actually defines the operation).
>
> For OCL expressions in a UML model, in general, Chapter 12 indicates that
> the element referenced by the Constraint::constrainedElement property is
> the context, and its owner (or nearest owning classifier) is the contextual
> classifier. The Constraint::context feature has no bearing on OCL.
>
> So, for example, the context of a derivation constraint is the Property in
> the constrainedElement collection and the contextual classifier is the
> Classifier that owns the property. Transition guards are different; their
> contextual classifier is the Classifier, if any, that owns the Statemachine
> containing the transition.
>
> In a UML model, the way to define additional constraints on an inherited
> feature in some classifier context is to actually *redefine* the feature in
> the subtype and constrain it.
>
> HTH,
>
> Christian
>
> Andreas Maier wrote:
>
>> The context defined for the "self" keyword in the OCL spec, and the
>> context defined in an OCL "context" keyword does not always seem to be
>> the same.
>>
>> For invariant constraints, it is the same.
>>
>> For all other kinds of constraints, it does not seem to be the same.
>>
>> For example, for precondition constraints, the OCL spec defines "self"
>> as follows:
>>
>> > The name self can be used in the expression referring to the object
>> > on which the operation was called.
>>
>> The keyword "context" however seems to specify the operation itself,
>> rather than the object on which it is invoked:
>>
>> context Typename::operationName(param1 : Type1, ... ): ReturnType
>> pre : param1 > ...
>>
>> So in a way, we have two different contexts.
>>
>> -> Am I missing anything ?
>>
>> -> Which of the two contexts does the "context" association end of the
>> Constraint metaclass reference ? (Always the "self" context ?)
>>
>> Andy
>