Hi
I
understood the specification and the meaning of the
different notations very well. I’ve already raised a
duplicate OMG issue with respect to the flaw in the OCL
spec, whereas Ed pointed me to the following existing issue:
http://www.omg.org/issues/ocl2-rtf#Issue14980
Nevertheless,
I have a use case where it would be practical to see ‘+=’
move an existing element to the end, also in case of a
property on the left-hand side. This is my use case:
We
created an Ecore2QVTo transformation that generates the QVTo
code to deepclone a given Ecore model instance using
operational mappings. For example, in case of Ecore itself
as an input, the transformation would come up with a mapping
EClass
:: EClass2EClass : EClass {
// delegate the cloning to all EClass features
}
The
advantage of this approach over QVTo’s built-in deepclone is
the ability to override particular mappings, such that they
modify the clone in a certain sense. In our situation, we
use this to normalize a given model in a
semantics-preserving manner. We have a chain of
normalization steps, where we sense that the effort to
create and plug-in new normalizations is remarkably low.
However, we now face the problem that our generated QVTo
code does not preserve the order of multi-valued properties.
To illustrate the problem, I created an example based on
Ecore itself as a familiar meta model. In the following
example, an EPackage P is to be cloned, containing classes A
and B where A extends B (please think of all Ecore features
as changeable in order to understand the problem):
Clone
package P
Delegate cloning to class A extends B
Delegate cloning to superclass B
Adds cloned B to cloned P (think of EClassifier::ePackage as
changeable for this to work)
Adds cloned A to cloned P (think of EClassifier::ePackage as
changeable for this to work)
Delegate cloning to class B
Fetch cloned B from trace
Attempts to add cloned A,B to cloned P using ‘+=’ notation
(nothing happens because P already contains cloned B,A)
Finally,
the order of classifiers in the cloned package is B,A (was
A,B in the original). Using ‘:=’ instead of ‘+=’ still
doesn’t solve the problem for n:n features.
Actually
not a bug in QVTo, just something where I’m curious about
your opinions and ideas to solve that problem.
Thanks
in advance
Christopher
Von: qvto-dev-bounces@xxxxxxxxxxx
[mailto:qvto-dev-bounces@xxxxxxxxxxx]
Im Auftrag von Sergey Boyko
Gesendet: Freitag, 14. Februar 2014 17:27
An: QVTOML developer mailing list
Betreff: Re: [qvto-dev] Incremental assignment on
unique feature
Hi Christopher,
On
Wed, Feb 12, 2014 at 5:26 PM, Christopher Gerking <christopher.gerking@xxxxxxxxxxxxxxxx>
wrote:
Hi
Ed
Associating
‘+=’ with the OCL ‘append’ was perhaps never
intended. The spec statement
“append
it depending on the isReset property”
is
probably just natural language.
You
are not quite understood specification in this
section.
Actually
it means that there's different notations depending
on 'isReset' property: "The notation uses the ‘:='
symbol if isReset is true and the symbol '+='
otherwise.".
In
other words in case 'isReset' is 'true' then the
feature is first cleared and only after that the new
value is added. In case 'isReset' is 'false' then
the new value is added to the feature.
However,
Eclipse QVTo takes this seriously and calls
‘append’ on an ordered OCL collection, and
‘including’ for an unordered one. This makes
sense, because I see no definition of
Collection::including or OrderedSet::including
in OCL <= 2.4.
As
far as I see none of OCL versions defines
'including' for Collection or OrderedSet.
Also
looking at the definition of 'closure' iterator I
see (OCL "11.9.1 Collection"):
add is 'append' if the source collection is
ordered, 'including' otherwise.
QVTo
just repeats OCL in that sense.
What
is more interesting here is how
'OrderedSet(T)::append (object: T)' defined. It it
looks like there's mistake. OCL "11.7.3 OrderedSet"
defines:
append
(object: T) : OrderedSet(T)
The
set of elements, consisting of all elements of
self, followed by object.
post: result->size() = self->size() + 1
post: result->at(result->size() ) = object
post: Sequence{1..self->size()
}->forAll(index : Integer |
result->at(index) = self ->at(index))
As
it clearly seen this definition is not correct. In
case when OrderedSet already contains added element
then it's size definitely won't increment.
Here
precondition is omitted:
pre: not self->includes(object)
And
this means that current behavior when the existing
element is first removed and then added to the
OrderedSet (in case it's already contained in that
OrderedSet) is wrong.
So
the answer to the original question is that behavior
of '+=' (and QVTO as consequence because it relies
on OCL definition of OrderedSet::append()) is not
consistent on OCL side.
Interesting
that the same problem I found in pivot version of
OCL. Looks like OMG issue should be raised.
What
do you mean by adding at end if necessary? Only
if not already contained?
Regards
Christopher
Hi
Christopher
I presume you mean unique, ordered feature.
For a non-ordered feature the order is
clearly specified as indeterminate.
I've raised a QVT issue
AssignExp to an Collection should make
clear that the results is
target->including(source)->excluding(null)
which should exploit an OCL definition of
OrderedSet::including to be add at end if
necessary.
Since Classic Eclipse OCL is a bit flaky on
OrderedSet, QVTo may want its own utility
method.
I don't see where '+=' is associated with
'append'. The spec is nice and vague:
additive semantics.
Regards
Ed
On
12/02/2014 08:43, Christopher Gerking
wrote:
Hi
I
recently discovered an anomaly with
respect to an incremental AssignExp, and
I’m not quite sure whether this is simply
underspecified or a bug.
What
should happen if a += is executed on a
unique feature which, however, does
already contain the added element (but not
in the last place)?
Obviously
the element can’t be added twice, but
should it move to the end? Currently, it
does not move.
Section
8.2.2.11 AssignExp is kind of vague, but
at least states that the required behavior
is to “append it depending on the isReset
property”. A call to “append” on an
ordered OCL collection (and also += as a
shorthand in QVTo) will always “move” the
element to the end. Thus, we have
different behaviors for += depending on
whether there is an OCL collection or an
EMF feature on the left-hand side.
What
do you think?
Kind
regards
Christopher