Home » Archived » M2M (model-to-model transformation) » How to use distinct and foreach in called rules?
How to use distinct and foreach in called rules? [message #89594] |
Tue, 02 September 2008 03:08  |
Eclipse User |
|
|
|
Hello,
I wrote a transformation using a foreach in a called rule and I obtained a
compilation error.
The purpose of the transformation is to generate from one element named
Interface two elements Interface1 and Interface2. The element Interface
defines operations and attributes. Interface1 will contain services
derived from operations and Interface2 the attributes.
See below for the rule I already wrote:
rule System {
from
systemDesign : design!System
to
systemImpl : impl!System(
Name <- systemDesign.Name,
Description <- (systemDesign.defineClassifier->select(i |
i.oclIsTypeOf(design!Interface)).asSequence()).size().toStri ng(),
Components <- systemDesign.defineClassifier->select(c |
c.oclIsTypeOf(design!Package)),
-- One interface defined one interface1 and one interface2 in the
-- implementation model
Interfaces <- interfaces1.append(interfaces2)
),
interfaces1 : distinct impl!Interface1 foreach(interface in
(systemDesign.defineClassifier->select(e|e.oclIsTypeOf(design!Package)))- >collect(i|i.defineClassifier)->flatten()->asSet())(
Name <- '1'+interface.Name,
services<-thisModule.NewServices(interface)
),
interfaces2 : distinct impl!Interface2 foreach(interface in
(systemDesign.defineClassifier->select(e|e.oclIsTypeOf(design!Package)))- >collect(i|i.defineClassifier)->flatten()->asSet())(
Name <- '2'+interface.Name
)
}
rule NewServices (interface :design!Interface)
{
to
operations : distinct impl!Service foreach(operation in
interface.defineOperation)(
Name <- operation.Name,
Description <- operation.Description
)
do
{
operations;
}
}
The design metamodel defined Packages that contains Interfaces that
contains Operations. To transform the design model to implementation model
I will transform Interfaces to Interface1 that defines services (one
service for one operation defined in design model) and to Interface2 that
defines attributes.
I try to go threw the Packages, Interfaces and Operations using foreach.
It works fine in the matched rule System but I got a compilation error
with the called rule NewServices.
INFO: Warning, could not find mathing node for ForEachOutPatternElement in
mode calledRuleCreate
INFO: Warning, could not find mathing node for ForEachOutPatternElement in
mode calledRuleInit
GRAVE: ERROR: no slot reserved for variable: operations used at 68:3-68:13.
GRAVE: ****** BEGIN Stack Trace
GRAVE: exception:
GRAVE: null
java.lang.reflect.InvocationTargetException
at sun.reflect.GeneratedMethodAccessor37.invoke(Unknown Source)
...
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.GeneratedMethodAccessor37.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at
org.eclipse.m2m.atl.engine.vm.InstanceNativeOperation.exec(I nstanceNativeOperation.java:79)
... 131 more
Caused by: java.lang.NullPointerException
at
org.eclipse.m2m.atl.engine.vm.ASMOperation.addVariableInstru ction(ASMOperation.java:112)
at org.eclipse.m2m.atl.engine.vm.ASMEmitter.emit(ASMEmitter.jav a:128)
... 135 more
What could I do in order not to use distinct foreach in the called rule?
Thanks for your help,
Mel
|
|
| |
Re: How to use distinct and foreach in called rules? [message #89695 is a reply to message #89594] |
Tue, 02 September 2008 09:49   |
Eclipse User |
|
|
|
Hello,
Actually their use is deprecated. You can use lazy rules instead.
I think if you rewrite it with a lazy rule, thinks will be come more clear:
rule System {
from systemDesign : design!System
to systemImpl : impl!System(
Name <- systemDesign.Name,
Interfaces <-
thisModule.createInterface1(systemDesign.defineClassifier->select(e|e.oclIsTypeOf(design!Package))- >collect(i|i.defineClassifier)->flatten()->asSet())
Interfaces <-
thisModule.createInterface2(systemDesign.defineClassifier->select(e|e.oclIsTypeOf(design!Package))- >collect(i|i.defineClassifier)->flatten()->asSet())
)
}
lazy rule createInterface1 {
from systemDesign : design!Package
to systemImpl : impl!Interface1 (
Name <- '1'+interface.Name,
services<-thisModule.NewServices(interface)
)
}
lazy rule createInterface2 {
from systemDesign : design!Package
to systemImpl : impl!Interface2 (
Name <- '2'+interface.Name
)
}
Good luck,
Alfons
"Melb" <melanie.bats@enix.org> schreef in bericht
news:c77ca8eca4a1c01531c72f51eeb5b148$1@www.eclipse.org...
> Hello,
>
> I wrote a transformation using a foreach in a called rule and I obtained a
> compilation error.
> The purpose of the transformation is to generate from one element named
> Interface two elements Interface1 and Interface2. The element Interface
> defines operations and attributes. Interface1 will contain services
> derived from operations and Interface2 the attributes.
>
> See below for the rule I already wrote:
> rule System {
> from systemDesign : design!System
> to systemImpl : impl!System(
> Name <- systemDesign.Name,
> Description <- (systemDesign.defineClassifier->select(i |
> i.oclIsTypeOf(design!Interface)).asSequence()).size().toStri ng(),
> Components <- systemDesign.defineClassifier->select(c |
> c.oclIsTypeOf(design!Package)),
> -- One interface defined one interface1 and one interface2 in the --
> implementation model
> Interfaces <- interfaces1.append(interfaces2)
> ),
> interfaces1 : distinct impl!Interface1 foreach(interface in
> (systemDesign.defineClassifier->select(e|e.oclIsTypeOf(design!Package)))- >collect(i|i.defineClassifier)->flatten()->asSet())(
> Name <- '1'+interface.Name,
> services<-thisModule.NewServices(interface)
> ),
> interfaces2 : distinct impl!Interface2 foreach(interface in
> (systemDesign.defineClassifier->select(e|e.oclIsTypeOf(design!Package)))- >collect(i|i.defineClassifier)->flatten()->asSet())(
> Name <- '2'+interface.Name
> ) }
>
> rule NewServices (interface :design!Interface)
> {
> to
> operations : distinct impl!Service foreach(operation in
> interface.defineOperation)(
> Name <- operation.Name,
> Description <- operation.Description
> )
> do
> {
> operations; }
> }
> The design metamodel defined Packages that contains Interfaces that
> contains Operations. To transform the design model to implementation model
> I will transform Interfaces to Interface1 that defines services (one
> service for one operation defined in design model) and to Interface2 that
> defines attributes.
>
> I try to go threw the Packages, Interfaces and Operations using foreach.
> It works fine in the matched rule System but I got a compilation error
> with the called rule NewServices.
>
> INFO: Warning, could not find mathing node for ForEachOutPatternElement in
> mode calledRuleCreate
> INFO: Warning, could not find mathing node for ForEachOutPatternElement in
> mode calledRuleInit
> GRAVE: ERROR: no slot reserved for variable: operations used at
> 68:3-68:13.
> GRAVE: ****** BEGIN Stack Trace
> GRAVE: exception: GRAVE: null
> java.lang.reflect.InvocationTargetException
> at sun.reflect.GeneratedMethodAccessor37.invoke(Unknown Source)
> ...
> Caused by: java.lang.reflect.InvocationTargetException
> at sun.reflect.GeneratedMethodAccessor37.invoke(Unknown Source)
> at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
> at java.lang.reflect.Method.invoke(Unknown Source)
> at
> org.eclipse.m2m.atl.engine.vm.InstanceNativeOperation.exec(I nstanceNativeOperation.java:79)
> ... 131 more
> Caused by: java.lang.NullPointerException
> at
> org.eclipse.m2m.atl.engine.vm.ASMOperation.addVariableInstru ction(ASMOperation.java:112)
> at org.eclipse.m2m.atl.engine.vm.ASMEmitter.emit(ASMEmitter.jav a:128)
> ... 135 more
>
> What could I do in order not to use distinct foreach in the called rule?
>
> Thanks for your help,
> Mel
|
|
| |
Re: How to use distinct and foreach in called rules? [message #89726 is a reply to message #89695] |
Tue, 02 September 2008 13:34   |
Eclipse User |
|
|
|
My example may have confused you. It;s incorrect sorry.
You can define two lazy rules accepting one input element and producing one
target element. Then you can call the iteratively:
Interfaces <- collection_source_elements->collect(i |
thisModule.createInterface1(i) );
Interfaces <- collection_source_elements->collect(i |
thisModule.createInterface2(i) );
Alfons
"Alfons Laarman" <a.w.laarman@student.utwente.nl> schreef in bericht
news:g9jg92$21n$1@build.eclipse.org...
> Hello,
>
> Actually their use is deprecated. You can use lazy rules instead.
> I think if you rewrite it with a lazy rule, thinks will be come more
> clear:
>
> rule System {
> from systemDesign : design!System
> to systemImpl : impl!System(
> Name <- systemDesign.Name,
> Interfaces <-
> thisModule.createInterface1(systemDesign.defineClassifier->select(e|e.oclIsTypeOf(design!Package))- >collect(i|i.defineClassifier)->flatten()->asSet())
> Interfaces <-
> thisModule.createInterface2(systemDesign.defineClassifier->select(e|e.oclIsTypeOf(design!Package))- >collect(i|i.defineClassifier)->flatten()->asSet())
> )
> }
> lazy rule createInterface1 {
> from systemDesign : design!Package
> to systemImpl : impl!Interface1 (
> Name <- '1'+interface.Name,
> services<-thisModule.NewServices(interface)
> )
> }
> lazy rule createInterface2 {
> from systemDesign : design!Package
> to systemImpl : impl!Interface2 (
> Name <- '2'+interface.Name
> )
> }
>
> Good luck,
>
> Alfons
>
> "Melb" <melanie.bats@enix.org> schreef in bericht
> news:c77ca8eca4a1c01531c72f51eeb5b148$1@www.eclipse.org...
>> Hello,
>>
>> I wrote a transformation using a foreach in a called rule and I obtained
>> a compilation error.
>> The purpose of the transformation is to generate from one element named
>> Interface two elements Interface1 and Interface2. The element Interface
>> defines operations and attributes. Interface1 will contain services
>> derived from operations and Interface2 the attributes.
>>
>> See below for the rule I already wrote:
>> rule System {
>> from systemDesign : design!System
>> to systemImpl : impl!System(
>> Name <- systemDesign.Name,
>> Description <- (systemDesign.defineClassifier->select(i |
>> i.oclIsTypeOf(design!Interface)).asSequence()).size().toStri ng(),
>> Components <- systemDesign.defineClassifier->select(c |
>> c.oclIsTypeOf(design!Package)),
>> -- One interface defined one interface1 and one interface2 in the --
>> implementation model
>> Interfaces <- interfaces1.append(interfaces2)
>> ),
>> interfaces1 : distinct impl!Interface1 foreach(interface in
>> (systemDesign.defineClassifier->select(e|e.oclIsTypeOf(design!Package)))- >collect(i|i.defineClassifier)->flatten()->asSet())(
>> Name <- '1'+interface.Name,
>> services<-thisModule.NewServices(interface)
>> ),
>> interfaces2 : distinct impl!Interface2 foreach(interface in
>> (systemDesign.defineClassifier->select(e|e.oclIsTypeOf(design!Package)))- >collect(i|i.defineClassifier)->flatten()->asSet())(
>> Name <- '2'+interface.Name
>> ) }
>>
>> rule NewServices (interface :design!Interface)
>> {
>> to
>> operations : distinct impl!Service foreach(operation in
>> interface.defineOperation)(
>> Name <- operation.Name,
>> Description <- operation.Description
>> )
>> do
>> {
>> operations; }
>> }
>> The design metamodel defined Packages that contains Interfaces that
>> contains Operations. To transform the design model to implementation
>> model I will transform Interfaces to Interface1 that defines services
>> (one service for one operation defined in design model) and to Interface2
>> that defines attributes.
>>
>> I try to go threw the Packages, Interfaces and Operations using foreach.
>> It works fine in the matched rule System but I got a compilation error
>> with the called rule NewServices.
>>
>> INFO: Warning, could not find mathing node for ForEachOutPatternElement
>> in mode calledRuleCreate
>> INFO: Warning, could not find mathing node for ForEachOutPatternElement
>> in mode calledRuleInit
>> GRAVE: ERROR: no slot reserved for variable: operations used at
>> 68:3-68:13.
>> GRAVE: ****** BEGIN Stack Trace
>> GRAVE: exception: GRAVE: null
>> java.lang.reflect.InvocationTargetException
>> at sun.reflect.GeneratedMethodAccessor37.invoke(Unknown Source)
>> ...
>> Caused by: java.lang.reflect.InvocationTargetException
>> at sun.reflect.GeneratedMethodAccessor37.invoke(Unknown Source)
>> at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
>> at java.lang.reflect.Method.invoke(Unknown Source)
>> at
>> org.eclipse.m2m.atl.engine.vm.InstanceNativeOperation.exec(I nstanceNativeOperation.java:79)
>> ... 131 more
>> Caused by: java.lang.NullPointerException
>> at
>> org.eclipse.m2m.atl.engine.vm.ASMOperation.addVariableInstru ction(ASMOperation.java:112)
>> at org.eclipse.m2m.atl.engine.vm.ASMEmitter.emit(ASMEmitter.jav a:128)
>> ... 135 more
>>
>> What could I do in order not to use distinct foreach in the called rule?
>>
>> Thanks for your help,
>> Mel
>
>
|
|
|
[ATL] Re: How to use distinct and foreach in called rules? [message #89800 is a reply to message #89726] |
Wed, 03 September 2008 04:32  |
Eclipse User |
|
|
|
Hello Alfons,
Ok now it's clear. I succeed to replace foreach statement by lazy rules.
Now, my rule is defined as following :
-- IsCSInterface : An interface is a client server interface when there is
an operation with role defined to none
helper context design!Interface def: isCSInterface() : Boolean =
if self.defineOperation->exists(i|i.oclIsTypeOf(design!Operation) and
i.Role =#none) then
true
else
false
endif;
-- IsSRInterface : An interface is a sender receiver interface when there
is an operation with role defined to read or write
helper context design!Interface def: isSRInterface() : Boolean =
if self.defineOperation->exists(i|i.oclIsTypeOf(design!Operation) and
(i.Role =#read or i.Role =#write)) then
true
else
false
endif;
rule System {
from
systemDesign : design!System
to
systemImpl : impl!System(
Name <- systemDesign.Name,
Description <- (systemDesign.defineClassifier->select(i |
i.oclIsTypeOf(design!Interface)).asSequence()).size().toStri ng(),
Components <- systemDesign.defineClassifier->select(c |
c.oclIsTypeOf(design!Package)),
-- One interface defined one CS interface and one SR interface in the
-- implementation model
Interfaces <-
(systemDesign.defineClassifier->select(package|package.oclIsTypeOf(design!Package)))- >collect(package|package.defineClassifier-> collect(interface|thisModule.CreateCSInterface(interface))). append((systemDesign.defineClassifier- >select(package|package.oclIsTypeOf(design!Package)))->collect(package|package.defineClassifier- > collect(interface|thisModule.CreateSRInterface(interface)))) )
}
lazy rule CreateCSInterface{
from
interface : design!Interface(interface.isCSInterface())
to
CSInterface: impl!CSInterface(
Name <- 'CS' + interface.Name,
services<-
interface.defineOperation->collect(operation|thisModule.CreateService(operation)))
}
lazy rule CreateSRInterface{
from
interface : design!Interface(interface.isSRInterface())
to
SRInterface: impl!SRInterface(
Name <- 'SR' + interface.Name)
}
I want to create a CSInterface in implementation model if there are
operations defined in Interface in design model. So I defined an helper
isCSInterface that checks if the interface defines operations. Then I use
this helper in the lazy rule :
lazy rule CreateCSInterface{
from
interface : design!Interface(interface.isCSInterface())
...
I did the same for SRInterface if attributes exists in interface in design
model.
But nothing change, both CSInterface and CSInterface are always created.
I am sure that the helper works as I already test it in a matched rule.
So is it possible to use helpers in lazy rule? If not how could I obtained
the expected behaviour?
Thanks for your help,
Mel
|
|
|
Goto Forum:
Current Time: Fri May 09 14:20:06 EDT 2025
Powered by FUDForum. Page generated in 0.03551 seconds
|