Issue 14918: OCL 2.1 11.2.5 Numeric = and <> operations should compare values rather than objects (ocl2-rtf) Source: Model Driven Solutions (Dr. Edward Willink, ed(at)willink.me.uk) Nature: Uncategorized Issue Severity: Summary: OCLAny::=() is defined as 'True if self is the same object as object2.' This is not overloaded for numeric types, and it is not specified that a numeric value may not have multiple instances. The definition therefore implies that: 1 = 1 may often evaluate to false, and that 1.0 = 1 must evaluate to false even though (1.0 <= 1) and (1.0 >= 1) will evaluate true Suggest overload {Boolean, Real, String}::{=,<>} to use values rather than objects. Resolution: The use of object should be clarified so that Class instances are compared by object identity. DataType instances are compared by value. This resolution overlaps with null/invalid clarification and so the change below includes changes for Issue 18437. Revised Text: In 11.3.1 OclAny replace =(object2 : OclAny) : Boolean True if self is the same object as object2. Infix operator. post: result = (self = object2) <> (object2 : OclAny) : Boolean True if self is a different object from object2. Infix operator. post: result = not (self = object2) by =(object2 : OclAny) : Boolean Evaluates to invalid if object2 is invalid. Evaluates to true if self is the same object as object2. Evaluates to true if self and object2 are instances of the same DataType and have the same value. Evaluates to false otherwise. Infix operator. post: result = (self = object2) <> (object2 : OclAny) : Boolean Evaluates to invalid if object2 is invalid. Evaluates to false if self is the same object as object2. Evaluates to false if self and object2 are instances of the same DataType and have the same value. Evaluates to true otherwise. Infix operator. post: result = not (self = object2) Actions taken: January 2, 2010: received issue December 23, 2013: closed issue Discussion: End of Annotations:===== ronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: ApoEAJklP0tUXebz/2dsb2JhbADRTIQxBA Date: Sat, 02 Jan 2010 18:56:24 +0000 From: Ed Willink User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-GB; rv:1.9.1.5) Gecko/20091204 Thunderbird/3.0 To: issues@omg.org Subject: OCL 2.1 11.2.5 Numeric = and <> operations should compare values rather than objects X-Plusnet-Relay: c7b893149f9e819f734970fb3019af3e Hi OCLAny::=() is defined as 'True if self is the same object as object2.' This is not overloaded for numeric types, and it is not specified that a numeric value may not have multiple instances. The definition therefore implies that: 1 = 1 may often evaluate to false, and that 1.0 = 1 must evaluate to false even though (1.0 <= 1) and (1.0 >= 1) will evaluate true Suggest overload {Boolean, Real, String}::{=,<>} to use values rather than objects. Regards From: "Rouquette, Nicolas F (316A)" To: Ed Willink , "ocl2-rtf@omg.org" Date: Sat, 16 Jan 2010 11:49:38 -0800 Subject: Re: issue 14918 -- OCL 2.1 11.2.5 Numeric = and <> operations should compare values Thread-Topic: issue 14918 -- OCL 2.1 11.2.5 Numeric = and <> operations should compare values Thread-Index: AcqWqlEb5TLtHfuQQVKd/L1kf8kEFQAOrgd0 Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: acceptlanguage: en-US X-Source-IP: altvirehtstap02.jpl.nasa.gov [128.149.137.73] X-Source-Sender: nicolas.f.rouquette@jpl.nasa.gov X-AUTH: Authorized Ed, Sequence{3, 3.0}->count(3.0) = 2 The reasons is different than you stated. It.s really: Sequence{UnlimitedNatural, Real}->Count(Real) So, there is a conversion from 3 as an UnlimitedNatural to 3.0 as a Real. Please avoid narrowing conversions from Integer to UnlimitedNatural or Real to UnlimitedNatural. What happens if you had: Sequence{-3, 3, 3.0}->count(3.0) or: Sequence{-3,3,3}->count(3) or: Sequence{-3,6/2,3}->count(3) In all these cases, the result is 2 with safe conversions. - Nicolas. On 1/16/10 4:48 AM, "Ed Willink" wrote: Hi The problem of value object identity is much more widespread. All the collection operations such as count(), includes() etc are based on objects, so it is unclear whether Set{ 3.oclAsType(UnlimitedNatural), 3.oclAsType(Integer), 3.oclAsType(Real) }->size() is 1, 2 or 3. and whether Sequence{3, 3.0}->count(3.0) is 1 or 2. For 3.oclAsType(UnlimitedNatural) and 3.oclAsType(Integer) to be different 'objects' would be very confusing, so 3.oclAsType(Integer) and 3.oclAsType(Real) must be the same 'object' too. It is presumably sufficient to specify that each distinct numeric value is notionally represented by a singleton value object of the narrowest possible PrimitiveType. Thus 3 and 3.0 are both represented by the 3.oclAsType(UnlimitedNatural) singleton. Implementations may use multiple non-singleton value objects, but these may not be observably distinct. Therefore: Set{ 3.oclAsType(UnlimitedNatural), 3.oclAsType(Integer), 3.oclAsType(Real) }->size() = 1. Sequence{3, 3.0}->count(3.0) = 1. Regards Ed Willink On 06/01/2010 21:44, Juergen Boldt wrote: X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: ApoEAJklP0tUXebz/2dsb2JhbADRTIQxBA Date: Sat, 02 Jan 2010 18:56:24 +0000 From: Ed Willink User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-GB; rv:1.9.1.5) Gecko/20091204 Thunderbird/3.0 To: issues@omg.org Subject: OCL 2.1 11.2.5 Numeric = and <> operations should compare values rather than objects X-Plusnet-Relay: c7b893149f9e819f734970fb3019af3e Hi OCLAny::=() is defined as 'True if self is the same object as object2.' This is not overloaded for numeric types, and it is not specified that a numeric value may not have multiple instances. The definition therefore implies that: 1 = 1 may often evaluate to false, and that 1.0 = 1 must evaluate to false even though (1.0 <= 1) and (1.0 >= 1) will evaluate true Suggest overload {Boolean, Real, String}::{=,<>} to use values rather than objects. Regards Ed Willink Juergen Boldt Director, Member Services Object Management Group 140 Kendrick St Building A Suite 300 Needham, MA 02494 USA tel: +1 781 444 0404 x 132 fax: +1 781 444 0320 email: juergen@omg.org www.omg.org From: "Rouquette, Nicolas F (316A)" To: Ed Willink , "ocl2-rtf@omg.org" Date: Sun, 17 Jan 2010 09:37:36 -0800 Subject: Re: issue 14918 -- OCL 2.1 11.2.5 Numeric = and <> operations should compare values Thread-Topic: issue 14918 -- OCL 2.1 11.2.5 Numeric = and <> operations should compare values Thread-Index: AcqXaQbvjo339vK6QOamdm5je7vbAgAMrrU6 Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: acceptlanguage: en-US X-Source-IP: altvirehtstap01.jpl.nasa.gov [128.149.137.72] X-Source-Sender: nicolas.f.rouquette@jpl.nasa.gov X-AUTH: Authorized Agreed. - Nicolas. On 1/17/10 3:33 AM, "Ed Willink" wrote: Hi Nicolas Thanks, we agree on the results of my earlier example, but the rationale can be clearer. My description mentioning PrimitiveType was a very poor exposition of the principle of regarding a numeric object as a reference to a point in the (extensible to Complex) Number Plane. All numeric operations are then determined, in principle, by the well-understood properties of numbers. In practice, there is a requirement that the type system does not conflict with numerical ideals; this motivates some of the overload signatures. You demonstrate that by performing pair-wise type widening we get the 'right' answer. More challengingly: Sequence(OclAny){3, 3.0, '3'}->count(-(-3)) = 2 since UnlimitedNatural 3 widens to Integer 3 for successful comparison with Integer 3 Real 3.0 is successfully compared to Integer 3 widened to Real String '3' widens to OclAny and fails to compare to Integer 3 widened to OclAny. If the specification clearly defines pair-wise type widening and 'object' identity for equal widened numeric values, the problems vanish and there is clear design direction for the overloads required to correctly integrate a user-defined ComplexNumber. Regards Ed Willink On 16/01/2010 19:49, Rouquette, Nicolas F (316A) wrote: Re: issue 14918 -- OCL 2.1 11.2.5 Numeric = and <> operations should compare values Ed, Sequence{3, 3.0}->count(3.0) = 2 The reasons is different than you stated. It.s really: Sequence{UnlimitedNatural, Real}->Count(Real) So, there is a conversion from 3 as an UnlimitedNatural to 3.0 as a Real. Please avoid narrowing conversions from Integer to UnlimitedNatural or Real to UnlimitedNatural. What happens if you had: Sequence{-3, 3, 3.0}->count(3.0) or: Sequence{-3,3,3}->count(3) or: Sequence{-3,6/2,3}->count(3) In all these cases, the result is 2 with safe conversions. - Nicolas. On 1/16/10 4:48 AM, "Ed Willink" wrote: Hi The problem of value object identity is much more widespread. All the collection operations such as count(), includes() etc are based on objects, so it is unclear whether Set{ 3.oclAsType(UnlimitedNatural), 3.oclAsType(Integer), 3.oclAsType(Real) }->size() is 1, 2 or 3. and whether Sequence{3, 3.0}->count(3.0) is 1 or 2. For 3.oclAsType(UnlimitedNatural) and 3.oclAsType(Integer) to be different 'objects' would be very confusing, so 3.oclAsType(Integer) and 3.oclAsType(Real) must be the same 'object' too. It is presumably sufficient to specify that each distinct numeric value is notionally represented by a singleton value object of the narrowest possible PrimitiveType. Thus 3 and 3.0 are both represented by the 3.oclAsType(UnlimitedNatural) singleton. Implementations may use multiple non-singleton value objects, but these may not be observably distinct. Therefore: Set{ 3.oclAsType(UnlimitedNatural), 3.oclAsType(Integer), 3.oclAsType(Real) }->size() = 1. Sequence{3, 3.0}->count(3.0) = 1. Regards Ed Willink On 06/01/2010 21:44, Juergen Boldt wrote: X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: ApoEAJklP0tUXebz/2dsb2JhbADRTIQxBA Date: Sat, 02 Jan 2010 18:56:24 +0000 From: Ed Willink User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-GB; rv:1.9.1.5) Gecko/20091204 Thunderbird/3.0 To: issues@omg.org Subject: OCL 2.1 11.2.5 Numeric = and <> operations should compare values rather than objects X-Plusnet-Relay: c7b893149f9e819f734970fb3019af3e Hi OCLAny::=() is defined as 'True if self is the same object as object2.' This is not overloaded for numeric types, and it is not specified that a numeric value may not have multiple instances. The definition therefore implies that: 1 = 1 may often evaluate to false, and that 1.0 = 1 must evaluate to false even though (1.0 <= 1) and (1.0 >= 1) will evaluate true Suggest overload {Boolean, Real, String}::{=,<>} to use values rather than objects. Regards Ed Willink Juergen Boldt Director, Member Services Object Management Group 140 Kendrick St Building A Suite 300 Needham, MA 02494 USA tel: +1 781 444 0404 x 132 fax: +1 781 444 0320 email: juergen@omg.org www.omg.org X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AkQFAA5FUUtUXebq/2dsb2JhbACCFZhJsWIJi2+CLAYVgWsEjXM Date: Sat, 16 Jan 2010 12:48:33 +0000 From: Ed Willink User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-GB; rv:1.9.1.5) Gecko/20091204 Thunderbird/3.0 To: ocl2-rtf@omg.org Subject: Re: issue 14918 -- OCL 2.1 11.2.5 Numeric = and <> operations should compare values X-Plusnet-Relay: fd22f001dd98e3fb3064c756ddd89442 Hi The problem of value object identity is much more widespread. All the collection operations such as count(), includes() etc are based on objects, so it is unclear whether Set{ 3.oclAsType(UnlimitedNatural), 3.oclAsType(Integer), 3.oclAsType(Real) }->size() is 1, 2 or 3. and whether Sequence{3, 3.0}->count(3.0) is 1 or 2. For 3.oclAsType(UnlimitedNatural) and 3.oclAsType(Integer) to be different 'objects' would be very confusing, so 3.oclAsType(Integer) and 3.oclAsType(Real) must be the same 'object' too. It is presumably sufficient to specify that each distinct numeric value is notionally represented by a singleton value object of the narrowest possible PrimitiveType. Thus 3 and 3.0 are both represented by the 3.oclAsType(UnlimitedNatural) singleton. Implementations may use multiple non-singleton value objects, but these may not be observably distinct. Therefore: Set{ 3.oclAsType(UnlimitedNatural), 3.oclAsType(Integer), 3.oclAsType(Real) }->size() = 1. Sequence{3, 3.0}->count(3.0) = 1. Regards Ed Willink On 06/01/2010 21:44, Juergen Boldt wrote: X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: ApoEAJklP0tUXebz/2dsb2JhbADRTIQxBA Date: Sat, 02 Jan 2010 18:56:24 +0000 From: Ed Willink User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-GB; rv:1.9.1.5) Gecko/20091204 Thunderbird/3.0 To: issues@omg.org Subject: OCL 2.1 11.2.5 Numeric = and <> operations should compare values rather than objects X-Plusnet-Relay: c7b893149f9e819f734970fb3019af3e Hi OCLAny::=() is defined as 'True if self is the same object as object2.' This is not overloaded for numeric types, and it is not specified that a numeric value may not have multiple instances. The definition therefore implies that: 1 = 1 may often evaluate to false, and that 1.0 = 1 must evaluate to false even though (1.0 <= 1) and (1.0 >= 1) will evaluate true Suggest overload {Boolean, Real, String}::{=,<>} to use values rather than objects. Regards Ed Willink Juergen Boldt Director, Member Services Object Management Group 140 Kendrick St Building A Suite 300 Needham, MA 02494 USA tel: +1 781 444 0404 x 132 fax: +1 781 444 0320 email: juergen@omg.org www.omg.org X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AsMFAP6DUktUXebz/2dsb2JhbACCFphLggyscQmKKoIsBhWBawSNcw Date: Sun, 17 Jan 2010 11:33:44 +0000 From: Ed Willink User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-GB; rv:1.9.1.5) Gecko/20091204 Thunderbird/3.0 To: "ocl2-rtf@omg.org" Subject: Re: issue 14918 -- OCL 2.1 11.2.5 Numeric = and <> operations should compare values X-Plusnet-Relay: 17da0f1cc16aef54219d47ed90c7fbdf Hi Nicolas Thanks, we agree on the results of my earlier example, but the rationale can be clearer. My description mentioning PrimitiveType was a very poor exposition of the principle of regarding a numeric object as a reference to a point in the (extensible to Complex) Number Plane. All numeric operations are then determined, in principle, by the well-understood properties of numbers. In practice, there is a requirement that the type system does not conflict with numerical ideals; this motivates some of the overload signatures. You demonstrate that by performing pair-wise type widening we get the 'right' answer. More challengingly: Sequence(OclAny){3, 3.0, '3'}->count(-(-3)) = 2 since UnlimitedNatural 3 widens to Integer 3 for successful comparison with Integer 3 Real 3.0 is successfully compared to Integer 3 widened to Real String '3' widens to OclAny and fails to compare to Integer 3 widened to OclAny. If the specification clearly defines pair-wise type widening and 'object' identity for equal widened numeric values, the problems vanish and there is clear design direction for the overloads required to correctly integrate a user-defined ComplexNumber. Regards Ed Willink On 16/01/2010 19:49, Rouquette, Nicolas F (316A) wrote: Ed, Sequence{3, 3.0}->count(3.0) = 2 The reasons is different than you stated. It.s really: Sequence{UnlimitedNatural, Real}->Count(Real) So, there is a conversion from 3 as an UnlimitedNatural to 3.0 as a Real. Please avoid narrowing conversions from Integer to UnlimitedNatural or Real to UnlimitedNatural. What happens if you had: Sequence{-3, 3, 3.0}->count(3.0) or: Sequence{-3,3,3}->count(3) or: Sequence{-3,6/2,3}->count(3) In all these cases, the result is 2 with safe conversions. - Nicolas. On 1/16/10 4:48 AM, "Ed Willink" wrote: Hi The problem of value object identity is much more widespread. All the collection operations such as count(), includes() etc are based on objects, so it is unclear whether Set{ 3.oclAsType(UnlimitedNatural), 3.oclAsType(Integer), 3.oclAsType(Real) }->size() is 1, 2 or 3. and whether Sequence{3, 3.0}->count(3.0) is 1 or 2. For 3.oclAsType(UnlimitedNatural) and 3.oclAsType(Integer) to be different 'objects' would be very confusing, so 3.oclAsType(Integer) and 3.oclAsType(Real) must be the same 'object' too. It is presumably sufficient to specify that each distinct numeric value is notionally represented by a singleton value object of the narrowest possible PrimitiveType. Thus 3 and 3.0 are both represented by the 3.oclAsType(UnlimitedNatural) singleton. Implementations may use multiple non-singleton value objects, but these may not be observably distinct. Therefore: Set{ 3.oclAsType(UnlimitedNatural), 3.oclAsType(Integer), 3.oclAsType(Real) }->size() = 1. Sequence{3, 3.0}->count(3.0) = 1. Regards Ed Willink On 06/01/2010 21:44, Juergen Boldt wrote: X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: ApoEAJklP0tUXebz/2dsb2JhbADRTIQxBA Date: Sat, 02 Jan 2010 18:56:24 +0000 From: Ed Willink User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-GB; rv:1.9.1.5) Gecko/20091204 Thunderbird/3.0 To: issues@omg.org Subject: OCL 2.1 11.2.5 Numeric = and <> operations should compare values rather than objects X-Plusnet-Relay: c7b893149f9e819f734970fb3019af3e Hi OCLAny::=() is defined as 'True if self is the same object as object2.' This is not overloaded for numeric types, and it is not specified that a numeric value may not have multiple instances. The definition therefore implies that: 1 = 1 may often evaluate to false, and that 1.0 = 1 must evaluate to false even though (1.0 <= 1) and (1.0 >= 1) will evaluate true Suggest overload {Boolean, Real, String}::{=,<>} to use values rather than objects. Regards Ed Willink Juergen Boldt Director, Member Services Object Management Group 140 Kendrick St Building A Suite 300 Needham, MA 02494 USA tel: +1 781 444 0404 x 132 fax: +1 781 444 0320 email: juergen@omg.org www.omg.org Ed Willink