Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » VIATRA2 » Please criticise my transformation
Please criticise my transformation [message #645339] Thu, 16 December 2010 16:57 Go to next message
Tassilo Horn is currently offline Tassilo Horn
Messages: 93
Registered: July 2009
Member
Hi all,

I've finished my first transformation. It's a slight extension of the
ATL tutorial's Families2Persons transformation. Basically, on the
source side there are Families connected to Members with different
relations (father, mother, sons, daughters), and on the target side,
there are Males and Females with an abstract supertype Person, and
a Male relates to his wife, and parents to their children.

My transformation seems to work properly (at least, I get what I
expect), but since it is my first self-made VIATRA2 transformation, I'd
be very happy for comments and improvement suggestions!

Especially, the transformation seem overly verbose to me because of
pretty much code duplication (like in the childParentMapping pattern).

The complete eclipse project containing the model space and the
transformation can be downloaded from

http://www.uni-koblenz.de/~horn/Families2PersonsVIATRA2.tar. gz

Ok, so this is my code:

--8<---------------cut here---------------start------------->8---
namespace familymodel2genealogy;

import Families.metamodel;
import Persons.metamodel;

machine FamilyModel2Genealogy {

// ENTRY POINT

rule main() = call transform();

// PATTERNS

pattern memberMapping(M, P) = {
Member(M);
Person(P);
Member.member2person(Traces, M, P);
}

pattern maleMemberMapping(M, P) = {
Male(P);
find memberMapping(M, P);
}

pattern femaleMemberMapping(M, P) = {
Female(P);
find memberMapping(M, P);
}

pattern familyModelMapping(FM, G) = {
FamilyModel(FM);
Genealogy(G);
FamilyModel.familymodel2genealogy(Traces, FM, G);
}

pattern isFemale(M) = {
Member(M);
Family(SomeFamily);
Family.mother(X, SomeFamily, M);
} or {
Member(M);
Family(SomeFamily);
Family.daughters(X, SomeFamily, M);
}

pattern familyMapping(F, A) = {
Family(F);
Address(A);
Family.family2address(X, F, A);
}

pattern childParentMapping(C, PC, PP) = {
Member(C);
find memberMapping(C, PC);
Family(Fam);
Family.sons(S, Fam, C);
Member(P);
Family.father(X, Fam, P);
find memberMapping(P, PP);
} or {
Member(C);
find memberMapping(C, PC);
Family(Fam);
Family.daughters(S, Fam, C);
Member(P);
Family.father(X, Fam, P);
find memberMapping(P, PP);
} or {
Member(C);
find memberMapping(C, PC);
Family(Fam);
Family.daughters(S, Fam, C);
Member(P);
Family.mother(X, Fam, P);
find memberMapping(P, PP);
} or {
Member(C);
find memberMapping(C, PC);
Family(Fam);
Family.sons(S, Fam, C);
Member(P);
Family.mother(X, Fam, P);
find memberMapping(P, PP);
}

pattern mappedChild(PC, PP) = {
Person(PC);
Person(PP);
Person.children(X, PP, PC);
}

pattern mainFamily(M, F) = {
Member(M);
Family(F);
Family.father(X, F, M);
} or {
Member(M);
Family(F);
Family.mother(X, F, M);
} or {
Member(M);
Family(F);
Family.sons(X, F, M);
} or {
Member(M);
Family(F);
Family.daughters(X, F, M);
}

// GT RULES

gtrule transformFamilyModel(out FM, out G) = {
precondition pattern unmappedFamilyModel(FM) = {
FamilyModel(FM);
neg find familyModelMapping(FM, NoGenealogy);
}
postcondition
find familyModelMapping(FM, G)
action {
move(G, Persons.model);
rename(G, name(FM) + "Genealogy");
call members2Persons(FM, G);
call families2Addresses(FM, G);
call createRelations(FM);
}
}

gtrule transformFamily(out F, in G) = {
precondition pattern unmappedFamily(F, S, T, G) = {
Family(F);
Genealogy(G);
neg find familyMapping(F, NoAddress);
Family.street(S) in F;
Family.town(T) in F;
}
postcondition pattern mappedFamily(F, A, G) = {
find familyMapping(F, A);
Genealogy(G);
}
action {
move(A, Persons.model);
rename(A, name(F) + "Address");
let Street = undef, Town = undef in seq {
new(Address.street(Street) in A);
new(Address.town(Town) in A);
setValue(Street, value(S));
setValue(Town, value(T));
}
}
}

gtrule transformMaleMember(out M, in G) = {
precondition pattern unmappedMember(M, FN, LN, G) = {
Member(M);
Family(F);
Member.firstName(FN) in M;
find mainFamily(M, F);
Family.lastName(LN) in F;
Genealogy(G);
neg find isFemale(M);
neg find memberMapping(M, NoPerson);
}
postcondition pattern mappedMember(M, P, G) = {
find maleMemberMapping(M, P);
Person(P);
Genealogy(G);
Genealogy.persons(X, G, P);
}
action {
move(P, Persons.model);
rename(P, name(M));
let FullName = undef in seq {
new(Person.fullName(FullName) in P);
setValue(FullName, value(FN) + " " + value(LN));
}
}
}

gtrule transformFemaleMember(out M, in G) = {
precondition pattern unmappedMember(M, FN, LN, G) = {
Member(M);
Family(F);
Member.firstName(FN) in M;
find mainFamily(M, F);
Family.lastName(LN) in F;
Genealogy(G);
find isFemale(M);
neg find memberMapping(M, NoPerson);
}
postcondition pattern mappedMember(M, P, G) = {
find femaleMemberMapping(M, P);
Person(P);
Genealogy(G);
Genealogy.persons(X, G, P);
}
action {
move(P, Persons.model);
rename(P, name(M));
let FullName = undef in seq {
new(Person.fullName(FullName) in P);
setValue(FullName, value(FN) + " " + value(LN));
}
}
}

gtrule connectSpouse(out H) = {
precondition pattern husband(H, W, PH, PW) = {
Member(H);
Member(W);
Male(PH);
Female(PW);
find maleMemberMapping(H, PH);
find femaleMemberMapping(W, PW);
neg find isFemale(H);
find isFemale(W);
Family(Family);
Family.father(X, Family, H);
Family.mother(X2, Family, W);
}
postcondition pattern spouse(PH, PW) = {
Male(PH);
Female(PW);
Male.wife(S, PH, PW);
}
}

gtrule connectMemberToAddress(out M) = {
precondition pattern familyMember(M, P, A) = {
Member(M);
Person(P);
find memberMapping(M, P);
Address(A);
Family(F);
find mainFamily(M, F);
find familyMapping(F, A);
}
postcondition pattern livesAt(P, A) = {
Person(P);
Address(A);
Person.address(X, P, A);
}
}

gtrule connectParents(out C) = {
precondition pattern unconnectedChild(C, PC, PP) = {
Member(C);
Person(PC);
Person(CC);
find childParentMapping(C, PC, PP);
neg find mappedChild(PC, PP);
}
postcondition pattern connectedChild(C, PC, PP) = {
Member(C);
Person(PC);
Person(PP);
Person.children(HC, PP, PC);
}
}

// ASM RULES

rule transform() = seq {
let G = undef in
forall FM with apply transformFamilyModel(FM, G)
do println("Transformed " + fqn(FM) + " to " + fqn(G));

println("--- Transformation terminated. ");
}

rule members2Persons(in FM, in G) = seq {
forall MMember in FM with apply transformMaleMember(MMember, G)
do println("Transformed " + fqn(MMember));
forall FMember in FM with apply transformFemaleMember(FMember, G)
do println("Transformed " + fqn(FMember));
}

rule families2Addresses(in FM, in G) = seq {
forall Family in FM with apply transformFamily(Family, G)
do println("Transformed " + fqn(Family));
}

rule createRelations(in FM) = seq {
forall Member in FM with apply connectSpouse(Member)
do println("Connected spouse of " + fqn(Member));
forall Member in FM with apply connectMemberToAddress(Member)
do println("Connected Address of " + fqn(Member));
iterate call connectChildrenToParents(FM);
}

rule connectChildrenToParents(in FM) = seq {
choose Child in FM with apply connectParents(Child)
do println("Connected parents of " + fqn(Child));
}
}
--8<---------------cut here---------------end--------------->8---

Thank a lot for any suggestions!

Bye,
Tassilo
--
Dipl.-Inform. Tassilo Horn | Room: B015
University of Koblenz-Landau, Campus Koblenz | Phone: +49 (261) 287-2745
Institute for Software Technology | Mail: horn@uni-koblenz.de
Universitätsstr. 1, 56070 Koblenz, Germany |
Re: Please criticise my transformation [message #646006 is a reply to message #645339] Tue, 21 December 2010 14:45 Go to previous messageGo to next message
Zoltan Ujhelyi is currently offline Zoltan Ujhelyi
Messages: 215
Registered: July 2009
Senior Member
Hi,

sorry for a late response.

I looked at the transformation, it seems working, however, in case of GT Rules it seems that often postconditions and actions are used together.

I think, it would be easier to read if the transformation rules would be expressed either purely declaratively (pre- and postcondition form), or purely imperatively (precondition and action), as it is hard to understand at first, what does the transformation do.

About the verboseness of the language I understand your concern. We have some ideas how to make the language more concise, but it is hard - especially because we don't have the resources to port the existing transformations, so backwards compatibility is an issue.

On the other hand, if you have some idea how to make it, we are glad to discuss them.

Zoltán Ujhelyi

PS.: Do you allow us to list your transformation in the VIATRA wiki among the transformations as an example. It may be used as a comparison between ATL and VIATRA. Thank you. Zoltán
Re: Please criticise my transformation [message #646027 is a reply to message #646006] Tue, 21 December 2010 16:14 Go to previous messageGo to next message
Tassilo Horn is currently offline Tassilo Horn
Messages: 93
Registered: July 2009
Member
Zoltán Ujhelyi <ujhelyiz@mit.bme.hu> writes:

Hi Zoltán,

> sorry for a late response.

I have to thank you for your helpful replies, so there's nothing you
have to be sorry for. :-)

> I looked at the transformation, it seems working, however, in case of
> GT Rules it seems that often postconditions and actions are used
> together.
>
> I think, it would be easier to read if the transformation rules would
> be expressed either purely declaratively (pre- and postcondition
> form), or purely imperatively (precondition and action), as it is hard
> to understand at first, what does the transformation do.

Hm, I can replace some imperative code like "move(A, Persons.model)" in
an action by using "Address(A) in Persons.model" in the postcondition.
But as far as I can see, rename() and setValue() are only available in
the action part, right?

So would you prefer splitting any rule with both postcondition and
action into two separate rules with identical preconditions? One with
only a postcondition for creating elements, and a second one with only
an action to rename the element and set attribute values?

> About the verboseness of the language I understand your concern. We
> have some ideas how to make the language more concise, but it is hard
> - especially because we don't have the resources to port the existing
> transformations, so backwards compatibility is an issue.
>
> On the other hand, if you have some idea how to make it, we are glad
> to discuss them.

I have no idea of how to make it, but things that I'd pretty much like
to omit is including conditions in preconditions that are already
implied by pattern calls. Example:

pattern memberMapping(M, P) = {
Member(M);
Person(P);
Member.member2person(Traces, M, P);
}

gtrule connectPersonToAddress(out M) = {
precondition pattern familyMember(M, P, A) = {
Member(M); // redundant
Person(P); // redundant
find memberMapping(M, P); // implies the two above
Address(A);
Family(F);
find mainFamily(M, F);
find familyMapping(F, A);
}
// ...
}

The "find memberMapping(M, P)" already implies that M is a Member and P
is a Person, so having to specify that again seems redundant to me, at
least from a plain user's perspective.

> PS.: Do you allow us to list your transformation in the VIATRA wiki
> among the transformations as an example. It may be used as a
> comparison between ATL and VIATRA.

Sure, but please name me as the author including my (obfuscated) email
address, because I will use that transformation in the related work of
my dissertation, and I do not want to be accused of having copied &
pasted that example from the VIATRA2 wiki.

I've based it on the ATL tutorial transformation available at

http://wiki.eclipse.org/ATL/Tutorials_-_Create_a_simple_ATL_ transformation

but extended the metamodels in various ways to make it more interesting.

I've written that transformation in ATL, QVTo, QVTr, GrGen.NET, and now
I'm doing it in Tefkat. Others will follow.

If you want, I can send you all of them. Simply drop me a mail.

Bye,
Tassilo
--
Dipl.-Inform. Tassilo Horn | Room: B015
University of Koblenz-Landau, Campus Koblenz | Phone: +49 (261) 287-2745
Institute for Software Technology | Mail: horn@uni-koblenz.de
Universitätsstr. 1, 56070 Koblenz, Germany |
Re: Please criticise my transformation [message #646129 is a reply to message #646027] Wed, 22 December 2010 09:22 Go to previous messageGo to next message
Zoltan Ujhelyi is currently offline Zoltan Ujhelyi
Messages: 215
Registered: July 2009
Senior Member
Hi,

Quote:
Hm, I can replace some imperative code like "move(A, Persons.model)" in
an action by using "Address(A) in Persons.model" in the postcondition.
But as far as I can see, rename() and setValue() are only available in
the action part, right?

So would you prefer splitting any rule with both postcondition and
action into two separate rules with identical preconditions? One with
only a postcondition for creating elements, and a second one with only
an action to rename the element and set attribute values?

You are right, there is no real support for these elements as far as I know. So you need both postcondition and action to write these patterns. So consider my previous idea as invalid. Very Happy

Quote:
The "find memberMapping(M, P)" already implies that M is a Member and P
is a Person, so having to specify that again seems redundant to me, at
least from a plain user's perspective.

You are right, this is redundant. Currently, it is possible to remove the line Person(P) in this case, and the transformation would run this way, but it results in a warning, as it is not possible to calculate the type information for the pattern locally. So in this case it is not needed for execution, only the parser marks that this might cause problems (in some corner cases).

Quote:
Sure, but please name me as the author including my (obfuscated) email address, because I will use that transformation in the related work of
my dissertation, and I do not want to be accused of having copied &
pasted that example from the VIATRA2 wiki.

That's natural - it was your work after all. Thanks for sharing it with us.

Zoltán Ujhelyi
Re: Please criticise my transformation [message #646147 is a reply to message #646129] Wed, 22 December 2010 11:13 Go to previous message
Tassilo Horn is currently offline Tassilo Horn
Messages: 93
Registered: July 2009
Member
Zoltán Ujhelyi <ujhelyiz@mit.bme.hu> writes:

Hi Zoltán,

> You are right, there is no real support for these elements as far as I
> know. So you need both postcondition and action to write these
> patterns. So consider my previous idea as invalid. :d

Ok, but I support your statement that in general it is preferrable to
stick with one concept only.

>> The "find memberMapping(M, P)" already implies that M is a Member and
>> P is a Person, so having to specify that again seems redundant to me,
>> at least from a plain user's perspective.
>
> You are right, this is redundant. Currently, it is possible to remove
> the line Person(P) in this case, and the transformation would run this
> way, but it results in a warning, as it is not possible to calculate
> the type information for the pattern locally. So in this case it is
> not needed for execution, only the parser marks that this might cause
> problems (in some corner cases).

Yes, I already tested that, but I'm a person who is totally unable to
accept any warnings in his code. :-)

> Quote:
>> Sure, but please name me as the author including my (obfuscated) email
>> address, because I will use that transformation in the related work of
>> my dissertation, and I do not want to be accused of having copied &
>> pasted that example from the VIATRA2 wiki.
>
> That's natural - it was your work after all. Thanks for sharing it with us.

And I'm happy to help the community.

Bye,
Tassilo
--
Dipl.-Inform. Tassilo Horn | Room: B015
University of Koblenz-Landau, Campus Koblenz | Phone: +49 (261) 287-2745
Institute for Software Technology | Mail: horn@uni-koblenz.de
Universitätsstr. 1, 56070 Koblenz, Germany |
Previous Topic:Importing Ecore metamodel into Modelspace with VIATRA2 R3.1
Next Topic:Copy rule
Goto Forum:
  


Current Time: Sun Sep 21 02:12:18 GMT 2014

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

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