eclipse-ocl / org.eclipse.ocl

Eclipse Public License 2.0
0 stars 0 forks source link

[evaluator] OclVoid and OclInvalid handling #396

Closed eclipse-ocl-bot closed 3 hours ago

eclipse-ocl-bot commented 3 hours ago

| --- | --- | | Bugzilla Link | 282882 | | Status | CLOSED FIXED | | Importance | P3 normal | | Reported | Jul 08, 2009 12:10 EDT | | Modified | May 27, 2011 06:41 EDT | | Version | 2.0.0 | | Blocks | 156363, 287977 | | Reporter | Laurent Goubet |

Description

I'm currently writing JUnit tests to try and cover the whole "EvaluationVisitorImpl#visitOperationCall" method of the implementation. Yet I stumbled upon incoherencies between the specification (2.0) and the OCL implementation (1.3)... and I cannot make heads or tails of the specification when it comes to defining semantics of operations with null and invalid.

Here is a sample of the current results of some operations :\ ----------8<----------\ null = 'test' == false\ null = null == true\ OclInvalid = 'test' == false\ OclInvalid = OclInvalid == true\ ---------->8----------

The specification tells us in section A2.2, page 189 that the result of the "=" operation should be &#8869; if either argument is equal to &#8869; . What is "&#8869;" ? Section A2.6.1 at page 199 clearly spells out that "the domain of OclVoid is I(OclVoid) = {&#8869;}" which implies that &#8869; is "OclVoid" or "null", or "the undefined value".

This means that "null" = 'test'" should return "null" ? And even worse, "OclInvalid" = 'test'" should return "false" ?

Worse still is that section 11.5.1 at page 143 tells us that "[/] evaluates to OclInvalid if [divider] is equal to 0" while section A2.1.1 at page 186 spells out that "The result of a division by zero is undefined" (or &#8869; in that context).

What this means is : I am totally confused as to what I should have my JUnit expect... unfortunately version 2.2 of the spec is already on its way and I doubt issues can still be taken into account at this point. I believe we should fix the implementation to comply with the specification ... yet I don't know what means "comply with the specification" on that particular issue. What would be your interpretation? Here are a few exemples that can serve as a starting point to try and get to a conclusion as to what should be done (sorry if this doesn't get through well ... This is directly copy/pasted from excel) :

expression      current result  specification   \
                    section page\

A null = 'test' false A2.2 189\ B null = null true A2.2 189\ C OclInvalid = 'test' false A2.2 189\ D OclInvalid = OclInvalid true A2.2 189\ E 1 / 0 OclInvalid A2.1.1 186\ F 1 + null null A2.1.4 188\ G 1 + OclInvalid null A2.1.4 188

Obviously, my preference would be that\ A == false\ B == true\ C == OclInvalid\ D == OclInvalid\ E == OclInvalid\ F == OclInvalid\ G == OclInvalid

which would be going against the specification on all points ... except if I misunderstood something and "&#8869;" is the invalid value.

I'll use the results of the discussions here for the JUnit test I am writing and attach it here afterwards.

eclipse-ocl-bot commented 3 hours ago

By Laurent Goubet on Jul 08, 2009 12:15

I should have expected that the bugzilla wouldn't like that character :(. It's the "perp" character (8869) on http://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references .

eclipse-ocl-bot commented 3 hours ago

By Alexander Igdalov on Jul 08, 2009 13:45

As I see it, this part of the spec is too clever to be understood by a human being;-) Perhaps, this is the reason why it is heavily outdated. Seriously speaking, I think these sections come from the times when the 'null' and 'invalid' literals were not yet separated. The perp character represents an undefined value which according to section A 2.1.1 is aimed to identify both an absence of a value (case 1, null) and an evaluation error (case 2, invalid). AFAIU, the undefined value was later dropped; null and invalid were introduced instead. This is why sections A 2.1.4 and A 2.2 should be treated with caution.\ As for the examples, my preferences are the same as yours.

eclipse-ocl-bot commented 3 hours ago

By Alexander Igdalov on Jul 08, 2009 15:12

