Issue 1790: Lack of features commonly used in OCL
Issue 3513: OCL: Usage of qualifiers
Issue 5971: OCL 2: OrderedSet
Issue 5973: OCL 2: what is a collection?
Issue 6528: Provide access to the sender of a message
Issue 6530: status of objects and tuples
Issue 6533: Template return types in operation signatures
Issue 6534: Up- and Down-casts with oclAsType().
Issue 6535: Lack of operation specifications
Issue 6536: Additional annotations in the OCL Standard Library
Issue 6538: Exception of strict evaluation (implies)
Issue 6539: Exception of strict evaluation (forAll, exists)
Issue 6540: Exception of strict evaluation (queries)
Issue 6541: Exception of strict evaluation (=)
Issue 6547: Incomplete and missing well-formedness rules
Issue 6548: Satisfaction of Operation Specifications
Issue 6549: Satisfaction of Operation Specifications (2)
Issue 6550: Satisfaction of Operation Specifications (3)
Issue 6551: Add select/reject/collectNested to Collection
Issue 6553: Clarify the semantics of forAll
Issue 6554: Clarify the UML semantics of IfExpEval
Issue 6557: Introduce a "tuplejoin" operator
Issue 6559: Issue: Virtual machine
Issue 6561: Issue: Unspecified syntax and semantics for Integer, Real, and String
Issue 6563: Issue: Comments
Issue 6565: Issue: Grammar of OCL
Issue 6566: Issue: Abstract syntax tree
Issue 6571: Issue: Syntax of Operation Call, Iterator, and Iterate Expressions
Issue 6572: Issue: Parsing Tuple Types and Collection Types as Arguments
Issue 6573: Issue: OclAny operations of tuples and collections
Issue 6574: Issue: Signature of Environment
Issue 6600: The index seems incomplete
Issue 6601: compliance points strategies
Issue 6609: OclUndefined / allInstances() clarification.
Issue 6614: Example with TupleType
Issue 6879: The notation for testing the type of a metaclass is too verbose
Issue 6880: The notation for selecting elements should be more intuitive
Issue 6881: notation for selecting unique element within a list should be more concise
Issue 6882: There is no simple way to invoke an "if then else" on a collection
Issue 6883: The notation when nesting "if then else" is too verbose
Issue 6884: The notation when nesting "if then else" is too verbose
Issue 6885: Improve the notation when defining local variables
Issue 6886: Allow applying iteration operations on single objects
Issue 6887: Allow implicit type casting to boolean when a boolean is expected
Issue 6889: Automatic casting between strings and enumeration values
Issue 6890: Suppress the usage of an Ocl prefix in standard library operations
Issue 6891: Allow defining standard library functions
Issue 6892: Allow defining default values for parameters in operations
Issue 6893: Provide specific notational support when testing stereotypes
Issue 6894: Add a generic text formatter operator '%
Issue 6895: Make usage of tuples less complex and less verbose
Issue 7455: Add an import statement to OCL files (with package - endpackage block)
Issue 7457: Add a concrete syntax to allow OCL users to add additional IteratorExp’s
Issue 7466: rewrite well-formedness
Issue 7500: context Classifier (02)
Issue 7501: context Operation
Issue 7502: context Parameter::asAttribute(): Attribute
Issue 7503: context State::getStateMachine() : StateMachine
Issue 7504: context VariableDeclaration::asAttribute() : Attribute
Issue 7505: parameters of the referredOperation
Issue 7506: parameters of the referredOperation
Issue 7507: An additional attribute refParams lists all parameters of the referred
Issue 7508: 1] The type of the attribute is the type of the value expression.
Issue 7509: context LocalSnapshot
Issue 7510: outgoingMessages results in the sequence of OclMessageValues
Issue 7511: context IfExpEval inv:
Issue 7512: sub evaluations (in the sequence bodyEvals)
Issue 7513: sub evaluations (in sequence bodyEvals) have different environment.
Issue 7514: ocl message expression
Issue 7515: isSent attribute
Issue 7516: add ’and’ between both expression parts
Issue 7517: result value of an association class call expression evaluation
Issue 7518: value of an association end call expression evaluation
Issue 7519: missing ’inv:’ twice
Issue 7520: an iterate expression evaluation
Issue 7521: arguments
Issue 7522: inv: model.sentSignal->size() = 1 implies
Issue 7523: arguments of the return message of an ocl message expression
Issue 7524: Only one of the attributes isPost and isPre may be true at the same time.
Issue 7525: ’element’ should be ’elements’
Issue 7526: ’element’ should be ’elements’ (02)
Issue 7527: ’Element’ should be ’NameValueBinding’
Issue 7528: history of an object is ordered.
Issue 7529: The history of an object is ordered.(02)
Issue 7530: The operation allPredecessors
Issue 7531: elements in a tuple value
Issue 7532: value of an association class call expression
Issue 7533: result value of an association end call expression
Issue 7534: result value of an association class call expression
Issue 7535: result value of an association end call expression
Issue 7536: result value of an association end call expression (02)
Issue 7537: result value of an attribute call expression
Issue 7538: value of a collection item
Issue 7539: result value of a collection literal expression evaluation
Issue 7540: number of elements in the result value
Issue 7541: value of a collection range
Issue 7542: result value of an if expression
Issue 7543: elements in the result value
Issue 7544: value of a collection range
Issue 7545: sub evaluations
Issue 7546: sub evaluations (02)
Issue 7722: Section: 6.5.4.3 Combining Properties
Issue 7972: OCL Constraints in many levels
Issue 8620: Section: 7.4
Issue 8621: Section: 7.4.5
Issue 8622: Section: 7.5.3
Issue 8623: Section: 7.5.8
Issue 8624: Section: 7.5.9
Issue 8625: Section: 7.5.11
Issue 8626: Section: 7.5.13
Issue 8627: Section: 7.6.2
Issue 8628: Section: 8.2
Issue 8634: Section: 8.3
Issue 8635: Section: 8.3.4
Issue 8636: Section: 8.3.5
Issue 8637: Section: 8.3.1
Issue 8638: Section: 8.3.8
Issue 8639: Section: 9.1
Issue 8640: Section: 9.3 CollectionLiteralPartsCS
Issue 8641: Section: 10.1
Issue 8642: Section: 10.2
Issue 8643: Section: 10.2.1 Element
Issue 8644: Section: 10.2.1 NameValueBinding
Issue 8645: Section: 10.2.2 LocalSnapshot
Issue 8646: Section: 10.2.3 ObjectValue
Issue 8647: Section: 10.3
Issue 8648: Section: 10.3.1 LoopExpEval
Issue 8649: Section: 10.3.1 VariableExpEval
Issue 8650: Section: 10.3.2 AssociationEndCallExpEval
Issue 8651: Section: 10.3.2 OperationCallExp
Issue 8652: Section: 10.3.2 NavigationCallExpEval
Issue 8653: Section: 10.3.4 OclMessageArgEval
Issue 8654: Section: 10.3.4 OclMessageArgEval
Issue 8655: Section: 10.3.4 OclMessageExpEval
Issue 8656: Section: 10.3.5
Issue 8657: Section: 10.4
Issue 8658: Section: 10.4.3 IntegerLiteralExpEval
Issue 8659: Section: 11.2.1
Issue 8660: Section: 11.5.1
Issue 8661: Section: 11.5.4
Issue 8665: Section: 11.9.2 sortedBy
Issue 8666: Section: 11.9.3 & 11.9.4
Issue 8667: Section: 1 - 13
Issue 8789: The spec does not describes the syntax of integer, real or string literals
Issue 8808: Container of additional operations
Issue 10786: Naming of Constraints in OCL (02)
Issue 10787: OCL Collections applied to Properties
Issue 1790: Lack of features commonly used in OCL (ocl2-ftf)
Click here for this issue's archive.
Nature: Enhancement
Severity: Significant
Summary: Summary: The current specification for OCL lacks many of the features we commonly
use when doing formal specification of class interfaces, e.g. the ability
to specify the frame condition, the ability to specify postconditions
case-wise, the ability to specify when exceptions are thrown, etc.
To bring OCL closer to the state of the art, I would like to see these
considered as future extensions.
Resolution:
Revised Text: This issue needs to be resolved by the OCL 2.0 Finalization Task Force
Actions taken:
August 10, 1998: received issue
July 22, 1999: Deferred to UML 1.4/2.0.
December 2, 2004: Transferred to OCL 2.0 FTF
Discussion: This issue needs to be resolved by the OCL 2.0 Finalization Task Force. This is an UML 1.x issue transferred to the OCL 2 FTF.
Not all the extra facilities suggested by the text of this issue have been incorporated to the
OCL2 specification. Specific facilities for specifying constraints on class interfaces could
be considered within the context of an RTF.
Disposition: Deferred
Issue 3513: OCL: Usage of qualifiers (ocl2-ftf)
Click here for this issue's archive.
Source: Klasse Objecten (Dr. Jos Warmer, j.warmer@klasse.nl)
Nature: Uncategorized Issue
Severity:
Summary:
Qualifiers, written in brackets after the path name of a feature call,
can express two different things.
- qualifying use: A qualifier is used to give the qualifing value of
a qualified association (chapter 7.5.7).
- navigational use: A qualifier is used to refine the navigation to
association classes. While this navigational use is necessary
only with recursive associations, it is legal for every navigation
to an association class (chapter 7.5.5).
There is no way to distinguish these two sorts of qualifiers. There are
even expressions where both uses of the qualifiers would be necessary at
once, but this problem is restricted to such models that contain a
recursive, qualified association that has an association class.
Example where navigational and qualifing use cannot be distinguished:
There are two classes "Bank" and "Person", with a association between
them qualified by the account number (an Integer). The association end
at the class Person is named "customers".
An additional class "Company" has an attribute "customers" of type
Integer.
Now consider the subexpression "bank.person[customers]" in the context
of Company. "bank" clearly is a navigational expression. But "customers"
could either mean the attribute of Company, since Company is the context
of the expression (that is qualifying use as defined in 7.5.7); or
"customer" could mean the name of the association end (navigational use
as defined in 7.5.5). In the first case, the result type would be
Person, in the second case Set(Person).
Discussion: This is an OCL 1 issue transferred to the OCL 2 FTF. Deferred for timing constraints.
OrderedSet isn't discussed in the section on semantics
Deferred for timing reasons
OCL 2 doesn't really define what a collection is. In essence, a particular UML construct is arbitrarily designated as the OCL collection, and a series of properties are assigned to it This question arises in 2 different ways: - can you sub-class one of the concrete descendents in a UML diagram - by referring to the OCL package - and thereby add functionality to your own collection types - are all parameterised classifiers collections? if you define a parameterised class, how does an OCL user or environment know whether it's a collection or not? perhaps a stereotype should be intrroduced to allow for unambiguous resolution of these issues
Deferred for timing reasons
Consider the operation: Account::withdraw (amount: Money) Suppose a Person object sends the operation, and we want to state that the person has to be the owner of the account. Access to the sender of the message is needed. One might for instance imagine that the concrete syntax defines a keyword sender, and we could then write: context: Account::withdraw (amount: Money) pre: sender = self.owner
Discussion: Asking for an improvement of the language. Better solved in a RTF
Description: Provide a notation for the status of an object
Rationale:
It would be convenient to have a notation for denoting the status of an object. The type of such a status is a tuple. With such a notation it would be possible to compare the status of two objects or to compare the status of an object with a tuple. If not available, comparisons have to be performed on an attribute by attribute basis. Consider e.g.
p, p1 and p2 are Person(s)
p1.all = p2.all -- the 2 persons have same status, i.e.
is nicer and less error-prone than comparing all attributes:
p1.firstName = p2.firstName and p1.name = p2.name and ...
It would also be possible to compare with a tuple:
p.all = Tuple = Tuple {firstName = 'Alfred', name = 'Strohmeier', ...}
Discussion: Asking for an improvement of the language. Better solved in a RTF
Description: At some places, template parameter T appears in operation signatures, e.g., oclAsType(typename:OclType) : T (e.g., Sect. 6.2.1). At other places, this is denoted by "instance of OclType" or <<the return type of the invoked operation>>. It would be more meaningful when these informal return type descriptions are replaced by "OclAny". An additional constraint about the actual return type should be given when necessary.
Deferred for timing reasons
Description: This is not treated consistently throughout the document. As the formal semantics already allows both up- and downcasts, this should also be allowed in Sect. 2.4.6.
Deferred for timing reasons
Author: Stephan Flake (flake@c-lab.de) Description: Some operation specifications are still missing (they are marked by --TBD), e.g., oclAsType(). For this operation, a proposed specification is as follows (provided that OclType is a powertype): 1: context OclAny::oclAsType(typename:OclType) : OclAny 2: post: if OclType.allInstances() 3: ->select(t:OclType | self.oclIsTypeOf(t)) 4: ->exists(t:OclType | typename.conformsTo(t) or t.conformsTo(typename)) then 5: result = self and result.oclIsTypeOf(typename) 6: else 7: result = OclUndefined and result.oclIsTypeOf(OclVoid) 8: endif For a comparison, a complex OCL specification for ENUMERATION TYPE OclType can be found in the paper "OclType - A Type or Metatype?".
Deferred for timing reasons
Author: Stephan Flake (flake@c-lab.de) Description: The OCL Standard Library type system should make use of the notation offered by the official UML specification. In particular, abstract types (like OclAny, Collection(T)), datatypes (Integer, Set(T)), and enumeration types (OclState) can be denoted in italics and stereotyped, respectively. An ellipsis can be used to indicate that further types are imported from a referred UML user model. Moreover, OrderedSet(T) is missing in the OCL Standard Library Type type system.
Deferred for timing reasons
Author: Thomas Baar (thomas.baar@epfl.ch) Description: Exception from strict evaluation for IMPLIES is incomplete and contradicts set-theoretical semantics Rationale: On page 2-10 only one exception from strict evaluation for IMPLIES is given: False IMPLIES x == True However, based on the official semantics of IMPLIES given on page A-12 also x IMPLIES True == True
Deferred for timing reasons
Author: Thomas Baar (thomas.baar@epfl.ch)
Description: Exception of strict evaluation should be extended to forAll, exists
Rationale: Suppose r(o1) = undef, r(o2) = false What is value of Exp = {o1, o2}->forAll(x| r(x)) ? One could argue, because of strict evaluation, the value of Exp is undef. However, this would contradict the semantics of forAll als 'iterated and' given on page A.28. Similarily, for exists.
A note should be added on page 2-10 on evalution of expressions based on iterate.
Deferred for timing reasons
Author: Thomas Baar (thomas.baar@epfl.ch) Description: Strict evaluation for queries yields to contradictions in specifications Rationale: Queries can be specified in two ways, as invariants and in form of pre/post conditions. Suppose we specify query q(arg) as post: if (arg.oclIsUndefined()) then result = true else result = false endfi Having this, the following invariant should evaluate always to true: self.q(arg) = true or self.q(arg) = false. However, the invariant evaluates to undef once arg evaluates to undef thanks to strict evaluation. There is a misconception of strict evaluation when it comes to queries. The idea of queries is to have user-defined functions on classes. Why should the user be restricted only to such function which return undef once one of its arguments is undef? Using OCL, the user can even specify queries which can handle undefined arguments (e.g. see post specification of q(arg) ). Obviously, the post specification for q(arg) makes sense. The rule of strict evaluations for queries should be weakened to the case where the owner of the query (the object upon the query was called) is undefined.
Deferred for timing reasons
Author: Thomas Baar (thomas.baar@epfl.ch) Description: contradiction for evaluation of navigation expression Rationale: Suppose to have two classes A, B and an association with multiplicity 0..1 on B between them. The invariant context A inv: self.b = self.b is evaluated for an instance of A not having an associated instance of B to i) true, when the expression self.b has the type Set(B), because self.b is evaluated to emptyset and emptyset = emptyset is evaluated to true ii) undef, when the expression self.b has the type B, because self.b is evaluated to undef and undef = undef is evaluated to undef thanks to strict evaluation of '=' This is a contradiction since the expression self.b can be both of type set(B) and B! The examples also shows, that x = x is not a tautology unlike in almost all other logics including classical predicates logic. This is especially confusing because OCL claims to be based on classical predical logic!
Deferred for timing reasons
Author: Sten Loecher (Sten.Loecher@inf.tu-dresden.de) Description: OCL specification contains incomplete/ missing well-formedness rules Rationale: The following list contains the concerned classes of the OCL metamodel and provides information about the required changes to the OCL specification. AssociationClassCallExp: missing rule to describe the type AssociationEndCallExp: missing rule to describe the type AttributeCallExp: multiplicity, order, and unambiguousness must be considered CollectionLiteralExp: OrderedSetType must be added IteratorExp: well-formedness rules needed for iterator operations one, any, collectNested, and sortedBy OclMessageExp: missing rule to describe the type OclExpressionWithTypeArgExp: missing rule to describe the type OperationCallExp: missing rule to describe the type
Deferred for timing reasons
Author: Hubert Baumeister (baumeist@informatik.uni-muenchen.de), Rolf Hennicker (hennicke@informatik.uni-muenchen.de), Alexander Knapp (knapp@informatik.uni-muenchen.de) Description: Change Definition A.34 to allow the precondition to be weakened Rationale: It is commonly accepted that a program S satisfying an operation specification may weaken the precondition. This corresponds to Bertrand Meyer's view of software specifications as contracts between clients of a program and program provider. This is in accordance with the explanation following Def. A.34: "In other words, the program S accepts each environment satisfying the precondition as input and produces an environment that satisfies the postcondition." This sentence admits the possibility that S may be defined for environments not satisfying the precondition. However Def. A.34 requires S to be defined exactly on the environments for which the precondition holds. Therefore, we propose to replace Def. A.34 by: DEFINITION A.34 (SATISFACTION OF OPERATION SPECIFICATIONS) An operation specification with pre- and postconditions is satisfied by a program S in the sense of total correctness if the computation of S is a function fS such that the restriction of fS to the domain of R is a total function fS|_dom(R): dom(R) -> im(R) and graph(fS|_dom(R)) \subseteq R. Comment by Daniel Jackson (dnj@mit.edu) i'd be very wary of linking any particular notion of refinement to a modelling language. different circumstances might need different notions, and there's no reason that the language should be tied to one. i wonder, for example, if you've considered the difference between preconditions as disclaimers and preconditions as firing conditions. even for the standard notion of preconditions as disclaimers, your particular definition seems too narrow to me. requiring the program to be a function will rule out many reasonable implementations that are non-deterministic -- hash tables, for example.
Deferred for timing reasons
Author: Achim D. Brucker (brucker@inf.ethz.ch), Burkhart Wolff (wolff@informatik.uni-freiburg.de) Description: Change Definition A.34 to allow the precondition to be weakened Rationale: It is commonly accepted that a program S satisfying an operation specification may weaken the precondition. This corresponds to Bertrand Meyer's view of software specifications as contracts between clients of a program and program provider. This is in accordance with the explanation following Def. A.34: "In other words, the program S accepts each environment satisfying the precondition as input and produces an environment that satisfies the postcondition." This sentence admits the possibility that S may be defined for environments not satisfying the precondition. However Def. A.34 requires S to be defined exactly on the environments for which the precondition holds. Therefore, we propose to replace Def. A.34 by: DEFINITION A.34 (SATISFACTION OF OPERATION SPECIFICATIONS) An operation specification with pre- and postconditions is satisfied by a specification S if the restriction of S to the domain of R (denoted S|_dom(R)) is included in R, i.e. S|_dom(R) \subseteq R. This is equivalent to: \forall x, y. x:dom(R) & (x,y):S --> (x,y):R. In particular, S may be a program, i.e. a computation function in the sense of total correctness.
Deferred for timing reasons
Author: Hubert Baumeister (baumeist@informatik.uni-muenchen.de), Rolf Hennicker (hennicke@informatik.uni-muenchen.de), Alexander Knapp (knapp@informatik.uni-muenchen.de) Description: Change Definition A.34 to allow the precondition to be weakened Rationale: It is commonly accepted that a program S satisfying an operation specification may weaken the precondition. This corresponds to Bertrand Meyer's view of software specifications as contracts between clients of a program and program provider. This is in accordance with the explanation following Def. A.34: "In other words, the program S accepts each environment satisfying the precondition as input and produces an environment that satisfies the postcondition." This sentence admits the possibility that S may be defined for environments not satisfying the precondition. However Def. A.34 requires S to be defined exactly on the environments for which the precondition holds. Therefore, we propose to replace Def. A.34 by: DEFINITION A.34 (SATISFACTION OF OPERATION SPECIFICATIONS) An operation specification with pre- and postconditions is satisfied by a program S in the sense of total correctness if the computation of S is a function fS such that the restriction of fS to the domain of R is a total function fS|_dom(R): dom(R) -> im(R) and graph(fS|_dom(R)) \subseteq R.
Deferred for timing reasons
Author: Hubert Baumeister (baumeist@informatik.uni-muenchen.de), Rolf Hennicker (hennicke@informatik.uni-muenchen.de), Alexander Knapp (knapp@informatik.uni-muenchen.de) Description: Add select/reject/collectNested to Collection Rationale: The definition of any on Collection (page 6-16f.) uses select on Collection. However, select is not defined for Collection. Similarly, the definition of collect on Collection (page 6-17) uses collectNested on Collection, which is not defined on Collection. We therefore propose to add select and collectNested (and possibly reject) to Collection.
Deferred for timing reasons
Author: Hubert Baumeister (baumeist@informatik.uni-muenchen.de),
Rolf Hennicker (hennicke@informatik.uni-muenchen.de),
Alexander Knapp (knapp@informatik.uni-muenchen.de)
Description: Clarify the semantics of forAll
Rationale:
According to the informal explanation (page 6-16) the following Expression Set { 1 }->forAll(x | x/0 < 0) would evaluate to false. However, according to the OCL definition it evaluates to undefined. Thus we propose to omit "otherwise, result is false" in the informal explanation.
Deferred for timing reasons
Author: Hubert Baumeister (baumeist@informatik.uni-muenchen.de), Rolf Hennicker (hennicke@informatik.uni-muenchen.de), Alexander Knapp (knapp@informatik.uni-muenchen.de) Description: Clarify the UML semantics of IfExpEval Rationale: The specification on page 5-21 of the evaluation of if_then_else omits the case when the condition evaluates to undefined. Thus the sentence should read: "The result value of an if expression is the result of the thenExpression if the condition is true, it is the result of the elseExpression if the condition is false, else it is undefined."
Deferred for timing reasons
Author: Herman Balsters (h.balsters@bdk.rug.nl) Description: OCL 2.0 is not as expressive as SQL (as opposed to common belief) and needs to be extended to this end Rationale: In my paper "Modeling Database Views with Derived Classes in the UML/OCL-framework" of this years UML conference (see proc. pp. 295-309) I investigated the issue of expressibility of OCL 2.0 w.r.t. to the query langauge SQL. I have demonstrated in that paper that OCL 2.0 is not as expressive as SQL (as opposed to common belief), and that OCL needs an additional "tuplejoin" operator to achieve the desired result. If this issue cannot be dealt with in this phase, I propose it be retained and examined at the next stage.
This is a request to improve the language. Should better be solved in a RTF.
Description: The OCL 2.0 specification should be behaviour-oriented and not implementation-oriented (see section 4.3). Rationale: The idea of using OCL to describe itself is interesting from the research point of view, but unfortunately OCL is not a suitable metalanguage to define the meaning of other textual languages. I think that the best thing to do is to define a virtual machine and to describe the behaviour of the virtual machine using natural language. This technique was successfully used for languages like C, C++, Java, C#, and Prolog. I see no reasons why such a technique would fail for OCL. After all, OCL is less complex than modern programming language like C++, Java, or C#. A proper description and implementation of the OCL virtual machine will create all the conditions to have a language that is platform/tool independent.
This is a request to improve language definition. Should better be solved in a RTF.
Description: The specification does not describes the syntax of integer, real or string literals. Also, it does not contain the description of the allowed set of values. Rationale: Specifying the syntax and the semantics of basic types will increase the portability of OCL programs. In order to describe the semantics of basic types, the specification should describe the set of values, the allowed operations, and the standard used to perform the allowed operations. I think that it will be also useful to allow different types of integers and reals, like Integer(16), Integer(32), Integer(64), Real(32), and Real(64), in order to optimize the computational process.
This is a request to improve language definition and extend its expresiveness. Should better be solved in a RTF.
Description: OCL 2.0 comments start with -- Rationale: This means that an expression like --4 cannot be interpreted as an arithmetic expression without inserting at least one space between the first - and the second -. I think that this problem can be resolved if the OCL comments start with // instead of --.
Deferred for timing reasons
Description: The grammar presented in 4.3, which is in my opinion a semantic grammar, is not suitable to describe the syntax of OCL. Rationale: Introducing non-terminals like primary-expression, selection-expression, and operation-call-expression will solve all the problems and will reduce the number of ambiguities. Hence, the grammar contained in the specification will suffer less changes in order to be used to design and implement a deterministic parser. This is the case of the specifications for C, C++, Java, C#, and Prolog.
Decision deferred to an RTF. It would imply a lot of changes.
Description: Some of the elements presented in 3.3.10 (e.g. EnumLiteralExp, children of ModelPropertyCallExp) cannot be constructed without using semantic information (e.g. the type of the expression determines if a name denotes an attribute, an association end, or an operation). Rationale: Usually a parser produces an AST. The semantic analyser augments the AST by computing for each node from AST the values of the attached attributes. The semantic analysis also checks if there are static semantics errors and reports them. Using other terms in the AST and hence other non-terminals in 4.5 (e.g. dot-selection-expression, arrow-selection-expression, call-expression etc.) will solve this problem.
Decision deferred to an RTF. It would imply a lot of changes.
Description: Syntax for the above constructions is extremely ambiguous and it might involve backtracking.
Rationale: According to OCL specification
* self.f(x, y)
* Set{1,2,3}->select(x, y| x+y = 3)
* Set{1,2,3,4,5,6}->iterate(x; acc:Integer=0 | acc + x)
describe an operation call, an iterator, and an iterate expression.
In order to make the distinction between an iterator call and an operation call we need in this case a three token lookahead, starting from x. The problem gets even more complicated if we consider that an argument for an operation call can be an expression.
In order to solve this problem, which is a potential source of problems for the implementation (error-prone, inefficiency aso), we think that these OCL constructs should contain some extra syntax markers. There are several choices:
* change the comma marker from iterator calls to something else, maybe a semicolon
* add a syntax marker to an iterator name
* do not allow the default types
The above choices will allow to a deterministic parser to deal with the enumerated problems more efficiently. I do not agree with textual language in which variables are given a default type according to the context in which they are used, especially if these languages are design for industrial use. The same problems were in previous versions of C standard, which allowed implicit type int for variables in constructions like
x;
Now, the latest C standard states that variables with default type are not allowed.
Deferred for timing reasons
Description: One issue we have discovered is about expressions of the form: expr.oclAsTypeOf( Type ) The OCL standard does not support Type as a collection or tuple type. Rationale: We think that the syntax should be extended to support collection and tuple types. This will make the language more symmetric and increase the expressiveness of the language.
This issue asks for an improvement of the language. Should better be solved in a RTF.
Description: The OCL specification does not allow operations like = or <> to be performed tuple values. It also forbids operations like oclIsKindOf and oclIsTypeOf on collections. Rationale: Add such operations to tuple and collection types signatures directly or by inheritance, will make the language more powerfull (e.g. a set of dogs can be casted to a set of animals).
This issue asks for an improvement of the language. Should better be solved in a RTF.
Description: The specification (in the standard) of the Environment class is missing a few things that are used or referred to elsewhere in the standard; some are missing altogether and some are missing from the class diagram: The association from an environment to its parent. The operations lookupImplicitSourceForOperation, lookupPathName, addEnvironment Rationale: We show a more complete specification below. We also add a convenience method addVariableDeclaration; although not necessary as addElement can be used to add a VariableDeclaration, this operation avoids the need to construct the VariableDeclaration before adding it to the environment. The specification of the Environment operations uses various methods on the bridge classes; we have added these operations to the classes, as shown in the previous section about the bridge classes.
Deferred for timing reasons
The index seems incomplete and leaves out interesting items (e.g., the definition of standard library functions).
Deferred for timing reasons
The compliance points strategies mentioned in the OCL 2.0 spec are different from the UML 2.0 infra, super and MOF 2.0 specs. We need to align the OCL spec on this
Deferred for timing reasons
think the operation allInstances() is under-specified in the current version of the OCL 2.0 specification. It does not seem to be clear whether OclUndefined is included in the returned set or not: According to the 1.5 specification of allInstances(), the instances of all subtypes are included. OclVoid is a subtype of all other types, thus OclUndefined would be a part of the set. I assume this is not the intended behaviour. For example, the "all names must be different" expression example would always yield OclUndefined or false, but never true.
Deferred for timing reasons
Typo in an example with TupleType Section 7.5.15: In the example constraint, expression attr: Statistics : Set(TupleType(& This must be Tuple only, according to the concrete syntax.
Deferred for timing reasons
Suggestion: Use special characters to denote a call to oclIsKindOf and oclIsTypeOf. For instance, use '#ActionState' instead of 'oclIsKindOf(ActionState)' and use '##ActionState' instead of 'oclIsTypeOf(ActionState)'
This is a request to improve the language. Better solved in a RTF.
Suggestion: Use brackets as an alternate option to denote a call to the "select"
function. Notation: mylist[iterator | condition]
Example:
self.ownedElement[#Class and name="MyClass"]
-- #Class is a shorthand for oclIsKindOf(MyClass)
equivalent to :
self.ownedElement->select(oclIsKindOf(Class) and name="MyClass")
This is a request to improve the language. Better solved in a RTF.
Suggestion: Use brackets with a "!" prefixing mark
Example:
self.ownedElement[! #Class and name="MyClass"]
means
self.ownedElement->select(oclIsKindOf(Class) and name="MyClass")->first()
This is a request to improve the language. Better solved in a RTF.
Suggestion: Define an "alt" collection function, with a specific notation, as in:
mylist->alt(iterator | condition? thenExp, elseExp)
The expression elseExp is not evaluated if condition returns true
This is a request to improve the language. Better solved in a RTF.
Suggestion: Define a "switch" collection function, with a sepecific notation, as in:
mylist->switch( iterator | cond1 ? exp1, cond2 ? exp2, …, else ? expN)
The expressions cond2 is not evaluated if cond1 returns true and so on.
This is a request to improve the language. Better solved in a RTF.
Suggestion: Define a "switch" collection function, with a sepecific notation, as in:
mylist->switch( iterator | cond1 ? exp1, cond2 ? exp2, …, else ? expN)
The expressions cond2 is not evaluated if cond1 returns true and so on.
This is a request to improve the language. Better solved in a RTF.
This is to avoid using the unreadable and unfriendly "let … in …" notation.
Suggestion: Use the result of a variable initialization as in:
if (let c = self.address)="" then "UNKNOWN"
else if c.includes(Set{"Irak","Afganifsthan"}) then "DANGEROUS"
else "OK" endif endif endif …
This is a request to improve the language. Better solved in a RTF.
Use a DOT instead of an ARROW is this situation.
myinstance.anycollectionfunction() equivalent to
Set{myinstance}->anycollectionfunction(…)->first()
This is a request to improve the language. Better solved in a RTF.
Example1: if list.select(...) then … equivalent to
if list.select(...)->notEmpty() then …
Example2: if item then … equivalent to
if item<>OCLUndefined then ...
This is a request to improve the language. Better solved in a RTF.
Make optional the qualification of enumeration values. Example: Be able to write 'self.aggregationKind="Composite" ' as an alternative to 'self.aggregationKind=AggregationKind::Composite'.
This is a request to improve the language. Better solved in a RTF.
When a name conflicts happen, it should be possible to resolve by qualifying the
names.
This is a request to improve the language. Better solved in a RTF.
Allow defining standard library functions (including iteration operators) that have a variable number of parameters.
This is a request to improve the language. Better solved in a RTF.
Allow defining default values for parameters in operations
This is a request to improve the language. Better solved in a RTF.
Suggestion: Use the STAR character. Quotes could be used in case of blanks
characters in stereotype names.
Example: self.ownedElement.select(kindOf(Class) and *EJBEntity)
returns all the classes stereotyped by the EJBEntity stereotype or a derived
stereotype.
Example: self.ownedElement.select(kindOf(Class) and **EJBEntity)
returns all the classes stereotyped by the EJBEntity stereotype.
This is a request to improve the language. Better solved in a RTF.
Example: self.comment = "My name is %s" % self.firstname
This is a request to improve the language. Better solved in a RTF.
Suggestions:
- Make type spec of internal fields optional.
- Make field name in tuples optional (using positional access)
This is a request to improve the language. Better solved in a RTF.
1. Add an import statement to OCL files (with package - endpackage block). At the moment one can only reference a type from another package using its complete path name. It would be more convenient to be able to import a package or other model element in the OCL files and use the simple name of a type in the OCL expressions.
Deferred for timing reasons
Add a concrete syntax to allow OCL users to add additional IteratorExp’s. People using OCL have the need to define their own iterators and should be able to do so in a standardized way.
This is a request to improve the language. Better solved in a RTF.
We would like to be able to rewrite well-formedness rules like: context IfExp inv: self.condition.type.oclIsKindOf(Primitive) and self.condition.type.name = ’Boolean’ as context IfExp inv: self.condition.type.oclIsKindOf(Primitive) and This is more clear that the first expression where the matching is done by name. Because the metamodel resides on a level higher than the standard library, we need a way to get access to the standard library elements. One solution is to define a package ’StandardLibrary’ that contains a Classifier called ’StdLib’, that holds the following attributes: • + Collection: CollectionType; • + Set: SetType; • + OrderedSet: OrderedSetType; • + Sequence: SequenceType; • + Bag: BagType; • + String: Primitive; • + OclMessage: OclMessageType; • + OclVoid : VoidType; Other solutions might be possible, but the above has been proven to work in the Octopus tool.
Discussion: This issue will be deferred. There is a question of representing formally the standard library as an ordinary UML package, which is not going to be solved for OCL 2.1 release. Disposition: Deferred
def: allReceptions() : Set(Reception) = self.allFeatures->select(f | f.oclIsKindOf(Reception)) ==> should be: context Classifier def: allReceptions() : Set(UML14::CommonBehavior::Reception) = self.feature->select(f | f.oclIsKindOf(UML14::CommonBehavior::Reception))->collect( f | f.asReception() ) where asReception() is defined as operation to Feature: + asReception() : Reception
def: hasMatchingSignature(paramTypes: Sequence(Classifier)) : Boolean =
-- check that operation op has a signature that matches the given parameter lists
let sigParamTypes: Sequence(Classifier) = self.allAttributes.type in
(
( sigParamTypes->size() = paramTypes->size() ) and
( Set{1..paramTypes->size()}->forAll ( i |
paramTypes->at (i).conformsTo (sigParamTypes->at (i))
)
)
)
==> ’self.allAttributes.type’ should be ’self.Parameter.type->asSequence()’34. context Parameter::asAttribute(): Attribute pre: -- none post: result.name = self.name post: result.type = self.type post: result.multiplicity = 1 post: result.targetscope = ScopeKind::instance post: result.ownerscope = ScopeKind::instance post: result.ordering = OrderingKind::unordered post: result.visibility = VisibilityKind::private post: result.stereotype.name = ’OclHelper’ ==> ’result.multiplicity = 1’ should be ’result.multiplicity = Multiplicity::one’
post: result = if statemachine->notEmpty() then stateMachine else -- must be part of a composite state state.container.getStateMachine() endif context Transition::getStateMachine() : StateMachine post: result = if statemachine->notEmpty() then stateMachine else -- state is not empty state.getStateMachine() endif ==> in both expressions ’statemachine’ should be stateMachine
post: result.constraint.bodyExpression = self.initExpression ==> should be: post: result.constraint.bodyExpression.oclAsType(OCLContextualClassifier::Expre ssionInOcl).bodyExpression = self.initExpression
37. -- [2] The parameters of the referredOperation become attributes of the instance -- of OclMessageType context OclMessageType inv: referredOperation->size() = 1 implies self.feature = referredOperation.Parameter->collect(p | p.asAttribute().oclAsType(Feature) ).asOrderedSet() ==> should be: context OclMessageType inv: referredOperation->size() = 1 implies self.feature = referredOperation.Parameter->collect(p | p.asAttribute() ).asOrderedSet()
37. -- [2] The parameters of the referredOperation become attributes of the instance -- of OclMessageType context OclMessageType inv: referredOperation->size() = 1 implies self.feature = referredOperation.Parameter->collect(p | p.asAttribute().oclAsType(Feature) ).asOrderedSet() ==> should be: context OclMessageType inv: referredOperation->size() = 1 implies self.feature = referredOperation.Parameter->collect(p | p.asAttribute() ).asOrderedSet()
38. -- [3] An additional attribute refParams lists all parameters of the referred -- operation except the return and out parameter(s). context OperationCallExp def: refParams: Sequence(Parameter) = referredOperation.parameters- >select (p | p.kind <> ParameterDirectionKind::return or p.kind <> ParameterDirectionKind::out) ==> ’parameters’ should be ’Parameter’
context TupleLiteralExpPart inv: attribute.type = value.type ==> should be removed, class does not exist
Errors found in UML-based-semantics
1. context LocalSnapshot
def: let allPredecessors() : Sequence(LocalSnapshot) =
if pred->notEmpty then
pred->union(pred.allPredecessors())
else
Sequence {}
endif
def: let allSuccessors() : Sequence(LocalSnapshot) =
if succ->notEmpty then
succ->union(succ.allSuccessors())
else
Sequence {}
==> remove ’let’ from both expressions, add ’endif’ after the second-- that have been in the output queue of the object between the last
-- postcondition snapshot and its associated precondition snapshot.
context OclExpEval::outgoingMessages() : Sequence( OclMessageValue )
pre: -- none
post:
let end: LocalSnapshot =
history->last().allPredecessors()->select( isPost = true )->first() in
let start: LocalSnapshot = end.Pre in
let inBetween: Sequence( LocalSnapshot ) = start.allSuccessors()->excluding( end.allSuccessors())->including(
start ) in
result = inBetween.outputQ->iterate (
-- creating a sequence with all elements present once
m : oclMessageValue;
res: Sequence( OclMessageValue ) = Sequence{}
| if not res->includes( m )
then res->append( m )
else res
endif )
==> ’pre’ should be ’Pre’resultValue = if condition then thenExpression.resultValue else elseExpression.resultValue ==> missing ’endif’
4. -- [2] All sub evaluations (in the sequence bodyEvals) have a different -- environment. The first sub evaluation will start with an environment in which -- all iterator variables are bound to the first element of the source. Note that -- this is an arbitrary choice, one could easily well start with the last element -- of the source, or any other combination. context LoopExpEval inv: let bindings: Sequence( NameValueBindings ) = iterators->collect( i | NameValueBinding( i.varName, source->asSequence()->first() ) in bodyEvals->at(1).environment = self.environment->addAll( bindings ) ==> missing closing bracket before ’in’
5. -- [3] All sub evaluations (in the sequence bodyEvals) have a different
-- environment. The environment is the same environment as the one from the
-- previous bodyEval, where the iterator variable or variables are bound to the
-- subsequent elements of the source.
context LoopExpEval
inv:
let SS: Integer = source.value->size()
in if iterators->size() = 1 then
Sequence{2..SS}->forAll( i: Integer |
bodyEvals->at(i).environment = bodyEvals->at(i-1).environment
->replace( NameValueBinding( iterators->at(1).varName,
source.value->asSequence()->at(i) )))
else -- iterators->size() = 2
Sequence{2..SS*SS}->forAll( i: Integer |
bodyEvals->at(i).environment = bodyEvals->at(i-1).environment
->replace( NameValueBinding( iterators->at(1).varName,
source->asSequence()->at(i.div(SS) + 1) ))
->replace( NameValueBinding( iterators->at(2).varName,
source.value->asSequence()->at(i.mod(SS)) )) ) endif
==> two closing brackets before ’endif’ should be removed6. -- [2] The result value of an ocl message expression is the sequence of the -- outgoing messages of the ‘self’ object that matches the expression. Note that -- this may result in an empty sequence when the expression does not match to any -- of the outgoing messages. context OclMessageExpEval inv: resultValue = environment.getValueOf( ’self’ ).outgoingMessages->select( m | m.target = target.resultValue and m.name = self.name and self.arguments->forAll( expArg: OclMessageArgEval | not expArg.resultValue.oclIsUndefined() implies m.arguments->exists( messArg | messArg.value = expArg.value )) ==> add one closing bracket after expression
7. -- [4] The isSent attribute of the resulting ocl message value is true only if -- the message value is in the outgoing messages of the ‘self’ object. context OclMessageExpEval inv: if resultValue.oclIsUndefined() resultValue.isSent = false else resultValue.isSent = true endif ==> add ’then’ after ’oclIsUndefined()’
8. -- [1] An ocl message argument evaluation has either an ocl expression -- evaluation, or an unspecified value expression evaluation, not both. context OclMessageArgEval inv: expression->size() = 1 implies unspecified->size() = 0 expression->size() = 0 implies unspecified->size() = 1 ==> add ’and’ between both expression parts
9. -- [2] The result value of an association class call expression evaluation that
-- has qualifiers, is determined according to the following rule. The ‘normal’
-- determination of result value is already given in section 5.3.7
-- ("Well-formedness Rules of the Evaluations package").
==> missing ’context .... inv:’
==> missing brackets and comma; the whole expression should be:
let
-- the attributes that are the formal qualifiers. Because and
association
-- class has two or
-- more association ends, we must select the qualifiers from the other
end(s),
-- not from -- the source of this expression. We allow only 2-ary associations.
formalQualifiers : Sequence(Attribute) =
self.model.referredAssociationClass.connection->any( c |
c <> self.navigationSource).qualifier.asSequence() ,
-- the attributes of the class at the qualified end. Here we already
assume
-- that an
-- AssociationEnd will be owned by a Classifier, as will most likely be
the
-- case in the
-- UML 2.0 Infrastructure.
objectAttributes: Sequence(Attribute) =
self.model.referredAssociationClass.connection->any( c |
c <> self.navigationSource).owner.feature->select( f |
f.isOclType( Attribute ))->asSequence() ,
-- the rolename of the qualified association end
qualifiedEnd: String = self.model.referredAssociationClass.connection-
>any( c
|
c <> self.navigationSource).name ,
-- the values for the qualifiers given in the ocl expression
qualifierValues : Sequence( Value ) = self.qualifiers->asSequence() ,
-- the objects from which a subset must be selected through the
qualifiers
normalResult =
source.resultValue.getCurrentValueOf(referredAssociationClass.name)
in
-- if name of attribute of object at qualified end equals name of formal
-- qualifier then
-- if value of attribute of object at qualified end equals the value
given in
-- the exp
-- then select this object and put it in the resultValue of this
expression.
qualifiers->size <> 0 implies
normalResult->select( obj |
Sequence{1..formalQualifiers->size()}->forAll( i |
objectAttributes->at(i).name = formalQualifiers->at(i).name and
obj.qualifiedEnd.getCurrentValueOf( objectAttributes->at(i).name ) =
qualifiersValues->at(i) ))10. -- [2] The result value of an association end call expression evaluation that has
-- qualifiers, is determined according to the following rule. The ‘normal’
-- determination of result value is already given in section 5.3.7
-- ("Well-formedness Rules of the Evaluations package").
==> add ’inv’, remove ’implies’, add comma. It should be:
-- [2] The result value of an association end call expression evaluation that has
-- qualifiers, is determined according to the following rule. The ‘normal’
-- determination of result value is already given in section 5.3.7
-- ("Well-formedness Rules of the Evaluations package").
inv: let
-- the attributes that are the formal qualifiers
formalQualifiers : Sequence(Attribute) =
self.model.referredAssociationEnd.qualifier ,
-- the attributes of the class at the qualified end
objectAttributes: Sequence(Attribute) =
(if self.resultValue.model.isOclKind( Collection )
then self.resultValue.model.oclAsType( Collection ).elementType->
collect( feature->asOclType( Attribute ) )
else self.resultValue.model->collect( feature->asOclType( Attribute ) )
endif).asSequence() ,
-- the values for the qualifiers given in the ocl expression
qualifierValues : Sequence( Value ) = self.qualifiers.asSequence() ,
-- the objects from which a subset must be selected through the
qualifiers
normalResult =
source.resultValue.getCurrentValueOf(referredAssociationEnd.name)
in
-- if name of attribute of object at qualified end equals name of formal
-- qualifier then
-- if value of attribute of object at qualified end equals the value
given in
-- the exp
-- then select this object and put it in the resultValue of this
expression.
qualifiers->size <> 0 implies
normalResult->select( obj |
Sequence{1..formalQualifiers->size()}->forAll( i |
objectAttributes->at(i).name = formalQualifiers->at(i).name and
obj.getCurrentValueOf( objectAttributes->at(i).name ) =
qualifiersValues->at(i) ))11. -- [1] The condition evaluation corresponds with the condition of the expression, -- and likewise for the thenExpression and the else Expression. context IfExpEval inv: condition.model = model.condition thenExpression.model = model.thenExpression elseExpression.model = model.elseExpression ==> missing ’inv:’ twice
12. -- [1] The model of the result of an iterate expression evaluation is equal to -- the model of the result of the associated IterateExp. context IterateExpEval inv: result.model = model.result ) ==> remove last bracket
13. -- [4] The arguments of an ocl message expression evaluation must correspond to
-- the formal input parameters of the operation, or the attributes of the signal
-- indicated in the ocl message expression.
context OclMessageExpEval
inv: model.calledOperation->size() = 1 implies
Sequence{1.. arguments->size()} ->forAll( i | arguments->at(i).variable->size() = 1 implies
model.calledOperation.operation.parameter->
select( kind = ParameterDirectionKind::In )->at(i).name =
arguments->at(i).variable
and
arguments->at(i).expression->size() = 1 implies
model.calledOperation.operation.parameter->
select( kind = ParameterDirectionKind::In )at(i).type =
arguments->at(i).expression.model
==> missing ’->’ before ’at’, and missing final closing bracketSequence{1.. arguments->size()} ->forAll( i |
arguments->at(i).variable->size() = 1 implies
model.sentSignal.signal.feature->select(
arguments->at(i).variable )->notEmpty()
and
arguments->at(i).expression->size() = 1 implies
model.sentSignal.signal.feature.oclAsType(StructuralFeature).type =
arguments->at(i).expression.model
==> missing final closing bracket15. -- [5] The arguments of the return message of an ocl message expression
-- evaluation must correspond to the names given by the formal output parameters,
-- and the result type of the operation indicated in the ocl message expression.
-- Note that the Parameter type is defined in the UML 1.4 foundation package.
context OclMessageExpEval
inv: let returnArguments: Sequence{ NameValueBindings ) =
resultValue.returnMessage.arguments ,
formalParameters: Sequence{ Parameter } =
==> ’{’ should be ’(’ (twice), and ’}’ should be ’)’16. -- [1] Only one of the attributes isPost and isPre may be true at the same time. context LocalSnapshot inv: isPost implies isPre = false inv: ispre implies isPost = false ==> second invariant: ’ispre’ should be ’isPre’
17. -- [1] All elements belonging to a sequence value have unique index numbers. inv: self.element->isUnique(e : Element | e.indexNr) ==> missing context statement: context SequenceTypeValue, ==> ’element’ should be ’elements’
18. -- [1] All elements belonging to a set value have unique values. inv: self.element->isUnique(e : Element | e.value) ==> missing context statement: context SetTypeValue ==> ’element’ should be ’elements’
19. -- [1] All elements belonging to a tuple value have unique names.inv: self.elements->isUnique(e : Element | e.name) ==> missing context statement: context TupleValue ==> ’Element’ should be ’NameValueBinding’
20. -- [1] The history of an object is ordered. The first element does not have a -- predecessor, the last does not have a successor. context ObjectValue inv: history->oclIsTypeOf( Sequence(LocalSnapShot) ) inv: history->last().succ->size = 0 inv: history->first().Pre->size = 0 ==> should be: context ObjectValue inv: history->oclIsTypeOf( StandardLibrary::StdLib.Sequence(LocalSnapShot) ) inv: history->last().succ->size = 0 inv: history->first().Pre->size = 0
21. -- [1] The history of an object is ordered. The first element does not have a -- predecessor, the last does not have a successor. context ObjectValue inv: history->oclIsTypeOf( StandardLibrary::StdLib.Sequence(LocalSnapShot) ) inv: history->last().succ->size = 0 inv: history->first().Pre->size = 0 ==> ’size’ should be ’size()’ (twice)
22. -- [1] The operation allPredecessors returns the collection of all snapshots
-- before a snapshot, allSuccessors returns the collection of all snapshots after
-- a snapshot.
context LocalSnapshot
def: allPredecessors() : Sequence(LocalSnapshot) =
if pred->notEmpty then
pred->union(pred.allPredecessors())
else
Sequence {}
endif
def: allSuccessors() : Sequence(LocalSnapshot) =
if succ->notEmpty then
succ->union(succ.allSuccessors())
else
Sequence {}
endif
==> ’notEmpty’ should be ’notEmpty()’ (twice)23. -- [1] The elements in a tuple value must have a type that conforms to the type -- of the corresponding tuple parts. context TupleValue inv: elements->forAll( elem | let correspondingPart: Attribute = self.model.allAttributes()->select( part | part.name = elem.name ) in elem.value.model.conformsTo( correspondingPart.type ) ) ==> ’Attribute’ should be ’UML14::Core::Attribute’ ==> ’select’ should be ’any’
24. -- [1] The result value of an association class call expression is the value
-- bound to the name of the association class to which it refers. Note that the
-- determination of the result value when qualifiers are present is specified in
-- section 5.4.3 ("Well-formedness rules for the AS-Domain-Mapping.exp-eval
-- Package"). The operation getCurrentValueOf is an operation defined on
-- ObjectValue in section 5.2.3 ("Additional operations for the Values Package").
context AssociationClassCallExpEval inv:
qualifiers->size = 0 implies
resultValue =
source.resultValue.getCurrentValueOf(referredAssociationClass.name)
==> ’size’ should be ’size()’
==> ’resultValue’ should be ’resultValue->oclAsType(OCLDomain::Values::ObjectValue)’25. -- [1] The result value of an association end call expression is the value bound
-- to the name of the association end to which it refers. Note that the
-- determination of the result value when qualifiers are present is specified in
-- section 5.4.3 ("Well-formedness rules for the AS-Domain-Mapping.exp-eval
-- Package").
context AssociationEndCallExpEval inv:
qualifiers->size = 0 implies
resultValue =
source.resultValue.getCurrentValueOf(referredAssociationEnd.name)
==> ’size’ should be ’size()’
==> ’resultValue’ should be ’resultValue->oclAsType(OCLDomain::Values::ObjectValue)’26. -- [1] The result value of an association class call expression is the value
-- bound to the name of the association class to which it refers. Note that the
-- determination of the result value when qualifiers are present is specified in
-- section 5.4.3 ("Well-formedness rules for the AS-Domain-Mapping.exp-eval
-- Package"). The operation getCurrentValueOf is an operation defined on
-- ObjectValue in section 5.2.3 ("Additional operations for the Values Package").
context AssociationClassCallExpEval inv:
qualifiers->size() = 0 implies
resultValue =
source.resultValue.getCurrentValueOf(referredAssociationClass.name)
==> ’name’ should be ’value’27. -- [1] The result value of an association end call expression is the value bound
-- to the name of the association end to which it refers. Note that the
-- determination of the result value when qualifiers are present is specified in -- section 5.4.3 ("Well-formedness rules for the AS-Domain-Mapping.exp-eval
-- Package").
context AssociationEndCallExpEval inv:
qualifiers->size() = 0 implies
resultValue =
source.resultValue.getCurrentValueOf(referredAssociationEnd.name)
==> ’name’ should be ’value’28. -- [1] The result value of an association end call expression is the value bound
-- to the name of the association end to which it refers. Note that the
-- determination of the result value when qualifiers are present is specified in
-- section 5.4.3 ("Well-formedness rules for the AS-Domain-Mapping.exp-eval
-- Package").
context AssociationEndCallExpEval inv:
qualifiers->size() = 0 implies
resultValue =
source.resultValue.getCurrentValueOf(referredAssociationEnd.name)
==> ’name’ should be ’value’29. -- [1] The result value of an attribute call expression is the value bound to the -- name of the attribute to which it refers. context AttributeCallExpEval inv: resultValue = if source.resultValue->isOclType( OCLDomain::Values::ObjectValue) then source.resultValue->asOclType( ObjectValue ) .getCurrentValueOf(referredAttribute.name) else -- must be a tuple value source.resultValue->asOclType( TupleValue ) .getValueOf(referredAttribute.name) endif ==> ’isOclType’ should be ’oclIsTypeOf’ ==> ’asOclType’ should be ’oclAsType’ ==> ’name’ should be ’value’ (twice)
30. -- [1] The value of a collection item is the result value of its item expression. -- The environment of this item expression is equal to the environment of the -- collection item evaluation. context CollectionItemEval inv: element = item.resultValue inv: item.environment = self.environment ==> an association should be added between CollectionLiteralPartEval and EvalEnvironment
31. -- [2] The result value of a collection literal expression evaluation is a -- collection literal value, or one of its subtypes. context CollectionLiteralExpEval inv: resultValue.isOclKind( OCLDomain::Values::CollectionValue ) ==> ’isOclKind’ should be ’oclIsKindOf’
32. -- [3] The number of elements in the result value is equal to the number of -- elements in the collection literal parts, taking into account that a -- collection range can result in many elements. context CollectionLiteralExpEval inv: resultValue.elements->size() = parts->collect( element )->size()->sum() ==> ’resultValue’ should be ’resultValue->oclAsType(OCLDomain::Values::CollectionValue)’
33. -- [1] The value of a collection range is the range of integer numbers between -- the result value of its first expression and its last expression. context CollectionRangeEval inv: element.isOclType( Sequence(Integer) ) and element = getRange( first->asOclType(Integer), last->asOclType(Integer) ) ==> ’asOclType’ should be ’oclAsType’ (twice)
34. -- [1] The result value of an if expression is the result of the thenExpression -- if the condition is true, else it is the result of the elseExpression. context IfExpEval inv: resultValue = if condition then thenExpression.resultValue else elseExpression.resultValue endif ==> ’condition’ should be ’condition.resultValue->oclAsType(Boolean) = true’
35. -- [4] The elements in the result value are the elements in the
-- literal parts, taking into account that a collection range can result
-- elements.
context CollectionLiteralExpEval inv:
let allElements : Bag(Value) = parts->collect(
Sequence{1..allElements->size()}->forAll( i:
resultValue.elements->at(i).name = ’’ and
resultValue.elements->at(i).value = allElements->
self.kind = CollectionKind::Sequence implies
resultValue.elements->at(i).indexNr = i )
==> should be
context CollectionLiteralExpEval inv:
let allElements : Sequence(Value) = parts->collect(
in
Sequence{1..allElements->size()}->forAll( i:
resultValue->oclAsType(OCLDomain::Values::CollectionValue).
>any(x | x.indexNr = i).value
= allElements->at(i) and
self.kind = CollectionKind::Sequence implies
resultValue.elements->at(i).indexNr = i )36. -- [1] The value of a collection range is the range of integer numbers between -- the result value of its first expression and its last expression. context CollectionRangeEval inv: element.isOclType( Sequence(Integer) ) and element = getRange( first->oclAsType(Integer), last->oclAsType(Integer) ==> ’isOclType’ should be ’oclIsTypeOf’
37. -- [1] All sub evaluations have a different environment. The first sub evaluation -- will start with an environment in which all iterator variables are bound to -- the first element of the source, plus the result variable which is bound to -- the init expression of the variable declaration in which it is defined. context IterateExpEval inv: let bindings: Sequence( NameValueBindings ) = iterators->collect( i | NameValueBinding( i.varName, source->asSequence()->first() )) in bodyEvals->at(1).environment = self.environment->addAll( bindings ) ->add( NameValueBinding( result.name, result.initExp.resultValue )) ==> ’NameValueBindings’ should be ’NameValueBinding’
38. -- [1] All sub evaluations have a different environment. The first sub evaluation -- will start with an environment in which all iterator variables are bound to -- the first element of the source, plus the result variable which is bound to -- the init expression of the variable declaration in which it is defined. context IterateExpEval inv: let bindings: Sequence( NameValueBinding ) = iterators->collect( i | NameValueBinding( i.varName, source->asSequence()->first() )) in bodyEvals->at(1).environment = self.environment->addAll( bindings ) ->add( NameValueBinding( result.name, result.initExp.resultValue )) ==> ’varName’ should be ’value’
"[1] Married people are of age >= 18 context Person inv: self.wife->notEmpty() implies self.wife.age >= 18 and self.husband->notEmpty() implies self.husband.age >= 18" has to be "[1] Married people are of age >= 18 context Person inv: (self.wife->notEmpty() implies self.wife.age >= 18) and (self.husband->notEmpty() implies self.husband.age >= 18)" because of the precedence rules same mistake in http://www.omg.org/docs/ptc/03-10-14.pdf, "UML 2.0 OCL Final Adopted specification", chapter 7.5.3, page 18.
I been using rational rose and bold for delphi in some projects. This have worked very well for me. When adding constraints to my models i have some times whished that there whas a way to do this on different levels. Eg. error-constraints (if persisted the object would be a dirty data) , warning-constraints these can be broken but there is high probability that the object is ill formed from the system user perspective (example a new customer whith no billing adress) and finally a hint-contraint that when broken indicates that the object containes strange data (example a new customer object with the same phone number as a existing customer) My own solution to this have been to add contraints of the first type to the model. This have enabeld me to create generic code dealing with if the user should be allowed to save a object or not. The other types of constraints have been added as coments as a way to make the model as complete as possibel. The implementation of checking and dealing with these constraints later in the project have ben solved in a mutch less generic and cumbersom way. I thin´k that if the standard included a way to specify different levels of ocl statements in the model this would benefit the model driven way to make software
I'm not certain if I should report this issue to the OCL group or to the UML Superstructure group, but... the Basic Types listed in OCL do not agree with the Primitive Types listed in the UML Superstucture. OCL lists "Real" as a primitive (basic type), UML Superstructure does not, instead listing UnlimitedNatural as a primitive type. Shouldn't the two agree?
Typo - In the 2nd para, 3rd sent., the "t" of "type conformance error" is not italicized as is the rest of the phrase. Table 4 does not address the UML 2.0 (pct/04-10-02)use of UnlimitedNaturals as a type. This type probably Conforms to/Is a subtype of Real since UnlimitedNaturals are integers equal to or greater than 0.
Typo - 2nd line of para under Missing AssociationEnd names, add a "s" to "tarting." Combining Properties example [2] does not show/express any combined properties; it just expresses the size property of the set employee.
In last paragraph on page 20 change the word "dotted" to "dashed" and in Fig. 3 change the dashed line denoting Dependency as an AssociationClass to a dotted line. This will agree with Fig. 1 example of an association class as well as the Notation described for AssociationClass on pg 45 of UML Superstructure (ptc/04-10-02).
Although the definition of oclAsType may be obvious, this is an appropriate sub-section to place a paragraph describing oclAsType. It is the only prrdefined property on All Objects that is not defined in this section.
The example of Set {1,2,5,88} is more of an example of an ordered set as is Set {'apple','orange','strawberry'}. The example of a Sequence {1,3,45,2,3} does not exhibit any apparent order although a Sequence is defined as an ordered Bag. It might be wise to alter these examples to: Set {1,88,5,2}, Set ['strawberry','apple','orange'} and Sequence {1,2,3,3,45}
The example using Bike and Car as two separate subtypes of Transport does not make any mention of Set(Car), Bag(car), or Collection(Car). Either delete reference to Car as a separate subtype of Transport or add some comments about a collection of some sort of Car conforming (and not conforming) to some other collection. I may be confused, but the statement "Note that Set(Bicycle) does not conform to Bag(Bicycle)" does not make a lot of sense to me. Wouldn't it be better to say that "Set(Bicycle) does not conform to Bag(car)?"
In the 2nd paragraph, shange "The value of the reject operation..." to "The value of the collect operation..."
Typos - 1st line, 3rd para under The Types Package, delete "and" between "CollectionType" and "its." - 2nd sent., 3rd para under The Types Package, change "taken in account" to "taken into account." - 2nd sent., under OclMessageType, change "Like to the collection" to "Like collection." - Last sent. under TupleType, delete the word "to." In sub-section CollectionType, there is no mention of the fourth concrete subclass which is shown in fig. 5 as OrderedSetType. Add this to the list of concrete subclasses or change fig. 5 to indicate that OrderedSetType is not a subclass of CollectionType (possibly a subclass of SetType?). Sub-section 7.5.11 also indicates only three different collection types. In addition, CollectionTypes [1] on pg 36 ("--all instances of SetType, SequenceType, BagType conform to a CollectionType if the elementTypes conform") makes no mention of OrderedSetType.
Fig. 6 does not agree with fig. 12 (pg 60) in the number of subclasses that inherit from OCLExpression. Fig. 6 nor the subsequene notation have any mention of LetExp. Please add this to Chapter 8.
Association arguments under OclMessageExp uses "SignalArgs" as the classifier name but fig. 9 and later in this section the name is given as OclMessageArg. Change SignalArgs to OclMessageArgs. In the notation for OclMessageArg, it is stated that "OclMessageArg has either a specified or an unspecified value." Would these then be attributes to OclMessageArg? UnspecifiedValueExp shows an association of type:Classifier in fig. 9. Add this to the notation or delete the association from the fig.
CollectionItem shows an association - item:OclExpression - in the fig. 10. CollectionLiteralExp shows an association in fig. 10 - parts:CollectionLiteralPart. This is an ordered association. CollectionRange shows two associations in fig. 10 - first:OclExpression and last:OclExpression. UML 2.0 (ptc/04-10-02) doesn't recognize Real as a primitive type but does use UnlimitedNatural. Need to add UnlimitedNatural as a primitive type. The attribute symbol for PrimitiveLiteralExp is not shown in fig. 10. TuppleLiteralExp shows an association in fig. 10 - tuplePart:VariableDeclaration. The statement that TupleLiteralExp "contains a name and a value for each part of the tuple type" implies attributes but these are not shown in fig. 10 or listed as attributes in the notation. Add a notation for VariableDeclaration.
The association parentOperation nor the class OperationCallExp of OCLExpression is not shown in either fig. 6 or 9 but in fig. 7. Change the reference to fig. 7 page 44 in the association definition for parentOperation under OclExpression. Two additional associations vor VariableDeclaration are shown in fig. 6--baseExp:IterateExp and loopExpr:LoopExp. Add these to the notation or delete these associations from fig. 6.
The def:lookupAssociationClass(name: String) has the same phrase after the arrow as the def:;ppli[AssociationEnd(name: String). I'm not familiar with OCL but this doesn't seem right to me. The context Operation and the context Signal each contain two equal sign separated only by a comment. I don't think this is correct either.
In fig. 13, the operations lookupLocal() and Lookup() appear twice with the same name. Is this proper? Grammer - Delete the words "for" and "as" in the last line on page 62. Bulletted paragraph beginning "If neither of the above..." implies only two choices so remove third bullet at top of page 63 and move line out flush with margin of bullet beginning "If not, check self..."
There is inconsistency in the spelling of "CollectionLiteralPartsCS" sometimes using the "s" after "Part" and sometimes capitalizing the "S" after "Part". This becomes even more confusing when the next production is "CollectionLiteralPartCS" - notice no"s" following "Part".
Typo - Fig. 14, "Ocl-AbstractSyntax" should be "OCL-AbstractSyntax" to agree with naming format shown in other two packages
The last paragraph on pg 94 that describes fig. 15 does not agree in names with the value names shown in fig. 15. StaticValue equates to the daya values the paragraph mentions and OclVoidValue apparently equates to "UndefinedValue." Since "UndefinedValue" and "OclVoidValue" both have the format of a class name this could lead to confusion. OclVoidValue, as later defined, is an undefined value so please change "UndefinedValue" in the open paragraph of this section.
The statement "An element represents a single component of a tuple value" is not directly diagrammed in fig. 16. Should it be?
NameValueBinding show an attribute and an association in fig. 16 that are not mentioned in the description/definition as are other attributes and associations in other descriptions/definitions.
Typos - Change "ispre" to "isPre" and reword [2] to "...postcondition snapshot does it have an associated..."
[1] still uses the term "UndefinedValue" when I think it should be "OclVoidValue" to agree with fig. 15 and name of term being defined previously. Typo - delete the lase "endif" that is flush with the margin.
Fig. 20 does not diagram the class OclEvaluation. Should it?
For the association bodyEvals the name of the associated class does not agree with the class name in fig. 20
The name of the association in fig. 20 is "referredVariable." Please correct either the text or the figure
The association definition says that the referredAssociationEnd is the name of the AssociationEnd to which the corresponding NavigationCallExp is a reference. Shouldn't the be to which the corresponding AssociationEndCallExp is a reference?
The subtype name on fig. 21 is OperationCallExpEval which I believe is correct. Please change the title of this sub-section
Add the association "qualifiers" to OclExpEval as is shown in fig. 21
The association variable is not diagrammed in fig. 23. Please add it to the fig
Fig. 23 shows an additional association of unspecified as the UnspecifiedValueExpEval that represents the unspecified evaluation. If this is supposed to represent the association variable, the description and the figure do not agree in any way.
Fig. 23 shows an attribute for OclMessageExpEval and that the association arguments is ordered. Neither of these are mentioned in the text
None of the attributes or associations diagrammed are mentioned in the text. If there is no intention of mentioning them in their respective expression evaluations make a note of this in the opening description of the section. TupleliteralExpPartEval is not diagrammed in fig. 24 but VariableDeclEval is diagrammed and not mentioned in the text. Please correct.
There is no caption for the figure on pg. 122. Although fig. 27 appears on pg 121 with its caption and fig. 28 is on pg. 132, use of the word "figures" on pg. 120 indicates that the fig. on pg 122 is a separate figure. Please clarify with a caption for the fig. on pg 122.
To be consistent with other sub-sections, use [1] before the OCL well-formedness rule
Last line on page is a sentence fragment
If /(r:Real):Real then shouldn't a constraint be added to the definition that the value of self divided by r as long as r<>0? A number divided by 0 is not a real number.
What is the difference in meaning between the definitions of or(b:Boolean): Boolean and xor(b:Boolean): Boolean? or(b:Boolean): Boolean says True if either self or b is true which implies "but not both" which is the ending phrase of the definition of xor(b:Boolean): Boolean.
The restriction to sort the OrderedSet with the lowest value coming first is very restrictive. Sometimes it is beneficial to sort in reverse order. Think about a statement that would allow a > sort order.
Typo - pg 151 change "The standard iterator expression" to "The standard iterator expressions." The reject expression for both Bag and Sequence have "source->select(iterator | not body) on the left side of the equals symbol. Shouldn't the word "iterate" be used instead of "select?" The sortedBy expression is very restrictive if the sort order must always have the lowest value first. A statement that a sort order could be by a > value would be nice.
General comments: OCL primitive types do not agree with UML primitive types. Multiplicity symbology for "infinite" is different. UML uses "*" whereas OCL uses "n." Capitalize the word "Boolean" as it is named for the 19th Century mathematicial George Boole. In most places it is capitalized but there are several places where it is not. I hope my comments have not been too annoying. Please consider everything I know about OCL I have learned from reading this document so if my comments don't make a lot of sense, then possibly clarification in the document may be needed.
1) The specification does not describes the syntax of integer, real or string literals. The specification does not describes the syntax of integer, real or string literals. Specifying the syntax and the semantics of basic types will increase the portability of OCL programs
OCL allows defining additional operations which are conceptually treated as operations of the metaclasses. However, except for special cases where the "additional operation" is effectively defined in the original metamodel, these "additional operations" are extensions to the original metamodel. No indication in the specification is given on what extension mechanism is used. This makes the exchange of OCL specifications through XMI incomplete and ill-formed.
OCL Specification, v2.0 Section "7.3.3. Invariants" provides a means to name an invariant as in: "context" <contextdeclaration> "inv" <constraintname> ":" ... The document does not seem to define this capability formally and I would like to see it also applied to pre, post, body, init, and derived constraints.
OCL Specification, v2.0
The specification does not make it clear how to apply collection operations to properties.
For instance, assume
class A {
int x[];
}
It appears that an invariant constraint that asserts that one of the entries in A.x must be 5 might be
context A
inv self.x->exists( p | p=5 )
However, this is a guess and does not appear to be entirely justified by the text.