Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » OCL » oclIsTypeOf/oclIsKindOf, OclVoid and OclInvalid
oclIsTypeOf/oclIsKindOf, OclVoid and OclInvalid [message #1008267] Mon, 11 February 2013 11:55 Go to next message
Adrian Price is currently offline Adrian Price
Messages: 57
Registered: July 2009
Member
Good day MDT.OCL,

I am in the process of porting from org.eclipse.ocl_1.2.0 to
org.eclipse.ocl_3.1.0. Many existing constraints seem to have broken,
apparently as a consequence of what appears to be a change in the
*implemented* semantics of oclIsKindOf and oclIsTypeOf. From what I can
tell, in MDT-OCL-1.2.0 (OMG OCL-2.0?), calling either of these methods
against null or invalid returned false; in MDT-OCL-3.1.0 (OMG
OCL-2.3.0/1?), they return now true. We are using the mature API and
evaluator.

According to both OCL-2.0 and OCL-2.3.1 specifications, OclInvalid
conforms to all types and OclVoid conforms to all types (except
OclInvalid in OCL-2.3.1). Thus the new observed behaviour agrees with
the latest OCL spec. and the old behaviour does not. For example:

let list : Sequence(MyType) = {} (or some other expression that yields
null or invalid)
in list->first().oclIsKindOf(MySubType) implies
list->first().oclAsType(MySubType).someOperation()

In MDT-OCL-1.2.0 list->first().oclIsKindOf(MySubType) returned false;
now it returns true, with the result that the constraint now invokes
someOperation() against invalid, which according to the spec. ought to
return invalid but in fact throws a runtime exception - I presume this
is a bug?

So I would like confirmation that the original oclIsKindOf/oclIsTypeOf
behaviour was incorrect, as are all constraints which use unguarded
calls to these methods. By which I mean - if there's any possibility
that the receiver of an oclIsKindOf/oclIsTypeOf call might be null or
invalid, the call should be guarded by a 'not xxx.oclIsUndefined' or the
logical equivalent. In the example above, this might take the form:
in list->notEmpty() and list->first().oclIsKindOf(MySubType) implies
list->first().oclAsType(MySubType).someOperation()

The behaviour that results from OclInvalid and OclVoid conforming to all
user types is somewhat counter-intuitive, though. In Java, 'null
instanceof Type' always returns false whereas OCL constraints which
perform type checking must now explicitly guard against null or invalid
to avoid false positive results, especially when a type cast ensues.

I feel I must be missing something here - if anyone can enlighten me, I
should be greatly obliged.

Thanks & regards,

Adrian Price
TIBCO Software Inc.
Re: oclIsTypeOf/oclIsKindOf, OclVoid and OclInvalid [message #1008268 is a reply to message #1008267] Mon, 11 February 2013 14:06 Go to previous messageGo to next message
Ed Willink is currently offline Ed Willink
Messages: 4098
Registered: July 2009
Senior Member
<html>
<head>
<meta content="text/html; charset=ISO-8859-1"
http-equiv="Content-Type">
</head>
<body bgcolor="#FFFFFF" text="#000000">
Hi<br>
<br>
Interesting.<br>
<br>
The specification:<br>
<br>
2.0: <i>oclIsKindOf(typespec : OclType) : Boolean<br>
Evaluates to true if the self conforms to the type identified by
typespec.</i><br>
2.3.1: <i>oclIsKindOf(type : Classifier) : Boolean<br>
Evaluates to true if the type of self conforms to t. That is, self
is of type t or a subtype of t.</i><br>
(In OCL 2.5, the troublesome argument may become a Metaclass(T)
template analoguous to Java's Class&lt;T&gt;)<br>
<br>
There is essentially no change in OCL 2.0 to 2.3.1. What has also
evolved is the relative conformance of OclVoid and OclInvalid (not
relevant to your problem).<br>
<br>
However there is a conflicting specification that any navigation
from null or invalid is invalid.<br>
<br>
2.0: 7.4.10 <i>In general, an expression where one of the parts is
undefined will itself be undefined.</i><br>
2.3.1: 7.5.11 <i>In general, an expression where one of the parts
is null or invalid will itself be invalid.</i><br>
<br>
7.x is non-normative, in the main spec we only get<br>
<br>
2.0: 11.2.3 <i>Any property call applied on null results in
OclInvalid, except for the operation oclIsUndefined().</i><br>
2.3.1: 11.2.3 <i>Any property call applied on null results in
invalid, except for the oclIsUndefined(), oclIsInvalid(),
=(OclAny) and &lt;&gt;(OclAny) operations.</i><br>
<br>
but this is only for property calls rather than operation calls
despite the excepts being operation calls.<br>
<br>
The Annex that provides the philosophy says <i>An isKindOf type
test expression is<br>
true if the expression value lies within the domain of the
specified target type or one of its subtypes. Note that these type<br>
cast and test expressions also work with undefined values since
every value &#8211; including an undefined one &#8211; has a welldefined<br>
type.</i><br>
<br>
So the specification says: invalid.oclIsKindOf(Boolean) = true<br>
<br>
A challenging case is: aCollection-&gt;select(oclIsKindOf(X)), Are
nulls filtered or not?<br>
<br>
In my opinion all oclXXX operations are non-standard and so their
overloads should be explicitly defined for each of OclVoid and
OclInvalid. (OCL 2.3 at least made the "=" overload explicit.)<br>
<br>
-------------------<br>
<br>
Looking at the code, MDT/OCL 1.2 introduced<br>
<br>
<a class="header"
href="eclipse-javadoc:%E2%98%82=org.eclipse.ocl/src%3Corg.eclipse.ocl.options%7BEvaluationOptions.java%E2%98%83EvaluationOptions%5ELAX_NULL_HANDLING%E2%98%82Option">Option</a>&lt;<a
class="header"
href="eclipse-javadoc:%E2%98%82=org.eclipse.ocl/src%3Corg.eclipse.ocl.options%7BEvaluationOptions.java%E2%98%83EvaluationOptions%5ELAX_NULL_HANDLING%E2%98%82Boolean">Boolean</a>&gt;
org.eclipse.ocl.options.<a class="header"
href="eclipse-javadoc:%E2%98%82=org.eclipse.ocl/src%3Corg.eclipse.ocl.options%7BEvaluationOptions.java%E2%98%83EvaluationOptions">EvaluationOptions</a>.LAX_NULL_HANDLING<br>
<br>
to make the behaviour you identify configurable. The commented
default polarity seems inverted, so I suspect that the default
accidentally took the strict view of the specification rather than
compatibility as the default and you are the first to notice
publicly.<br>
<br>
Setting the option to false gets what you want and as of the Juno
release there is an OCL preference page where you can configure it,
if you don't want to do so programmatically.<br>
<br>
We can't change the MDT/OCL default now since three releases have
been the strict way.<br>
<br>
-------------------<br>
<br>
The OCL behaviour is supposed to be rigorous, but also helpful.<br>
<br>
What you complain about seems unhelpful and unnecessary.<br>
<br>
Your problem is for invalid propagation rather than null, so I think
we just need to give priority to invalid propagation over
conformance.<br>
<br>
-------<br>
<br>
For the Ecore-based OCL that you're using you must adjust the
LAX_NULL_HANDLING option.<br>
<br>
I think that there's enough wriggle room in the specification for
the new Pivot-based OCL to change now by removing the
invoke-with-invalid declaration from oclIsKindOf, oclIsTypeOf,
oclAsType, oclType.<br>
<br>
I've raised an OMG issue for this. Also
<a class="moz-txt-link-freetext" href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=400448">https://bugs.eclipse.org/bugs/show_bug.cgi?id=400448</a>.<br>
<br>
&nbsp;&nbsp;&nbsp; Regards<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Ed Willink<br>
<br>
On 11/02/2013 11:55, Adrian Price wrote:
<blockquote cite="mid:kfam6s$j04$1@xxxxxxxxe.org" type="cite">Good
day MDT.OCL,
<br>
<br>
I am in the process of porting from org.eclipse.ocl_1.2.0 to
org.eclipse.ocl_3.1.0. Many existing constraints seem to have
broken, apparently as a consequence of what appears to be a change
in the *implemented* semantics of oclIsKindOf and oclIsTypeOf.
From what I can tell, in MDT-OCL-1.2.0 (OMG OCL-2.0?), calling
either of these methods against null or invalid returned false; in
MDT-OCL-3.1.0 (OMG OCL-2.3.0/1?), they return now true. We are
using the mature API and evaluator.
<br>
<br>
According to both OCL-2.0 and OCL-2.3.1 specifications, OclInvalid
conforms to all types and OclVoid conforms to all types (except
OclInvalid in OCL-2.3.1). Thus the new observed behaviour agrees
with the latest OCL spec. and the old behaviour does not. For
example:
<br>
<br>
let list : Sequence(MyType) = {} (or some other expression that
yields null or invalid)
<br>
&nbsp; in list-&gt;first().oclIsKindOf(MySubType) implies
<br>
&nbsp;&nbsp;&nbsp; list-&gt;first().oclAsType(MySubType).someOperation()
<br>
<br>
In MDT-OCL-1.2.0 list-&gt;first().oclIsKindOf(MySubType) returned
false; now it returns true, with the result that the constraint
now invokes someOperation() against invalid, which according to
the spec. ought to return invalid but in fact throws a runtime
exception - I presume this is a bug?
<br>
<br>
So I would like confirmation that the original
oclIsKindOf/oclIsTypeOf behaviour was incorrect, as are all
constraints which use unguarded calls to these methods. By which I
mean - if there's any possibility that the receiver of an
oclIsKindOf/oclIsTypeOf call might be null or invalid, the call
should be guarded by a 'not xxx.oclIsUndefined' or the logical
equivalent. In the example above, this might take the form:
<br>
&nbsp; in list-&gt;notEmpty() and
list-&gt;first().oclIsKindOf(MySubType) implies
<br>
&nbsp;&nbsp;&nbsp; list-&gt;first().oclAsType(MySubType).someOperation()
<br>
<br>
The behaviour that results from OclInvalid and OclVoid conforming
to all user types is somewhat counter-intuitive, though. In Java,
'null instanceof Type' always returns false whereas OCL
constraints which perform type checking must now explicitly guard
against null or invalid to avoid false positive results,
especially when a type cast ensues.
<br>
<br>
I feel I must be missing something here - if anyone can enlighten
me, I should be greatly obliged.
<br>
<br>
Thanks &amp; regards,
<br>
<br>
Adrian Price
<br>
TIBCO Software Inc.
<br>
</blockquote>
<br>
</body>
</html>
Re: oclIsTypeOf/oclIsKindOf, OclVoid and OclInvalid [message #1008403 is a reply to message #1008268] Tue, 12 February 2013 10:48 Go to previous messageGo to next message
Adrian Price is currently offline Adrian Price
Messages: 57
Registered: July 2009
Member
Hi Ed,

Thanks, as always, for your quick and informative response - much
appreciated!

I had in fact already seen the 'lax null handling' option and discounted
it on the basis that it seemed to be enabled by default. I've tried
setting it to FALSE but still found there were many constraints failing
which were working just fine in the older OCL runtime. Having stepped
through the code I've formed the tentative conclusion that the option is
in fact correctly labelled and is indeed aiming for backwards
compatibility - but failing to achieve it. Perhaps there are places in
the mature evaluator which ought to be taking account of the option but
aren't?

I accept that there are technical reasons why OclVoid and OclInvalid
both conform to all user types. However, if the logical consequence is
that null/invalid.oclIsKindOf/oclIsTypeOf(UserType) always return true,
in practical terms it means that constraints must always guard
xxx.oclIsKindOf/oclIsTypeOf() with not xxx.oclIsUndefined() - which as
you say, seems unhelpful and unnecessary: constraints become
unnecessarily complex and verbose.

Given that experimentation revealed that many of our existing
constraints fail regardless of the 'lax null handling' setting, do you
think we might be more likely to obtain backwards-compatible behaviour
under the new pivot-based evaluator?

Thanks,

--A
Re: oclIsTypeOf/oclIsKindOf, OclVoid and OclInvalid [message #1008415 is a reply to message #1008403] Tue, 12 February 2013 12:09 Go to previous messageGo to next message
Ed Willink is currently offline Ed Willink
Messages: 4098
Registered: July 2009
Senior Member
Hi

On 12/02/2013 10:48, Adrian Price wrote:
> Given that experimentation revealed that many of our existing
> constraints fail regardless of the 'lax null handling' setting, do you
> think we might be more likely to obtain backwards-compatible behaviour
> under the new pivot-based evaluator?

The new pivot-based behavior is in examples plugins so it has no strong
legacy behaviour; just a goal to the right things for OCL '2.5', so no
it will not be inherently backwards compatible, except that the
behaviour you want is sensible and so can be the forward direction.
However large parts of the behaviour are in the modelled library so you
have the option to define your own OCL Standard Library that replicates
your favourite semantics.

There is very little chance that the Ecore-based behaviour will change;
every tiny change seems to upset somebody.

Regards

Ed
Re: oclIsTypeOf/oclIsKindOf, OclVoid and OclInvalid [message #1009142 is a reply to message #1008415] Thu, 14 February 2013 14:38 Go to previous message
Ed Willink is currently offline Ed Willink
Messages: 4098
Registered: July 2009
Senior Member
Hi

https://bugs.eclipse.org/bugs/show_bug.cgi?id=400448 raised and fixed so
that for the new pivot-based OCL invalid propagates fopr oclIsKindOf,
oclIsTypeOf, oclType and toString.

Only the modeled library and JUnit tests needed changing.

The change improves code generation a little by removing the need for
quite a few try/catch blocks.

Regards

Ed Willink


On 12/02/2013 12:09, Ed Willink wrote:
> Hi
>
> On 12/02/2013 10:48, Adrian Price wrote:
>> Given that experimentation revealed that many of our existing
>> constraints fail regardless of the 'lax null handling' setting, do
>> you think we might be more likely to obtain backwards-compatible
>> behaviour under the new pivot-based evaluator?
>
> The new pivot-based behavior is in examples plugins so it has no
> strong legacy behaviour; just a goal to the right things for OCL
> '2.5', so no it will not be inherently backwards compatible, except
> that the behaviour you want is sensible and so can be the forward
> direction. However large parts of the behaviour are in the modelled
> library so you have the option to define your own OCL Standard Library
> that replicates your favourite semantics.
>
> There is very little chance that the Ecore-based behaviour will
> change; every tiny change seems to upset somebody.
>
> Regards
>
> Ed
>
Previous Topic:[OCLinEcore] Import using metamodel URI
Next Topic:EssentialOCL editing support in papyrus for OrderedSet
Goto Forum:
  


Current Time: Sat Oct 25 21:11:42 GMT 2014

Powered by FUDForum. Page generated in 0.03585 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software