Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Archived » M2M (model-to-model transformation) » [ATL] Creating new elements recursively
[ATL] Creating new elements recursively [message #102786] Wed, 01 April 2009 12:40
Marcel  is currently offline Marcel Friend
Messages: 54
Registered: July 2009
Member
Hello,

I am relatively new to ATL and I am trying to write my first somewhat
larger transformation. I have problems with creating elements recursively.

I am working with a simple state machine like language. There are states
connected with transitions. These transitions can have an effect
consisting of a number of statements. This is modeled in Ecore with a
[0..*] reference to a 'statement' metaclass. One type of statement is a
send statement.
The objective of part of my transformation is to split the 'list of
statements' of the effect of a transition after every statement. Suppose
the effect of a transition looks like s_1, ..., s_n, send statement,
s_n+2, ..., s_m, where s_i are statements that are not send statements.
The idea is that this effect is transformed into s_1, ..., s_n, send
statement and that a new state and transition are added. This new
transition has as target state the state that was the target of the
original state and as effect the remaining statements s_n+2, ..., s_m.
This new state should become the target of the old transformation and the
source of the new one. Schematically: A-->B should become A-->NEW-->B.
It is possible that the effect of a transition contains multiple send
statements. In this case, the effect should be split after every send
statement and new states and transitions should be created. I wanted to
implement this using called rules as follows:

--This rule determines whether the recursion should continue or end
rule Split(t_in: slco!Transition){
do {
if t_in.hasEffectSendStatements()
then thisModule.SplitRecurse(t_in)
else thisModule.SplitEnd(t_in)
endif;
}
}

--Recursive step
rule SplitRecurse(t_in: slco!Transition){
to t1_out: slco!Transition(
name <- t_in.name,
source <- t_in.source,
target <- s_out,
effect <- t_in.getStatementsThroughFirstSend()
),

s_out: slco!State(
incoming <- t_in,
outgoing <- t2_out
),

t2_out: slco!Transition(
source <- s_out,
target <- t_in.target,
effect <- t_in.getStatementsAfterFirstSend()
)

do {
thisModule.stateId <- thisModule.stateId + 1;
s_out.name <- 'Split_State_' +
thisModule.stateId.toString();
thisModule.transitionId <- thisModule.transitionId + 1;
t2_out.name <- 'Split_Transition_' +
thisModule.transitionId.toString();

thisModule.Split(t2_out);
}
}

--Recursion end
rule SplitEnd(t_in: slco!Transition){
to t_out: slco!Transition(
name <- t_in.name,
source <- t_in.source,
target <- t_in.target,
effect <- t_in.effect
)
}


The helpers are as follows:

helper def : stateId : Integer = 0;
helper def : transitionId : Integer = 0;

helper context slco!Transition def: hasEffectSendStatements(): Boolean =
self.effect->exists(a | a.oclIsTypeOf(slco!SendSignalStatement));

helper context slco!Transition def: getIndexOfFirstSend(): Integer =
let x : slco!SendSignalStatement = self.effect->asSequence()->select(a |
a.oclIsTypeOf(slco!SendSignalStatement))->asSequence()->first()
-- variable x contains the first occurence of a send statement
in self.effect->asSequence()->indexOf(x);

helper context slco!Transition def: getStatementsThroughFirstSend():
Sequence(slco!Statement) =
let i: Integer = self.getIndexOfFirstSend()
-- i points to the send statement
in self.effect->asSequence()->subSequence(0, i);

helper context slco!Transition def: getStatementsAfterFirstSend():
Sequence(slco!Statement) =
let i: Integer = self.getIndexOfFirstSend() + 1
-- i points to the first statement after the send statement
in let n: Integer = self.effect->asSequence()->size()
-- n points to the last statement
in if i<=n --only if there are statemenst after the send statement
then self.effect->asSequence()->subSequence(i, n)
else Sequence{}
endif;

Now I want to invoke the Split rule for all transitions as follows:

rule StateMachine{
from stateMachine_in : slco!StateMachine
to stateMachine_out: slco!StateMachine(
name <- stateMachine_in.name,
vertices <- stateMachine_in.vertices,
transitions <- stateMachine_in.transitions->collect(a |
thisModule.Split(a))
)
}

When I try to execute this, I get the following error message:

SEVERE: ****** BEGIN Stack Trace
SEVERE: message: ERROR: could not find operation including on Module
having supertypes: [OclAny]
SEVERE: A.main() : ??#28 null
SEVERE: local variables = {self=split_send : ASMModule}
SEVERE: local stack = []
SEVERE: A.__exec__() : ??#68 null
SEVERE: local variables = {e=TransientLink {rule = 'StateMachine',
sourceElements = {stateMachine_in = IN!TestStateMachine}, targetElements =
{stateMachine_out = OUT!TestStateMachine}, variables = {}},
self=split_send : ASMModule}
SEVERE: local stack = []
SEVERE: A.__applyStateMachine(1 : NTransientLink;) : ??#33 140:19-140:80
SEVERE: local variables = {stateMachine_out=OUT!TestStateMachine,
stateMachine_in=IN!TestStateMachine, link=TransientLink {rule =
'StateMachine', sourceElements = {stateMachine_in = IN!TestStateMachine},
targetElements = {stateMachine_out = OUT!TestStateMachine}, variables =
{}}, self=split_send : ASMModule, a=IN!Init_to_0}
SEVERE: local stack = [OUT!TestStateMachine, OUT!TestStateMachine]
SEVERE: ****** END Stack Trace
INFO: Execution terminated due to error (see launch configuration to allow
continuation after errors).
SEVERE: ERROR: could not find operation including on Module having
supertypes: [OclAny]

I am quite sure that the helpers are correct. I tested them on a number of
cases.

I have two questions.
First, what is wrong with my code?
Second, should I implement recursion like this, or are there better ways
to achieve the same?
Previous Topic:[ATL] Do a if else in a matched rule ( do {} )
Next Topic:[ATL] Questions about Ecore data type
Goto Forum:
  


Current Time: Thu Apr 25 13:26:04 GMT 2024

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

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

Back to the top