Good and bad news! Fortunately, the spec clearly states what to do in cases A-E. Unfortunately, our assumptions on C and D differ from the standard:(\ Cases A-D: 11.2.5, p. 140. Case E: 11.5.1, 11.5.2.\ NB: My preference to evaluate C and D to invalid is because of the following. Take D: invalid = invalid. Seems it is ok to return 'true' in this case (which is what the spec states). However, this must be equivalent to 'exprA = exprB' when both exprA and exprB are invalid. The writer of this expression expected to make a comparison of exprA and exprB, however, there occurred evaluation errors in both exprA and exprB. Unfortunately, after the comparison which returns true according to the spec the traces of errors vanish and the further evaluation is probably incorrect.

eclipse-ocl-bot commented 3 hours ago

By Laurent Goubet on Jul 09, 2009 04:07

(In reply to comment #2)

this part of the spec is too clever to be understood by a human being

that was my conclusion too :p.

(In reply to comment #3)

Good and bad news! Fortunately, the spec clearly states what to do in cases A-E. Unfortunately, our assumptions on C and D differ from the standard:( Cases A-D: 11.2.5, p. 140. Case E: 11.5.1, 11.5.2. NB: My preference to evaluate C and D to invalid is because of the following. Take D: invalid = invalid. Seems it is ok to return 'true' in this case (which is what the spec states). However, this must be equivalent to 'exprA = exprB' when both exprA and exprB are invalid. The writer of this expression expected to make a comparison of exprA and exprB, however, there occurred evaluation errors in both exprA and exprB. Unfortunately, after the comparison which returns true according to the spec the traces of errors vanish and the further evaluation is probably incorrect.

I totally aggree with this and would rather have all calls with "invalid" arguments fail miserably except for oclIsUndefined and oclIsInvalid. That was stated in the 2.0 specification in 11.2.4 (page 138) : "Any property call applied on invalid results in OclInvalid, except for the operations oclIsUndefined() and oclIsInvalid()". Has this statement been altered in 2.2 or can we use it to tell that the new parts they added to have "OclInvalid = OclInvalid return true" is ambiguous and return OclInvalid instead of true to keep the error handling right?

eclipse-ocl-bot commented 3 hours ago

By Ed Willink on Jul 11, 2009 07:37

Let's start by clarifying the terminolgy.

'perp' is bottom and explained much better than I can in http://en.wikipedia.org/wiki/Bottom_type.

Similarly top is explained in http://en.wikipedia.org/wiki/Top_type.

Bottom is the subtype of ALL other types. Bottom is therefore the OclInvalid type which is an instance of the InvalidType meta-type, and which has the sole instance invalid.

The OclVoid type is the subtype of all types except OclInvalid, so the OclVoid type could be called nearly-bottom. OclVoid is an instance of the VoidType meta-type and has the sole instance null.

Top is the supertype of ALL other types. Top is therefore the OclAny type which is an instance of the AnyType meta-type. There is no specially named instance of OclAny.

Appendix A makes an intuitive extension from type theory to use top and bottom symbols for the special instance values as well as their types. As with conventional class/object/instance terminology, the meaning is obvious from context but compounds confusion when you're confused.

invalid is generated/propagated by OCL whenever some tooling is unhappy.

null is (I think) never generated by OCL. null originates from explicit concrete syntax or an absence of model content. Since null is not generated, Appendix A can survive without an update for nearly-bottom. On input, null or invalid trigger bottom behaviour; on output bottom is invalid rather than null.

11.2.3 Any operation on null returns invalid (bottom), except oclIsUndefined() and oclIsInvalid().

therefore: A => invalid, B => invalid, F => invalid

11.2.5 OclVoid= introduces a conflicting a semantic

therefore: B=> true

11.2.4 Any operation on invalid (bottom), returns invalid (bottom), except oclIsUndefined() and oclIsInvalid().

therefore: C => invalid, D => invalid, G=> invalid

11.2.5 OclInvalid= introduces a conflicting a semantic

therefore: D=> true

11.5.1, 11.5.2 E => invalid

The proposed standard seems unclear only on B and D.

As Alex points out in #3, the clarifications in 11.2.5 lead to dangerous results. These conflicts arise from Issue 6611 where the discussion indicates an intent to clarify. I have sent a message to ocl2-rtf to highlight this conflict.

Since the current wording of 2.2 has a clear conflict, we must choose for now and hope that we anticipate the eventual specification. I think we should ignore the Issue 6611 contribution to 11.2.5, which means that we have no 2.2/2.0 divergence on this functionality.

eclipse-ocl-bot commented 3 hours ago

By Alexander Igdalov on Jul 11, 2009 08:39

(In reply to comment #5)

Let's start by clarifying the terminolgy.

'perp' is bottom and explained much better than I can in http://en.wikipedia.org/wiki/Bottom_type.

Similarly top is explained in http://en.wikipedia.org/wiki/Top_type.

Great! Thanks for these links to scientific explanations!

Bottom is the subtype of ALL other types. Bottom is therefore the OclInvalid type which is an instance of the InvalidType meta-type, and which has the sole instance invalid.

In fact, there used to be two bottoms in OCL 2.0 - OclVoid and OclInvalid. In OCL 2.2 there is none, because OclVoid as well as OclInvalid do not conform to each other. See 11.2.3 and 11.2.4.

As Alex points out in #3, the clarifications in 11.2.5 lead to dangerous results. These conflicts arise from Issue 6611 where the discussion indicates an intent to clarify. I have sent a message to ocl2-rtf to highlight this conflict.

Great! Thanks!\

Since the current wording of 2.2 has a clear conflict, we must choose for now and hope that we anticipate the eventual specification. I think we should ignore the Issue 6611 contribution to 11.2.5, which means that we have no 2.2/2.0 divergence on this functionality.

I am also inclined to deviate from the 2.2 standard here. But before that I would like to find out your opinion on the examples. What would be your personal preferences? In particular, do you think that A and B should result in invalid?

eclipse-ocl-bot commented 3 hours ago

By Ed Willink on Jul 11, 2009 15:49

In fact, there used to be two bottoms in OCL 2.0 - OclVoid and OclInvalid. In\ OCL 2.2 there is none, because OclVoid as well as OclInvalid do not conform to\ each other. See 11.2.3 and 11.2.4.

Yes. I didn't read carefully enough.

Oddly VoidType conforms to InvalidType and not vice-versa. But that is a different meta-level.

But OclAny.isOclUndefined() treats invalid as conformant to null, which matches\ my null is nearly bottom idea.

I'll raise another OCL issue suggesting that no bottoms is just as bad as two. There should be just one called invalid. I can also list at least ten places where invalid is incorrectly spelled as Invalid or OclInvalid.


The semantics of operations on null appear very inconsistent, so while I would prefer to keep the current behaviour for A and B, there is nothing in the 2.0 spec to justify the current code and the 2.2 changes just add a contradiction that allows us to 'fix' B but not A.

I guess I need to raise a new issue or elaborate the earlier issue for this.

Supposing this issue was accepted, in order to offer 2.0 compliant behaviour when a user requests strict 2.0 compliance, we must change the 2.0.0 code to behave in a different way to 1.3.0!

This is why we will need fine-grained behaviour control. A user must be able to specify:

OclInvalid conforms to OclVoid: true/false\ OclVoid conforms to OclInvalid: true/false\ OclVoid.=(OclInvalid) returns: false/invalid\ OclVoid.=(OclVoid) returns: true/invalid\ OclVoid.=(OclAny) returns: false/invalid\ OclInvalid.=(OclInvalid) returns: true/invalid\ OclInvalid.=(OclVoid) returns: false/invalid\ OclInvalid.=(OclAny) returns: false/invalid

...

Selection of e.g. MDT-OCL-1.3.0 behaviour can then give the traditional 2.0 behaviour by populating all the options appropriately.

eclipse-ocl-bot commented 3 hours ago

By Ed Willink on Aug 22, 2009 08:34

Seemingly overlooked in the foregoing discussion is that EssentialOCL.g currently implements

"null" => OclVoid instance correct\ "OclVoid " => OclVoid type correct

"OclInvalid" => OclInvalid instance wrong\ "Invalid" => OclInvalid type wrong

OclInvalid and Invalid are interchanged and Invalid is a misspelling of invalid!

I will do these as soon as the 3.0.0 increment bug is +1'd.

eclipse-ocl-bot commented 3 hours ago

By Ed Willink on Aug 22, 2009 10:28

It's not surprising Christian implemented OclInvalid as the instance of Invalid; it's pretty much what Section 8.2.1 says quite a few times.

However Section 11 is much more precisely the other way around, with perhaps definitively a Section heading OclInvalid adjacent to OclVoid both defining M1 types.

Since the OCL 2.0 and imminent 2.1 specifications are so dreadfully worded, perhaps we should provide an enabled by default ParserOption to allow any of invalid/Invalid/OclInvalid as the invalid literal with warnings for Invalid/OclInvalid. This would unfortunately prevent use of Invalid/OclInvalid as variable names or implicit feature names; but who capitalises variable or feature names anyway?

eclipse-ocl-bot commented 3 hours ago

By Ed Willink on Aug 28, 2009 16:07

Created attachment 145981 OclInvalid/Invalid/invalid interchange

Attached patch corrects to realise as per 11.x

invalid is the instance of OclInvalid is the instance of InvalidType.

A number of method names get more regular. Clearly right but:

From an API perspective this is a problem:

getInvalid and getOclInvalid interchange. In one direction the change from Object to Classifier will may be more obvious than gthe opposite Classifier to Object.

We have a difficult decision. Do this now or for always be wrong or at least confusing.

If we are going to do this, please +1 soon. It may be slightly painful to reimplement this after some intervening updates.

:notepad_spiral: OclInvalid.patch

eclipse-ocl-bot commented 3 hours ago

By Laurent Goubet on Aug 31, 2009 03:40

I am totally for fixing the OclInvalid/invalid naming issue now rather than later. There'll be quite a few replaces to do in the unit tests of bug 287977, but it'll be easier now.

+1 for applying this patch

eclipse-ocl-bot commented 3 hours ago

By Adolfo Sanchez-Barbudo Herrera on Aug 31, 2009 05:52

(In reply to comment #11)

I am totally for fixing the OclInvalid/invalid naming issue now rather than later. There'll be quite a few replaces to do in the unit tests of bug 287977, but it'll be easier now.

+1 for applying this patch

I agree with the simple idea of interchanging OclInvalid and Invalid, including the changes in the grammar ("OclInvalid" => the type and "invalid" => the value).

+1 for the patch. However some remarks:

eclipse-ocl-bot commented 3 hours ago

By Ed Willink on Sep 01, 2009 16:16

Patch for invalid naming confusion committed to HEAD. Laurent's original semantics issues remain to be resolved, hopefully in a clearer context.

I left the copyrights as-is and started an mdt-ocl-dev thread to discuss them.

I find the copyright on EssentialOcl.g unacceptable:

Copyright (c) 2005, 2009 IBM Corporation, Zeligsoft Inc., Borland Software Corp., and others.

Since I contributed 6 fixes compared to Zeligsoft and Borland with one each, it could be

Copyright (c) 2005, 2009 IBM Corporation, E.D.Willink, Zeligsoft Inc., Borland Software Corp., and others.

I prefer either reverting to

Copyright (c) 2005, 2009 IBM Corporation and others.

or advancing to

Copyright (c) 2005, 2009 Eclipse Modeling Project and others.

eclipse-ocl-bot commented 3 hours ago

By Adolfo Sanchez-Barbudo Herrera on Sep 01, 2009 17:50

Hi Ed,

I have just replied to dev-list, the following Eclipse link may help:

http://www.eclipse.org/legal/copyrightandlicensenotice.php

I have also participated in several discussions related to bugs which involved changes in the grammars, derived from my work on a OCL-extension grammar. Unfortunately, I don't know if this grants any copyright, merit or whatever ;P.

IMO, I would incline on one of the following:

Cheers,\ Adolfo.

eclipse-ocl-bot commented 3 hours ago

By Ed Willink on Oct 08, 2009 06:27

Language discussion of OclVoid and OclInvalid started in bug 291721.

This bug awaits a patch to solve the original problem.

eclipse-ocl-bot commented 3 hours ago

By Ed Willink on Feb 01, 2011 03:10

New evaluator complies with OCL 2.3.

eclipse-ocl-bot commented 3 hours ago

By Ed Willink on May 27, 2011 02:23

Closing since fixed in mature code too.

eclipse-ocl-bot commented 3 hours ago

By Ed Willink on May 27, 2011 06:41

Resolved for Indigo is 3.1.0 not 3.2.0.