Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
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 07:08 Go to next message
Melanie Bats is currently offline Melanie BatsFriend
Messages: 35
Registered: July 2009
Member
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 #89607 is a reply to message #89594] Tue, 02 September 2008 07:11 Go to previous messageGo to next message
Melanie Bats is currently offline Melanie BatsFriend
Messages: 35
Registered: July 2009
Member
Hello,

I am sorry I forgot to set the prefix ATL in the title.

Best regards,
Mel
Re: How to use distinct and foreach in called rules? [message #89695 is a reply to message #89594] Tue, 02 September 2008 13:49 Go to previous messageGo to next message
Alfons Laarman is currently offline Alfons LaarmanFriend
Messages: 71
Registered: July 2009
Member
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 #89710 is a reply to message #89695] Tue, 02 September 2008 15:43 Go to previous messageGo to next message
Melanie Bats is currently offline Melanie BatsFriend
Messages: 35
Registered: July 2009
Member
Hi Alfons,

It seems that I am a little bit lost with lazy rules...

My source model looks like this:
System
Package 1
Interface 1.1
Attribute 1.1.1
Operation 1.1.1
Operation 1.1.2
Interface 1.2
Operation 1.2.1
Package 2
Interface 2.1
Operation 2.1.1

My target model would be defined as following:
System
CSInterface 1.1
Service 1.1.1
Service 1.1.2
SRInterface 1.1
Attribute 1.1.1
CSInterface 1.2
Service 1.2.1
CSInterface 2.1
Service 2.1.1

The transformation algorithm will be :
1 - For each Package in source I have to get the Interface elements
defined.
2 - After that, for each Interface I need to create two elements,
CSInterface and SRInterface, in target.
3 - Then for each CSInterface I need to get the corresponding operations
in Interface in order to create the

Service elements.

Here the rule I tried to write:
rule System {
from
systemDesign : design!System
to
systemImpl : impl!System(
Interfaces <-
(systemDesign.defineClassifier->select(package|package.oclIsTypeOf(design!Package)))
-- Get the Packages

-> collect(package|thisModule.CreateCSInterfaces(package.define Classifier))
-- Create the CSInterfaces for each Package
}

lazy rule CreateCSInterfaces {
from
interfaces : Sequence(design!Interface) ???
to
CSInterfaces : Sequence(impl!Interface) ???
}

I don't know how to write the lazy rule to iterate over the interfaces?
How to iterate without using foreach statement?

Do you have an idea?

Best regards,
Mel
Re: How to use distinct and foreach in called rules? [message #89726 is a reply to message #89695] Tue, 02 September 2008 17:34 Go to previous messageGo to next message
Alfons Laarman is currently offline Alfons LaarmanFriend
Messages: 71
Registered: July 2009
Member
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 08:32 Go to previous message
Melanie Bats is currently offline Melanie BatsFriend
Messages: 35
Registered: July 2009
Member
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
Previous Topic:[UML2 to UML2] Add Classes to a UML2 model via ATL
Next Topic:[ATL] rule for abstract metaclass
Goto Forum:
  


Current Time: Wed Jul 17 20:41:27 GMT 2024

Powered by FUDForum. Page generated in 0.04662 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top