| 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; |
| }; |
| } |
| } |
| } |