Home » Modeling » ATL » Migration from ATL to EMFTVM
Migration from ATL to EMFTVM [message #1039708] |
Fri, 12 April 2013 09:40  |
Eclipse User |
|
|
|
Dear all,
I am migrating quite a lot of code from ATL to EMFTVM. I thought the modification would be quite straight forward but I experienced several differences. Is there some documentation about the differences; or some guidelines on how to do this kind of migration?
For instance, a difference is that in atl, the any() operator returns OclUndefined if no object is found; while emftvm thows an exception in that case. Another important difference is that atl allows to initialize a local variable to OclUndefined and then to give avalue to this variable in the do section; while EMFTVM does not allow this.
Some how the question is: what are the constructs of atl that should be avoided when using EMFTVM?
Thanks,
Etienne.
|
|
|
Re: Migration from ATL to EMFTVM [message #1041075 is a reply to message #1039708] |
Sun, 14 April 2013 11:23   |
Eclipse User |
|
|
|
Op 12-04-13 15:40, EtienneB Mising name schreef:
> For instance, a difference is that in atl, the any() operator returns
> OclUndefined if no object is found; while emftvm thows an exception in that
> case. Another important difference is that atl allows to initialize a local
> variable to OclUndefined and then to give avalue to this variable in the do
> section; while EMFTVM does not allow this.
EMFTVM includes a re-implementation of the OCL standard library, this time
based on OCL 2.2 instead of OCL 2.0. OCL 2.2 introduces OclVoid and OclInvalid
as a replacement for OclUndefined. As ATL syntax uses OclUndefined, I decided
to use the following mapping:
OclVoid -> OclUndefined (null in Java)
OclInvalid -> throw exception (fail fast principle)
OCL specifies the semantics of any() as select()->first() for Sequence. I
interpreted the outcome of first() on an empty Sequence to be OclInvalid,
hence exception. This is also compatible with the way Java treats collections.
That said, transforming empty collections to OclUndefined and vice versa is a
very common scenario in ATL, so this should be easy to do. Also, Java
collections cannot contain null values, so there is no ambiguity in returning
OclUndefined on Sequence::first().
Anyone else like to comment on this?
Dennis
|
|
| | | | |
Re: Migration from ATL to EMFTVM [message #1050628 is a reply to message #1042702] |
Sat, 27 April 2013 09:39   |
Eclipse User |
|
|
|
Dear all,
Continuing the migration, I experienced another important difference: this has to do with adding elements to a list of the output model.
I filed a bug for this, which was not really a bug but maybe something more difficult to deal with on my end.
Here is a reference to the bug I initially posted:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=406100
after trying a lot to have this working, I am still quite puzzled by the answer.
Here is basically my need.
I have an element of class C that contains an attribute ATTR and list L. I am not using the refining mode however my input and output metamodels are the same. When I match an element c of type C, I want to copy the list from c in a list of c' (image of c). This is easy, and I do it in a matched rule. Now, when I match the attribute ATTR of c in another matched rule, I want to add an element in the image of L, produced by the previous rule.
Usinf the ATL runtime, I would basically write something like this: c'.L.add(...); in a "do" section. To be precise, c' can be retreived in this second rule using the resolveTemp operation.
However the 'add' operation is not supported by EMFTVM. Trying to use attribute helpers make the code very difficult to write, read, understand and debug...
So, I am asking for some advice to add elements to a list in different rules? Could rules inheritence be of any help here?
I could basically create c' and L' in a rule R1 and add elements to L' in a rule R2 that matches L and inherits from R1. Would that be how you would proceed? If so, my problem is that I have L defined in a resource res1 and c defined in another resource res2 that reference res1. As I only pass res1 as an input resource, my matched rules will thus only apply to elements from the resource res1 and L will not be matched. Thus R1 would be a matched rule and R2 a lazy rule... And I cannot use inheritence.
Finally, another option is to add res2 as an input of the model transformation. Then my question is: can I have an unknown number of input resources? I basically take resources from a set of file that varies, this set being provided by the users of my tool...
I am quite lost now: I think EMFTVM provides really nice features (specially for rules inheritence and traces mechanisms) but to my opinion it either needs an "add()" operation for lists of the output models, or a way to give a list of input models without enumerating each of them in advance.
What do you think? I hope I have been clear in enumerating the different problems/solutions; don't hesitate to ask if it is not the case.
Thanks in advance for your answer and best regards,
Etienne.
|
|
|
Re: Migration from ATL to EMFTVM [message #1050771 is a reply to message #1050628] |
Sat, 27 April 2013 14:45   |
Eclipse User |
|
|
|
Op 27/04/13 15:39, EtienneB Mising name schreef:
> So, I am asking for some advice to add elements to a list in different rules?
> Could rules inheritence be of any help here?
You should normally try to collect all elements you want to assign to the list
reference in the same rule as where you create the element that owns the list
reference:
rule ... {
from ...
to t : MM!C (
list <- MM!Child.allInstances()->select(c | ...)->union(...)
)
}
>
> I could basically create c' and L' in a rule R1 and add elements to L' in a
> rule R2 that matches L and inherits from R1. Would that be how you would
> proceed? If so, my problem is that I have L defined in a resource res1 and c
> defined in another resource res2 that reference res1. As I only pass res1 as
> an input resource, my matched rules will thus only apply to elements from the
> resource res1 and L will not be matched. Thus R1 would be a matched rule and
> R2 a lazy rule... And I cannot use inheritence.
You can indeed not mix rule types in rule inheritance.
>
> Finally, another option is to add res2 as an input of the model
> transformation. Then my question is: can I have an unknown number of input
> resources? I basically take resources from a set of file that varies, this set
> being provided by the users of my tool...
You can add many unknown models to your run config, and you can use their
contents in matched rules, as long as you don't require those rules to match
on specific input models. So like this:
rule ... {
from s : MM!Class
to ...
}
....and not like this:
rule ... {
from s : MM!Class in IN
to ...
}
NOTE that this doesn't work in the other ATL VMs, as the compiler always
compiles in a filter on a specific input model. This was done to work around
the issue that the other ATL VMs could otherwise match metamodel elements in
addition to input model elements. EMFTVM does not require this workaround, and
can match over all input (and in/out) models in general.
>
> I am quite lost now: I think EMFTVM provides really nice features (specially
> for rules inheritence and traces mechanisms) but to my opinion it either needs
> an "add()" operation for lists of the output models, or a way to give a list
> of input models without enumerating each of them in advance.
You could perhaps use the trace model to collect the elements created by your
various rules, and use that to assign to your reference list. That way you
don't even have to come up with a complex expression to collect the elements.
>
> What do you think? I hope I have been clear in enumerating the different
> problems/solutions; don't hesitate to ask if it is not the case.
> Thanks in advance for your answer and best regards,
> Etienne.
>
>
I've given some ideas to write your transformation in an alternative way. It
will generally be much easier to get ATL/EMFTVM to do what you want using
declarative/functional style programming and matched or lazy rules. In
addition, you can use reflection on the trace model.
Hope this helps!
Dennis
|
|
| | | | | | | | |
Re: Migration from ATL to EMFTVM [message #1219646 is a reply to message #1219565] |
Thu, 05 December 2013 03:09   |
Eclipse User |
|
|
|
Dennis Wagelaar wrote on Wed, 04 December 2013 17:38Dennis Wagelaar wrote on Wed, 04 December 2013 17:20Victor Pavon wrote on Wed, 04 December 2013 10:24Hello,
I'm trying to migrate from ATL to EMFTVM but I have some issues with TupleType. I have several unique lazy rule where the element from is a Tuple, because the generation of an unique element depends of several constrains that are represents in the differents tuple values. That rules work properly with ATL but when I migrate to EMFTVM I get the error:
org.eclipse.m2m.atl.emftvm.util.VMException: java.lang.NoSuchFieldException: Field org.eclipse.m2m.atl.emftvm.util.Tuple::beanName not found
The rule is this:
unique lazy rule presentationObject {
from
beanNameAndContainer : Type(beanName : String, objectContainer : mmMIGRARIAMVC!ObjectRequestContainer)
to
presentationObject : mmMIGRARIAMVC!PresentationObject (
name <- beanNameAndContainer.beanName,
container <- (beanNameAndContainer.objectContainer),
)
}
That's a bug in EMFTVM: you may report it in bugzilla.
You may work around this bug by accessing the tuple entry using the "get" operation:
beanNameAndContainer.get ('beanName')
Thank you Dennis, it works properly
[Updated on: Thu, 05 December 2013 03:09] by Moderator
|
|
| | | | | | | | | | | |
Re: Migration from ATL to EMFTVM [message #1228958 is a reply to message #1223251] |
Wed, 08 January 2014 07:20   |
Eclipse User |
|
|
|
Thank you very much, Dennis.
Dennis Wagelaar wrote on Sun, 22 December 2013 23:43op 20-12-13 18:38, Victor Pavon schreef:
> Hello Dennis,
>
> about the operation toSequence(), isn't it supported in EMFTVM?
>
> Best regards, Víctor.
String::toSequence() is indeed not (yet) supported; it's not part of the OCL
2.2 spec, but is an ATL addition. You can implement it as follows, however:
helper context String def : toSequence() : Sequence(String) =
Sequence{}
->includingRange(0, self.size() - 1)
->collect(i | self.charAt(i).toString());
Cheers,
Dennis
|
|
| | |
Goto Forum:
Current Time: Tue Jul 22 19:17:51 EDT 2025
Powered by FUDForum. Page generated in 0.08385 seconds
|