Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » ATL » [ATL] Containment references cannot span across models(They can - ATL collections cause the problem)
[ATL] Containment references cannot span across models [message #1009619] Fri, 15 February 2013 11:48 Go to next message
Gunnar Arndt is currently offline Gunnar Arndt
Messages: 57
Registered: June 2012
Member
Hi members,

I have to fight with output elements written to the wrong file in a transformation with several (hierarchic) output metamodels, i.e. there are output metamodels otx.ecore and quantity.ecore, which is a sub-model of otx.ecore.

All output should be written to output.otx, the output file of the main model (otx.ecore); but sometimes, output from the sub-model (quantity.ecore) is written to its output file output.quantity instead.

As I have recently figured out, the problem seems to be caused by the ATL 'collect', which creates its own intermediate collection:

lazy rule SubtractAtom2Term {
    from
    	source: transformate!SubtractAtom
    to
    	otxTerm: otx!Subtract(
                -- This works as desired, i.e. the quantity goes to output.otx:
                numeral <- source.numeral->createQuantity(),
                -- This does not work, i.e. the quantities go to output.quantity:
                subtrahend <- source.subtrahends->collect(s | s->createQuantity())
                -- Error message: Containment references cannot span across models.
    	)
}


As posted here before, cross-model references are activated.

Any suggetions? Maybe how to work around using the 'collect'?
Thank you for any input.
Re: [ATL] Containment references cannot span across models [message #1009692 is a reply to message #1009619] Fri, 15 February 2013 14:35 Go to previous messageGo to next message
Hugo Bruneliere is currently offline Hugo Bruneliere
Messages: 604
Registered: July 2009
Senior Member
Hello,

What is createQuantity(): a lazy rule or a helper?
And which type of value is it supposed to return?

Regards,

Hugo


------------------------------------------
Hugo Bruneliere - R&D Engineer
AtlanMod research team (Inria, EMN & LINA)
Ecole des Mines de Nantes
Nantes - France
------------------------------------------
Re: [ATL] Containment references cannot span across models [message #1009706 is a reply to message #1009619] Fri, 15 February 2013 14:57 Go to previous messageGo to next message
Gunnar Arndt is currently offline Gunnar Arndt
Messages: 57
Registered: June 2012
Member
Hugo, thanks for the quick reply.

It is a helper which calls a lazy rule:
helper context transformate!QuantityVariable def: createQuantity(): quantity!Quantity = thisModule->QuantityVariable2Quantity(self);

lazy rule QuantityVariable2Quantity {
    from    
        source: transformate!QuantityVariable
    to
        output: quantity!Quantity(
            -- ...
        )
}


This is just an example, there are many helpers of the same name in different contexts, all of which return an otx or a quantity output object that can be assigned to otx!Subtract.numeral[1] and otx!Subtract.subtrahend[0..*]

Output objects from the otx main-metamodel can be assigned no problem, but object from the quantity sub-metamodel can be assigned when the helper is called directly (as for the numeral), but go to the other output file when the helper is called by 'collect' (as for subtrahend; resulting error message about containment references).
Re: [ATL] Containment references cannot span across models [message #1009752 is a reply to message #1009706] Fri, 15 February 2013 16:29 Go to previous messageGo to next message
Hugo Bruneliere is currently offline Hugo Bruneliere
Messages: 604
Registered: July 2009
Senior Member
I don't know if your error could come from this but helpers are not not intended to create elements in the target model(s).
They are supposed to only navigate input model(s) and return input model element(s) (or values of a primitive type), the creation of elements being let to matched rules (directly or indirectly by a call to a lazy rule in one of their assignments).

Also, the notation for calling a lazy rule is thisModule.ruleName(elementName), the -> operator being used for collections only.

Hugo


------------------------------------------
Hugo Bruneliere - R&D Engineer
AtlanMod research team (Inria, EMN & LINA)
Ecole des Mines de Nantes
Nantes - France
------------------------------------------
Re: [ATL] Containment references cannot span across models [message #1009807 is a reply to message #1009752] Fri, 15 February 2013 19:04 Go to previous messageGo to next message
Dennis Wagelaar is currently offline Dennis Wagelaar
Messages: 164
Registered: September 2012
Senior Member

Op 15-02-13 17:29, Hugo Bruneliere schreef:
> I don't know if your error could come from this but helpers are not not
> intended to create elements in the target model(s).
> They are supposed to only navigate input model(s) and return input model
> element(s) (or values of a primitive type), the creation of elements being let
> to matched rules (directly or indirectly by a call to a lazy rule in one of
> their assignments).

No, this works.

The trick might be in the output metamodel identifier you use: quantity
instead of otx. ATL uses the metamodel identifier to determine into which
output model the element should be generated. You lazy rule says
"quantity!Quantity".

Of course, when you then assign an element inside your quantity output model
to a *containment* reference of an element inside your otx metamodel, the
assigned element is *moved* to the otx output model.

Instead of using "quantity!Quantity", you can also use "otx!Quantity". As otx
includes quantity, this should work.

Can you give us your "create..." statement? That will clear up a lot.

Dennis


Cheers,
Dennis
Re: [ATL] Containment references cannot span across models [message #1010814 is a reply to message #1009619] Mon, 18 February 2013 09:34 Go to previous messageGo to next message
Gunnar Arndt is currently offline Gunnar Arndt
Messages: 57
Registered: June 2012
Member
Hugo and Dennis, thank you for your help. Seems we're going into detail on this...

@Dennis:

  1. You can find the 'create' helper on top of my second post - it is the helper which calls the lazy rule. Please note that there are many such helpers (in different contexts, but of the same name) in my transformation, which call different lazy rules.
  2. I do not know how to use the main model identifier (otx) in order to create sub-model (quantity) elements; Hugo and I have discussed that approach in another thread before, with no success on my side.
    The name spaces in the XML schemata (otx.xsd imports quantity.xsd) and the Ecore model generated from them are org.iso.otx and org.iso.otx.quantity, but stuff like otx!"org::iso::otx::quantity::Quantity" leads to an error in ATL.


Maybe I should make even clearer why I think that the collection created by ATL is the problem: Both output bindings (numeral and subtrahend) in the given lazy rule call the helper createQuantity, which in both cases returns a sub-model (quantity) element.
If the helper is called directly (numeral), the sub-model element is inserted correctly into the main model output file - there is no containment reference, as it is directly contained. But if the helper is called by an iterator (collect), the sub-model output elements (Quantities) are written to the quantity output file, which would require a cross-file reference.

I'm wondering why that happens when using collect only.


[Updated on: Mon, 18 February 2013 10:37]

Report message to a moderator

Re: [ATL] Containment references cannot span across models [message #1035938 is a reply to message #1010814] Sun, 07 April 2013 18:00 Go to previous messageGo to next message
Dennis Wagelaar is currently offline Dennis Wagelaar
Messages: 164
Registered: September 2012
Senior Member

Op 18-02-13 10:35, Gunnar Arndt schreef:
> Hugo and Dennis, thank you for your help. Seems we're going into detail on
> this...
>
> @Dennis:
>
> You can find the 'create' helper on top of my second post - it is the helper
> which calls the lazy rule. Please note that there are many such helpers (in
> different contexts, but of the same name) in my transformation, which call
> different lazy rules.
> I do not know how to use the main model identifier (otx) in order to create
> sub-model (quantity) elements; Hugo and I have discussed that approach in
> another thread before, with no success on my side.
> The name spaces in the XML schemata (otx.xsd imports quantity.xsd) and the
> Ecore model generated from them are org.iso.otx and org.iso.otx.quantity, but
> stuff like "org::iso::otx::Quantity" leads to an error in ATL.

Hmm, ATL normally detects the imports closure of Ecore metamodels by following
the outward references/inheritance relationships of each EClass it traverses.
Unless no otx metaclass has an explicit reference to a quantity metaclass,
this approach should be able to find quantity EClasses as part of the otx
metamodel, e.g. OTX!Quantity or OTX!"org::iso::otx::Quantity".

>
> Maybe I should make even clearer why I think that the collection created by
> ATL is the problem: Both output bindings (numeral and subtrahend) in the given
> lazy rule call the helper createQuantity, which in both cases returns a
> sub-model (quantity) element.
> If the helper is called directly (numeral), the sub-model element is inserted
> correctly into the main model output file - there is no containment reference,
> as it is directly contained. But if the helper is called by an iterator
> (collect), the sub-model output elements (Quantities) are written to the
> quantity output file, which would require a cross-file reference.
>
> I'm wondering why that happens when using collect only.

In the first case you're assigning to "numeral" and in the second case you're
assigning to "subtrahend". Those are different properties. Please verify
against both.

Dennis


Cheers,
Dennis
Re: [ATL] Containment references cannot span across models [message #1036295 is a reply to message #1009619] Mon, 08 April 2013 07:41 Go to previous messageGo to next message
Gunnar Arndt is currently offline Gunnar Arndt
Messages: 57
Registered: June 2012
Member
Dennis, thank you for the idea, but I cannot do that: the property 'numeral' is a NumericTerm[1..*], i.e. an EList<NumericTerm>, whereas 'subtrahend' is just a NumericTerm[0..1]. The value assigned to subtrahend goes to the correct output document (otx), but those assigned through an OCL collection go to the sub-model output document (quantity).
I've recently taken notice of the possibility to explicitely state the target output model in a rule using the keyword 'in', like so:
-- org.iso.otx.quantities is a sub-model of org.iso.otx
create OUT: otx, quant: quantities from IN: transformate;

-- ...

lazy rule QuantityVariable2Quantity {
    from    
        source: transformate!QuantityVariable
    to
        output: quantity!Quantity in OUT(
            -- ...
        )
}

I'm going to test that as soon as possible.

[Updated on: Mon, 08 April 2013 08:17]

Report message to a moderator

Re: [ATL] Containment references cannot span across models [message #1037460 is a reply to message #1009619] Tue, 09 April 2013 15:26 Go to previous messageGo to next message
Gunnar Arndt is currently offline Gunnar Arndt
Messages: 57
Registered: June 2012
Member
Using the 'in' keyword does not work either - it can only be used to send objects to one of "their" output models.
Re: [ATL] Containment references cannot span across models [message #1220033 is a reply to message #1009619] Mon, 09 December 2013 09:06 Go to previous message
Gunnar Arndt is currently offline Gunnar Arndt
Messages: 57
Registered: June 2012
Member
A solution is described in http://www.eclipse.org/forums/index.php/m/1220031/#msg_1220031
Previous Topic:[ATL] Load the genmodel instead of the Ecore file?
Next Topic:Plugin ATL
Goto Forum:
  


Current Time: Wed Sep 17 11:34:48 GMT 2014

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

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