Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » Epsilon » Mapping of abstract types
Mapping of abstract types [message #1841968] Fri, 04 June 2021 16:21 Go to next message
Tomas Wall is currently offline Tomas WallFriend
Messages: 53
Registered: April 2021
Member
Hello,

I am currently trying to learn ETL, and I am using a simple example. I want to map between two Ecore metamodels that contain the same object and relationships (I know this is not ideal, but it is just for learning purposes).
In the photo I have attached the image of the metamodel.
https://ibb.co/8rW7KHW
Up until now I have been able to write the following rules.

rule Forest2Forest
transform s: model1!Forest
to t: model2!Forest
{
t.name=s.name;
t.house::=s.getHouses();
t.tree::=s.getTrees();
t.river::=s.getRivers();
}

rule House2House
transform s: model1!House
to t: model2!House
{
t.name=s.name;
}
rule Tree2Tree
transform s: model1!Tree
to t: model2!Tree
{
t.name=s.name;
}
rule River2River
transform s: model1!River
to t: model2!River
{
t.name=s.name;
}

rule Path2Path
transform s: model1!Path
to t: model2!Path
{
t.name=s.name;
t.sourceObject ...?
t.targetObject ...?
}

operation model1!Forest getHouses() {
	return model1!House.all;
}
operation model1!Forest getRivers() {
	return model1!River.all;
}
operation model1!Forest getTress() {
	return model1!Tree.all;
}


However, I am a bit stuck when it comes to the relation between the path and the object. The idea is that a path has one sourceObject that can be a House, a Tree, or a River, and one targetObject that can be a House, a Tree, or a River. I am not sure how the transformation rules in such relationship should be. Should I create a transformation rule for the Object too? If so how to show that an object can either be a house, a tree, or a river?

Hope I was clear :)

