blob: d535db21a29ba78cb112863fc9c63ad2e480d92a [file]
import FamiliesMM : 'Families.ecore#/';
import NamesMM : 'Names.ecore#/';
import PersonsMM : 'Persons.ecore#/';
package org::eclipse::qvtd::xtext::qvtrelation::tests::persons2names2families
{
------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------
-- This is a bidirectional implementation of Benchmarx' Families2Person transformation.
--
-- The hard (configurable forward) transformation from families+persons to families uses an intermediate names model to plan the family formation.
-- The easy (reverse) transformation ffrom families to persons is direct.
------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------
transformation Persons2Names2Families(
persons:PersonsMM,
familiesRight:FamiliesMM,
names:NamesMM,
familiesLeft:FamiliesMM
) {
target persons { -- persons <= familiesRight
input familiesRight;
output persons;
}
target families { -- persons+familiesLeft => names => familiesRight
{input familiesLeft; input persons;}
via names;
output familiesRight;
}
attribute PREFER_EXISTING_FAMILY_TO_NEW : Boolean[1] = 'true';
attribute PREFER_CREATING_PARENT_TO_CHILD : Boolean[1] = 'true';
query getForename(p : PersonsMM::Person[1]) : String[1] {
let safeName = '' + p.name -- workaround Bug 550602
in let index = safeName.indexOf(', ')
in safeName.substring(index+2, safeName.size())
}
query getSurname(p : PersonsMM::Person[1]) : String[1] {
let safeName = '' + p.name -- workaround Bug 550602
in let index = safeName.indexOf(', ')
in safeName.substring(1, index-1)
}
top relation FPtoN0_PersonRegister2NamesRegister
{
domain persons pr : PersonRegister;
domain familiesLeft fr : FamilyRegister;
enforce domain names nr : NameRegister;
}
relation N0_Surname2Surname
{
primitive domain surname : String[?];
enforce domain names sn : Surname {
name = surname
};
}
top relation PtoN1__Person2NamesRegister
{
sn : NamesMM::Surname;
domain persons pr : PersonRegister {
persons = p : Person
};
domain familiesLeft fr : FamilyRegister;
enforce domain names nr : NameRegister {
surnames = sn
};
when {
FPtoN0_PersonRegister2NamesRegister(pr, fr, nr);
N0_Surname2Surname(getSurname(p), sn);
}
where {
PtoN2_Person2Surname(p, sn);
}
}
abstract relation PtoN2_Person2Surname
{
domain persons p : Person[1];
enforce domain names sn : Surname;
}
relation PtoN2_Female2Surname overrides PtoN2_Person2Surname
{
domain persons p : Female[1];
enforce domain names sn : Surname {
females = p
};
where {
PtoN3_Female2FamilyGroup(p, sn);
}
}
relation PtoN2_Male2Surname overrides PtoN2_Person2Surname
{
domain persons p : Male[1];
enforce domain names sn : Surname {
males = p
};
where {
PtoN3_Male2FamilyGroup(p, sn);
}
}
abstract relation PtoN3_Female2FamilyGroup
{
domain persons p : Female[1];
enforce domain names sn : Surname;
}
relation PtoN3_Mother2NewFamilyGroup overrides PtoN3_Female2FamilyGroup
{
domain persons p : Female[1];
enforce domain names sn : Surname {
familyGroups = fg : FamilyGroup {
forenames = sonPlan : FemaleMotherForename {
person = p,
name = getForename(p)
}
}
};
when {
not this.PREFER_EXISTING_FAMILY_TO_NEW;
this.PREFER_CREATING_PARENT_TO_CHILD;
}
}
relation PtoN3_Daughter2NewFamilyGroup overrides PtoN3_Female2FamilyGroup
{
domain persons p : Female[1];
enforce domain names sn : Surname {
familyGroups = fg : FamilyGroup {
forenames = sonPlan : FemaleDaughterForename {
person = p,
name = getForename(p)
}
}
};
when {
not this.PREFER_EXISTING_FAMILY_TO_NEW;
not this.PREFER_CREATING_PARENT_TO_CHILD;
}
}
abstract relation PtoN3_Male2FamilyGroup
{
domain persons p : Male[1];
enforce domain names sn : Surname;
}
relation PtoN3_Father2NewFamilyGroup overrides PtoN3_Male2FamilyGroup
{
domain persons p : Male[1];
enforce domain names sn : Surname {
familyGroups = fg : FamilyGroup {
forenames = sonPlan : MaleFatherForename {
person = p,
name = getForename(p)
}
}
};
when {
not this.PREFER_EXISTING_FAMILY_TO_NEW;
this.PREFER_CREATING_PARENT_TO_CHILD;
}
}
relation PtoN3_Son2NewFamilyGroup overrides PtoN3_Male2FamilyGroup
{
domain persons p : Male[1];
enforce domain names sn : Surname {
familyGroups = fg : FamilyGroup {
forenames = sonPlan : MaleSonForename {
person = p,
name = getForename(p)
}
}
};
when {
not this.PREFER_EXISTING_FAMILY_TO_NEW;
not this.PREFER_CREATING_PARENT_TO_CHILD;
}
}
relation FtoN0_Family2Surname
{
domain familiesLeft f : Family[1] ;
enforce domain names sn : Surname {
families = f
};
}
top relation FtoN1_Family2FamilyGroup
{
domain familiesLeft f : Family;
enforce domain names fg : FamilyGroup {
surname = sn : Surname
};
when {
FtoN0_Family2Surname(f, sn);
}
}
top relation FtoN1_Family2SurnameContainment
{
sp : NamesMM::Surname[?];
domain persons pr : PersonRegister;
domain familiesLeft fr : FamilyRegister {
families = f : Family
};
enforce domain names nr : NameRegister {
surnames = sp
};
when {
FPtoN0_PersonRegister2NamesRegister(pr, fr, nr);
N0_Surname2Surname(f.name, sp);
}
where {
FtoN0_Family2Surname(f, sp);
}
}
top relation FtoN2_Daughter2DaughterPlan
{
domain familiesLeft fm : FamilyMember[1] {
daughtersInverse = f : Family
};
enforce domain names fg : FamilyGroup {
forenames = fn : DaughterForename {
familyMember = fm,
name = fm.name
}
};
when {
FtoN1_Family2FamilyGroup(f, fg);
}
}
top relation FtoN2_Father2FatherPlan
{
domain familiesLeft fm : FamilyMember[1] {
fatherInverse = f : Family
};
enforce domain names fg : FamilyGroup {
forenames = fn : FatherForename {
familyMember = fm,
name = fm.name
}
};
when {
FtoN1_Family2FamilyGroup(f, fg);
}
}
top relation FtoN2_Mother2MotherPlan
{
domain familiesLeft fm : FamilyMember[1] {
motherInverse = f : Family
};
enforce domain names fg : FamilyGroup {
forenames = fn : MotherForename {
familyMember = fm,
name = fm.name
}
};
when {
FtoN1_Family2FamilyGroup(f, fg);
}
}
top relation FtoN2_Son2SonPlan
{
domain familiesLeft fm : FamilyMember[1] {
sonsInverse = f : Family
};
enforce domain names fg : FamilyGroup {
forenames = fn : SonForename {
familyMember = fm,
name = fm.name
}
};
when {
FtoN1_Family2FamilyGroup(f, fg);
}
}
top relation NtoF1_NamesRegister2FamilyRegister
{
domain names nr : NameRegister;
enforce domain familiesRight fr : FamilyRegister;
}
top relation NtoF1_FamilyGroup2Family
{
name : String;
domain names fg : FamilyGroup {
surname = sn : Surname {
nameRegister = nr : NameRegister,
name = name
}
};
enforce domain familiesRight f : Family {
familiesInverse = fr : FamilyRegister,
name = name
};
when {
NtoF1_NamesRegister2FamilyRegister(nr, fr);
}
}
top relation NtoF1_DaughterPlan2Daughter
{
name : String;
domain names fn : DaughterForename {
familyGroup = fg : FamilyGroup,
name = name
};
enforce domain familiesRight fm : FamilyMember {
daughtersInverse = f : Family,
name = name
};
when {
NtoF1_FamilyGroup2Family(fg, f);
}
}
top relation NtoF1_FatherPlan2Father
{
name : String;
domain names fn : FatherForename {
familyGroup = fg : FamilyGroup,
name = name
};
enforce domain familiesRight fm : FamilyMember {
fatherInverse = f : Family,
name = name
};
when {
NtoF1_FamilyGroup2Family(fg, f);
}
}
top relation NtoF1_MotherPlan2Mother
{
name : String;
domain names fn : MotherForename {
familyGroup = fg : FamilyGroup,
name = name
};
enforce domain familiesRight fm : FamilyMember {
motherInverse = f : Family,
name = name
};
when {
NtoF1_FamilyGroup2Family(fg, f);
}
}
top relation NtoF1_SonPlan2Son
{
name : String;
domain names fn : SonForename{
familyGroup = fg : FamilyGroup,
name = name
};
enforce domain familiesRight fm : FamilyMember {
sonsInverse = f : Family,
name = name
};
when {
NtoF1_FamilyGroup2Family(fg, f);
}
}
top relation NtoF1_FemaleDaughterPlan2Daughter
{
name : String;
domain names fn : FemaleDaughterForename {
familyGroup = fg : FamilyGroup,
name = name
};
enforce domain familiesRight fm : FamilyMember {
daughtersInverse = f : Family,
name = name
};
when {
NtoF1_FamilyGroup2Family(fg, f);
}
}
top relation NtoF1_FemaleMotherPlan2Mother
{
name : String;
domain names fn : FemaleMotherForename {
familyGroup = fg : FamilyGroup,
name = name
};
enforce domain familiesRight fm : FamilyMember {
motherInverse = f : Family,
name = name
};
when {
NtoF1_FamilyGroup2Family(fg, f);
}
}
top relation NtoF1_MaleFatherPlan2Father
{
name : String;
domain names fn : MaleFatherForename {
familyGroup = fg : FamilyGroup,
name = name
};
enforce domain familiesRight fm : FamilyMember {
fatherInverse = f : Family,
name = name
};
when {
NtoF1_FamilyGroup2Family(fg, f);
}
}
top relation NtoF1_MaleSonPlan2Son
{
name : String;
domain names fn : MaleSonForename {
familyGroup = fg : FamilyGroup,
name = name
};
enforce domain familiesRight fm : FamilyMember {
sonsInverse = f : Family,
name = name
};
when {
NtoF1_FamilyGroup2Family(fg, f);
}
}
/* top relation FtoP0_FamilyRegister2PersonRegister {
domain familiesRight fr : FamilyRegister{};
enforce domain persons pr : PersonRegister{};
where {
FtoP1_Father2Male(fr, pr);
FtoP1_Mother2Female(fr, pr);
FtoP1_Son2Male(fr, pr);
FtoP1_Daughter2Female(fr, pr);
}
} */
--------------------------------------------------------------------------------------------------------------
-- Transform Fathers to Males
--------------------------------------------------------------------------------------------------------------
top relation FtoP1_Father2Male {
domain familiesRight fr : FamilyRegister {
families = f : Family {
father = m1 : FamilyMember
}
};
enforce domain persons pr:Persons::PersonRegister {
persons = m2:Persons::Male
};
where {
FtoP2_FamilyNames2PersonName(f, m1, m2);
}
}
--------------------------------------------------------------------------------------------------------------
-- Transform Mothers to Females
--------------------------------------------------------------------------------------------------------------
top relation FtoP1_Mother2Female {
domain familiesRight fr : FamilyRegister {
families = f : Family {
mother = m1 : FamilyMember
}
};
enforce domain persons pr:Persons::PersonRegister {
persons = m2:Persons::Female
};
where {
FtoP2_FamilyNames2PersonName(f, m1, m2);
}
}
--------------------------------------------------------------------------------------------------------------
-- Transform Sons to Males
--------------------------------------------------------------------------------------------------------------
top relation FtoP1_Son2Male {
domain familiesRight fr : FamilyRegister {
families = f : Family {
sons = m1 : FamilyMember
}
};
enforce domain persons pr:Persons::PersonRegister {
persons = m2:Persons::Male
};
where {
FtoP2_FamilyNames2PersonName(f, m1, m2);
}
}
--------------------------------------------------------------------------------------------------------------
-- Transform Daughters to Females
--------------------------------------------------------------------------------------------------------------
top relation FtoP1_Daughter2Female {
domain familiesRight fr : FamilyRegister {
families = f : Family {
daughters = m1 : FamilyMember
}
};
enforce domain persons pr:Persons::PersonRegister{
persons = m2:Persons::Female
};
where {
FtoP2_FamilyNames2PersonName(f, m1, m2);
}
}
--------------------------------------------------------------------------------------------------------------
-- Transform FamilyNames2PersonName
--------------------------------------------------------------------------------------------------------------
relation FtoP2_FamilyNames2PersonName {
personname: String;
surname: String;
fullname: String;
index: Integer;
domain familiesRight f : Family {
name = surname
},
m1 : FamilyMember {
name = personname
}
default_values {
index = fullname.indexOf(', ');
surname = fullname.substring(1, index-1);
personname = fullname.substring(index+2, fullname.size());
};
enforce domain persons m2 : Person {
name = fullname
}
default_values {
index = surname.size();
fullname = surname + ', ' + personname;
};
}
}
}