-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathFamiliesToPersons.page
123 lines (99 loc) · 2.54 KB
/
FamiliesToPersons.page
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
---
title: `FamiliesToPersons` Model Transformation in Clafer
...
An example `FamiliesToPersons` inspired by [ATL/Tutorials - Create a simple ATL transformation](http://wiki.eclipse.org/ATL/Tutorials_-_Create_a_simple_ATL_transformation).
We let the reader appreciate the simplicity, conciseness, and declarative nature of this transformation in Clafer.
First, we specify the `Family` model.
```clafer
enum Gender = male | female
abstract Family
familyName -> string
members -> Member +
[ this.lastName = familyName ]
abstract Member
lastName -> string
firstName -> string
gender -> Gender
```
Now, let's create two sample families: the Browns and the Smiths.
```clafer
theBrowns : Family
[ familyName = "Brown" ]
[ members = John ]
John : Member
[ firstName = "John" ]
[ gender = male ]
theSmiths : Family
[ familyName = "Smith" ]
[ members = Alice, Bob]
Alice : Member
[ this.firstName = "Alice" ]
[ this.gender = female ]
Bob : Member
[ this.firstName = "Bob" ]
[ this.gender = male ]
```
Next, we specify the `Person` model.
`Person`s point to `Member`s and have the corresponding first and last names.
```clafer
abstract Person -> Member
fName -> string = this.firstName
lName -> string = this.lastName
```
`Male`s are persons whose gender is `male`.
```clafer
Male : Person 2..*
[ this.gender = male ]
```
Analogously, `Feamale`s.
```clafer
Female : Person +
[ this.gender = female ]
```
Now, we're ready to specify the actual model transformation which maps `male` `Member`s to `Male`s and `female` `Member`s to `Female`s.
```clafer
[ all member : Member | member.gender.dref = male => (one m : Male | m.dref = member) ]
[ all member : Member | member.gender.dref = female => (one m : Female | m.dref = member) ]
```
When instantiating this model (e.g., using the ClaferIDE), the following result is generated:
```{.clafer .ide}
```
```
=== Instance 1 ===
```
The inputs
```
female
male
theBrowns
John
lastName$1 = "Brown"
firstName$1 = "John"
gender$1 = male
familyName$1 = "Brown"
members$1 = John
theSmiths
Alice
lastName$2 = "Smith"
firstName$2 = "Alice"
gender$2 = female
Bob
lastName$3 = "Smith"
firstName$3 = "Bob"
gender$3 = male
familyName$2 = "Smith"
members$2 = Bob
members$3 = Alice
```
The result
```
Female = Alice
fName$1 = "Alice"
lName$1 = "Smith"
Male$1 = John
fName$2 = "John"
lName$2 = "Brown"
Male$2 = Bob
fName$3 = "Bob"
lName$3 = "Smith"
```