Issue 8902: Section 8.3.9 of the final Adopted Version of the OCL 2.0 Spec
Issue 8917: allInstances
Issue 8918: Navigating across non navigable associations
Issue 8922: Section 8.3.9 of the final Adopted Version of the OCL 2.0 Spec
Issue 8937: Notation for accessing class operations is inconsistent
Issue 8982: Circular imports
Issue 9171: Introduction and oclType()
Issue 9404: inability to uniquely reference association ends
Issue 9405: Wrong subtyping of PropertyCallExp and NavigationCallExp
Issue 9796: Section: 7.3.4
Issue 9913: Section: 8.3.5
Issue 9914: Section: 7.5.9
Issue 9915: Using "def"
Issue 10344: Section: 7.4.9
Issue 10346: Section: 7.8
Issue 10430: Section 7.6.3
Issue 10431: Section 9.2.2
Issue 10432: Section "IteratorExpCS"
Issue 10433: 11.2.3
Issue 10434: 11.2.4 (OclInvalid) - similar criticism as 11.2.3
Issue 10435: 11.8.1
Issue 10436: 11.2.5
Issue 10437: 11.2.5 (02)
Issue 10438: 11.7.1
Issue 10439: Recommendations re ptc/2005-06-06
Issue 10561: inclusion of Regular Expression support
Issue 10782: Naming of Constraints in OCL
Issue 10825: ownership of association ends does not matter for traversal in OCL
Issue 10921: TypeType
Issue 10946: Collection element type serialization
Issue 10969: Usage of initialization and derivation constraints on the same property
Issue 11085: 8.2.2 Well-formedness Rules for the Types Package
Issue 11086: missing closing parethesis inthese two expressions
Issue 11097: Dynamic typing with allInstances()
Issue 11098: Section: 7.4.7, 7.4.9, 9.3.2
Issue 12378: Section 8.2 InvalidType
Issue 12419: CollectionType and CollectionKind
Issue 12438: last line on page 28
Issue 12439: Section: A/1.1.1 Types
Issue 12440: Section: A/1.1.5 Associations
Issue 12441: Section: A/1.1.5 Associations -- missing word
Issue 12442: Section: A/1.1.5 Associations
Issue 12443: Section: A/1.1.6 Generalization
Issue 12444: Section: A/1.1.6 Generalization - editorial issues
Issue 12445: Section: A/1.2.1 Objects
Issue 12446: Section: A/1.2.4 System State
Issue 12447: Section: A/2.2 Common Operations on All Types
Issue 12448: section 7.4.6 (p. 12)
Issue 12449: no explanations about how to manipulate optional and multivalued attributes
Issue 12450: The Tuple constructor is problematic
Issue 12451: OrderedSet collection
Issue 12452: Recursivity is not explicitly addressed with examples
Issue 12453: Mismatch between the definition of operators in, e.g., Section 11.7.1 and i
Issue 12454: The constraint [1] on the TupleLiteralPart metaclass is overconstrained
Issue 12456: Errors in examples
Issue 12457: Section: A/2.3 Enumeration Types
Issue 12458: Section: A/2.3 Enumeration Types -- editorial
Issue 12459: Section: Definition A.23 (Semantics of Navigation Operations)
Issue 12460: Section: A.2.5.2 Definition A.24 (Type Expressions)
Issue 12461: Section: A.2.5.5 Collection Operations
Issue 12464: Section: A/2.5.5 Collection Operations - just before table A.3
Issue 12468: Section: A/2.5.5 Collection Operations - Table A.3
Issue 12469: A.2.5.5 Collection Operations
Issue 12470: There are two instances of missing and misplaced parentheses
Issue 12471: Section: A.2.5.6 Set Operations
Issue 12472: Section: A.2.5.6 Set Operations Table A.4
Issue 12473: Section: A.2.5.8 Sequence Operations
Issue 12474: Section: A.3.1.1 Syntax of Expressions
Issue 12475: Section: A.3.1.1 Syntax of Expressions
Issue 12476: Section: A.3.1.1 Syntax of Expressions (Definition A.29)
Issue 12477: Syntax of Expressions (second sentence after Definition A..29)
Issue 12478: Section: A.2.6 Special Types
Issue 12479: Section: A.2.6.1 Definition A.26 (Special Types)
Issue 12484: Section 8.2.1 Type Conformance on page 37
Issue 12485: Section 8.2 page 35 InvalidType
Issue 12486: Section: A.2.7 Type Hierarchy
Issue 12487: Section: A.3.1.1 Syntax of Expressions
Issue 12488: Section: A.3.1.2 Semantics of Expressions
Issue 12489: Section: A.3.1.2 Semantics of Expressions, Definition A.30 part ii
Issue 12490: Section: A.2.5.8 Sequence Operations
Issue 12491: Section: A.3.1.2 Semantics of Expressions
Issue 12493: Section: A.3.2.2 Syntax and Semantics of Postconditions
Issue 12494: Section: A.3.2.2 Syntax and Semantics of Postconditions (02)
Issue 12495: Section: A.3.2.2 Syntax and Semantics of Postconditions (03)
Issue 12496: Section: A.3.2.2 Syntax and Semantics of Postconditions (04)
Issue 12562: CMOF serializations of its metamodels not published
Issue 12581: OCL 2.0 8.2 Collection Type name distinguishability
Issue 12582: OCL 2.0 8.2 Collection Type packaging
Issue 12795: Special Types violate UML Generalization Semantics
Issue 12854: OCL 2.0 Issue: References to Additional Attributes and Operations
Issue 12943: OCL 2.0: CollectionType constraint for invalid elements is incorrect
Issue 12944: Type of a type expression
Issue 12945: Missing definition of of iterators for OrderedSets
Issue 12946: The operation asSet, asSequence, asBag and asOrderedSet missing for OrderedSets
Issue 12947: Clarify the common supertype of Bag and Sequence
Issue 12948: Making OclAny denote any object
Issue 12949: Incosistency between UnlimitedInteger and UnlimitedNatural
Issue 12950: No way to represent type parameters in the standard library
Issue 12951: Use of MOF reflection in EssentialOCL should be clarified
Issue 12952: Use of simple quotes and double quotes in strings
Issue 12953: Exact type of Set{} and missing Set(MyType){} literal definitions
Issue 13057: Section: 7.5.15
Issue 13076: The concrete syntax given is extremely difficult to implement
Issue 13077: The following collection operations would be useful for the HL7 GELLO project:
Issue 13225: Redundant CollectionLiteralExp::kind complicates collection type extension
Issue 13535: doubts about the iterator variables
Issue 13536: type of the iterator variable is expected or not?
Issue 13537: have tuple fields and let variables to have the declaration of their types explicity?
Issue 13915: Role 'collectionTypes' should be 'collectionType'
Issue 13944: [OCL-2.1 RTF] Transitive closure operator
Issue 14094: Erroneous operation names 'isOclType' and 'asOclType'
Issue 14196: Missing specification of UnlimitedNatural
Issue 14197: OCL 2.0, 2.1 inconsistent definition of null and invalid
Issue 14199: OCL 2.0, 2.1 Inaccurate well-formedness constraints for IteratorExp
Issue 14200: OCL 2.0 Inadequate Headings and PDF index
Issue 14222: OCL 2.1 Inconsistent implementation of Issue 6532 and contradictory resolution of Issues 7341 and 10437
Issue 14224: Inconsistent lookup for underscored symbols
Issue 14225: Set operations for OrderedSet
Issue 14236: OCL 2.1 Incomplete resolution 9913 InvalidLiteralExpCS and NullLiteralExpCS
Issue 14237: OCL 2.0 and 2.1 Section 9.3 CollectionRangeCS incorrect operator spelling
Issue 14357: OCL 2.1 Resolution of missing Concrete Syntaxes and Reserved Words
Issue 14576: OCL 2.1 11.7: Clarifying Collection Well-formedness rules
Issue 14577: OCL 2.1 11.7 Inflexible Collection operation signatures
Issue 14582: OCL 2.1 7.4.7 Inconsistent Operator Associativity and Precedence
Issue 14583: OCL 2.1 7.4.9 true, self, Bag and String are not reserved words
Issue 14584: OCL 2.1 9.3 Inferred TupleLiteralExp part type
Issue 14585: OCL 2.1 9.3 Missing TypeLiteralExpCS
Issue 14586: OCL 2.1 12.2.5 named-self classifierContextDeclCS
Issue 14587: OCL 2.1 12.2.3 Incomplete resolution of Issue 9796 for attrOrAssocContextCS
Issue 14591: OCL 2.1 12 Definition Accessibility Semantics
Issue 14592: OCL 2.1 12 Definition Referencability Semantics
Issue 14593: OCL 2.1 12 UML alignment
Issue 14594: OCL 2.1 12 Definition uses LetExp
Issue 14595: OCL 2.1 12 Inconsistencies
Issue 14596: OCL 2.1 12 Essential MOF support
Issue 14597: OCL 2.1 12 Typos
Issue 14598: OCL 2.1 12 Incompleteness
Issue 14599: OCL 2.1 12 Documents
Issue 14639: OCL 2.1 Loop iterators are not ordered and other inconsistencies
Issue 14642: OCL 2.1 13.2 Reflection in OCL meta-models (correction to Issue 1 2951)
Issue 14851: OCL 2.1 Nested Collection Iteration
Issue 14861: OCL 2.1 Inadequate definition of run-time meta-model
Issue 14881: Undefined operation tail()
Issue 14882: Undefined operation tail()
Issue 14883: Undefined operation tail() on p 130
Issue 14884: wrong parameter type for addNamespace operation call
Issue 14885: lookupProperty instead of lookupAttribute
Issue 14886: wrong variable name
Issue 14887: Issue 14593 (UML alignment: Attribute)
Issue 14888: No postcondition for NamedElement::getType() when self.oclIsKindOf(Namespace)
Issue 14918: OCL 2.1 11.2.5 Numeric = and <> operations should compare values rather than objects
Issue 14980: OCL 2.1 11.7.3 OrderedSet addition well-formedness rules
Issue 14981: OCL 2.1 Implicit Conversion to Collection Literal
Issue 14982: OCL 2.1 11.7.3 Missing OrderedSet::flatten overload
Issue 14983: OCL 2.1 11.7 Missing OrderedSet::excluding and including
Issue 14984: OCL 2.1 11.7.3 Missing OrderedSet::-
Issue 14985: OCL 2.1 11.2 Conflicting {OclVoid, OclInvalid}::{oclIsTypeOf, oclIsKindOf, oclAsType} semantics
Issue 14986: OCL 2.1 Feature Overloading Semantics are not defined
Issue 15005: OCL 2.1 8.3.8 OclInvalid::allInstances
Issue 15009: OCL 2.1 11.2.3 Navigated Implicit Conversion to Collection Literal
Issue 15010: Collection::sum is not realisable for empty collection of user defined type
Issue 15013: OCL 2.1 Overload resolution
Issue 15037: OCL 2.1 Section 10 problems
Issue 8902: Section 8.3.9 of the final Adopted Version of the OCL 2.0 Spec (ocl2-rtf)
Click here for this issue's archive.
Nature: Uncategorized Issue
Severity:
Summary: I refer to Section 8.3.9 of the final Adopted Version of the OCL 2.0 Spec,
the two additional operations on the OclExpression.
"withAtPre" and "withAsSet".
I am wondering where the two referred operations "atPre" and "asSet"
(not restricted to collections) are "predefined"(?).
Resolution:
Revised Text:
Actions taken:
June 7, 2005: received issue
Discussion: The 'asSet' operation is predefined for collections but the 'atPre' is not at all a predefined operation. However fixing this issue implies re-synchronizing chapter 9 (concrete syntax) with chapter 8 (abstract syntax) which requires extra time. Deferred
Issue 8917: allInstances (ocl2-rtf)
Click here for this issue's archive.
Source: SAP AG (Mr. David Frankel, david.frankel@sap.com)
Nature: Uncategorized Issue
Severity:
Summary:
It is not entirely clear from the OCL 2.0 specification whether the allInstances operation returns instances of subclasses of the designated type. In other words, it isn't 100% clear whether t.allInstances( ) returns instances of subclasses of t. Recommendation: The best solution would be to have two operations, one which returns instances of subclasses and one which does not. A second-best solution would be to make it clear that allInstances returns instances of subclasses. In this case, an OCL programmer could use the oclIsTypeOf( ) operation as a filter to write a derived operation that does not return instances of subclasses. If allInstances does not return instances of subclasses, it would not be nearly as straightforward to write a derived operation that does return instances of subclasses.
To obtain all instances of a class that are not instances of some specializing class, it is sufficient to be able to select them fron the allInstances set: t.allInstances()->select(oclIsTypeOf(t)).
The spec ptc/03-10-14 lists navigating across non navigable associations as a compliance point. However, all text describing the rules for doing so have been removed from this version. The rules need to be defined more clearly in the OCL syntax.
The following rules for navigation using non-navigable associations extend the text in sections 7.5.4 Navigation to Association Classes, and sections 7.5.5 Navigation from Association classes,
When a non-navigable association is between different classes, following the association to an opposite end class is specified by:
("self" | <class name>) "." <association class name>["[" < opposite role name> "]"]"." <role name>
Note the optional component is redundant, but is allowed, but not recommended.
When a non-navigable association is between the same classes, following the association to an opposite end class is specified by:
("self" | <class name>) "." <association class name>"[" < opposite role name> "]." <role name>
Non navigability of an association end has no impact in the property navigation notation, so we do not feel the need for introducing an explicit text. Disposition: Closed, no change
I refer to Section 8.3.9 of the final Adopted Version of the OCL 2.0 Spec, the two additional operations on the OclExpression. "withAtPre" and "withAsSet". I am wondering where the two referred operations "atPre" and "asSet" (not restricted to collections) are "predefined"(?).
A simple duplication of issue 8902 Disposition: See Issue 8902 for disposition
The OCL 2.0 spec is inconsistent on whether class operations, including predefined operations, should be accessed using '.' or '::' notation. E.g. should it be Person.allInstances() or Person::allInstances() The spec uses Person.allInstances() in the text, but the concrete syntax specifies '::'. It seems that most tools have adopted the '.' notation used in the examples which is also backwards compatible with previous versions of OCL. There has also been some adoption of the '::' notation, for example in Warmer and Kleppe's OCL book, see: http://www.klasse.nl/english/boeken/ocl-book-errata.pdf Note: This issue was originally pointed out by Anthony Shuttleworth of Paranor. Proposed solution: The '.' notation is widely used and backwards compatible with previous versions of OCL. It should not be made invalid in OCL 2.0. It may be appropriate to also support the '::' notation if this has been widely adopted.
Accessing static features using ‘::’ is unambiguously an invocation of a static property and not a property of the Classifier metaclass. OCL’s TypeExp is, effectively, a Classifier literal expression, so that the ‘.’ operator should invoke features of the Classifier metaclass. An example of this is allInstances(), which is inherited from OclAny (which Classifier implicitly specializes) or allFeatures() (from UML).
Are two packages allowed to mutually import each other? I can't find anything preventing this in the spec, but was wondering if it causes some kind of "infinite" import loop.
This is a UML issue that has is already solved. In principle an implementation can avoid infinite import loop even in presence of cycles. Disposition: Close, no change
I only recently joined the OCL rtf at the request of David Frankel (who
is now with SAP) - I have not seen any activity on this mailing list as
yet so I hope this is an appropriate forum to raise this question.
First let me introduce myself - I am lead for a proof-of-concept project
investigating the use of OCL to express integrity constraints on models.
Hopefully I will get a chance next year to attend a f2f meeting so that
I can meet you all.
On to my specific question: we have noticed that some time between OCL
1.1 and UML 1.4 "oclType", as a predefined feature, was removed. (I have
been unable to find any versions of OCL between 1.1 and UML 1.4).
I thought it would be best if we found out whether this removal was
intentional before officially raising it as an issue. The reason is that
we find a) this is a useful reflective feature to have and 2) it is
still used in some current OMG specifications (note that it is used
inconsistently).
e.g.:
- UML2 Infrastructure - (ptc/03-09-15) pg.89:
Classifier::maySpecializeType(c : Classifier) : Boolean;
maySpecializeType = self.oclIsKindOf(c.oclType)
- Meta Object Facility (MOF) 2.0 Core Specification (ptc/03-10-04) -
pg.68
ExtentImpl::addObject(ObjectInstance o, String suppliedId
[0..1]): String
pre: not(self.entry.identifier includes suppliedId)
post: oclIsNew(e) and oclType(e) = IdentifierEntry and
e.object = o and
self.entry includes e
self.entry->select(ex | ex.identifier = e.identifier)->size() =
1 -- the new id is unique and
(suppliedId <> null implies e.identifier = suppliedId)
It appears that oclType was removed because MOF reflection provides the Element::getMetaClass() to obtain the metaclass of a model element. However, this is insufficient for three reasons: 1.Element in MOF is defined at the metamodeling level. OCL constraints in a model are defined at the modeling level and, therefore, constrain the run-time instances of the classes described by the model. These Classes do not inherit Element. 2.The UML Infrastructure does not merge the Reflection capability from MOF. Therefore, the UML metamodel cannot use Element::getMetaClass() in its own OCL constraints (to constrain UML models). 3.The result of Element::getMetaClass() is Class, which is the metatype for metaclasses, not Type. Thus, it would not be applicable to the values of DataTypes. For these reasons, OCL must define its own reflection capability for models (not metamodels). This is consistent with the oclIsKindOf and oclAsType. Also, it seems more natural to define it as an operation as MOF does with getMetaClass() than as an attribute
Section 7.5.3 of ptc/05-06-06 starts with the following: "Starting from a specific object, we can navigate an association on the class diagram to refer to other objects and their properties. To do so, we navigate the association by using the opposite association-end:" However, unlike in UML 1.x, in UML2 this may well be ambiguous (since names of ends owned by Associations only have to be unique within the Association and not within the context of the Class). OCL should therefore explicitly allow qualification using the name of the Association itself as well as the end name (it is not clear whether this is currently allowed as part of the syntax for 'associationendname' so there should be an example to show this. This would make it consistent with the metamodel which allows reference to specific Properties. For example we could have associations A1 and A2 both linking classes C1 and C2 and each with ends c1 and c2 owned by the respective associations. OCL does not then address the fact that aC1.c2 is ambiguous - unlike the case with unnamed ends it does not even say that it may be ambiguous and is hence disallowed. However rather than disallowing the navigation OCL should have a syntax to allow qualification by the association name For example aC1.A1::c2 The same could be used for missing association end names: If A1 had unnamed ends then one could use aC1.A1::C2
The proposed qualification by the association name solves the issue in a consistent way. Notice however that in the case of missing association end names, OCL already have a convention which is to use the class name with the first letter lowerized.
In section 8.3.2 of ptc/05-06-06 PropertyCall is shown as a subclass of NavigationCallExp -this seems the wrong way round: NavigationCallExp seems to be a specialization for when the Property is an AssociationEnd. To illustrate this, the description of NavigationCallExp starts with the following, which would not apply if the Property in question were an ownedAttribute of a class: "A NavigationCallExp is a reference to an AssociationEnd or an AssociationClass defined in a UML model."
NavigationCallExp must be the supertype of PropertyCallExp for two reasons: 1.In the reverse case, AssociationClassCallExp would inherit the referredProperty attribute from PropertyCallExp. However, this would not be applicable because association-class navigation is not a property invocation. 2.A Property can function like an association end even in the absence of an explicit Association, simply by having a Class as its type. Also, in contradiction of the submitter’s assertion, association ends commonly are ownedAttributes of Classes The text does reference the UML 1.x AssociationEnd metaclass, which is incorrect
We consider a Sequence of instances of a class called 'Example'. This class has an integer attribute called 'ex'. If we have a method specification written as follow: pre: datalist->isTypeOf(Sequence(Example)) post: Sequence{1..datalist->size()}->forAll(n | datalist->at(n).ex = datalist@pre->at(n).ex) I not sure if is correct writes the same specification with the next sentences: pre: datalist->isTypeOf(Sequence(Example)) post: datalist->forAll(n | n.ex = n@pre.ex) The generic questions is: What does the '@pre' operator mean when it is applied to iterators variables (as 'n' in the example)? Is correct the @pre use in this cases? I hope you understand my dude and sorry any gramatical error because my written english is very poor.
The usage of @pre is only applicable to the features of model classifiers, as indicated in Section 7.5.14 (Previous Values in Postconditions) which identifies both attributes and operations as “properties”, and in Definition A.31 (Syntax of Expressions in Postconditions) in which it is stated that @pre may be applied to operations that depend on system state, such as operation calls and attribute navigation on objects. The Abstract Syntax Model is ambiguous in the model of expressions involving @pre. It only defines an additional operation on the OclExpression metaclass that serves as a factory for OperationCallExps that represent invocations of an atPre() operation. This atPre() operation in not defined, neither in the Standard Library nor as an additional operation, itself. This proposed resolution is clearer, more concise, and simpler. It also does not pre-suppose a mechanism by which evaluation of @pre expressions may be accomplished
The abstract syntax defines the classes NullLiteralExp and InvalidLiteralExp but the concrete syntax does not define these literal values. --- I would like to return 'null' in certain OCL expressions for example: context Person::foo() : Person body: if age > 10 then self else null endif Currenty the only correct way to do this is not very straight forward: context Person::foo() : Person body: if age > 10 then self else OclVoid.allInstances()->any() endif The same is true for the singelton instance of OclUndefined.
The spec states: ---- The operation oclInState(s) results in true if the object is in the state s. Values for s are the names of the states in the statemachine(s) attached to the Classifier of object. ---- How does this relate to the uml metamodell? A BehavioredClassifier may have several ownedBehaviors but only one(!) of those behaviors may be the behavior of the classifier himself. The other behaviors may be specifications for behavioral features of the classifier. ---- Clarification: Possible states for the operation oclInState(s) are all states of the statemachine that defines the classifier's behavior (property 'classifierBehavior' of the 'BehavioredClassifier' metaclass).
The clarification suggested by the author of the issue solves the problem.
Using "def" I would like to specify static (classifier scoped) properties and operations.
Notation for calling static operations was available but there was no notation their definition (except when the operation is taken from a UML diagram). This is somehow inconsistent. The solution is to add the "static" prefix before the "def" keyword to define static helpers.
Hi, I'm reading through the latest OCL spec to get up to date before applying for a System Analyst job, I saw a possible minor issue in the list of the OCL keywords. Indeed, having read it so far, I would add the following ones but pls let me know if there is a reason why it wouldnt apply: body, derive, init, and self
'self' is the name of a pre-defined variable and is not a keyword. However body, derive and 'init' are keywords that are used in some parts of section 7 and explicitly defined in section 9 (concrete service). So menyioning of these three keywords is missing in 7.4.9.
Hello I recently wrote a comment about the OCL keyword list to amend if I'm correct. As I continue reading through the specification, I found that in "7.8 Resolving Properties", 2 inv contraints are specified and mentionned to have a different meaning. I specified the difference between the 2 below and was wondering if you wanted maybe to check that 1. it was correct and 2. add it to the specs so people can make sure they understand well where the difference stands, despite it is fairly straightforward from the explanation in this chapter. >From your specs: context Person inv: employer->forAll(employee->exists(p | p.lastName = name)) inv: employer->forAll(employee->exists(self.lastName = name)) Given explanation on the difference: Invariant constraint 1: Specifies that in the Company a person works for, there exists for all the employees of the company (Person instances) the value of their attribute lastName matching the value of the attibute Name in an instance of Company Invariant constraint 2: Specifies that in the Company a person works for, there exists for all the employees of the company (Person instances) the value of the person's attribute lastName matching the value of the attibute Name in an instance of Company iterator The difference is that in the invariant 1, we specify that the value of the lastName attribute for all the Person instances employed by a company must be found in an instance of the Company by matching the name attribute's value, whereas in the invariant 2, we specify that the value in the lastName attribute of a Person p working for a Company must match the value of the name's attribute in one of the Company's set of Person/employees, thus its related instance. I hope it makes sense and look forward hearing about your comments.
The difference given by the author of the two variants is good. However we prefer not to extend section 7.8 with this detailed explanation since the focus here is on syntax subtilities and a reader can make himself the exercise of interpreting correctly the two invariants. Disposition: Close, No Change.
"The forAll operation has an extended variant in which more than one iterator is used. Both iterators..." Which is it "more than one" (two, three...) or "Both" (two) ?
"The OCL specification puts no restriction on visibility." I don't think this statement is true. For example, self is bound to the instance in context. There is a whole prior section on scoping.
In fact the text refers to the visibility concept related to UML properties (public, private, protected …). Visibility is not used here in its general meaning. This can be clarified to avoid any confusion.
There is a left-paren in rule [A] . Rules [D] and [E] are identical.
The parentheses in alternative [A] are balanced; they delineate the optional variable-declaration list (including the ‘|’ bar) and, as a nested optional construct, the second variable. The [D] and [E] alternatives should be identical in form; this reflects the fundamental similarity of the structure of association-end navigation and assocation-class navigation, even down to the qualifiers list. Disposition: Closed, no change
"The type OclVoid is a type that conforms to all other types. It has one single instance called null which corresponds with the UML Null Literal value specification. " This text could be clearer. What does "called null" mean? Is it saying that the name "null" refers to this instance? A suggested rewrite: "It has one instance, identified by 'null.' The instance null corresponds to the UML Null Literal."
The statements in the discussion of both OclVoid to OclInvalid that they conform to all other types is problematic, because that implies that they conform to one another, resulting in a generalization cycle. They should neither of them conform to the other, as both are intended as undefined values of ordinary expressions in degenerate situations.
11.2.4 (OclInvalid) - similar criticism as 11.2.3 (issue 10433)
The statements in the discussion of both OclVoid to OclInvalid that they conform to all other types is problematic, because that implies that they conform to one another, resulting in a generalization cycle. They should neither of them conform to the other, as both are intended as undefined values of ordinary expressions in degenerate situations.
"When new iterator expressions are added to the standard library, there mapping to existing constructs should be fully defines. - What does that mean? It sounds like an admonition to spec writers. - also "defined" not "defines" - also "their" not "there"
It means that someone defining a new iterator should provide the semantics using the technique used in Section 11.9 for the pre-defined iterators. This could be made clearer by explicitly referring to this Section 11.9. BTW Section 11.8.1 duplicates somehow the sentence that is above in the preamble of 11.8 "Whenever a new iterator is added to the library, the mapping to the iterate expression must be defined. If this is not done, the semantics of the new iterator are undefined." This duplication leaves the impression of a copy/paste problem. To avoid this we remove the sentence in the preamble and adjust the sentence in 11.8.1.
oclIsTypeOf(typespec : OclType) : Boolean "Evaluates to true if the self is of the type identifid by typespec.." oclIsKindOf(typespec : OclType) : Boolean "Evaluates to true if the self conforms to the type identified by typespec" >From those descriptions I cannot distinguish these two. Isn't a dog "of the type" mammal" and wouldn't a dog "conform to the type" mammal? (Subtypes always conform to the supertype). I suspect that you intend that one of these evaluates to TRUE if and only if self is of type typespec *and not also of a subtype of typespec* . You might say just that.
Note that this resolution depends on the proposal for resolution of Issue 6532 that discards the OclType metatype in favour of Classifier.
oclAsType(typespec : OclType) : T
"Evaluates to self, where self is of the type identified by typespec.
post: (result = self) and result.oclIsTypeOf(typeName)
(BTW , that ought to be "typespec" not typeName).
This description is inadequate. The text in 7.4.6 describes the important
condition on the use of this method ("An object can only be re-typed to one
of its subtypes.") But chapter 7 is informative, not normative. Even with
that text moved into 11.2.5, additional discussion is required. For example,
referring to the properties that are only defined on the subtype, what would
the value of those properties be, once the object is re-typed?
Note that this resolution depends on the proposal for resolution of Issue 6532 that discards the OclType metatype in favour of Classifier.
null "conforms to all other types." Thus I suppose null->isEmpty() and null->notEmpty() are defined. What do these methods evaluate to when applied to null? This should be discussed in this section.
Similarly as when we write self.manager->isEmpty() this is a short writing of self.manager.asSet()->isEmpty(), the meaning of null->isEmpty() could be Set{}->isEmpty(), except that the decision on what kind of literal collection it is (set, bag, ordered set, sequence). By convention for null we decide the implicit casting is Bag{}.
Apart this syntax convention, null
We add a note to clarify this point.
Recommendation: The specification would be better were it to additionally describe a practical grammar useful to tool implementors and persons trying to understand what constitutes legal OCL syntax. Of course, we all know that even practical OCL grammars are permissive of strings that aren't meaningful (for example, 7->isEmpty() is typically legal) but more can be done than is expressed by the current description. I am not suggesting that you replace the current method of description, but that you add (perhaps only as an informative, non-normative appendix) a conventional grammar. The spec, after all, is supposed to serve the purposes of implementors. There are published papers describing practical grammars for OCL, or I can supply you with one, if you'd like. PS By "practical grammar" I mean one that limits the look-ahead to a finite number wherever possible. It is, of course, the use of OclExpression in the RHS of so many productions that runs up against the infinite look-ahead problem, and makes the published grammar unusable by implementors.
Good suggestion. Deferred since such grammar need to be defined carefully.
The Object Constraint Language (OCL) is an integral part of the Unified Modeling Language (UML) and is often used separately as a general constraint specification language in software development tools. For example, OCL is incorporated in the Generic Modeling Environment (GME) developed by the Institute of Software Integrated Systems (ISIS) of Vanderbilt University (http://www.isis.vanderbilt.edu/default.asp The GME implementation extends the OCL standard to include Regular Expressions. A Regular Expression is a pattern that describes (or matches) a set of strings where the pattern is itself a string and conforms to a specific syntax. Regular Expressions are ideal for expressing format constraints on OCL String values. Moreover, Regular Expressions are widely used, familiar to many software developers and complement the OCL’s already powerful constraint specification syntax. Unfortunately, Regular Expressions are not currently supported in OCL Version 2.0. Augmenting the OCL standard with Regular Expressions will improve OCL’s constraint specification capabilities for String values with a powerful, familiar notation and would also codify existing practice as manifested in tools such as GME. Please consider the inclusion of Regular Expression support in future releases of the Object Constraint Language (OCL) specification.
Good suggestion. It can be done by augmenting the standard library. Deferred for timing reasons. Disposition: Deferred
I find in the OCL document section "7.3.3. Invariants" that I can name an invariant as in: "context" <contextdeclaration> "inv" <constraintname> ":" ... I haven't figured out how to parse the document well enough to be clear if this is formally defined. And the real question is whether this applies to pre, post, body, init, and derived constraints. Does it? If not it would be useful to add.
The syntax is in fact already formally defined in Section 12.12.6 InvOrDefCS. Disposition: Closed, no change
during work on the definition of the UML Profile for CIM (an activity
performed jointly between OMG and DMTF), we recently found the following
issue with OCL 2. Please record this issue officially and let me know the
issue number for it.
Issue: No explicit statement that ownership of association ends does not
matter for traversal in OCL
Nature: Clarification
Severity: Minor
Summary:
The UML Superstructure spec 2.1.1 defines in section 6.5.2 "Diagram
Format" that any meta-association has two ends, regardless of whether
the ends are owned by the association or the associated classifiers.
However, the Superstructure spec only describes those association
ends that are owned by the associated classifiers. Furthermore, a
major OCL engine (from Eclipse) does not currently support
meta-association traversal in OCL towards ends owned by the
meta-association.
This may leave the impression to some readers that OCL would only
support meta-association traversal in the direction of ends owned by
the associated classifiers.
I understand that the intention is in OCL to support traversal of
meta-associations in any direction, regardless of whether the target
end is owned by the association or the associated classifier. It
would be helpful to state that explicitly in the OCL specification.
The intent for OCL to support navigation of association-owned ends is retained, with clarification of the implication on implementations.
I would like to log the following issue against OCL formal/06-05-01. TypeType, appearing on Fig. 8.1 (p.34), Fig. 13.1 (p.172), and section 11.3.2 (p.140) is not defined
Not only is the TypeType metatype not defined, it is not used by the Expressions package (at least, not as indicated by the abstract-syntax mappings in Section 9.3 Concrete Syntax). Moreover, the usage of the UML Classifier metaclass in OCL obviates the need for an OclType enumeration in OCL 2.x. A similar argument can be made for the obsoletion of the ElementType metatype and its instance the OclElement enumeration. The expressive power of the UML infrastructure makes it possible for the OCL StateExp to define an association with the UML State metaclass without the need for an artificial enumeration type.
The OCL abstract syntax for Collections has no property to persist the element type
of the collection.
It is therefore not possible to serialise a TypeExp.referredType referring to
for example OrderedSet(String) without synthesising an
OrderedSet_String and finding some artificial scope for it .. and then encountering
ambiguities as to whether two distinct OrderedSet_String types are really distinct.
Suggest:
Introduce a CollectionTypeExp extending TypeExp to add
CollectionTypeExp.referredElementType : Type[0..1]
with the constraint that the inherited TypeExp.referredType be a collection type.
The submitter’s proposal does not address the problem of referencing nested collection types (collections of collections). Nor does it address other implicitly-generated types such as MessageTypes and TupleTypes. A more general solution is to provide, in the top-level constraint context, ownership of these types so that they can be serialized together with the constraint that depends on them. The assumption is that a namespace is not required for these types as they are artificial, anyway, and that replication of equivalent types in multiple constraints can be resolved by the OCL tool. Currently, OCL defines well-formedness rules for the Classifier metaclass stipulating that for every classifier, there is at most one instance of each of the four concrete collection types. It is not at all clear how this should relate to the Environment construct, or what the scope of allInstances() is, in practice. Moreover, it is not necessary to require this uniqueness of collection types because the conformance rules completely define the equivalence of collection types of the same kind and element type. An OCL tool may be given the freedom to replicate collection types for its own purposes, for example to ensure consistent serialization of expressions without compromising the OCL semantics. It is worth noting that no such uniqueness restriction is currently defined for the other dynamically-generated types, the TupleTypes and MessageTypes.
The OCL 2.0 spec seems to allow usage of initialization constraints
and derivation constraints on the same property. For example in
7.3.7, it says "Initial and derivation expressions may be mixed
together after one context.", which is a string indication that it is
not precluded. Having both initialization and derivation constraints
is an overspecification of the initial value of the property, since
the derivation constraint must be satisfied at any time, which
probably includes the initialization time.
Also, the spec does not seem to contain a statement about how many
initialization and derivation constraints are allowed on a property.
By the nature of these constraints, it seems sensible to have at most
one of them.
The following clarifications are suggested to address this issue:
(1) clarify whether "at any time" for derivation constraints
includes the initialization. Suggestion: Derivation should include
initialization.
(2) clarify whether both kinds of constraints are allowed on the
same property. Suggestion: Both are allowed but must not be
contradictory.
(3) clarify how many initialization and derivation constraints are
allowed on a property. Suggestion: At most one initialization
constraint and at most one derivation constraint.
The suggested clarifications make sense. Added in section 7.3.7. Revised Text:
Thhis expression context TupleType inv: TupleType.allInstances()->forAll (t | ( t.allProperties()->forAll (tp | -- make sure at least one tuplepart has the same name -- (uniqueness of tuplepart names will ensure that not two -- tupleparts have the same name within one tuple) self.allProperties()->exists(stp|stp.name = tp.name) and -- make sure that all tupleparts with the same name conforms. self.allProperties()->forAll(stp | (stp.name = tp.name) and stp.type.conformsTo(tp.type)) ) implies self.conformsTo(t) ) ) should be context TupleType inv: TupleType.allInstances()->forAll (t | ( t.allProperties()->forAll (tp | -- make sure at least one tuplepart has the same name -- (uniqueness of tuplepart names will ensure that not two -- tupleparts have the same name within one tuple) self.allProperties()->exists(stp|stp.name = tp.name) and -- make sure that all tupleparts with the same name conforms. self.allProperties()->forAll(stp | (stp.name = tp.name) implies stp.type.conformsTo(tp.type)) ) implies self.conformsTo(t) ) ) it means "implies" instead of "and" in this part: (stp.name = tp.name) and stp.type.conformsTo(tp.type)
Fixing needed "(stp.name = tp.name) and …" becomes "(stp.name = tp.name) implies …"
missing closing parethesis inthese two expressions: [2]The parameters of the referredOperation become attributes of the instance of MessageType. context MessageType: inv: referredOperation->size()=1 implies Set{1..self.ownedAttribute->size()}->forAll(i | self.ownedAttribute.at(i).cmpSlots( referredOperation.ownedParameter.asProperty()->at(i)) [3]The attributes of the referredSignal become attributes of the instance of MessageType. context MessageType inv: referredSignal->size() = 1 implies Set{1..self.ownedAttribute->size()}->forAll(i | self.ownedAttribute.asOrderedSet().at(i).cmpSlots( referredSignal.ownedAttribute.asOrderedSet()->at(i))
Correct, two parenthesis are missing.
I have an issue with OclAny::allInstances() method, as described in the
11.2.5 section of the OCL2 spec (06-05-01.pdf).
If I understand correctly, OCL is a statically typed language (e.g. as stated
in the beginning of 8.2 section or 8.3 section OclExpression paragraph).
Every expression has a type and this type can be statically determined by
analyzing the expression and its context.
Most of the concepts in the OCL spec follows this rule, however I have
an issue with the allInstances() method, defined on OclAny. Specifically,
the "Returns all instances of self. Type T is equal to self." statement is problematic.
When allInstances is used on the literal type specifier, there is no problem.
E.g.
context classFoo inv:
somepackage::classBar.allInstances()->size() < self.limit
Here, return type of the expression "somepackage::classBar.allInstances()" can be determined
by static analysis ("at compile time") - it is Set(classBar).
However when allInstances is invoked on variable, calculated by some expression,
and all the staticallity of OCL crumbles and the hell breaks loose :D.
And there are no restrictions, on what objects allInstances() can be invoked, the only rules are
that the object to be classifier and the instance set be finite.
E.g.
(singleton rule - all the classes must have at most 1 instance)
context Class inv:
self.allInstances()->size() <= 1
Now, what is the type of the self.allInstances() expression? Well, it depends on what is the self object -
and self object is supplied at run time. If we evaluate this constraint on classFoo,
we see that type of "self.allInstances()" must be Set(classFoo), if we evaluate this constraint on
classBar, type of expression must be Set(classBar). Hence the type of expression can not be determined
at "compile time", it must be determined at "run time".
E.g. we have 2 classes classFoo and classBar; classFoo has a field someField, classBar doesn't.
context whatever inv:
let s:Set(Classifier) = Set{classFoo, classBar} in
s->allInstances()->any(true)->any(true).someField = someValue
Now what is the type of s->allInstances()->any(true)->any(true) expression?
We have:
expression |expression type |expression value
---------------------------------------------------------------------------------
s |Set(Classifier) |Set{classFoo, classBar}
s->allInstances() |Set(Set(???)) |Set{ Set_of_instances_of_classFoo, Set_of_instances_of_classBar}
s->allInstances()->any(true) |Set(???) |either Set_of_instances_of_classFoo or Set_of_instances_of_classBar
s->allInstances()->any(true)->any(true) |???? |either instance of classFoo or instance of classBar
Now the question arises: can we access someField property?
Here we must have a runtime introspection check in the OCL evaluation code -
if s->allInstances()->any(true)->any(true) returned instance of classFoo,
we can access the field, if instance of classBar - we must runtime-fail here.
Please advise. Is this a problem of the spec or I am wrong somewhere?
Granted, we are making jumps 2 levels down in metamodel hierarchy here
(first from metamodel to model elements-classes, then from classes to instances of those classes),
but there is nothing in the spec, what precludes this.
The description of allInstances() is already clear that it may only be applied to classifiers of finite extent, such as user-defined Classes. In particular, it does not apply to DataTypes, which by definition have unbounded extents, and this includes collection types such as Set(Classifier). Thus, much of the submitter’s argument is faulty. Disposition: Closed, no change
The operator precedence rules in 9.3.2 are identical to the precedence rules in 7.4.7. Both sets are incomplete in that they do not specify the precedence of the 'let' operator. For example, in a UML profile, a constraint on a 'Property' stereotype might be: not self.base_Property.allNamespaces()->exists(oclIsKindOf(Profile) or oclIsKindOf(Stereotype)) implies let prop:Property=self.base_Property in prop.defaultValue->isEmpty() To parse properly (with RSA 7.0.0.2), this constraint must instead be written as: not self.base_Property.allNamespaces()->exists(oclIsKindOf(Profile) or oclIsKindOf(Stereotype)) implies (let prop:Property=self.base_Property in prop.defaultValue->isEmpty()) This suggests that the 'let' operator has a lower precedence than that of the 'implies' operator. Of course, there is an alternative way to write this constraint that does not expose this issue: let prop:Property=self.base_Property in not prop.allNamespaces()->exists(oclIsKindOf(Profile) or oclIsKindOf(Stereotype)) implies prop.defaultValue->isEmpty() The suggestion is to revise 7.4.7 and 9.3.2 to account for *all* keywords in 7.4.9. The keywords defined in 7.4.9 but not accounted for in 7.4.7 or in 9.3.2 are: - attr - context - def - endpackage - in - inv - let - oper - package - post - pre The keywords referenced in 7.4.7 or in 9.3.2 that are *not* defined in 7.4.9 are: - @pre Nicolas F. Rouquette Principal Computer Scientist http://www.jpl.nasa.gov Jet Propulsion Laboratory, Caltech M/S 301-270 Pasadena, CA 91109, USA phone: +1-818-354-9600 fax: +1-818-393-4100 e-mail: nicolas.f.rouquette@jpl.nasa.gov
Most of the keywords listed by the submitter are not used in the syntax of expressions, but of constraint context declarations. Only the ‘let’ and ‘in’ keywords need to be addressed.
For the InvalidType it is stated that: "The only instance of InvalidType is Invalid, which is further defined in the standard library. Furthermore Invalid has exactly one runtime instance called OclInvalid." It should read: "The only instance of InvalidType is OclInvalid, which is further defined in the standard library. Furthermore OclInvalid has exactly one runtime instance called invalid." because this is in line with ch. 11.2.4, p. 138:"It [OclInvalid] has one single instance called invalid. [...] OclInvalid is itself an instance of the metatype InvalidType
The statements in the discussion of both OclVoid to OclInvalid that they conform to all other types is problematic, because that implies that they conform to one another, resulting in a generalization cycle. They should neither of them conform to the other, as both are intended as undefined values of ordinary expressions in degenerate situations
The abstractness of CollectionType and corresponding existence of the Collection CollectionKind is inconsistent:
--
9.3 collectionTypeCS synthesized attributes, page 79, contains:
kind = CollectionKind::Collection implies collectionTypeCS.ast.oclIsKindOf(CollectionType)
using CollectionKind::Collection.
--
8.3.5 CollectionKind, page 48, Collection is not one of the enumeration values.
--
11.6.1, page 144, specifies that Collection is an instance of CollectionType
requiring Collection to not be abstract.
--
8.2 CollectionType, page 34, CollectionType is identified as an abstract class.
--
An expression like the following is valid:
context Package
def getClasses() : Set(Class) =
let c : Collection(Type) = self.ownedType in
c->select(oclIsKindOf(Class))->asSet()
and demonstrates the need for a concrete CollectionType.
--
Recommendation:
Collection should not be abstract; change Fig 8.1, 8.2 CollectionType text.
CollectionKind requires a Collection value; change Fig 8.7, 8.3.5 CollectionKind.
There is no inconsistency in CollectionType being concrete while Collection(T) is abstract; they are defined on different metalevels. Indeed, the Collection(T) type would not exist if CollectionType were abstract, as it would then not be permitted to have instances
The last line on page 28 is an example in Java-like code that is supposed to show the accumulation of values into a Bag. The line currently is acc = <expression-with-elem-and-acc> Since such an assignment would not add to the Bag, but more likely produce a compile error in Java, I would think use of the common method name "add" would be more appropriate: acc.add(<expression-with-elem-and-acc>);
The following grammatically incorrect sentence is present in the document: All type domains include an undefined value that allows to operate with unknown or “null” values. This could be corrected in various ways, a couple of which would be: All type domains include an undefined value that allows one to operate with unknown or “null” values. or All type domains include an undefined value that allows operations with unknown or “null” values.
The rresolution needs to take into account the fact that Null and Invalid are introduced in OCL2 replacing undefined.
The next to last line of Definition A.4 begins, "that associates (sa) = <oc, c>." I think this should read instead, "that associates (sa) = <c, c>." If I am mistaken, then a note to remind the reader what "oc" means would be helpful, as would a note describing why the classes are not the same.
Between the definitions of "participating" and "navends" is a sentence that, "The following function navends give ...." The s is missing on "gives". It should instead read, "The following function navends gives ...."
In the definition of "navends" the symbol for "and", which was a nice looking capital lambda in previous definitions, is here a more traditional, at least in my mind, "and" sign. Consistency would be nice
At the top of page 182 there are 3 definitions, all of which have the index domain, i.e. C' an element of parents(c), in the wrong place horizontally. In the first two it appears to be associated with the small union symbol, rather than with the large one as it should be. In the third it seems not to be associated with anything in particular. Additionally, in the first line on the page there is an extraneous underscore in the name of the object of the first definition.
Problems were due to a semi-automatic Latex to Framemaker conversion. Mathematical symbols were often badly converted. The correct text is in the original from annex A of ptc/03-10-14.
In WF-1 there is an "is an element of" sign missing just before the "ATT" in the first line. In WF-2, at a minimum, the first small omega should have a t-sub-1 a bit after it so that the sameness of arguments from t-sub-1 through t-sub-n is clear for both small omegas. Also the second colon is on the wrong side of the small omega. On the other hand, I'm not sure why you don't write it in the same form as WF-1, since it's a similar statement. I hope you can interpret my attempts to get by without sub and superscripts. Since the reader has already waded through WF-1, wouldn't it be more useful like this? ? (? : tc x t1 x …x tn ? t, ?' : tc' x t1 x …x tn ? t' ? OP*c) : (? = ?' => tc = tc' ? t = t')
Problems were due to a semi-automatic Latex to Framemaker conversion. Mathematical symbols were often badly converted. The correct text is in the original from annex A of ptc/03-10-14.
In Definition A.10 Object Identifiers, part ii, you have the domain of a class c defined as: ICLASS(c') = U{oid(c) | c' ? CLASS ^ c' "gr<" c}. where I've used "gr<" for the generalization relation. I see 4 things that ought to be changed: 1. The initial c' should obviously be a c. 2. The oid(c) should be oid(c') 3. We have still another symbol for "and" 4. There's an extraneous newline before the final c.
Problems were due to a semi-automatic Latex to Framemaker conversion. Mathematical symbols were often badly converted. The correct text is in the original from annex A of ptc/03-10-14.
Definition 1.12 (System State) ends with "(the function pi(l) projects the ith component of a tuple or list l, whereas the function pi(l) projects all but the ith component):" Obviously the same notation can't mean opposite things, but what was intended here I don't yet know. Perhaps I will as I read on, but I thought I'd report this typo now so I don't forget.
Problems were due to a semi-automatic Latex to Framemaker conversion. Mathematical symbols were often badly converted. The correct text is in the original from annex A of ptc/03-10-14.
This is another omission of the word "one", making the sentence grammatically incorrect. It is also useful to have an operation that allows to check whether an arbitrary value is well defined or undefined. should be "... allows one to ...." or "... allows the checking of whether ...."
In section 7.4.6 (p. 12) it is said "An object can only be re-typed to one of its subtypes; ... If the actual type of the object is not a subtype of the type to which it is re-typed, the expression is undefined" While in section 7.5.8 (p. 19) it is said Whenever we have a class B as a subtype of class A, and a property p1 of both A and B, we can write: context B inv: self.oclAsType(A).p1 -- accesses the p1 property defined in A self.p1 -- accesses the p1 property defined in B and thus an example is shown where an object is retyped to its supertype. Both sections 7.4.6 and 7.5.8 should be joined into one. See slide 32 in my handouts to see a possible abstract of the joined section.
The problem is fixed by resolution of issue 7341. Casting and accessing properties from a supertype are two different things. Disposition: See Issue 7341 for disposition
There are no explanations about how to manipulate optional and multivalued attributes. On the other hand optional and multivalued associations are discussed in detail. For example, while I can use context Person inv: self.job->notEmpty() implies ... to test "whether there is an object or not when navigating the association", I do not know how do a similar test for optional attributes. Is it context Person inv: self.maidenName <> `' implies ... or context Person inv: self.maidenName -> notEmpty() implies ... ?
Associations are attributes. No further information is required. Disposition: Closed, no change
The Tuple constructor is problematic. It is not a first-class citizen in the specifications. It appears in many parts but it is not formally introduced.
The discussion of tuple literal expressions in Section 7.5.15 Tuples is quite thorough. The description of the abstract syntax of the TupleLiteralExp in Section 8.3.5 is terse but complete, and the concrete syntax of tuple literals in Section 9.3 is also complete. Disposition: Closed, no change
The OrderedSet collection is a later adjunction with respect to previous versions of OCL. However, it has not been systematically introduced in all relevant places. As one example among many, conformance rules in Table 7.3 (p.12) do not include OrderedSet. Also, the semantics defined in Appendix A should be extended to include OrderedSet. By the way, there is no place where the difference between OrderedSet and Sequence is discussed. From my understanding, they are much like the same concept. If it is not the case, the differences must be explicitly stated.
Various issue resolution solve the problem mentioned by the reporter. The table 7.3 was not yet completed. This resolution solves that. Regarding the difference between OrderedSet and Sequence it is very clear in the types section.
Recursivity is not explicitly addressed with examples, although it is mentioned in several places. For example, in p. 16 it is said "The right-hand-side of this definition may refer to the operation being defined (i.e., the definition may be recursive) as long as the recursion is not infinite." I my course I have put the following example (slide 19) A method that obtains the direct and indirect descendants of a person context Person::descendants(): Set body: result = self.children->union( self.children->collect(c | c.descendants()) ) But there is no way to verify whether the above definition, although conceptually correct, is OK with respect to OCL's syntax. Similarly, the same problem arises with recursive association classes, which is covered in Section 7.5.4. I have covered this in my course in slides 29-30 A person is currently married to at most one person context Person inv: self.marriage[wife]->select(m | m.ended = false)->size()=1 and self.marriage[husband]->select(m | m.ended = false)->size()=1 Operation that selects the current spouse of a person context Person::currentSpouse() : Person pre: self.isMarried = true body: if gender = Gender::male self.marriage[wife]->select(m | m.ended = false).wife else self.marriage[husband]->select(m | m.ended = false).husband end However, I suppose that the syntax for the operation currentSpouse is OK with respect to OCL's syntax, although it is not specified explicitly.
Deferred for timing reasons. In order to introduce the suggested examples in Section 7 some verification will be needed. Disposition: Deferred
Mismatch between the definition of operators in, e.g., Section 11.7.1 and in Table A.3: product operation is missing in the latter. By the way, there are many printing problems in this table. Similar mismatch: flatten operation is specified for Sets (p. 147) for Bags (p. 151) and for Sequences (p. 152) but are not mentioned in the corresponding tables in Annex A. By the way, whey flatten is not specified for OrderedSets? Why several methods specified for Sets and Bags (union, intersection, etc.) but not for OrderedSets?
For timing issues all issues concerning Annex A are deferred. Disposition: Deferred
The constraint [1] on the TupleLiteralPart metaclass is overconstrained. It requires that the type of the value of a tuple literal part be identical to the corresponding attribute of the tuple type. However, the value type should only be required to conform to the attribute type because tuple literals may optionally specify the part types (in the same fashion as variable declarations). Thus, a more appropriate formulation of this constraint would be: context TupleLiteralPart inv: attribute.type.conformsTo(value.type )
The examples are based on the sample model (Companies and Employees). However, as pointed out in http://www.empowertec.de/products/analyze-spec-expressions.htm there are many errors in the examples. You will find at the address http://cs.ulb.ac.be/oclnotes.pdf the slides that I use in my course in which I slighty modified the example so that all example expressions are (supposed to be) correct.
This may be simply my misunderstanding of what is intended. In the final sentence before Definition A.18 (Semantics of Enumeration Types), the word "interpreted" seems inappropriate. "Defined" is often used in such sentences is mathematics. I just wanted to draw attention to this in case it is a mistake. If not then my apologies
The last sentence of the page is missing the word "one" or, alternately, proper forms of the verbs "to follow" and "to retrieve". A correct form of this sentence would be, "Navigation operations: An object may be connected to other objects via association links. A navigation expression allows one to follow these links and to retrieve connected objects."
Maybe I misunderstand, but it seems to me that L(as)(ci), as defined, has some problems: 1. "(c1, . . . , c i, . . . , c j , . . . , c n )" is undefined in that one doesn't know what it is, and 2. c is undefined in "sCLASS(c)". It seems to me that what you want is "L(as)(ci) = {cj | i ? j ? (c1, . . . , ci, . . . , cj , . . . , cn ) ? I-sub-ASSOC(as)}" - where the characters following the c's are subscripts and each such combination should be underlined to show that it is an object, - and where I-sub-ASSOC(as) is an italic I with a subscripted "ASSOC(as)".
Problems were due to a semi-automatic Latex to Framemaker conversion. Mathematical symbols were often badly converted. The correct text is in the original from annex A of ptc/03-10-14..
This may not have been a problem with earlier versions of Adobe Acrobat/Reader but in looking at this section I see two typographical representations of "T-hat". The first two occurances are the letter T followed by a small circumflex substript. Subsequent occurances are a large circumflex followed by the letter T. It would be nice if this were fixed to be consistent, and even nicer if the circumflex could be placed over the T, as I imagine was intended.
Problems were due to a semi-automatic Latex to Framemaker conversion. Mathematical symbols were often badly converted. The correct text is in the original from annex A of ptc/03-10-14.
The 5th word of this section is "of" but was probably meant to be "on". Also, in Table A.3 in this section the entry in the second row, third column is pretty much unreadable because there are so many symbols written on top of each other. I checked this with Internet Explorer as well as Firefox, in case they affected Adobe Acrobat, but the entry looked equally bad in both.
Problems were due to a semi-automatic Latex to Framemaker conversion. Mathematical symbols were often badly converted. The correct text is in the original from annex A of ptc/03-10-14.
Just before Table A.3, is a sentence, "For this purpose, C, C, C2 ...." The second "C" should have a subscript "1" and the "C2" should have the 2 as a subscript.
Disposition: See Issue 12463 for disposition
Table A.3 has several problems in the "Semantics" column: Row 2: Besides being hard to read, the expression seems to be wrong. There is no operator between the C and capital pi (which I assume to be a Cartesian product), and the "is not an element of" seems like it couldn't be right. Maybe I'm at fault, but I can't make any sense of it. Row 4: There's no entry here. How about " C 'intersect' {v} = Ø" Row 6: The operator should be intersection, not Cartesian product, that is the capital pi should is the wrong symbol here. Rows 8 & 9: First, there shouldn't be anything in row 9's semantics column since the other columns are all blank. Are the c's supposed to be the capital C's? I can't make any sense of the expression, which could be my problem, but I don't think so.
In the paragraph under table A.3, toward the end, it says, "... count : Set(t) _ t ! Integer ...." These are the wrong symbols, of course. The underscore should be a cross and the ! should be an arrow. Also, just below this is the definition of I(count). This contains a 2 that should be a 0.
There are two instances of missing and misplaced parentheses. One is near the bottom of page 195 in the definition of I(count). The line begins, "I(count : Bag)(t) x t ? Integer)". That last closing paren does not match anything. I believe the line should instead begin "(I(count) : Bag(t) x t ? Integer) The other is at the top of page 196. It is currently "I(count : Collection)(t) x t ? Integer)(c,v)" and, I believe, should be "(I(count) : Collection(t) x t ? Integer)(c,v)"
The second sentence of this section ends, "... B is a value of type t.". It should say "... B is a value of type Bag(t).
The original text of Annex A (ptc/03-10-14) was left unchanged by the FTF. However some editorial copy/paste errors were introduced when moving from latex to framemaker. In the case of this issue this concerns the description text (not only the math symbols).
Table A.4 has several rows in the Semantics column where a "union" symbol is used where an "intersection" symbol should have been used. These are rows 3, 4, 5, and 6. Table A.5 of section A.2.5.7 has the same problem in rows 3 and 4.
There is one error in Table A.6 in the semantics column for the operation "first". The index should be 1, not i.
Definition A.29 (Syntax of Expressions), part iii, b ends with, "and e2 to en the arguments." Here the 2 is a subscript as it should be but the "n" in "en" should also be a subscript and isn't.
Problems were due to a semi-automatic Latex to Framemaker conversion. The correct text is in the original annex ptc/03-10-14. .
Definition A.29 (Syntax of Expressions), part v, appears to have several problems: 1. The symbol used for generalization is not what has always been used previously, see the two previous symbols in Definition A.10 part ii and in section A.1.2.2 just after it. 2. the first expression after the word "then", namely "(e asType t’) ? Exprt’" lacks a comma after it to separate it from the following expression. 3. I'm puzzled by the restrictions that t and t' must be related one way on the other. The restriction isn't strong enough to keep (e asType t’) from being undefined and seems unneeded for isTypeOf and isKindOf. A note here about this might help the reader. It would sure help me.
Definition A.29 (Syntax of Expressions), part vi reads it part, "... v1 ? Vart1, v2 ? Vart2, and ...." The first comma is a subscript along with the "t1" before it, the second one, that follows the "t2" subscript, isn't. Neither should be.
Problems were due to a semi-automatic Latex to Framemaker conversion. Mathematical symbols were often badly converted. The correct text is in the original from annex A of ptc/03-10-14. . Disposition: See issue 12474 for disposition
The second sentence after Definition A.29 is "For all t’ < t: if e ? Exprt’ then e ? Exprt’ ." The last prime should be removed.
Problems were due to a semi-automatic Latex to Framemaker conversion. Mathematical symbols were often badly converted. The correct text is in the original from annex A of ptc/03-10-14. . Disposition: See issue 12474 for disposition
The third bullet ends, "... as ? is an instance of every type." I don't know if the ? stands for OclAny, which isn't a member of the collection classes and so unlikely, or if ? is meant rather than ?. So I think this is an error.
Problems were due to a semi-automatic Latex to Framemaker conversion. Mathematical symbols were often badly converted. The correct text is in the original from annex A of ptc/03-10-14. .
At the very end if this section it says "I(undefined) = ?." Shouldn't that be "I(undefined) = {?}."? Definition A.14 says the semantics maps each type to a set.
Problems were due to a semi-automatic Latex to Framemaker conversion. Mathematical symbols were often badly converted. The correct text is in the original from annex A of ptc/03-10-14. . Disposition: See Issue 2478 for disposition
Section 8.2.1 Type Conformance on page 37 [1] Invalid conforms to all other types. context InvalidType inv: Classifier.allInstances()->forAll (c | self.conformsTo (c)) on page 38 [1] Void conforms to all other types. context VoidType inv: Classifier.allinstances()->forAll(c | self.conformsTo(c)) on page 37 [6] The Conforms operation on Types is anti-symmetric context Classifier inv: Classifier.allInstances()-> forAll(12,t2 | t1.conformsTo(t2) and t2.conformsTo(t1) implies t1 = t2) The first invariant yields Classifier.allInstances()->forAll (c | OclInvalid.conformsTo (c)) and thus OclInvalid.conformsTo (OclVoid) The second invariant yields Classifier.allInstances()->forAll (c | OclVoid.conformsTo (c)) and thus OclVoid.conformsTo (OclInvalid) Now the third invariant implies: OclInvalid = OclVoid
As in the proposed resolutions of Issues 10433 and 10434, OclVoid and OclInvalid cannot both be the bottom of a lattice-structured type system. It is better that OclVoid and OclInvalid be defined as conforming to all other types excepting one another.
InvalidType represents a type that conforms to all types. The only instance of InvalidType is Invalid, which is further defined in the standard library. Furthermore Invalid has exactly one runtime instance called OclInvalid. should be replaced by InvalidType InvalidType represents a type that conforms to all types. The only instance of InvalidType is OclInvalid, which is further defined in the standard library. Furthermore OclInvalid has exactly one runtime instance called invalid. This would follow the naming conventions and be in line with the notation for VoidType, OclVoid, null.
Disposition: See issue 12378 for disposition
The first two sentences of Definition A.27 (Type Hierarchy) seem to have errors in them. The relation "less than or equal" seems to be represented by an underscore in the first sentence. In the second sentence 2 is used where the "is an element of" symbol was intended, 0 is used where a prime mark is intended, and c simply follows t and t0 (t prime) rather than being a subscript as intended.
Problems were due to a semi-automatic Latex to Framemaker conversion. Mathematical symbols were often badly converted. The correct text is in the original from annex A of ptc/03-10-14. .
Definition A.29 (Syntax of Expressions)part iii, (b) ends, "...and e2 to en the arguments." The n in "en" should be a subscript but is not.
Disposition: See issue 12474 for disposition
Some problems with Definition A.30: 1. In the second sentence of Definition A.30 (Semantics of Expressions) it says, "I[[ e ]] : Env ? I(t)" but it seems instead that "I[[ e ]] : Exprt ? (Env ? I(t)). 2. It appears that r, which is not defined anywhere, is really supposed to be p. p, which is defined, only appears in part iv and it appears to be r there. 3. Also, it's confusing to use w in parts iii and iv since small omega (or script w maybe) is used previously. Further clarity would be added by putting empty parenthenes after omega in part iii to emphasize the fact that there are no arguments
Problems were due to a semi-automatic Latex to Framemaker conversion. Mathematical symbols were often badly converted. The correct text is in the original from annex A of ptc/03-10-14. .
Definition A.30, part ii says "I[[let v = e1 in e2]](r) = I[[e2]](s, ß{v / I[[e1]](r)})." Maybe the problem is my ignorance of the meaning of the / in that expression as well as the meaning of the notation "ß{...}". I would have expected instead something like, "... = I[[e2]](s, ß U {v = I[[e1]](r)})."
In the flattening expressions there are the expressions "C1 fg" and "Bag fg". These seem to stand for the creation of a new, empty collection and bag respectively. If these expressions are what was intended it would be nice to have a note explaining what they mean. I wasn't able to find any explanations or previous use of "fg".
It would be nice to have a definition of ß{x / y) in association with Definition A.30. Maybe it's defined elsewhere, but I don't see it. From what's written in this section, including the explanation of iteration on page 205 and 206, I get only a vague idea. P.S. So realizing now that this is not a typo, my revision request two previous to this (if I've counted correctly) should be ignored. That was the one about part ii of Definition A.30.
In the paragraph before Definition A.32 you will find, "An environment p = (s, ß is a pair ...." The closing paren. after ß is missing
Problems were due to a semi-automatic Latex to Framemaker conversion. Mathematical symbols were often badly converted. The correct text is in the original from annex A of ptc/03-10-14. The parenthesis problem reported here is just one of the problems that are in this section.
In the paragraph before Definition A.32 you will find, "... ppre = (spre, ßpre) describing a system state and variable assignments before the execution ...." Originally I had taken the ß's to be sets of assignments. Then I noticed that the text before this point refers to it repeatedly as an "assignment" in the singular. Now, here, and also in the middle of page 205 (which says, "ß' := ß{p1/I[[ e1 ]](r), . . . , pn /I[[ en ]](r)}.") the indication is that beta is multiple of assignments. Consistency would be very desirable.
Deferred for timing reasons. Disposition: Deferred
At the beginning of Definition A.32 you will find the sentence, "The semantics of an expression e ? Post-Exprt is a function I[[ e ]] : Env x Env ? I(t)." It doesn't seem that this can be right since the argument to I[[.]] is an element of Post-Expt-sub-t. So, similarly to Definition A.30, I would suggest that something akin to "I[[ e ]] : Post-Exprt ? (Env x Env ? I(t))" would be more appropriate.
Deferred for timing reasons. Disposition: Deferred
In the paragraph before Definition A.33 we have, "We say that a precondition P satisfies a pre-environment rpre – written as rpre |= P –....". In the explanation of Definition A.33 we have, "...the pre-environment rpre satisfies the precondition P....". One of these must be backwards. Does the environment satisfy the condition (2nd above) or does the condition satisfy the environment (1st above)?
Deferred for timing reasons. Disposition: Deferred
No CMOF models of OCL Abstract Syntax Unlike most successful specifications in the MOF and UML family, the OCL specification does not publish CMOF serializations of its metamodels. Publication of normative metamodels will greatly improve the clarity of the specification and assist tools in implementing it. XMI serializations of the following metamodels are recommended: - CompleteOCL Abstract Syntax (UML basis) - EssentialOCL Abstract Syntax (EMOF basis) Also, a separate document containing normative EBNF or RelaxNG grammars of: - CompleteOCL Concrete Syntax - EssentialOCL Concrete Syntax
Good suggestion. It cannot be treated in this ballot due to timing constraints. Disposition: Deferred
The name of a Set (or other Collection) is defined to use the element type name. This is not consistent with the UML requirement for distinguishability of namespace memebers. (UML Infra 9.14.2 Namespace). OCL should permit, and perhaps require, that the name of a Collection use the element type qualified name, so that two sets of distinct element type are not folded into indistinguishable names. This is a problem for model to model transformation where the same class name can easily occur on both input and output meta-model, and where the requirement to reify collection types can easily result in Set(input::name) and Set(output::name) in the same namespace.
Good remark. Now for the resolution we have the option to explicitly consider that the distinguishability rule does not apply for collections or follow the reporter suggestion, which could have some impact in pre-existing written OCL. I suggest to defer so that we take more time to examine the options. Disposition: Deferred
[Pending a resolution of Issue 10946] In order to use a collection type, it is is necessary to define that type and provide some container for it. OCL provides no guidance on what that container should be, or upon what the relative semantics of A::Set(E) is with respect to B::Set(E). QVT 1.0 has defined all CollectionType(ElementType) to be the same type regardless of the accidental package used for their containment. OCL should adopt the QVT definition (even if 10946 is adopted).
A sentence is needed to state that collection types can be replicated in different namespaces and still represent the same type. This is in line with 10946 resolution.
Special Types violate UML Generalization Semantics The definition of OclAny as a general of all classes in the UML model and of OclVoid and OclInvalid as specializations of all classes in the UML model are in violation of the semantics of generalization. Classifiers in the UML may only specialize other classifiers of the same or a conformant metaclass. From the description of Classifier in the UML: [3] A classifier may only specialize classifiers of a valid type. self.parents()->forAll(c | self.maySpecializeType(c)) [8] The query maySpecializeType() determines whether this classifier may have a generalization relationship to classifiers of the specified type. By default a classifier may specialize classifiers of the same or a more general type. It is intended to be redefined by classifiers that have different specialization constraints. Thus, it is not valid for OclAny (an instance of the AnyType metaclass) to be the general of any other class. Likewise, OclVoid and OclInvalid may not specialize any other class at all. This could be corrected in OclVoid and OclInvalid by redefining the maySpecializeType() query. For OclAny, the solution is not so straight-forward, as I don't see that OCL can redefine maySpecializeType() on behalf of the UML metaclasses; according to Section 7.4.4, it is not permitted to attempt to define an additional operation that clashes with an intrinsic operation of the context classifier.
The issue requires some further analysis. Deferred for timing reasons. Disposition: Deferred
Re: OCL 2.0 formal/06-05-01 The Abstract Syntax defines expressions that navigate properties and call operations of Classifiers: the PropertyCallExp and OperationCallExp, respectively. These work well for features of Classifiers that are defined by the UML model that is the subject of the OCL constraints. However, OCL also provides a mechanism for defining additional attributes and operations on behalf of a classifier: the definition constraint. As these definitions are extrinsic to the UML model, there are no Property and Operation elements for the respective expressions to reference. There are only Constraints with an «oclHelper» stereotype and a body expression. The very purpose of these definitions is to assist in the formulation of OCL constraints, so it is necessary that the abstract syntax be able to reference them. I can think of an obvious approach to resolution of this problem: add an association "referredDefinition : Constraint" with 0..1 multiplicity to both of the existing PropertyCallExp and OperationCallExp metaclasses. The 0..1 multiplicity of the existing referredProperty and referredOperation associations, as shown in Figure 8.3, appears to be in error (as the rest of the text and, in particular, the well-formedness rules of Section 8.3.7, assumes the reference to the referred features) but is required by this solution. Additional well-formedness rules would stipulate, for each expression, that exactly one of the referred feature of referred definition associations have a value. This suggestion is not entirely satisfactory, as it breaks the uniformity of references to features in call expressions and encodes, in the abstract syntax, a dependency on a feature's being an additional definition. However, this problem is a practical concern for the serialization and exchange of the OCL Abstract Syntax, as the current metamodel is incomplete.
The solution suggested by the reporter as recognized by him is not satisfactory. A more clean "conceptual" solution would be to allow OCL define modules (package) that extend the metamodels (as it works in QVT). Some further examination is needed of this issue to find the most appropriate solution. Disposition: Deferred
The second constraint on CollectionType in Section 8.2.2 does not make
sense. The instances of CollectionType are not collections, but the
types of collections. Thus, a collection type does not have elements
to be iterated. This constraint should be struck from Section 8.2.2:
[1] A collection cannot contain OclInvalid values.
context CollectionType
inv: self->forAll(not oclIsInvalid())
and replaced by a new invariant constraint in Section 11.7.1
“Collection” (which currently has no well-formedness rules):
[1] A collection cannot contain OclInvalid values.
context Collection
inv: self->forAll(not oclIsInvalid())
In the TypeExp definition (within section 8.3) there is no indication of what is the type returned by a type expression. Is it the generic object representing all types (oclType) or the referred type itself? We guess it is the referred type itself, but this need to be explicitly stated.
Summary:Since the iterators are redefined for each concrete collection type We would expect a "11.9.5 OrderedSet" section. Moreover, when defining nestedCollect for OrderedSet we should expect the type to be a Sequence (in constrast to Set::nestedCollect which type is a Bag).
The operation asSet, asSequence, asBag and asOrderedSet are not defined for OrderedSets in 11.7.3. Also, since these operations are available in all collections we would expect their definition at Collection level.
Summary: Does an OrderedSet conforms to a Set? Does an OrderedSet conforms to a Sequence? It seems that there is no automatic conformance between these concrete collection types (hence an explicit conversion need to be done when needed) However, for clarification, this should be stated in the definition of the respective concrete collection types to avoid OCL writers making wrong assumptions.
Summary: In the actual OCL2 spec OclAny represents any object except collections. However this is unaligned with UML2 and MOF2 where such kind of type does not exist Instead in MOF we have the generic Object which represents any object including primitive and collection values. Also, looking at the list of operations defined for OclAny we see that there is no real justification for creating this special type. Operations like 'allInstances' and 'oclIsNew' are also invalid for primitive types and hence are not specifically invalid for collections. Making OclAny to represent any object (equivalent to MOF::Object) will simplify the stdlib and will be consistent with UML2 and MOF2.
Summary: In Figure 8.6 we have UnlimitedNatural but in other parts of the spec there is a UnlimitedInteger definition.
The correct name is UnlimitedNatural. This error only occurs in Section 11.4.5.
Summary: The OCL metamodel does not provide means to encode type parameters in operations like the generic ones that are defined by Collection type in the standad library.
Summary: There is no clear indication weather MOF reflection is available in EssentialOCL (except in the provided xmi, ecore files of essential ocl).
Summary: Use of simple quotes in place of double quotes should be allowed, Specially in situations where the string contains double quotes (to avoid explicit use of escaping characters).
In fact simple quotes are used in OCL for introducing strings, so we guess the request is to allow use of double quotes as an option (like in Javascript). This issue requires some further analysis so I suggest to defer. Disposition: Deferred
Summary:
It is not clear what is the concrete type of Set{}. Is it Set(Object)??, Set(Void)??
Also it seems there is no way to explicitly define an empty collection with a given
type for the elements.Resolution of this issue requires some extra analysis Disposition: Deferred
Although it is clear that using a constructor to write an object to the system being modelled breaks the property of being side-effect free, it would be useful to return new objects as a result of the query functionality of OCL. It is possible to create a new Tuple for return from a function. For example: def: newDate1() : TupleType {day:Integer, month:Integer, year:Integer} = Tuple{day=10, month=12, year=1950}; It would be useful to have a similar way to generate a query result, but with a complex data type instead of a Tuple. For example: def: newDate2() : Date = Date{day=10, month=12, year=1950}; Rather than write this object to the model under query, it would only be returned as a query result so, under these circumstances, would not break the property of being side-effect free. This feature would be extremely useful to the HL7 GELLO project, which works with data models defined in absense of defined methods or constructors. If this feature were to only apply to classes marked in some way to guarantee they have no side-effects from construction then that would remain useful.
Resolution of this issue requires some extra analysis. Disposition: Deferred
The concrete syntax given is extremely difficult to implement, as documented in several places, including University of Dresden http://dresden-ocl.sourceforge.net/papers/ParserDesign.pdf Many languages have a syntax specified in a machine-readable form, (e.g. lex/yacc format). A standard, working, syntax for OCL would be very useful.
Good suggestion. A lot of people has expressed the need for having an alternate BNF based way of providing the syntax. This could be done but requires some analysis to ensure it will be compatible with the way it is actually provided. Disposition: Deferred
The HL7 GELLO project would find it useful to have additional collection operators in OCL. A method to define these in the underlying model would be good. Alternatively, we request the addition of the following operations: max, min: To determine the maximum or minimum value in a collection firstN: Returns a sequence with the first n elements of this sequence lastN: Returns a sequence with the last n elements of this sequence reverse: Returns a sequence in reverse order join(namesOfCollections; namesOfProperties; booleanExpression; orderByExpression) Where: - namesOfCollections is a list of strings separated by commas, where each string represents the name of a collection from where data is retrieved. - namesOfProperties is a list of strings separated by commas, where each string is the full description of the properties from the objects in the collections we want to get in the result. - booleanExpression is a valid boolean expression containing the conditions the elements from the collections defined in listOfCollections must satisfy in order to be included in the result - booleanExpression is a valid boolean expression containing the conditions the elements from the collections defined in listOfCollections must satisfy in order to be included in the result average: Calculate the average value in a collection stdev: Calculate the standard deviation of a collection variance: Calculate the variance of a collection median: Calculate the median of a collection mode: Calculate the mode of a collection
In the OCL specification we found some statements that indicate that the standard library can be extended (example 11.8.1), not only with new operations but also with iterator expressions. However the mechanism for representing the standard library itself (as a M1 instance of the OCL metamodel) is unclear (a Package containing types which in turn contain operations?) and the extension mechanism for the standard library is also undefined (a pure replacement of the Package, or a new Package importing the StdLib package?). Some other issues address specifically this problem, so the resolution of this issue will be formulated in a neutral way is respect to this representation issue: we confirm that new collection operations can be defined (adding a sentence) and we treat specifically the case of some generic operations that can be easily introduced: "reverse" as operation of "Sequence" and "OrderedSet", max, min as operations of Collection but with constraints on the type of parameters. We consider that average, stdev, variance, median and mode are too specific and can be defined as extensions. The proposed join functionality can be re-formulated as an iterator extending the standard library.
The CollectionLiteralExp class defines the 'kind' attribute to indicate the specific collection type of the literal (8.3.5 Literal Expressions). This information is redundant as the collection kind can be deduced from the 'type' association inherited from the TypedElement. As the attribute type is CollectionKind enumeration, it restricts to the set of predefined OCL collection types. Other languages that extend OCL, like QVT does, may need to define custom CollectionType subclasses but can't reuse CollectionLiteralExp as it's impossible to provide a suitable collection kind value. Proposed resolution: Remove the CollectionLiteralExp::kind attribute, eventually consider removing the CollectionKind enumeration.
The information CollectionLiteralExp::kind is effectively redundant since in theory it can be computed by inspecting the type information. I guess the 'kind' attribute was introduced to facilitate "very lazy" type instantiation (like not building the type associated with the tuple literal). One possible option, instead of removing the attribute, could be to state it is optional. I suggest deferring the resolution of this issue to give more time to people to discuss on the resolution proposal. Disposition: Deferred
I have a few doubts about the iterator variables. Reading the specification I am not sure about, for each iterator, how many iterator variables can have. Looking at sections 7.6 and 11.9 my conclusion in the following: -select --> It has zero or one iterator variables. (0..1) -reject --> It has zero or one iterator variables.(0..1) -collect --> It has zero or one iterator variables.(0..1) -forAll --> There is no restriction about the number of iterator variables. (0..*) -exists --> Unlike forAll, in section 7.6 there is no text saying anything about the number of variables. But in section 11.9 it seems that it is the same case that forAll. (0..*) -iterate --> It has one iterator variable. -collectNested --> It has zero or one iterator variables.(0..1) -one --> It has zero or one iterator variables.(0..1) -any --> It has zero or one iterator variables.(0..1) -isUnique -->It has zero or one iterator variables.(0..1) Is my conclusion correct in everything? or in wich parts am I confused? How can the most of the iterators be defined by the iterate iterator if iterate iterator can have only one variable iterator? I think the iterate iterator should not have restrictions about the number of iterator variables (0..*).
The assumption of the reporter concerning the number of iterators in the syntax is correct. The number of iterators is in fact explicily defined in Section 11.9. By the way, for the last question of the reporter, there is no issue at all since according to the abstract syntax the association end iterator is already declared as multivalued (see LoopExp::iterator [*] in Figure 8.2). We believe anyway that it is useful to add a sentence in Section 7 stating that 'exists' operator can potentially have multiple iterators since there is no example of this. Also some minor typo fixing is needed in 11.9.
I wrote an issue similar than this one but not equal so, the body could seem equal but it is not the case. I have a few doubts about the iterator variables. Reading the specification I am not sure about, for each iterator, if the type of the iterator variable is expected or not. For example: collection->select( v : Type | boolean-expression-with-v ) collection->select( v | boolean-expression-with-v ) Looking at sections 7.6 and 11.9 my conclusion is the following: -select --> It is NOT obligatory to write the type of the iterator variable. It appears in section 7.6. -reject --> It is NOT obligatory to write the type of the iterator variable. It appears in section 7.6. -collect --> It is NOT obligatory to write the type of the iterator variable. It appears in section 7.6. -forAll --> It is NOT obligatory to write the type of the iterator variable. It appears in section 7.6. -exists --> It is NOT obligatory to write the type of the iterator variable. It appears in section 7.6. -iterate --> In section 7.6 it seems that in both, for the iterator variable and for the accumulator variable, it is obligatory to write the type. -collectNested --> It is NOT obligatory to write the type of the iterator variable. It is a similar case than the collect. -one --> It is NOT obligatory to write the type of the iterator variable. -any --> It is NOT obligatory to write the type of the iterator variable. -isUnique -->It is NOT obligatory to write the type of the iterator variable. Is my conclusion correct in everything? or in which parts am I confused? I think that both, iterator variable and accumulator variable of the iterate iterator should have their types optional. In other words, to write the type of the iterator variable or the type of the accumulator variable should not be obligatory.
It is clear from the various examples in Section 7 that the type declaration of the iterator is optional in collection operations. By default VariableDeclarationCS is defined so that the type of the variable declared is optional. Disposition: Close, no change
have tuple fields and let variables to have the declaration of their types explicity?
By default a VariableDeclarationCS has the type declarator optional unless it is explicitly stated that it should be present. It is mandatory for Let (see disambiguation rules of LetExpCS) but not mandatory for tuples. To avoid that people ask the question again for let expression, we add a sentence in 7.4.3.
In Section 8.2.2, in Classifier well-formedness rules, 'collectionTypes' is used instead of 'collectionType'. This is not correct since in OCL, by convention, when not provided explicitly the name of an opposite role takes the name of the target class with first letter lowerized.
Specification: Object Constraint Language, formal/06-05-01 Section: 7.6 Collection Operations Summary: The concept of transitive closure is very useful for specifying well-formedness constraints on binary relations. For a binary relation r:A->A and elements x,y,z in A, r(x,y) is true when r relates x to y and r is transitive whenever for any x,y,z in A, r(x,y) and r(y,z) imply r(x,z). The transitive closure of a binary relation r:A->A is the smallest relation, ^r:A->A, that contains r and is transitive. In the UML specification, the definition of Classifier::allParents() : Classifier[*] as “all the direct and indirect ancestors of a generalized Classifier” could be equivalently paraphrased as the transitive closure of the Classifier::parents() : Classifier[*] relation. Specifying the notion of transitive closure for the OCL specification can be problematic as this notion refers to a meta-property not expressible in first order logic (i.e., the smallest relation satisfying a given property). However, the notion of transitive closure can be specified in the context of a particular API for evaluating OCL iterator expressions such as that of the Eclipse OCL implementation of the OCL2.0 specification: http://help.eclipse.org/ganymede/index.jsp?topic=/org.eclipse.ocl.doc/references/overview/OCLOverview.html http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.mdt/org.eclipse.ocl/plugins/org.eclipse.ocl/src/org/eclipse/ocl/internal/evaluation/IterationTemplateClosure.java?root=Modeling_Project&view=markup A synopsis of the algorithm for computing the transitive closure as an OCL iterator expression is available here: http://dev.eclipse.org/newslists/news.eclipse.modeling.mdt.ocl/msg01390.html
Erroneous operation names 'isOclType' and 'asOclType'. The operation 'isOclType' appears four times throughout the document. I presume it refers to 'oclIsTypeOf'. The operation 'asOclType' appears six times throughout the document. I presume it refers to 'oclAsType'.
The specification of the UnlimitedNatural type is largely missing and often trivially inconsistent.
The attached surprisingly large set of revised text recommendations endeavours to resolve every inconsistent use of invalid and null/void types and the failure to update the specification when undefined was split into null and invalid. The recommendations also correct many conversion errors that crept in when Word Processor formats were changed. Once these changes are incorporated, a very careful proof read against at least Annex A of 03-01-07 should be performed. The initial discussion identifies that the approved resolutions of Issues: 6611, 10433, 10434, 12349, 12378, 12484 and 12485 are at best deficient
The well-formedness constraints for IteratorExp are confusing, incomplete and sometimes wrong.
The OCL 2.0 specification would be much easier to read if: 1) The PDF had a full set of titles visible in the bookmarks: 8.3.*, Annex A.2 , Annex B and Index are missing completely. A.1 and A.3 apppear as subsections of 13.3. 2) There are a number of large sections such as 8.3.*, 9.3 and 10.4 with unnumbered headings for each AS or CS class. [11.5 is much better in this respect.] These are not in alphabetical order, not page aligned and not particularly distinct. It would be helpful to a) give them numbers so that they appear in the Bookmarks and are more distinct. b) put them in alphabetical order. [c) consider page aligning them.] [It would be good if the index was much more comprehensive too. e.g "at", "null", "any", "iterator", "UnlimitedNatural" ...]
Issue 7341 resolved that a bad oclAsType in 7.4.6 should return invalid. Issue 10437 resolved that the revised text for bad oclAsType in 11.2.5 should return null. Issue 6532 resolved that oclAsType in 7.5.9. return a Classifier. The changed specification has OclType.
Description: 9.3 Concrete Syntax As a convention to the concrete syntax, conflicting properties or conflicting class names can be aliased using the «_» (underscore) prefix. Inside an OCL expression that is written with the concrete syntax, when a property name or a class name is found to start with a «_›, firstly the symbol is lookup in the metamodel. If not found, the same symbol with the «_» skipped is tried. Should be As a convention to the concrete syntax, conflicting properties or conflicting class names can be aliased using the «_» (underscore) prefix. Inside an OCL expression that is written with the concrete syntax, when a property name or a class name is found to start with a «_», the symbol with the «_» skipped is looked up in the metamodel. Explanation: Consider that some class in the metamodel has two properties called '_self' and 'self' correspondingly. With the resolution rule defined in 9.3 one can never access 'self' property. On one hand, you cannot refer to it directly because it clashed the keyword self. One the other hand, '_self' would refer to '_self' property according to 9.3. Thus, both variants 'aClass.self' and 'aClass._self' are not helpful here.
MDT OCL implementation has assumed that OrderedSet is a subtype of Set. It has become clear (11.6.3) that this assumption was erroneous. As a result, operations which are defined on Sets in the standard library (like including, excluding, intersection, union, etc.) must be undefined on OrderedSet. However, many clients (including the ones of Operational QVT) have already written code relying on this behaviour (i.e. considering that OrderedSet is a subtype of Set, they used operations like including()). It would be very helpful to define such operations on OrderedSet. It would be also important to define these counterpart operations so that they would keep the order of the elements of the initial OrderedSet, e.g: including(object : T) : OrderedSet(T) The OrderedSet containing all elements of self plus object added as the last element. post: result = self.append(object)
Issue 9913 defines the missing InvalidLiteralExpCS and NullLiteralExpCS, but they are never referenced in the grammar. Suggest: Add to PrimitiveLiteralExpCS [E] PrimitiveLiteralExpCS ::= NullLiteralExpCS [F] PrimitiveLiteralExpCS ::= InvalidLiteralExpCS and [E] PrimitiveLiteralExpCS.ast = NullLiteralExpCS.ast [F] PrimitiveLiteralExpCS.ast = InvalidLiteralExpCS.ast (not forgetting UnlimitedNaturalLiteralExpCS
The definition of the CollectionRangeCS grammar is CollectionRangeCS ::= OclExpressionCS[1] ‘,’ OclExpressionCS[2] but everywhere else the operator is '..' Suggest change to CollectionRangeCS ::= OclExpressionCS[1] ‘..’ OclExpressionCS[2]
Define the concrete syntax of a simpleNameCS to avoid punctuation collisions, support Unicode characters, and add a double quoted form with escape sequences for awkward names. Define the concrete syntax of a StringLiteralExpCS to support escape sequences for awkward characters. Define the concrete syntax of RealLiteralExpCS and IntegerLiteralExpCS. Define a variety of effectively reserved words such as true, self, Bag, String as reserved.
The discussion of Issue 12953 suggests that two members of the RTF agreed that is unclear what T in e.g Set's including(Object : T) means. The first paragraph of Section 11.6 makes clear that the intent of the specification applies to e.g. Set(T) and so the well-formedness rules in 11.7 refer to e.g. Set(T)::including(Object: T), so T is the known element type of the collection. It is therefore a static error to attempt to invoke Set(T) including for an object incompatible with the known element type T. It would be helpful for the Section headings in 11.7 to have a (T) appended so that the 11.6 specification of T was clearly carried over from 11.6 to 11.7. e.g. Replace 11.7.1 Collection by 11.7.1 Collection(T)
The Collection(T)::product(c2 : Collection(T2))
signature carefully uses T2 to distinguish self and argument element types.
The same distinction is missing from
Collection(T)::"="(c : Collection(T))
Collection(T)::"<>"(c : Collection(T))
Collection(T)::includesAll(c : Collection(T))
Collection(T)::excludesAll(c : Collection(T))
Set(T)::union(s : Set(T))
Set(T)::union(b : Bag(T))
etc etc
The current definition makes at least one of
Set{1.0}->excluding(1.0) = Set{1}->excluding(1)
Set{1}->excluding(1) = Set{1.0}->excluding(1.0)
invalid through lack of a suitable collection operation.
For some operations, such as union, a T2 conforms to T well-formedness constraint is appropriate,
but for others, such as removeAll, T2 and T can be independent.
Issue 11098 resolved the missing precedence of let-in as lowest. This requires "2 * let a:Integer=1 in a + 1" to be interpreted as "(2 * (let a:Integer=1 in a)) + 1" making use of a non-trivial let body surprising and needlessly complicated. The problem with the open-ended right hand side can be resolved by assigning let-in the highest atomic expression precedence and defining its resolution as right-associative. The above example then has the obvious meaning "2 * (let a:Integer=1 in (a + 1))". Issue 6544 introduces ^ and ^^ at higher precedence than . and ->. However since these operators can only return left hand arguments for each other, there is no need to assign these to different levels. if-then-else-endif has an intermediate precedence in OCL 2.1. Since this term has keywords at start and end, the term is equivalent to an atomic expression. In so far as precedence is meaningful it is a high precedence. Parentheses should be bulletted at high precedence. Non commutative operators such as / have no defined order of evaluation leaving the value of "8 / 4 / 2" undefined. Binary operators should be specified as left-associative; i.e "(8 / 4) / 2". Section 9.3.2 duplicates 7.4.7.
[Splitting a major issue off from a number of minor issues in 14357, so that the resolutions do not get confused.] Define a variety of effectively reserved words such as true, self, Bag, String as reserved. Define which Complete OCL reserved words are Essential OCL reserved words.
Disambiguating rule 1 for TupleLiteralExp requires each VariableDeclaration to have a type and initExpression. However some examples in 7.5.15 omit the type, which is easily inferred from the initializer. However neither 8.3.7 nor 9.3 specifies this inference. Presumably the type is optional and to be inferred when omitted.
The expression 'a'.oclAsType(String) is not well-formed since the invocation of oclAsType is an OperationCallExpCS[E] for which String must be an OclExpressionCS. String is intended to be a literal expression with a Classifier value, but there is no well-formed OclExpressionCS that can represent such a value. Syntactically: String could be a VariableExpCS but is not the name of a visible VariableDeclaration. String could be a PropertyCallExpCS[B or C] or AssociationClassCallExpCS[B] but is not the name of a property. A TypeLiteralExpCS is required to allow use of at least typeCS[A] and more flexibly any typeCS.
The second half of 7.3.3 uses a named-self syntax that is missing from 12.2.5. context c : Company inv: c.numberOfEmployees > 50
When Issue 9796 updated terminology to use PropertyCallExpCS, attrOrAssocContextCS should have been updated to propertyContextCS.
Given the following:
context MyClass
def : isaMethod() : Boolean =
let Collection(Operation) myOperations = oclType().oclAsType(Class).ownedOperations()
in myOperations->exists(name = 'isaMethod')
is the value of isaMethod() true or false?
This is a more fundamental way of looking at the AST serializability problem in Issue 12854. (The suggested referredDefinition : Constraint [0..1] will not work because there may be 3 operation constraints and two property constraints.)
isaMethod() = false: OCL defininitions are not first class features and so there is no need to support their serialization.
isaMethod() = true: OCL definitions do as implied by Section 12.5 and provide reusable sub-expressions that can be used in an identical way to an atribute or operation.
It seems that an OCL evaluation needs to be defined in the following way.
Phase 1. Load MOF/UML meta-models and OCL contributions
Phase 2: Merge OCL definitions into MOF/UML meta-models
Phase 3: Execute the OCL to support queries/invariants/... on models
Phase 2 solves 12854 by requiring a merged meta-model to reify all definitions.
How the merged model is serialized is an implementation issueThe absence of synthesized and inherited attributes in 12.2 makes it unclear how an environment is maintained and so makes it unclear whether OCL supports forward and/or backward references. Presumably both forward and backward references are allowed, so a two phase behaviour is needed to enter all definition names in the environment(s) in phase 1 so that they are visible for lookup in phase 2.
12.1, 12.2 refer to UML 1.4. 12.1.1, 12.9, 12.12 defers until UML 2.0 is defined. 12.5, 12.8 uses Attribute and AssociationEnd rather than Property 12.5.1[1], 12.6.1[1], 12.7.1[1], 12.7.3[1] make use of self.constraint.stereotype.name. Constraint has keywords rather than stereotypes
12.5 define a definition body as one or more LetExps. No example wraps the expression as a LetExp. Is this an obsolete specification or an unobserved AST structural constraint? 12.5 defines synthesis of a variable or function, but fails to distinguish these from the equivalent property or operation
12.12: getClassifier and getPackage in text, but findClassifier and findPackage in signatures
12: Why no applicability to Essential MOF models? Although EMOF::Operation has no precondition feature, there is no problem in an operationContextDecl imposing a truth upon the operation. Similarly, if Initial value and Derived values are defined as Constraints in the same way as PreConditions, then the propertyContextDecl can constrain EMOF by imposing a truth upon the Property.default : String even though String is not an Expression
12.12 para 3 "OCl" for "OCL". 12.8 para 1 last sentence, 12.9 para 1 last sentence; both are unreadable. 12.12.2 No [B] rule 12.12.1/12.12.2 contextDeclCS/contextDeclarationCS
12.5.1[3], 12.6.1[2], 12.7.1[2], 12.8.1[2] are TBD.
12.2 defines a syntax for a standalone OCL document, but provides no mechanism to assist an implementation in locating packages or to partition into multiple reusable documents. a) Suggest addition of an ImportDeclarationCS ImportDeclarationCS ::= import StringLiteralExpCS where StringLiteralExpCS is a URI whose MOF/UML model content an implementation should make visible within the root environment. import is a new reserved word. b) Suggest addition of an IncludeDeclarationCS IncludeDeclarationCS ::= include StringLiteralExpCS where StringLiteralExpCS is a URI whose OCL document content an implementation should interpret (at most once) before proceeding. include is a new reserved word. c) Suggest addition of an OclDocumentCS OclDocumentCS ::= (ImportDeclarationCS)* (IncludeDeclarationCS | PackageDeclarationCS[A])* d) Suggest an OclPackage to own the Constraints for each Package and bypass the problem that Constriants do not have distinguishable names as required by Package content.
The iterators of LoopExp and LoopExpEval are not ordered, but the well-formedness constraints on them use ->at() which is only available for ordered collection. Usage of the AST property is subject to a variety of spelling, ordering and multiplicity inconsistencies.
Section 7.6.3 and 7.6.4 define extended variants of forAll and exists that have two iterators.
Figure 8.2 and Figure 13.3 show an unordered * multiplicity for LoopExp.iterator. The positioning of the VariableExp.referredVariable 0..1 multiplicity makes the diagram easy to mis-read.
Section 8.3.1 LoopExp defines iterator as "The iterator variables. These variables are, each in its turn, " implying an ordered collection.
Section 8.3.7 LoopExp [2] and [3] use iterator->forAll implying a collection.
Section 9.3 IteratorExpCS synthesized attributes use iterators->at(1) and at(2) requiring an ordered collection.
Section 9.3 IterateExpCS concrete syntax supports at most one iterator and one accumulator.
Section 9.3 IterateExpCS synthesized attributes use iterator.initExpression requiring a non-collection.
Figure 10.7 shows LoopExpEval.iterators as unordered 1..n.
Section 10.3.1 LoopExpEval defines iterators as "The names of the iterator variables".
Section 10.3.7 IterateExpEval [1] uses iterators->at(1) and iterators->at(2) implying an ordered collection with upper bound 2.
Section 10.3.7 LoopExpEval [1] has a two way if = 1 else, implying the upper bound is 2.
Section 10.3.7 LoopExpEval [3] uses iterators->at(1) and iterators->at(2) implying an ordered collection with upper bound 2.
Section 11.9.1 defines the mapping of forAll to iterate for multiple iterators, but IterateExpCS only supports a single iterator.
The above suggests that the specification should consistently treat iterators as having a 1..2 {ordered} multiplicity.
13.1 states that "EssentialOCL is the package exposing the minimal OCL required to work with EMOF. EssentialOcl depends on the EMOF Package." 13.1 states that "For convenience, because BasicOCL (respectively EssentialOCL) is - conceptually a subset of the complete OCL language for UML superstructure." MOF 06-01-01 defines EMOF and Figure 12.1 clearly shows a merge of Reflection. Therefore EssentialOCL has reflection. UML superstructure has almost everything, so BasicOCL has reflection. Issue 12951 provides the following revised text for 13.2. "The EMOF Reflection capability is not merged to the metamodel." This contradicts the above. If this is intended, OCL needs to redefine an EMOF as perhaps OMOF with the appropriate merges. Issue 9171 discusses why reflection is not available at the modelling level, but is available at the meta-modelling level. Presumably the intent is that MOF Reflection is present in the OCL meta-model, but is not necessarily present in the constrained models and so is not necessarily useable in OCL expressions. The revised text for Issue 12951 should be revisited to align with Issue 9171.
The OCL specification does not make clear whether an iteration over a Collection of Collections should operate on the flattened or unflattened source. The Appendix through lack of specification and explicit specification of flattening would suggest that the iterator for a Collection of Collections is a Collection. Most of the description in Section 7.6 is neutral through use of the term element. However In 7.6.1 "The variable v is called the iterator. When the select is evaluated, v iterates over the collection and the boolean expression-with-v is evaluated for each v. The v is a reference to the object from the collection and can be used to refer to the objects themselves from the collection." implies that the source collection is flattened; at least in OCL 2.0 where collections were not first class objects, this is a contradiction. In OCL 2.1, collections are nearly first class objects and so perhaps there is just an ambiguity. Similarly: In 7.6.2 "When we want to specify a collection which is derived from some other collection, but which contains different objects from the original collection (i.e., it is not a sub-collection), we can use a collect operation." In 7.6.3 "The forAll operation in OCL allows specifying a Boolean expression, which must hold for all objects in a collection:" In 7.6.4 "The exists operation in OCL allows you to specify a Boolean expression that must hold for at least one object in a collection". Suggest that the specification of iteration avoid the use of 'object', sticking only to 'element'. A clarifying paragraph at the end of 7.6.5 should state that for a 0 or 1 deep Collection source, element is a non-Collection object. For an N-deep Collection source, element is an (N-1)-deep Collection.
OCL 2.1 currently specifies an informal run-time meta-model in which all types conform to OclAny. Contributions to this meta-model come from - the user meta-model(s) - the standard library and its extensions - additional constraints Problem 1: An OCL AST for an OperationCallExp has a referredOperation that must be able to reference an operation that may come from any of these sources. Issue 12854 raised the problem of referencing additional operations and attributes. Problem 2: The almost trivial problem of referencing standard library features has not been raised. If an AST is to be portable between one OCL tool and another there must be a standard URI by which for instance OclAny::= is referenced. Where is this URI specified? Problem 3: The semantics of ambiguity resolution between alternative contributions is unclear. UML appears to leave overloading as a semantic variation point, so UML compliance is not helpful. Issue 14591 suggested that a first phase execution created at least a composite UML meta-model. Problem 4: OCL 2.1 made clear that there is no reflection at run-time, and introduced OclAny::oclType to compensate. This provides very limited capabilities, in particular there is no counterpart to Element::container(). A formal run-time model and meta-model can solve these problems. The run-time model is the OCL library model, it's meta-meta-model is the OCL library meta-model and it's meta-meta-meta-model is MOF/UML. NB The OCL library meta-model is not the OCL meta-model. The OCL library model comprises primarily oclstdlib::Classifier instances, one of which is named OclAny. OclAny::oclType() returns its oclstdlib::Classifier (NB not a uml::Classifier). The oclstdlib::Classifier::conformsTo property (like but not uml::Classifier::general) contributes to the reified type conformance hierarchy. The oclstdlib::Classifier::operations property (like but not uml::Classifier::operations) unifies the three sources of available operations, and three different derivations of oclstdlib::Operation accommodate the three types of contribution. The oclstdlib model therefore integrates the user's UML meta-model with the standard library and additional constraints and is built during the first phase of execution. The oclstdlib meta-model is much simpler than MOF; there is no need for Associations and ConformsTo is the only Relationship. The semantics of the oclstdlib model defined independently of UML ensure a clear definition of the meaning of OCL execution. The oclstdlib model should make no pretence at being UML because it is fundamentally different. One form of oclstdlib::Operation integrates a reference to a uml::Operation into a uniform behavioural structure. oclstdlib::Classifier ::conformsTo provides the modification of the user meta-model to insert OclAny as the bottom type, without modifying the user meta-model. With an oclstdlib metaModel, OclAny could provide reflective capabilities such as oclContainer(), oclContents(), oclGet(), oclSet() etc that provide useful reflective capabilities. self.oclType().operations can satisfactorily return a collection of operations even though the operations come from three diverse sources. self.oclType()->closure(conformsTo) will return the type conformance ancestry.
subclause [4] It reads: names->tail() It should read: names->subSequence(2, names.size()) Rationale: tail() is not an operation of Sequence
(Related to Issue 7539) It reads: isOclKind It should read: oclIsKindOf Rationale: per section 7.5.9 the operation name is "oclIsKindOf"
Related to Issue 7539) It reads: isOclKind It should read: oclIsKindOf Rationale: per section 7.5.9 the operation name is "oclIsKindOf"
(subclause [4])
It reads: let firstNamespace : ModelElement ... in ...
self.nestedEnvironment().addNamespace(firstNamespace)
It should read:
self.nestedEnvironment().addNamespace(firstNamespace.oclAsType(Namespace))
Rationale: the signature of addNamespace is (ns: Namespace) as defined in 9.4.1 subclause [7]
It reads: lookupAttribute It should read: lookupProperty Rationale: on section 8.3.8 an operation lookupProperty(attName : String) : Attribute is added to Classifier. The operation lookupAttribute is never defined in OCL or UML infra/superstructure (v2.1.2)
subclause [10]) It reads: let foundElement ... in result = if foundAttribute ... else foundElement ... (foundAttribute is undefined, I understand it means to "foundElement")
There are references to Attribute (from Core) in sections 7.5 , 8.2, 8.3.2, 8.3.8, 8.3.9, 9.3, 9.4.1, 10.3.2, 10.4.1, 10.4.3 while the UML infrastructure defines Property instead of Attribute
9.4.2 NamedElement
NamedElement, as defined by OCL, links to ModelElement (from Core) and has an operation getType(): Classifier
Postconditions are given when the referred modelelelement is an instance of Classifier, VariableDeclaration or State.
However, from subclause [4] of section 9.4.1 it follows that the referred modelelelement may also be an instance of Namespace.
(let firstNamespace : ModelElement = lookupLocal( names->first() ).referredElement, where lookupLocal returns an OCL NamedElement)
In the UML Infrastructure, Namespace specializes Core::NamedElement, which does not defines a type attribute (Core::TypedElement does)
Namespace is a generalization of Classifier.
At least, add:
post: referredElement.oclIsKindOf(Namespace) implies
result = -- TBD: when aligning with UML 2.0
Should it be result.oclIsUndefined() ?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.
The OrderedSet well-formedness constraints in 11.7.3 appear to have been
copied and pasted from Sequence. They need revision to consider the Set
consequences of .
Addition operations (includes, insertAt, union, append, prepend) have a
post-condition that the size increases, which is clearly not the case if
an additional element is equal to a pre-existing element.
In the particular case of insertAt there is an ambiguity as to whether
the insert index is the pre or post index. For instance when inserting 3
at index 5 into OrderedSet{1, 2, 3, 4, 5, 6} the pre-index insertion
yields OrderedSet{1,2,4,3,5,6} whereas the post-index insertion yields
OrderedSet{1,2,4,5,3,6}. While the post-index insertion satisfies the
'post: result->at(index) = object' constraint, it is presumably not the
intent.
The specification is very vague as to how and when a non-collection is converted to a collection.
11.2.3 states that 'If the source is the null literal, it is implicitly converted to Bag{}'.
7.5.3 states that 'Such a single object can be used as a Set as well. It then behaves as if it is a Set containing the single object. The usage as a set is done through the arrow followed by a property of Set.'
The collection type inconsistency between Bag{} and Set{x} makes compile-time type resolution difficult, since the null-ness of x cannot be known till run-time. It would be better to have either Set or Bag uniformly as the conversion collection type. Bag{} as the least useful seems more appropriate.
When a conversion is applicable is unclear.
In the example, self.manager->isEmpty() is intended to be interpreted as
if self.manager.isUndefined() then Set{} else Set{self.manager} endif->isEmpty()
so that null->isEmpty is also valid.
However is
null->excludesAll(null)
equivalent to
Bag{}->excludesAll(Bag{})
and so true?
A simple policy of 'wherever a collection is required and a non-collection is provided perform an implicit conversion to collection-literal' resolves this.
However are
null = Bag{}
or
Bag{} = null
both equivalent to
Bag{} = Bag{}
and so true?
In this case we have a problem of asymmetric overloading.
null = Bag{} satisfies the signature for OclVoid::=(OclAny) and so returns false.
Bag{} = null could satisfy the signature for Bag::=(Bag) and so return true with the help of an implicit conversion.
Presumably an additional OclVoid::=(Collection) overload is needed to restore symmetry.
Collection::flatten is overloaded for Bag, Sequence and Set but not for OrderedSet.
excluding and including are defined for Bag, Sequence and Set but not OrderedSet or Collection. The Collections would be more consistent with an OrderedSet::excluding and an OrderedSet::including. With all concrete Collection types defining excluding and including, the abstract Collection could also define Collection ::excluding and an Collection ::including supporting fully polymorphic addition and querying of collections.
The minus operation should be provided for OrderedSet as well as Set.
11.2.3 states clearly that "Any property call applied on null results in OclInvalid, except for the operations oclIsUndefined() and oclIsInvalid()." This is being revised by Issue 14197 in OCL 2.3 to: "Any property call applied on OclVoid results in invalid, except for the operations oclIsUndefined(), oclIsInvalid(), =(OclAny) and <>(OclAny)."
11.2.4 states clearly that "Any property call applied on invalid results in OclInvalid, except for the operations oclIsUndefined() and oclIsInvalid()." This is being revised by Issue 14197 in OCL 2.3 to: "Any property call applied on OclInvalid results in invalid, except for the operations oclIsUndefined() and oclIsInvalid()."
Therefore invalid.oclIsTypeOf(OclInvalid) => invalid and null.oclIsTypeOf(OclVoid) => invalid.
But the above are widely used in the specification as for example:
"oclIsUndefined() : Boolean
Evaluates to true if the self is equal to OclInvalid or equal to null.
post: result = self.isTypeOf( OclVoid ) or self.isTypeOf(OclInvalid)"
clearly expecting isTypeOf (a typo) to return true/false, not invalid sometimes.
Issue 14197 relaxed the OclVoid property list to allow = and <>. Perhaps all oclXXX operations should have an explicitly defined semantics for OclVoid and OclInvalid, supporting rather than denying reflective usage of the values as in self.isTypeOf( OclVoid ).
OCL supports feature overloading and attempts to comply with UML. OCL does not define feature overloading itself. UML leaves feature overloading as a semantic variation point.
The OCL behaviour is therefore undefined. However a variety of behaviours particularly those involving null and invalid only make sense if operations are selected at run-time according to the dynamic type.
The example from an earilier pending issue:
Sequence(OclAny){3, 3.0, '3'}->count(-(-3)) = 2
wherein
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.
is difficult to realise if static type resolution is applicable in which case all pair-wise value comparisons would use OclAny::= rather than Real::=.
Suggest:
OCL define that features are selected dynamically at run-time.
8.3.8 states that in regard to allInstances
"returns all instances of the classifier and the classifiers specializing it. May only be used for classifiers that have a finite
number of instances. This is the case, for example, for user defined classes because instances need to be created explicitly,
and for enumerations, the standard Boolean type, and other special types such as OclVoid and OclInvalid."
While it is true that OclInvalid has exactly one instance, the corresponding return of Set{invalid} is not well-formed.
Therefore the invocation OclInvalid.allInstances() must return invalid.
Suggest:
Replace "and OclInvalid" by ". But not for OclInvalid, for which the return is invalid"
The Issue 14981 considered use of explicit null as a Collection.
11.2.3 states that 'If the source is the null literal, it is implicitly converted to Bag{}'.
Surely when the null arises as a navigation result, the isOrdered and isUnique characteristics of the navigated property should determine what CollectionKind the null result is converted to?
However meta-modelling tools and meta-modellers pay little attention to the isUnique and isOrdered characteristics of zero and unit multiplicity properties. Using this overlooked information may cause surprises.
Collection::sum is defined to exploit an associative and commutative T::+(T). However for an empty collection, the result must be a zero value of the user defined type and there is no mechanism to determine its 0. Suggest: require a T::zero() and provide corresponding Real::zero() and Integer::zero() and UnlimitedNatural() operations.
Issue 6555 introduced the 'missing' Collection::=(Collection(T)) and Collection::=(Collection(T)).
Issue 12948 changed Collection to conform to OclAny
This means that "Set{} = 1" is no longer self-evidently invalid.
According to the inherited OclAny::=(OclAny), "Set{} = 1" should be semantically legal and evaluate to false.
But if Collection::=(Collection(T)) fully occludes OclAny::=(OclAny) ,"Set{} = 1" should be a semantic analysis failure and so invalid.
Conversely "1 = Set{}" is OclAny::=(OclAny) and unambiguously false (until a Real::=(Real) overload is introduced to accommodate value rather object identity).
OCL does not specify any policy for static or dynamic resolution of overloads.
A Java-like policy of static determination of the most derived valid signature, then dynamic dispatch on the self object would seem appropriate, but:
let c1 : OclAny = Set{1}, c2 : OclAny = Set{1} in c1 = c2
must select OclAny::=(OclAny) as the static signature. Collection::=(Collection(T)) is not a derived operation with the same signature, so evaluation should use OclAny::=(OclAny) rather than Collection::=(Collection(T)) and give erroneous results swhen the collections are compared by object identity rather than collection kind and content.
Either:
OCL must specify multi-dimensional dynamic overload resolution on source and arguments
Or:
OCL should specify Java-like single-dimension dynamic overload resolution and the signature of derived operations such as Collection::=(Collection(T)) should be changed to match their inherited signature, i.e. to Collection::=(OclAny).
[Or:
All derived functionality must be folded into the base (OclAny) operation.]
Section 10 is suffering seriously from lack of update and review.
The old AssociationClassCall/AssociationEndCall/ModelPropertyCall spellings are in use throughout.
OrderedSetValue is omitted throughout.
UnlimitedNaturalExpValue is omitted throughout.
TypeExpEval is omitted throughout thereby avoiding tackling the irregular semantics of the oclIsKindOf argument.
'undefined' does not distinguish null and invalid and is variously undefined, void, UndefinedValue, OclVoidValue and UnspecifiedValue including a reference to UnspecifiedValueExp that does not exist. There should be just an OclVoidValue and an OclInvalidValue.
OrderedSet is not used where elements are clearly unique e.g. Sequence(LocalSnapShot).
OCL is regularly spelled ocl or Ocl as a non-word prefix.
An Element::indexNr is imposed on all Collection elements. Surely a distinct OrderedCollectionValue intermediate value should use the stronger OrderedCollectionElement.
It is not specified whether Element::indexNr indexes from 0 or 1 or indeed even monontonically.
Figure 10.4 omits many {ordered}and {unique} constraints.
Figure 10.4 omits LocalSnapShot.pred and succ.
10.2.1 Element assserts that Element is a tuple NameValueBinding.
10.2.1 OclMessageValue italicises the wrong use of 'name'.
10.2.2 LocalSnapShot[1] refers to ispre rather than isPre.
10.2.2 LocalSnapShot[2] asserts that the result of an implicit collect is a boolean (missing ->any).
10.2.2 ObjectValue omits the doubly-linked list validity constraint
10.2.2 TupleValue assserts that a NameValueBinding is an Element.
10.2.3 SequenceTypeValue omits a constraint on the sequential validity of Element.indexNr
10.2.3 LocalSnapShot uses notEmpty rather than nonEmpty()
10.3 para 2 refers to a non-existent OclEvaluation class
10.3 para 2 has erroneous figure references to 10.6,7 rather than 10.7,8
10.3.2 OperationCallExpEval relies on UML semantics, but fails to resolve UML's unspecified behavioural variation point on operator overload resolution. See Issue 15013.
10.3.2 OperationCallExpEval spells forAll as forall.
10.3.2 CollectionRangeEval uses isOclType(Sequence(Integer)). Any such use of collection types was invalid in OCL 2.0. Use of a collection type is not valid concrete syntax in OCL 2.1/2. The resolution of 10439 for OCL 2.3 provides concrete syntax support, but the semantics remains undefined although perhaps intuitively obvious.
As separately raised isOclType etc are incorrect spellings.
The x .. y syntax could be used to advantage in places such as 10.3.3 CollectionRangeEval.
The explicit iterator is unnecessary in for instance 10.2.2 TupleValue.
Figure 10.14 has layout problems.
Figure 10.14 shows instances <-> model associations for both Concrete and Abstract classes. The model for derived classes should be marked as derived.
10.4.2 BooleanLiteralExpEval has an unresolved MOF/UML alignment.
10.4.2 EvalEnvironment has a missing constraint on uniqueness of binding names.
10.4.2 IfExpEval has missing and operators
Generally: the constraints should be validated by an OCL checking tool.