Best,
Tomas
Re: Mapping of abstract types [message #1841973 is a reply to message #1841968] Fri, 04 June 2021 20:39 Go to previous messageGo to next message
Tomas Wall is currently offline Tomas WallFriend
Messages: 53
Registered: April 2021
Member
Furthermore, another issue that I have here is the following. Let's image that the root element is not Forest, but there is another concept named city, and the city can contain 0 to many forests. We create three forests. Now if I use the operations that I have written above such as:

operation model1!Forest getHouses() {
	return model1!House.all;
}


It collects all houses, but it does not place them accordingly in the forest they belong. So I believe there must be something else that should be added to the operation to make sure that the houses in a specific forest are transformed as houses in that specific forest in the other ecore model.
Re: Mapping of abstract types [message #1841975 is a reply to message #1841973] Sat, 05 June 2021 06:42 Go to previous messageGo to next message
Dimitris Kolovos is currently offline Dimitris KolovosFriend
Messages: 2165
Registered: July 2009
Location: York, UK
Senior Member

Hi Tomas,

The two incomplete statements should read:

t.sourceObject  ::= s.sourceObject;
t.targetObject ::= s.targetObject;


as per https://www.eclipse.org/epsilon/doc/etl/#source-elements-resolution

Lines 6-8 of your transformation should also read:

t.house ::= s.houses;
t.tree ::= s.trees;
t.river ::= s.rivers;
t.paths ::= s.paths;


Does this answer your second question too?

Best,
Dimitris
Re: Mapping of abstract types [message #1841982 is a reply to message #1841975] Sat, 05 June 2021 19:44 Go to previous messageGo to next message
Tomas Wall is currently offline Tomas WallFriend
Messages: 53
Registered: April 2021
Member
Hi Dimistris,
Thank you for your answer. I am trying to learn how the relationship between components is translated into transformation rules and I have encountered some issues with the metamodels I have uploaded here.
This is the input https://ibb.co/StkMnQ6 and this is the output https://ibb.co/85cBGQs .

I mapped region to region and neighbourhood to zone and they work fine. However, now I want to map park2zone, and zone2zone. So the park, zone, and neighbourhood in the input model should be transformed into a zone in the output model. I wrote the rules, but there is something missing, and I cannot seem to find how to transform them.
The second thing I want to do is transform BigHouseArea2BigHouseArea. Now in the input model, the big house area is contained in the neighbourhood that will be transformed into a zone in the output model. Howeveer, the big house area in the output model , only has a reference with the region and big house, and this is where I get confused and cannot continue further with the transformation rules.

I am not sure how to proceed in this cases therefore your help would be deeply appreciated. These are the transformation rules I have written so far.

rule Region2Region
transform s: input!Region
to t: output!Region
{
t.name=s.name;
t.zone ::= s.neighbourhood;
}

rule Neighbourhood2Zone
transform s: input!Neighbourhood
to t:output!Zone
{
t.name=s.name;
}

rule Park2Zone
transform s: input!Park
to t:Zone
{
t.name=s.name;
//not sure what else should be added here or in some other tranformation for this to take place
}

rule Zone2Zone
transform s: input!Zone
to t: output!Zone
{
t.name=s.name;
//not complete
}

rule BigHouseArea2BigHouseArea
transform s: input!BigHouseArea
to t: output!BigHouseArea
{
t.name=s.name;
//in the input file there is a containment between the BigHouseArea and the Neighbourhood, while in the output, there is a reference between Region and BigHouseArea, and BigHouse and BigHouseArea.Should I add anything anywhere else to show these relationships?  
}


Note: The concepts and the relationships might look a bit weird, but this is just for learning purposes.

Thank you in advance,
Tomas!
Re: Mapping of abstract types [message #1842004 is a reply to message #1841982] Mon, 07 June 2021 05:55 Go to previous messageGo to next message
Dimitris Kolovos is currently offline Dimitris KolovosFriend
Messages: 2165
Registered: July 2009
Location: York, UK
Senior Member

Hi Tomas,

Could you please prepare a minimal example [1] I can use to run your transformation locally?

Best,
Dimitris

[1] https://www.eclipse.org/epsilon/doc/articles/minimal-examples/
Re: Mapping of abstract types [message #1842014 is a reply to message #1842004] Mon, 07 June 2021 09:20 Go to previous messageGo to next message
Tomas Wall is currently offline Tomas WallFriend
Messages: 53
Registered: April 2021
Member
Hi Dimitris,

This is the Epsilon version I currently have 2.2.0.202009032353
And these are the files.

Another issue that I also have, besides the one mentioned above is that i also want to map House to Houses, and Furniture to Furniture, but in the output model I also have HouseObjects, therefore when I transform from the input model to the output model, I also need to create the HouseObjects and Furniture should be contained in the HouseObjects, and I am not quite sure how to make that happen.

Many many thanks!

[Updated on: Mon, 07 June 2021 20:30]

Report message to a moderator

Re: Mapping of abstract types [message #1842040 is a reply to message #1842014] Tue, 08 June 2021 05:23 Go to previous messageGo to next message
Dimitris Kolovos is currently offline Dimitris KolovosFriend
Messages: 2165
Registered: July 2009
Location: York, UK
Senior Member

Hi Tomas,

Could you please try to reduce your example to the bare minimum I'd need to understand (i.e. remove unrelated classes/references/attributes/rules) and also include a hand-crafted copy of your expected target model in your zip file? It'd be great if you could also try to rationalise what remains of your metamodels (e.g. why would a SmallHouse have from/to references to a Block? why would a Region have a direct reference to one MansionGarden?).

Best,
Dimitris
Re: Mapping of abstract types [message #1842105 is a reply to message #1842040] Wed, 09 June 2021 11:24 Go to previous messageGo to next message
Tomas Wall is currently offline Tomas WallFriend
Messages: 53
Registered: April 2021
Member
Hi Dimitris,

I tried some other metamodels, as they are probably more comprehensible.
However, I cannot reduce them, as some of the issues I have include multiple elements and the relationship between them.
The metamodels have a similar logic, they have locations (of different kinds), and paths that connect the locations. Paths can also contain components.

So I have two metamodels, forestEcore and forestTextual. They contain more or less the same concepts with slight differences, and also some differences in the relationships.

My first goal is to transform from forestEcore to forestTextual.
In the following is the mapping I want to achieve:

These are done:
--------------------------------------------------------------
Forest -> Forest
SimpleLocation -> Location
CompoundLocation -> Location
EntryPosition -> EntryPosition
Crossroad -> Crossroad

These are not:
--------------------------------------------------------------
//for these two the issue I have is that in forestEcore they are contained in the Compound Location, while in the forextTextual, special position is contained in special position path which is contained in location, while start position is contained in initial path which is contained in the location. So when I make the transformations StartPosition2StartPosition I have to first create the path in the forestTextual and then place the StartPosition that is transformed, in that path.

StartPosition -> StartPosition
SpecialPosition -> SpecialPosition

// when I transform ComponentA2ComponentA, in forestEcore, ComponentA is contained in Path, while in forestTextual it is contained in ComponentCollection that does not exist at all in forestEcore, therefore I believe that when I transform them I have to create the ComponentCollection, which should be contained in the InternalPath, or Path, and it should contain ComponentA. How can I do that in Epsilon?

Component A -> ComponentA

// in forestEcore there is only one kind of path, while in forestTextual there are four which are subcategories of the path that is in forestEcore, depending on what they connect. So when I transform a path from forestEcore I need to check what they connect , so I can transform them accordingly. In the following I am also describing some pseudocode for each rule, but not sure how to write them in Epsilon

//when the paths are transformed, I should also make sure to include in the attributes the locations they connect.
Path -> Path // if (sourceArea== (simplelocation || compundlocation) && targetArea== (simplelocation || compundlocation) )
Path -> InitialPath // if (sourceArea==StartPosition)
Path -> SpecialPositionPath // if (targetArea==SpecialPosition)
Path -> InternalPath // if (sourceArea== null && targetArea== null )

--------------------------------------------------------------------------------

There are my main issues. As I mentioned sorry that I can have a more minimal example as the concepts are related to one another. In the zip file you can find the metamodels, the models and the transformation. The ecore model is the source model, and based on that source model, I have attached a handcrafted target model, that the transformation should output.

Would really appreciate your help.

Many thanks,
Tomas!
Re: Mapping of abstract types [message #1842109 is a reply to message #1842105] Wed, 09 June 2021 11:48 Go to previous messageGo to next message
Dimitris Kolovos is currently offline Dimitris KolovosFriend
Messages: 2165
Registered: July 2009
Location: York, UK
Senior Member

Hi Tomas,

I'm very sorry but I'm finding it difficult to follow this example too. You shouldn't really need a metamodel that contains 10+ classes and more than a dozen features to demonstrate the issue you're encountering. I'd encourage you to give this another go and simplify your metamodels so that they contain no more than 4-5 classes each, with self-evident semantics (e.g. it's not clear to me what a CompoundLocation, a ComponentA or a SpecialPosition represents in the real world).

If you're struggling to come up with suitable metamodels, perhaps you could draw some inspiration from [1].

Best,
Dimitris

[1] https://www.eclipse.org/epsilon/live/?etl

[Updated on: Wed, 09 June 2021 11:50]

Report message to a moderator

Re: Mapping of abstract types [message #1842110 is a reply to message #1842109] Wed, 09 June 2021 12:30 Go to previous messageGo to next message
Tomas Wall is currently offline Tomas WallFriend
Messages: 53
Registered: April 2021
Member
Hi Dimitris,

Ok, I will try to have a very minimal example, for each of these issues, instead of having one for all of them, and send it to you.

Many thanks!
Re: Mapping of abstract types [message #1842114 is a reply to message #1842110] Wed, 09 June 2021 14:11 Go to previous messageGo to next message
Tomas Wall is currently offline Tomas WallFriend
Messages: 53
Registered: April 2021
Member
Hi Dimitris,

I created an example in Epsilon for my first issue. I will try to do the same with the rest as it seems more convenient for both of us.
The issue that I have here is that on the target metamodel I have a 0 to * containment relationship, while in the source metamodel I have a 1 to 1 containment relationship, which I am not sure how to transform.
This is the link https://www.eclipse.org/epsilon/live/?58348590

Thank you,
Tomas!
Re: Mapping of abstract types [message #1842117 is a reply to message #1842114] Wed, 09 June 2021 14:47 Go to previous messageGo to next message
Dimitris Kolovos is currently offline Dimitris KolovosFriend
Messages: 2165
Registered: July 2009
Location: York, UK
Senior Member

Hi Tomas,

Replacing
t.area ::= s.area;

with
t.area ::= Sequence{s.area}; 

or
t.area.add(s.area.equivalent());

should do the trick.

Best,
Dimitris

[Updated on: Wed, 09 June 2021 14:47]

Report message to a moderator

Re: Mapping of abstract types [message #1842118 is a reply to message #1842117] Wed, 09 June 2021 14:59 Go to previous messageGo to next message
Tomas Wall is currently offline Tomas WallFriend
Messages: 53
Registered: April 2021
Member
Hi Dimitris,

Thanks a lot, it works perfectly fine. Now I extended the metamodel a bit to show another issue I have, presented in this link https://www.eclipse.org/epsilon/live/?f32e2091 .

I want to transform Tree2Tree, but in the source metamodel the tree is contained in the area, while in the target metamodel in TreeGroup, which does not exist as a concept in the source metamodel. So to do this transformation, I believe I should first create the TreeGroup which should be contained in the area and forest, and then transform tree to tree, where the tree should be contained in the TreeGroup. But I am not really sure on how to create these new elements that do not exist and specify their containers. Hope this is clear enough!

Many thanks,
Tomas!

Re: Mapping of abstract types [message #1842119 is a reply to message #1842118] Wed, 09 June 2021 15:06 Go to previous messageGo to next message
Dimitris Kolovos is currently offline Dimitris KolovosFriend
Messages: 2165
Registered: July 2009
Location: York, UK
Senior Member

Two options here. You could update your Area2Area rule to the following

rule Area2Area
	transform s : Source!Area
	to t : Target!Area,
	   tg : Target!TreeGroup {
	
	t.name = s.name;
	t.treegroup = tg;
	tg.tree ::= s.tree;
}


or (more imperatively)

rule Area2Area
	transform s : Source!Area
	to t : Target!Area {
	
	t.name = s.name;
	var tg : new Target!TreeGroup;
	t.treegroup = tg;
	tg.tree ::= s.tree;
}


Best,
Dimitris
Re: Mapping of abstract types [message #1842146 is a reply to message #1842119] Thu, 10 June 2021 09:16 Go to previous messageGo to next message
Tomas Wall is currently offline Tomas WallFriend
Messages: 53
Registered: April 2021
Member
Hi Dimitris,

Many thanks! I tried this solution on a similar example (now I extend elements), and in this other case, something is not right.
This is the link https://www.eclipse.org/epsilon/live/?baf3c267
In the target model I expect to have Project -> TaskCollection -> Task, but I only receive Project -> TaskCollection.

Many thanks,
Tomas
Re: Mapping of abstract types [message #1842147 is a reply to message #1842146] Thu, 10 June 2021 09:27 Go to previous messageGo to next message
Dimitris Kolovos is currently offline Dimitris KolovosFriend
Messages: 2165
Registered: July 2009
Location: York, UK
Senior Member

This is because your transformation is missing a rule that copies tasks across (e.g. Task2Task).

Best,
Dimitris
Re: Mapping of abstract types [message #1842169 is a reply to message #1842147] Thu, 10 June 2021 17:44 Go to previous messageGo to next message
Tomas Wall is currently offline Tomas WallFriend
Messages: 53
Registered: April 2021
Member
Thanks Dimitris,

That worked fine. Another issue I am having is that in a source metamodel I have a highway. In the target metamodel, this highway should be transformed to a highway or a capital highway. It should be transformed into a capital highway if it connects a capital to a city, and it should be transformed into a highway if it connects two cities. But I am not sure how to include this part.
This is the link to the example https://www.eclipse.org/epsilon/live/?2f8cb877 . The two transformation rules I am talking about are in the end.

Thanks,
Tomas!
Re: Mapping of abstract types [message #1842173 is a reply to message #1842169] Thu, 10 June 2021 18:12 Go to previous messageGo to next message
Dimitris Kolovos is currently offline Dimitris KolovosFriend
Messages: 2165
Registered: July 2009
Location: York, UK
Senior Member

You can achieve this by adding guards to your two rules as shown below.

rule highway2capitalhighway
  transform s: Source!Highway
  to t: Target!CapitalHighway {

  guard: s.targetLocation.isTypeOf(Source!Capital) or 
      s.sourceLocation.isTypeOf(Source!Capital)

  t.name=s.name;
}

rule highway2highway
  transform s: Source!Highway
  to t: Target!Highway {

  guard: not s.targetLocation.isTypeOf(Source!Capital) and 
      not s.sourceLocation.isTypeOf(Source!Capital)
    
  t.name=s.name;
}


Best,
Dimitris
Re: Mapping of abstract types [message #1842176 is a reply to message #1842173] Thu, 10 June 2021 19:37 Go to previous messageGo to next message
Tomas Wall is currently offline Tomas WallFriend
Messages: 53
Registered: April 2021
Member
Hi Dimiris,

Thanks for the answer! However, I have a question in this case. Why when I try the following guards:

rule highway2capitalhighway
transform s: Source!Highway
to t: Target!CapitalHighway
{
 guard: s.sourceLocation.isTypeOf(Source!Capital) 
t.name=s.name;
}
//highway2highway
//this should happen only when the highway
//in the source model connects a city
//to a city
rule highway2highway
transform s: Source!Highway
to t: Target!Highway
{
  guard: s.sourceLocation.isTypeOf(Source!City) 
t.name=s.name;
}


With these guards I am checking just the source location as that is what I am actually interested about and I am not using the keyword "not".
I just say that the source Location should be a city and the highway can be transformed into a highway. But that transformation never happens. Would you mind explaining why does this happen?

________________________________________________________

Another issue that I encounter (using the guards that you suggested, which work perfectly fine), is when I add this line
 t.capitalhighway::=s.highways;

to the Region2City rule. I do it in the same way as I did for
 t.highway::=s.highways;

but I get an error which you can see here
https://www.eclipse.org/epsilon/live/?3638b011


Many thanks,
Tomas

[Updated on: Thu, 10 June 2021 20:28]

Report message to a moderator

Re: Mapping of abstract types [message #1842180 is a reply to message #1842176] Fri, 11 June 2021 05:02 Go to previous messageGo to next message
Dimitris Kolovos is currently offline Dimitris KolovosFriend
Messages: 2165
Registered: July 2009
Location: York, UK
Senior Member

> I just say that the source Location should be a city and the highway can be transformed into a highway. But that transformation never happens. Would you mind explaining why does this happen?
This works fine if you fix the model by replacing the reference to "jp1" which doesn't exist to a city that exists e.g. "s2"

> but I get an error which you can see here https://www.eclipse.org/epsilon/live/?3638b011
This happens because you are attempting to assign a collection of values (s.highways is multi-valued) to a single-valued feature.

Best,
Dimitris
Re: Mapping of abstract types [message #1842203 is a reply to message #1842180] Fri, 11 June 2021 15:06 Go to previous messageGo to next message
Tomas Wall is currently offline Tomas WallFriend
Messages: 53
Registered: April 2021
Member
Hi Dimitris,

Thanks you for your answer. Does it exist any way around this in Epsilon ETL, or is that not possible?
Quote:

This happens because you are attempting to assign a collection of values (s.highways is multi-valued) to a single-valued feature.



Best,
Tomas
Re: Mapping of abstract types [message #1842213 is a reply to message #1842203] Sat, 12 June 2021 04:53 Go to previous messageGo to next message
Dimitris Kolovos is currently offline Dimitris KolovosFriend
Messages: 2165
Registered: July 2009
Location: York, UK
Senior Member

One option would be to select the first value of the multi-valued feature using the first() operation [1] and assign it to the single-valued feature i.e.

t.highway ::= s.highways.first();


Just to note that the metamodels have started growing/losing relevance to the real world (e.g. "class Highway extends Highways") so my suggestion would be to tidy them up a bit if you are to use them in further questions.

Also, please note that opposite references are not specified correctly (see [2]):

ref Highway[*]#incomingHighway incomingHighway ;
...
ref Location[1]#targetLocation targetLocation;


should instead be:

ref Highway[*]#targetLocation incomingHighway ;
...
ref Location[1]#incomingHighway targetLocation;


The Eclipse-based Emfatic editor should report this problem.

Best,
Dimitris

[1] https://www.eclipse.org/epsilon/doc/eol/#collections-and-maps
[2] https://www.eclipse.org/emfatic/#references

[Updated on: Sat, 12 June 2021 05:06]

Report message to a moderator

Re: Mapping of abstract types [message #1842257 is a reply to message #1842213] Mon, 14 June 2021 15:50 Go to previous messageGo to next message
Tomas Wall is currently offline Tomas WallFriend
Messages: 53
Registered: April 2021
Member
Hi Dimitris,

Thanks for all your help. While trying to do the transformation in the other direction I encountered this issue. Areas A1_1, A2_1, and A3 should be SimpleAreas in the target metamodel because they do not contain other states (s.states == null). However, everything is transformed into LargeAreas. I believe I am not adding some sort of containment relationship somewhere, but I am not really sure what the issue is. This is the link where I reproduced the issue. https://www.eclipse.org/epsilon/live/?7b0d30f2

Many thanks,
Tomas
Re: Mapping of abstract types [message #1842265 is a reply to message #1842257] Tue, 15 June 2021 04:56 Go to previous message
Dimitris Kolovos is currently offline Dimitris KolovosFriend
Messages: 2165
Registered: July 2009
Location: York, UK
Senior Member

Hi Tomas,

As the "states" feature is multi-valued, you should use "s.states.isEmpty()" instead of "s.states == null" to check this (and "not s.states.isEmpty()" instead of "s.states.isDefined()" further down).

Best,
Dimitris
Previous Topic:Empty placeholders instead of required values.
Next Topic:How to use the collection() method?
Goto Forum:
  


Current Time: Sat Apr 27 06:21:59 GMT 2024

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

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

Back to the top