This document discusses YAMTL, a model transformation language for performing model-to-model and model-to-text transformations at scale. YAMTL uses an internal DSL based on Xtend for defining model transformations. It allows for model-based pattern matching, traceability of model changes, and incremental execution of transformations. YAMTL aims to improve the performance and scalability of model transformations compared to other languages through features like lazy rule evaluation, optimized collection handling, and interoperability with Java libraries. The document outlines YAMTL's execution model and language features, and provides an example of using YAMTL to synchronize class and database models.
3. Scalable model transformation
Very Large Models (VLMs):
Model Transformation (MT)
a key bottleneck
Challenge to application
in industry
TL
Artur Boronat. 5th event Lowcomote Network. 14/4/2021
4. Yet Another Model Transformation Language
• Model-based pattern matching
• Model-to-model transformation
• Model-to-text transformation (via Xtend)
• Traceability model
• Forward model change propagation
• Incremental execution of model transformations
TL
Artur Boronat. 5th event Lowcomote Network. 14/4/2021
5. What is novel in YAMTL…
• Internal DSL of Xtend
• Interoperability with JVM tools and libraries:
• extensibility of MT functionality with Java libraries
• reuse of MT trafos within JVM programs
• High-level API to work with collections
• Succinct syntax to work with lambda expressions
• IDE support: type checker and debugger…
• MT abstractions atop Java/Xtend
• Interoperability among modeling tools: serialization via EMF
• High performance in comparison with MT languages of the same
type of expressiveness
TL
Artur Boronat. 5th event Lowcomote Network. 14/4/2021
6. Talk outline
• Model-to-model transformation
• outline of execution model
• language
• Model-to-model synchronization
• Performance experiments
TL
Artur Boronat. 5th event Lowcomote Network. 14/4/2021
8. MTs in YAMTL: ORM Example
name: String
«stereotype»
NamedElt
«stereotype»
Classifier
DataType
Package
isAbstract: Boolean
Class
*
owner
attr
*
type
*
super
*
classifiers
name: String
«stereotype»
Named
Type
Database
Column
Table
*
owner
col
*
type
*
types
*
tables
keyOf
key
*
0..1
name = "Item"
1:Class
multiValued: Boolean
Attribute
name = "product"
multiValued=false
2:Attribute
name = "Order"
4:Class
name = "date"
multiValued=false
3:Attribute
name = "items"
multiValued=true
5:Attribute
attr attr attr
name = "Item"
1:Class
2:Attribute
name = "Invoice"
4:Class
3:Attribute 5:Attribute
attr attr attr
name = "Item"
1:Table
name = "product"
2:Column
name = "Order"
6:Table
name = "date"
3:Column
name = "pk_Order"
7:Column
col
col
col
name =
"pk_Item"
4:Column
col
name = "fk_Item--items-->Order"
5:Column
col
name = "Item"
1:Table
name = "product"
2:Column
name = "Invoice"
6:Table
name = "pk_Invoice"
7:Column
col
col
col
name = "pk_Item"
4:Column
col
col
type
type
name = "String"
0:DataType
type
type
name = "String"
0:DataType
type
type
Source metamodel (class diagrams) Target metamodel (database schemas)
Initial source model
Propagation of delta a (case 4)
Ms Mt
Initial target model
TL
Artur Boronat. 5th event Lowcomote Network. 14/4/2021
9. Graphical Definition of CD2REL
_
where
rule C->T
attr
T : Table
col
PK_COL : Column
col
2:Column
COL : Column
2:Column
A : Attribute
C : Class
type COL : Column
A : Attribute
D : DataType
type
COL : Column
OTHER : Attribute C : Class
attr
C2 : Class
rule A->C
type
name = AN
COL : Column
name = AN
A : Attribute
name = "String"
D : DataType
rule R->FK
type name = “fk_$CN1--$AN-->$CN2”
COL : Column
name = AN
OTHER : Attribute
name = CN1
C1 : Class
attr
name = CN2
C2 : Class
TL
Artur Boronat. 5th event Lowcomote Network. 14/4/2021
10. YAMTL Module Declaration
class cd2db extends YAMTLModule {
new () {
header().in('cd', CD).out('db', DB)
ruleStore(
// rule declarations
)
helperStore(
// managed helpers
)
}
val CD = CDPackage.eINSTANCE
val DB = RelationalPackage.eINSTANCE
// other helpers as Xtend methods
}
Façade interface:
loading models,
execution, profiling
MT name
MT signature for
traceable models
inOut()
for in-place MT
TL
Artur Boronat. 5th event Lowcomote Network. 14/4/2021
11. Initialization
• Module instantiation: parsing and initialization of execution configuration
• Initialization of type extents (allInstances)
• Static attribute helpers
Execution Semantics
Matching phase
Deterministic rule applications:
• ∀rule ∀object
• Local search with user-defined plans
• Local/global filter conditions
• Multiple rule inheritance
• Model sensitive
Scheduling of matches
Execution phase
• Creation of trafo steps in matchPool
• Initialization of target objects
A. Boronat. Expressive and Efficient Model Transformation with an Internal DSL of Xtend. MODELS’18.
rule
transformation step
name = AN
COL : Column
rule A->C
type
name = AN
A : Attribute
name = "String"
D : DataType
name = "product"
2:Column
name = "product"
multiValued=false
2:Attribute
name = "String"
0:DataType
type
TL
Artur Boronat. 5th event Lowcomote Network. 14/4/2021
12. new Helper('string') [
(CD.dataType.allInstances as Iterable<DataType>)
.findFirst[name == 'String’]
]
YAMTL Rule
Managed helpers
• static attribute helpers
TL
Artur Boronat. 5th event Lowcomote Network. 14/4/2021
13. new Rule('AttributeToColumn’)
.in(‘type', CD.dataType)
.in('att', CD.attribute)
.with(#[‘type])
.filter[
val type = ‘type'.fetch as DataType
val att = 'att'.fetch as Attribute
att.type == type
]
.out('col', DB.column, [
val att = 'att'.fetch as Attribute
val col = 'col'.fetch as Column
col.name = att.name
])
YAMTL Rule
rule
• matched | lazy | uniqueLazy
• transient
input pattern
output pattern
:DataType
name = A
:Column
name = A
:Attribute
type
input pattern output pattern
TL
Artur Boronat. 5th event Lowcomote Network. 14/4/2021
14. new Rule('AttributeToColumn’)
.in(‘type', CD.dataType)
.in('att', CD.attribute)
.with(#[‘type])
.filter[
val type = ‘type'.fetch as DataType
val att = 'att'.fetch as Attribute
att.type == type
]
.out('col', DB.column, [
val att = 'att'.fetch as Attribute
val col = 'col'.fetch as Column
col.name = att.name
])
YAMTL Rule
input pattern
output pattern
:DataType
name = A
:Column
name = A
:Attribute
type
input pattern output pattern
input pattern elements
• with(VBLE) dependencies
• filter(EXPR): local constraint and
global constraints (optional)
• derivedWith(EXPR)
TL
Artur Boronat. 5th event Lowcomote Network. 14/4/2021
15. new Rule('AttributeToColumn’)
.in('att', CD.attribute)
.in(‘type', CD.dataType)
.derivedWith[
val att = 'att'.fetch as Attribute
att.type
]
.out('col', DB.column, [
val att = 'att'.fetch as Attribute
val col = 'col'.fetch as Column
col.name = att.name
])
YAMTL Rule
input pattern
output pattern
:DataType
name = A
:Column
name = A
:Attribute
type
input pattern output pattern
input pattern elements
• with(VBLE) dependencies
• filter(EXPR): local constraint and
global constraints (optional)
• derivedWith(EXPR)
TL
Artur Boronat. 5th event Lowcomote Network. 14/4/2021
16. new Rule('AttributeToColumn’)
.in('att', CD.attribute)
.filter[
val att = 'att'.fetch as Attribute
att.type instanceof DataType
]
.out('col', DB.column, [
val att = 'att'.fetch as Attribute
val col = 'col'.fetch as Column
col.name = att.name
])
YAMTL Rule
input pattern
output pattern
:DataType
name = A
:Column
name = A
:Attribute
type
input pattern output pattern
input pattern elements
• with(VBLE) dependencies
• filter(EXPR): local constraint and
global constraints (optional)
• derivedWith(EXPR)
TL
Artur Boronat. 5th event Lowcomote Network. 14/4/2021
17. new Rule('AttributeToColumn’)
.in('att', CD.attribute)
.filter[
val att = 'att'.fetch as Attribute
att.type instanceof DataType
]
.out('col', DB.column, [
val att = 'att'.fetch as Attribute
val col = 'col'.fetch as Column
col.name = att.name
])
YAMTL Rule
input pattern
output pattern
:DataType
name = A
:Column
name = A
:Attribute
type
input pattern output pattern
output pattern elements
• action(EXPR) dependencies
• using(VBLE, EXPR): local variables
• endWith(EXPR): imperative expression
TL
Artur Boronat. 5th event Lowcomote Network. 14/4/2021
18. new Rule('ClassToTable')
.in('c', CD.class_).build()
.out('t', DB.table, [
// environment vbles
val c = 'c'.fetch as Class
val t = 't'.fetch as Table
val pk_col = 'pk_col'.fetch as Column
// bindings
t.name = c.name
t.col += c.attr.fetch as List<Column>
t.col += pk_col
val list = c.incomingReferences
.fetch('ReferenceToFkColumn')
as List<Column>
if (list !== null)
t.col += list
]).build()
.out('pk_col', DB.column, [
// environment vbles
val c = 'c'.fetch as Class
val pk_col = 'pk_col'.fetch as Column
// bindings
pk_col.name = 'pk_' + c.name
]).build()
.build()
YAMTL Output Action
fetch
to access execution environment
name = "Item"
1:Class
name = "Item"
1:Table
name = "pk_Item"
4:Column
col
TL
Artur Boronat. 5th event Lowcomote Network. 14/4/2021
19. new Rule('ClassToTable')
.in('c', CD.class_).build()
.out('t', DB.table, [
// environment vbles
val c = 'c'.fetch as Class
val t = 't'.fetch as Table
val pk_col = 'pk_col'.fetch as Column
// bindings
t.name = c.name
t.col += c.attr.fetch as List<Column>
t.col += pk_col
val list = c.incomingReferences
.fetch('ReferenceToFkColumn')
as List<Column>
if (list !== null)
t.col += list
]).build()
.out('pk_col', DB.column, [
// environment vbles
val c = 'c'.fetch as Class
val pk_col = 'pk_col'.fetch as Column
// bindings
pk_col.name = 'pk_' + c.name
]).build()
.build()
YAMTL Output Action
fetch
to resolve references in…
name = "Item"
1:Class
name = "Item"
1:Table
name = "pk_Item"
4:Column
col
TL
Artur Boronat. 5th event Lowcomote Network. 14/4/2021
20. new Rule('ClassToTable')
.in('c', CD.class_).build()
.out('t', DB.table, [
// environment vbles
val c = 'c'.fetch as Class
val t = 't'.fetch as Table
val pk_col = 'pk_col'.fetch as Column
// bindings
t.name = c.name
t.col += c.attr.fetch as List<Column>
t.col += pk_col
val list = c.incomingReferences
.fetch('ReferenceToFkColumn')
as List<Column>
if (list !== null)
t.col += list
]).build()
.out('pk_col', DB.column, [
// environment vbles
val c = 'c'.fetch as Class
val pk_col = 'pk_col'.fetch as Column
// bindings
pk_col.name = 'pk_' + c.name
]).build()
.build()
YAMTL Output Action
a) declative rules
new Rule('AttributeToColumn')
.in('att', CD.attribute).filter([ ... ]).build()
.out('col', DB.column, [ ... ]).build()
.build(),
fetch
to resolve references in…
name = "Item"
1:Class
name = "Item"
1:Table
name = "pk_Item"
4:Column
col
TL
Artur Boronat. 5th event Lowcomote Network. 14/4/2021
21. new Rule('ClassToTable')
.in('c', CD.class_).build()
.out('t', DB.table, [
// environment vbles
val c = 'c'.fetch as Class
val t = 't'.fetch as Table
val pk_col = 'pk_col'.fetch as Column
// bindings
t.name = c.name
t.col += c.attr.fetch as List<Column>
t.col += pk_col
val list = c.incomingReferences
.fetch('ReferenceToFkColumn')
as List<Column>
if (list !== null)
t.col += list
]).build()
.out('pk_col', DB.column, [
// environment vbles
val c = 'c'.fetch as Class
val pk_col = 'pk_col'.fetch as Column
// bindings
pk_col.name = 'pk_' + c.name
]).build()
.build()
YAMTL Output Action
b) lazy rules
new Rule('ReferenceToFkColumn')
.uniqueLazy
.in('ref', CD.attribute).build()
.out('fk_col', DB.column, [ ... ]).build()
.build()
a) declative rules
new Rule('AttributeToColumn')
.in('att', CD.attribute).filter([ ... ]).build()
.out('col', DB.column, [ ... ]).build()
.build(),
fetch
to resolve references in…
name = "Item"
1:Class
name = "Item"
1:Table
name = "pk_Item"
4:Column
col
TL
Artur Boronat. 5th event Lowcomote Network. 14/4/2021
22. Reuse in YAMTL
• Multiple Rule Inheritance and abstract rules
• Matching semantics: leftmost top-down search for most concrete applicable
rule for each object
• Execution semantics of output element actions (inherits/overriding)
• Module composition by class extension
• Inheritance: by default
• Redefinition: when a rule (or a helper) in the extending module have a
compatible interface with one rule (or helper) in the extended module
• Module reuse in other JVM programs using imports
TL
24. Scalability with Model Changes
name = "Item"
1:Class
name = "product"
multiValued=false
2:Attribute
name = "Order"
4:Class
name = "date"
multiValued=false
3:Attribute
name = "items"
multiValued=true
5:Attribute
attr attr attr
type
name = "String"
0:DataType
type
type
name = "Item"
1:Table
name = "product"
2:Column
name = “Order”
6:Table
name = "date"
3:Column
name = "pk_Order"
7:Column
col
col
col
name = "pk_Item"
4:Column
col
name = "fk_Item--items-->Order”
5:Column
col
Ms
<latexit sha1_base64="0SDN0EP4VDnS3ovDB3TxsAeT7Kc=">AAAB6nicbVBNS8NAEJ3Ur1q/qh69LBbBU0lEqMeiFy9CRfsBbSib7aRdutmE3Y1QQn+CFw+KePUXefPfuG1z0NYHA4/3ZpiZFySCa+O6305hbX1jc6u4XdrZ3ds/KB8etXScKoZNFotYdQKqUXCJTcONwE6ikEaBwHYwvpn57SdUmsfy0UwS9CM6lDzkjBorPdz1db9ccavuHGSVeDmpQI5Gv/zVG8QsjVAaJqjWXc9NjJ9RZTgTOC31Uo0JZWM6xK6lkkao/Wx+6pScWWVAwljZkobM1d8TGY20nkSB7YyoGellbyb+53VTE175GZdJalCyxaIwFcTEZPY3GXCFzIiJJZQpbm8lbEQVZcamU7IheMsvr5LWRdVzq979ZaV+ncdRhBM4hXPwoAZ1uIUGNIHBEJ7hFd4c4bw4787HorXg5DPH8AfO5w8uNo23</latexit>
<latexit sha1_base64="0SDN0EP4VDnS3ovDB3TxsAeT7Kc=">AAAB6nicbVBNS8NAEJ3Ur1q/qh69LBbBU0lEqMeiFy9CRfsBbSib7aRdutmE3Y1QQn+CFw+KePUXefPfuG1z0NYHA4/3ZpiZFySCa+O6305hbX1jc6u4XdrZ3ds/KB8etXScKoZNFotYdQKqUXCJTcONwE6ikEaBwHYwvpn57SdUmsfy0UwS9CM6lDzkjBorPdz1db9ccavuHGSVeDmpQI5Gv/zVG8QsjVAaJqjWXc9NjJ9RZTgTOC31Uo0JZWM6xK6lkkao/Wx+6pScWWVAwljZkobM1d8TGY20nkSB7YyoGellbyb+53VTE175GZdJalCyxaIwFcTEZPY3GXCFzIiJJZQpbm8lbEQVZcamU7IheMsvr5LWRdVzq979ZaV+ncdRhBM4hXPwoAZ1uIUGNIHBEJ7hFd4c4bw4787HorXg5DPH8AfO5w8uNo23</latexit>
<latexit sha1_base64="0SDN0EP4VDnS3ovDB3TxsAeT7Kc=">AAAB6nicbVBNS8NAEJ3Ur1q/qh69LBbBU0lEqMeiFy9CRfsBbSib7aRdutmE3Y1QQn+CFw+KePUXefPfuG1z0NYHA4/3ZpiZFySCa+O6305hbX1jc6u4XdrZ3ds/KB8etXScKoZNFotYdQKqUXCJTcONwE6ikEaBwHYwvpn57SdUmsfy0UwS9CM6lDzkjBorPdz1db9ccavuHGSVeDmpQI5Gv/zVG8QsjVAaJqjWXc9NjJ9RZTgTOC31Uo0JZWM6xK6lkkao/Wx+6pScWWVAwljZkobM1d8TGY20nkSB7YyoGellbyb+53VTE175GZdJalCyxaIwFcTEZPY3GXCFzIiJJZQpbm8lbEQVZcamU7IheMsvr5LWRdVzq979ZaV+ncdRhBM4hXPwoAZ1uIUGNIHBEJ7hFd4c4bw4787HorXg5DPH8AfO5w8uNo23</latexit>
<latexit sha1_base64="0SDN0EP4VDnS3ovDB3TxsAeT7Kc=">AAAB6nicbVBNS8NAEJ3Ur1q/qh69LBbBU0lEqMeiFy9CRfsBbSib7aRdutmE3Y1QQn+CFw+KePUXefPfuG1z0NYHA4/3ZpiZFySCa+O6305hbX1jc6u4XdrZ3ds/KB8etXScKoZNFotYdQKqUXCJTcONwE6ikEaBwHYwvpn57SdUmsfy0UwS9CM6lDzkjBorPdz1db9ccavuHGSVeDmpQI5Gv/zVG8QsjVAaJqjWXc9NjJ9RZTgTOC31Uo0JZWM6xK6lkkao/Wx+6pScWWVAwljZkobM1d8TGY20nkSB7YyoGellbyb+53VTE175GZdJalCyxaIwFcTEZPY3GXCFzIiJJZQpbm8lbEQVZcamU7IheMsvr5LWRdVzq979ZaV+ncdRhBM4hXPwoAZ1uIUGNIHBEJ7hFd4c4bw4787HorXg5DPH8AfO5w8uNo23</latexit>
Mt
<latexit sha1_base64="wNWyCZUnhTaWWZImAiZa7+p1sC4=">AAAB6nicbVBNS8NAEJ3Ur1q/qh69LBbBU0lEqMeiFy9CRfsBbSib7aZdutmE3YlQQn+CFw+KePUXefPfuG1z0NYHA4/3ZpiZFyRSGHTdb6ewtr6xuVXcLu3s7u0flA+PWiZONeNNFstYdwJquBSKN1Gg5J1EcxoFkreD8c3Mbz9xbUSsHnGScD+iQyVCwSha6eGuj/1yxa26c5BV4uWkAjka/fJXbxCzNOIKmaTGdD03QT+jGgWTfFrqpYYnlI3pkHctVTTixs/mp07JmVUGJIy1LYVkrv6eyGhkzCQKbGdEcWSWvZn4n9dNMbzyM6GSFLlii0VhKgnGZPY3GQjNGcqJJZRpYW8lbEQ1ZWjTKdkQvOWXV0nrouq5Ve/+slK/zuMowgmcwjl4UIM63EIDmsBgCM/wCm+OdF6cd+dj0Vpw8plj+APn8wcvuo24</latexit>
<latexit sha1_base64="wNWyCZUnhTaWWZImAiZa7+p1sC4=">AAAB6nicbVBNS8NAEJ3Ur1q/qh69LBbBU0lEqMeiFy9CRfsBbSib7aZdutmE3YlQQn+CFw+KePUXefPfuG1z0NYHA4/3ZpiZFyRSGHTdb6ewtr6xuVXcLu3s7u0flA+PWiZONeNNFstYdwJquBSKN1Gg5J1EcxoFkreD8c3Mbz9xbUSsHnGScD+iQyVCwSha6eGuj/1yxa26c5BV4uWkAjka/fJXbxCzNOIKmaTGdD03QT+jGgWTfFrqpYYnlI3pkHctVTTixs/mp07JmVUGJIy1LYVkrv6eyGhkzCQKbGdEcWSWvZn4n9dNMbzyM6GSFLlii0VhKgnGZPY3GQjNGcqJJZRpYW8lbEQ1ZWjTKdkQvOWXV0nrouq5Ve/+slK/zuMowgmcwjl4UIM63EIDmsBgCM/wCm+OdF6cd+dj0Vpw8plj+APn8wcvuo24</latexit>
<latexit sha1_base64="wNWyCZUnhTaWWZImAiZa7+p1sC4=">AAAB6nicbVBNS8NAEJ3Ur1q/qh69LBbBU0lEqMeiFy9CRfsBbSib7aZdutmE3YlQQn+CFw+KePUXefPfuG1z0NYHA4/3ZpiZFyRSGHTdb6ewtr6xuVXcLu3s7u0flA+PWiZONeNNFstYdwJquBSKN1Gg5J1EcxoFkreD8c3Mbz9xbUSsHnGScD+iQyVCwSha6eGuj/1yxa26c5BV4uWkAjka/fJXbxCzNOIKmaTGdD03QT+jGgWTfFrqpYYnlI3pkHctVTTixs/mp07JmVUGJIy1LYVkrv6eyGhkzCQKbGdEcWSWvZn4n9dNMbzyM6GSFLlii0VhKgnGZPY3GQjNGcqJJZRpYW8lbEQ1ZWjTKdkQvOWXV0nrouq5Ve/+slK/zuMowgmcwjl4UIM63EIDmsBgCM/wCm+OdF6cd+dj0Vpw8plj+APn8wcvuo24</latexit>
<latexit sha1_base64="wNWyCZUnhTaWWZImAiZa7+p1sC4=">AAAB6nicbVBNS8NAEJ3Ur1q/qh69LBbBU0lEqMeiFy9CRfsBbSib7aZdutmE3YlQQn+CFw+KePUXefPfuG1z0NYHA4/3ZpiZFyRSGHTdb6ewtr6xuVXcLu3s7u0flA+PWiZONeNNFstYdwJquBSKN1Gg5J1EcxoFkreD8c3Mbz9xbUSsHnGScD+iQyVCwSha6eGuj/1yxa26c5BV4uWkAjka/fJXbxCzNOIKmaTGdD03QT+jGgWTfFrqpYYnlI3pkHctVTTixs/mp07JmVUGJIy1LYVkrv6eyGhkzCQKbGdEcWSWvZn4n9dNMbzyM6GSFLlii0VhKgnGZPY3GQjNGcqJJZRpYW8lbEQ1ZWjTKdkQvOWXV0nrouq5Ve/+slK/zuMowgmcwjl4UIM63EIDmsBgCM/wCm+OdF6cd+dj0Vpw8plj+APn8wcvuo24</latexit>
⇤
<latexit sha1_base64="OlYXa5TGZ2jG1EJYshioKcqCJPw=">AAAB6HicbVBNS8NAEJ3Ur1q/qh69LBZBPJREBD0WvXhswX5AG8pmO2nXbjZhdyOU0F/gxYMiXv1J3vw3btsctPXBwOO9GWbmBYng2rjut1NYW9/Y3Cpul3Z29/YPyodHLR2nimGTxSJWnYBqFFxi03AjsJMopFEgsB2M72Z++wmV5rF8MJME/YgOJQ85o8ZKjYt+ueJW3TnIKvFyUoEc9X75qzeIWRqhNExQrbuemxg/o8pwJnBa6qUaE8rGdIhdSyWNUPvZ/NApObPKgISxsiUNmau/JzIaaT2JAtsZUTPSy95M/M/rpia88TMuk9SgZItFYSqIicnsazLgCpkRE0soU9zeStiIKsqMzaZkQ/CWX14lrcuq51a9xlWldpvHUYQTOIVz8OAaanAPdWgCA4RneIU359F5cd6dj0VrwclnjuEPnM8fcAGMrg==</latexit>
<latexit sha1_base64="OlYXa5TGZ2jG1EJYshioKcqCJPw=">AAAB6HicbVBNS8NAEJ3Ur1q/qh69LBZBPJREBD0WvXhswX5AG8pmO2nXbjZhdyOU0F/gxYMiXv1J3vw3btsctPXBwOO9GWbmBYng2rjut1NYW9/Y3Cpul3Z29/YPyodHLR2nimGTxSJWnYBqFFxi03AjsJMopFEgsB2M72Z++wmV5rF8MJME/YgOJQ85o8ZKjYt+ueJW3TnIKvFyUoEc9X75qzeIWRqhNExQrbuemxg/o8pwJnBa6qUaE8rGdIhdSyWNUPvZ/NApObPKgISxsiUNmau/JzIaaT2JAtsZUTPSy95M/M/rpia88TMuk9SgZItFYSqIicnsazLgCpkRE0soU9zeStiIKsqMzaZkQ/CWX14lrcuq51a9xlWldpvHUYQTOIVz8OAaanAPdWgCA4RneIU359F5cd6dj0VrwclnjuEPnM8fcAGMrg==</latexit>
<latexit sha1_base64="OlYXa5TGZ2jG1EJYshioKcqCJPw=">AAAB6HicbVBNS8NAEJ3Ur1q/qh69LBZBPJREBD0WvXhswX5AG8pmO2nXbjZhdyOU0F/gxYMiXv1J3vw3btsctPXBwOO9GWbmBYng2rjut1NYW9/Y3Cpul3Z29/YPyodHLR2nimGTxSJWnYBqFFxi03AjsJMopFEgsB2M72Z++wmV5rF8MJME/YgOJQ85o8ZKjYt+ueJW3TnIKvFyUoEc9X75qzeIWRqhNExQrbuemxg/o8pwJnBa6qUaE8rGdIhdSyWNUPvZ/NApObPKgISxsiUNmau/JzIaaT2JAtsZUTPSy95M/M/rpia88TMuk9SgZItFYSqIicnsazLgCpkRE0soU9zeStiIKsqMzaZkQ/CWX14lrcuq51a9xlWldpvHUYQTOIVz8OAaanAPdWgCA4RneIU359F5cd6dj0VrwclnjuEPnM8fcAGMrg==</latexit>
<latexit sha1_base64="OlYXa5TGZ2jG1EJYshioKcqCJPw=">AAAB6HicbVBNS8NAEJ3Ur1q/qh69LBZBPJREBD0WvXhswX5AG8pmO2nXbjZhdyOU0F/gxYMiXv1J3vw3btsctPXBwOO9GWbmBYng2rjut1NYW9/Y3Cpul3Z29/YPyodHLR2nimGTxSJWnYBqFFxi03AjsJMopFEgsB2M72Z++wmV5rF8MJME/YgOJQ85o8ZKjYt+ueJW3TnIKvFyUoEc9X75qzeIWRqhNExQrbuemxg/o8pwJnBa6qUaE8rGdIhdSyWNUPvZ/NApObPKgISxsiUNmau/JzIaaT2JAtsZUTPSy95M/M/rpia88TMuk9SgZItFYSqIicnsazLgCpkRE0soU9zeStiIKsqMzaZkQ/CWX14lrcuq51a9xlWldpvHUYQTOIVz8OAaanAPdWgCA4RneIU359F5cd6dj0VrwclnjuEPnM8fcAGMrg==</latexit>
Given
t
<latexit sha1_base64="4TjH5hUkthMAn6UpgKadu6gHMWk=">AAAB73icbVBNS8NAEN3Ur1q/qh69LBbBU0lE0GPRi8cK9gPaUDabSbt0s4m7E6GE/gkvHhTx6t/x5r9x2+agrQ8GHu/NMDMvSKUw6LrfTmltfWNzq7xd2dnd2z+oHh61TZJpDi2eyER3A2ZACgUtFCihm2pgcSChE4xvZ37nCbQRiXrASQp+zIZKRIIztFK3H4JENsBBtebW3TnoKvEKUiMFmoPqVz9MeBaDQi6ZMT3PTdHPmUbBJUwr/cxAyviYDaFnqWIxGD+f3zulZ1YJaZRoWwrpXP09kbPYmEkc2M6Y4cgsezPxP6+XYXTt50KlGYLii0VRJikmdPY8DYUGjnJiCeNa2FspHzHNONqIKjYEb/nlVdK+qHtu3bu/rDVuijjK5IScknPikSvSIHekSVqEE0meySt5cx6dF+fd+Vi0lpxi5pj8gfP5AyB/kAM=</latexit>
<latexit sha1_base64="4TjH5hUkthMAn6UpgKadu6gHMWk=">AAAB73icbVBNS8NAEN3Ur1q/qh69LBbBU0lE0GPRi8cK9gPaUDabSbt0s4m7E6GE/gkvHhTx6t/x5r9x2+agrQ8GHu/NMDMvSKUw6LrfTmltfWNzq7xd2dnd2z+oHh61TZJpDi2eyER3A2ZACgUtFCihm2pgcSChE4xvZ37nCbQRiXrASQp+zIZKRIIztFK3H4JENsBBtebW3TnoKvEKUiMFmoPqVz9MeBaDQi6ZMT3PTdHPmUbBJUwr/cxAyviYDaFnqWIxGD+f3zulZ1YJaZRoWwrpXP09kbPYmEkc2M6Y4cgsezPxP6+XYXTt50KlGYLii0VRJikmdPY8DYUGjnJiCeNa2FspHzHNONqIKjYEb/nlVdK+qHtu3bu/rDVuijjK5IScknPikSvSIHekSVqEE0meySt5cx6dF+fd+Vi0lpxi5pj8gfP5AyB/kAM=</latexit>
<latexit sha1_base64="4TjH5hUkthMAn6UpgKadu6gHMWk=">AAAB73icbVBNS8NAEN3Ur1q/qh69LBbBU0lE0GPRi8cK9gPaUDabSbt0s4m7E6GE/gkvHhTx6t/x5r9x2+agrQ8GHu/NMDMvSKUw6LrfTmltfWNzq7xd2dnd2z+oHh61TZJpDi2eyER3A2ZACgUtFCihm2pgcSChE4xvZ37nCbQRiXrASQp+zIZKRIIztFK3H4JENsBBtebW3TnoKvEKUiMFmoPqVz9MeBaDQi6ZMT3PTdHPmUbBJUwr/cxAyviYDaFnqWIxGD+f3zulZ1YJaZRoWwrpXP09kbPYmEkc2M6Y4cgsezPxP6+XYXTt50KlGYLii0VRJikmdPY8DYUGjnJiCeNa2FspHzHNONqIKjYEb/nlVdK+qHtu3bu/rDVuijjK5IScknPikSvSIHekSVqEE0meySt5cx6dF+fd+Vi0lpxi5pj8gfP5AyB/kAM=</latexit>
<latexit sha1_base64="4TjH5hUkthMAn6UpgKadu6gHMWk=">AAAB73icbVBNS8NAEN3Ur1q/qh69LBbBU0lE0GPRi8cK9gPaUDabSbt0s4m7E6GE/gkvHhTx6t/x5r9x2+agrQ8GHu/NMDMvSKUw6LrfTmltfWNzq7xd2dnd2z+oHh61TZJpDi2eyER3A2ZACgUtFCihm2pgcSChE4xvZ37nCbQRiXrASQp+zIZKRIIztFK3H4JENsBBtebW3TnoKvEKUiMFmoPqVz9MeBaDQi6ZMT3PTdHPmUbBJUwr/cxAyviYDaFnqWIxGD+f3zulZ1YJaZRoWwrpXP09kbPYmEkc2M6Y4cgsezPxP6+XYXTt50KlGYLii0VRJikmdPY8DYUGjnJiCeNa2FspHzHNONqIKjYEb/nlVdK+qHtu3bu/rDVuijjK5IScknPikSvSIHekSVqEE0meySt5cx6dF+fd+Vi0lpxi5pj8gfP5AyB/kAM=</latexit>
M0
t
<latexit sha1_base64="AjUxWCbbOH+s5cscYP4rTUk9M74=">AAAB63icbVBNS8NAEJ3Ur1q/qh69LBbRU0lE0GPRixehgrWFNpTNdtMu3U3C7kQooX/BiwdFvPqHvPlv3LQ5aOuDgcd7M8zMCxIpDLrut1NaWV1b3yhvVra2d3b3qvsHjyZONeMtFstYdwJquBQRb6FAyTuJ5lQFkreD8U3ut5+4NiKOHnCScF/RYSRCwSjm0l0fT/vVmlt3ZyDLxCtIDQo0+9Wv3iBmqeIRMkmN6Xpugn5GNQom+bTSSw1PKBvTIe9aGlHFjZ/Nbp2SE6sMSBhrWxGSmfp7IqPKmIkKbKeiODKLXi7+53VTDK/8TERJijxi80VhKgnGJH+cDITmDOXEEsq0sLcSNqKaMrTxVGwI3uLLy+TxvO65de/+ota4LuIowxEcwxl4cAkNuIUmtIDBCJ7hFd4c5bw4787HvLXkFDOH8AfO5w+Q3o3p</latexit>
<latexit sha1_base64="AjUxWCbbOH+s5cscYP4rTUk9M74=">AAAB63icbVBNS8NAEJ3Ur1q/qh69LBbRU0lE0GPRixehgrWFNpTNdtMu3U3C7kQooX/BiwdFvPqHvPlv3LQ5aOuDgcd7M8zMCxIpDLrut1NaWV1b3yhvVra2d3b3qvsHjyZONeMtFstYdwJquBQRb6FAyTuJ5lQFkreD8U3ut5+4NiKOHnCScF/RYSRCwSjm0l0fT/vVmlt3ZyDLxCtIDQo0+9Wv3iBmqeIRMkmN6Xpugn5GNQom+bTSSw1PKBvTIe9aGlHFjZ/Nbp2SE6sMSBhrWxGSmfp7IqPKmIkKbKeiODKLXi7+53VTDK/8TERJijxi80VhKgnGJH+cDITmDOXEEsq0sLcSNqKaMrTxVGwI3uLLy+TxvO65de/+ota4LuIowxEcwxl4cAkNuIUmtIDBCJ7hFd4c5bw4787HvLXkFDOH8AfO5w+Q3o3p</latexit>
<latexit sha1_base64="AjUxWCbbOH+s5cscYP4rTUk9M74=">AAAB63icbVBNS8NAEJ3Ur1q/qh69LBbRU0lE0GPRixehgrWFNpTNdtMu3U3C7kQooX/BiwdFvPqHvPlv3LQ5aOuDgcd7M8zMCxIpDLrut1NaWV1b3yhvVra2d3b3qvsHjyZONeMtFstYdwJquBQRb6FAyTuJ5lQFkreD8U3ut5+4NiKOHnCScF/RYSRCwSjm0l0fT/vVmlt3ZyDLxCtIDQo0+9Wv3iBmqeIRMkmN6Xpugn5GNQom+bTSSw1PKBvTIe9aGlHFjZ/Nbp2SE6sMSBhrWxGSmfp7IqPKmIkKbKeiODKLXi7+53VTDK/8TERJijxi80VhKgnGJH+cDITmDOXEEsq0sLcSNqKaMrTxVGwI3uLLy+TxvO65de/+ota4LuIowxEcwxl4cAkNuIUmtIDBCJ7hFd4c5bw4787HvLXkFDOH8AfO5w+Q3o3p</latexit>
<latexit sha1_base64="AjUxWCbbOH+s5cscYP4rTUk9M74=">AAAB63icbVBNS8NAEJ3Ur1q/qh69LBbRU0lE0GPRixehgrWFNpTNdtMu3U3C7kQooX/BiwdFvPqHvPlv3LQ5aOuDgcd7M8zMCxIpDLrut1NaWV1b3yhvVra2d3b3qvsHjyZONeMtFstYdwJquBQRb6FAyTuJ5lQFkreD8U3ut5+4NiKOHnCScF/RYSRCwSjm0l0fT/vVmlt3ZyDLxCtIDQo0+9Wv3iBmqeIRMkmN6Xpugn5GNQom+bTSSw1PKBvTIe9aGlHFjZ/Nbp2SE6sMSBhrWxGSmfp7IqPKmIkKbKeiODKLXi7+53VTDK/8TERJijxi80VhKgnGJH+cDITmDOXEEsq0sLcSNqKaMrTxVGwI3uLLy+TxvO65de/+ota4LuIowxEcwxl4cAkNuIUmtIDBCJ7hFd4c5bw4787HvLXkFDOH8AfO5w+Q3o3p</latexit>
name = "Item"
1:Table
name = "product"
2:Column
name = "Invoice"
6:Table
name = "date"
3:Column
name = "pk_Invoice"
7:Column
col
col
col
name = "pk_Item"
4:Column
col
name = "fk_Item--items-->Invoice"
5:Column
col
s
<latexit sha1_base64="FgejQ7k3O1VsOBio6emr7bDNH4A=">AAAB73icbVBNS8NAEJ3Ur1q/qh69LBbBU0lE0GPRi8cK9gPaUDabSbt0s4m7G6GE/gkvHhTx6t/x5r9x2+agrQ8GHu/NMDMvSAXXxnW/ndLa+sbmVnm7srO7t39QPTxq6yRTDFssEYnqBlSj4BJbhhuB3VQhjQOBnWB8O/M7T6g0T+SDmaTox3QoecQZNVbq9kMUhg70oFpz6+4cZJV4BalBgeag+tUPE5bFKA0TVOue56bGz6kynAmcVvqZxpSyMR1iz1JJY9R+Pr93Ss6sEpIoUbakIXP190ROY60ncWA7Y2pGetmbif95vcxE137OZZoZlGyxKMoEMQmZPU9CrpAZMbGEMsXtrYSNqKLM2IgqNgRv+eVV0r6oe27du7+sNW6KOMpwAqdwDh5cQQPuoAktYCDgGV7hzXl0Xpx352PRWnKKmWP4A+fzBx77kAI=</latexit>
<latexit sha1_base64="FgejQ7k3O1VsOBio6emr7bDNH4A=">AAAB73icbVBNS8NAEJ3Ur1q/qh69LBbBU0lE0GPRi8cK9gPaUDabSbt0s4m7G6GE/gkvHhTx6t/x5r9x2+agrQ8GHu/NMDMvSAXXxnW/ndLa+sbmVnm7srO7t39QPTxq6yRTDFssEYnqBlSj4BJbhhuB3VQhjQOBnWB8O/M7T6g0T+SDmaTox3QoecQZNVbq9kMUhg70oFpz6+4cZJV4BalBgeag+tUPE5bFKA0TVOue56bGz6kynAmcVvqZxpSyMR1iz1JJY9R+Pr93Ss6sEpIoUbakIXP190ROY60ncWA7Y2pGetmbif95vcxE137OZZoZlGyxKMoEMQmZPU9CrpAZMbGEMsXtrYSNqKLM2IgqNgRv+eVV0r6oe27du7+sNW6KOMpwAqdwDh5cQQPuoAktYCDgGV7hzXl0Xpx352PRWnKKmWP4A+fzBx77kAI=</latexit>
<latexit sha1_base64="FgejQ7k3O1VsOBio6emr7bDNH4A=">AAAB73icbVBNS8NAEJ3Ur1q/qh69LBbBU0lE0GPRi8cK9gPaUDabSbt0s4m7G6GE/gkvHhTx6t/x5r9x2+agrQ8GHu/NMDMvSAXXxnW/ndLa+sbmVnm7srO7t39QPTxq6yRTDFssEYnqBlSj4BJbhhuB3VQhjQOBnWB8O/M7T6g0T+SDmaTox3QoecQZNVbq9kMUhg70oFpz6+4cZJV4BalBgeag+tUPE5bFKA0TVOue56bGz6kynAmcVvqZxpSyMR1iz1JJY9R+Pr93Ss6sEpIoUbakIXP190ROY60ncWA7Y2pGetmbif95vcxE137OZZoZlGyxKMoEMQmZPU9CrpAZMbGEMsXtrYSNqKLM2IgqNgRv+eVV0r6oe27du7+sNW6KOMpwAqdwDh5cQQPuoAktYCDgGV7hzXl0Xpx352PRWnKKmWP4A+fzBx77kAI=</latexit>
<latexit sha1_base64="FgejQ7k3O1VsOBio6emr7bDNH4A=">AAAB73icbVBNS8NAEJ3Ur1q/qh69LBbBU0lE0GPRi8cK9gPaUDabSbt0s4m7G6GE/gkvHhTx6t/x5r9x2+agrQ8GHu/NMDMvSAXXxnW/ndLa+sbmVnm7srO7t39QPTxq6yRTDFssEYnqBlSj4BJbhhuB3VQhjQOBnWB8O/M7T6g0T+SDmaTox3QoecQZNVbq9kMUhg70oFpz6+4cZJV4BalBgeag+tUPE5bFKA0TVOue56bGz6kynAmcVvqZxpSyMR1iz1JJY9R+Pr93Ss6sEpIoUbakIXP190ROY60ncWA7Y2pGetmbif95vcxE137OZZoZlGyxKMoEMQmZPU9CrpAZMbGEMsXtrYSNqKLM2IgqNgRv+eVV0r6oe27du7+sNW6KOMpwAqdwDh5cQQPuoAktYCDgGV7hzXl0Xpx352PRWnKKmWP4A+fzBx77kAI=</latexit>
name = "Item"
1:Class
name = "product"
multiValued=false
2:Attribute
name = "Invoice"
4:Class
name = "date"
multiValued=false
3:Attribute
name = "items"
multiValued=true
5:Attribute
attr attr attr
type
name = "String"
0:DataType
type
type
M0
s
<latexit sha1_base64="iD9JfYqQPMEmBDXu+yQBFQ1y9wY=">AAAB63icbVDLSgNBEOyNrxhfUY9eBoPoKeyKoMegFy9CBGMCyRJmJ7PJkHksM7NCWPILXjwo4tUf8ubfOJvsQRMLGoqqbrq7ooQzY33/2yutrK6tb5Q3K1vbO7t71f2DR6NSTWiLKK50J8KGciZpyzLLaSfRFIuI03Y0vsn99hPVhin5YCcJDQUeShYzgm0u3fXNab9a8+v+DGiZBAWpQYFmv/rVGyiSCiot4diYbuAnNsywtoxwOq30UkMTTMZ4SLuOSiyoCbPZrVN04pQBipV2JS2aqb8nMiyMmYjIdQpsR2bRy8X/vG5q46swYzJJLZVkvihOObIK5Y+jAdOUWD5xBBPN3K2IjLDGxLp4Ki6EYPHlZfJ4Xg/8enB/UWtcF3GU4QiO4QwCuIQG3EITWkBgBM/wCm+e8F68d+9j3lryiplD+APv8wePWY3o</latexit>
<latexit sha1_base64="iD9JfYqQPMEmBDXu+yQBFQ1y9wY=">AAAB63icbVDLSgNBEOyNrxhfUY9eBoPoKeyKoMegFy9CBGMCyRJmJ7PJkHksM7NCWPILXjwo4tUf8ubfOJvsQRMLGoqqbrq7ooQzY33/2yutrK6tb5Q3K1vbO7t71f2DR6NSTWiLKK50J8KGciZpyzLLaSfRFIuI03Y0vsn99hPVhin5YCcJDQUeShYzgm0u3fXNab9a8+v+DGiZBAWpQYFmv/rVGyiSCiot4diYbuAnNsywtoxwOq30UkMTTMZ4SLuOSiyoCbPZrVN04pQBipV2JS2aqb8nMiyMmYjIdQpsR2bRy8X/vG5q46swYzJJLZVkvihOObIK5Y+jAdOUWD5xBBPN3K2IjLDGxLp4Ki6EYPHlZfJ4Xg/8enB/UWtcF3GU4QiO4QwCuIQG3EITWkBgBM/wCm+e8F68d+9j3lryiplD+APv8wePWY3o</latexit>
<latexit sha1_base64="iD9JfYqQPMEmBDXu+yQBFQ1y9wY=">AAAB63icbVDLSgNBEOyNrxhfUY9eBoPoKeyKoMegFy9CBGMCyRJmJ7PJkHksM7NCWPILXjwo4tUf8ubfOJvsQRMLGoqqbrq7ooQzY33/2yutrK6tb5Q3K1vbO7t71f2DR6NSTWiLKK50J8KGciZpyzLLaSfRFIuI03Y0vsn99hPVhin5YCcJDQUeShYzgm0u3fXNab9a8+v+DGiZBAWpQYFmv/rVGyiSCiot4diYbuAnNsywtoxwOq30UkMTTMZ4SLuOSiyoCbPZrVN04pQBipV2JS2aqb8nMiyMmYjIdQpsR2bRy8X/vG5q46swYzJJLZVkvihOObIK5Y+jAdOUWD5xBBPN3K2IjLDGxLp4Ki6EYPHlZfJ4Xg/8enB/UWtcF3GU4QiO4QwCuIQG3EITWkBgBM/wCm+e8F68d+9j3lryiplD+APv8wePWY3o</latexit>
<latexit sha1_base64="iD9JfYqQPMEmBDXu+yQBFQ1y9wY=">AAAB63icbVDLSgNBEOyNrxhfUY9eBoPoKeyKoMegFy9CBGMCyRJmJ7PJkHksM7NCWPILXjwo4tUf8ubfOJvsQRMLGoqqbrq7ooQzY33/2yutrK6tb5Q3K1vbO7t71f2DR6NSTWiLKK50J8KGciZpyzLLaSfRFIuI03Y0vsn99hPVhin5YCcJDQUeShYzgm0u3fXNab9a8+v+DGiZBAWpQYFmv/rVGyiSCiot4diYbuAnNsywtoxwOq30UkMTTMZ4SLuOSiyoCbPZrVN04pQBipV2JS2aqb8nMiyMmYjIdQpsR2bRy8X/vG5q46swYzJJLZVkvihOObIK5Y+jAdOUWD5xBBPN3K2IjLDGxLp4Ki6EYPHlZfJ4Xg/8enB/UWtcF3GU4QiO4QwCuIQG3EITWkBgBM/wCm+e8F68d+9j3lryiplD+APv8wePWY3o</latexit>
⇤
<latexit sha1_base64="OlYXa5TGZ2jG1EJYshioKcqCJPw=">AAAB6HicbVBNS8NAEJ3Ur1q/qh69LBZBPJREBD0WvXhswX5AG8pmO2nXbjZhdyOU0F/gxYMiXv1J3vw3btsctPXBwOO9GWbmBYng2rjut1NYW9/Y3Cpul3Z29/YPyodHLR2nimGTxSJWnYBqFFxi03AjsJMopFEgsB2M72Z++wmV5rF8MJME/YgOJQ85o8ZKjYt+ueJW3TnIKvFyUoEc9X75qzeIWRqhNExQrbuemxg/o8pwJnBa6qUaE8rGdIhdSyWNUPvZ/NApObPKgISxsiUNmau/JzIaaT2JAtsZUTPSy95M/M/rpia88TMuk9SgZItFYSqIicnsazLgCpkRE0soU9zeStiIKsqMzaZkQ/CWX14lrcuq51a9xlWldpvHUYQTOIVz8OAaanAPdWgCA4RneIU359F5cd6dj0VrwclnjuEPnM8fcAGMrg==</latexit>
<latexit sha1_base64="OlYXa5TGZ2jG1EJYshioKcqCJPw=">AAAB6HicbVBNS8NAEJ3Ur1q/qh69LBZBPJREBD0WvXhswX5AG8pmO2nXbjZhdyOU0F/gxYMiXv1J3vw3btsctPXBwOO9GWbmBYng2rjut1NYW9/Y3Cpul3Z29/YPyodHLR2nimGTxSJWnYBqFFxi03AjsJMopFEgsB2M72Z++wmV5rF8MJME/YgOJQ85o8ZKjYt+ueJW3TnIKvFyUoEc9X75qzeIWRqhNExQrbuemxg/o8pwJnBa6qUaE8rGdIhdSyWNUPvZ/NApObPKgISxsiUNmau/JzIaaT2JAtsZUTPSy95M/M/rpia88TMuk9SgZItFYSqIicnsazLgCpkRE0soU9zeStiIKsqMzaZkQ/CWX14lrcuq51a9xlWldpvHUYQTOIVz8OAaanAPdWgCA4RneIU359F5cd6dj0VrwclnjuEPnM8fcAGMrg==</latexit>
<latexit sha1_base64="OlYXa5TGZ2jG1EJYshioKcqCJPw=">AAAB6HicbVBNS8NAEJ3Ur1q/qh69LBZBPJREBD0WvXhswX5AG8pmO2nXbjZhdyOU0F/gxYMiXv1J3vw3btsctPXBwOO9GWbmBYng2rjut1NYW9/Y3Cpul3Z29/YPyodHLR2nimGTxSJWnYBqFFxi03AjsJMopFEgsB2M72Z++wmV5rF8MJME/YgOJQ85o8ZKjYt+ueJW3TnIKvFyUoEc9X75qzeIWRqhNExQrbuemxg/o8pwJnBa6qUaE8rGdIhdSyWNUPvZ/NApObPKgISxsiUNmau/JzIaaT2JAtsZUTPSy95M/M/rpia88TMuk9SgZItFYSqIicnsazLgCpkRE0soU9zeStiIKsqMzaZkQ/CWX14lrcuq51a9xlWldpvHUYQTOIVz8OAaanAPdWgCA4RneIU359F5cd6dj0VrwclnjuEPnM8fcAGMrg==</latexit>
<latexit sha1_base64="OlYXa5TGZ2jG1EJYshioKcqCJPw=">AAAB6HicbVBNS8NAEJ3Ur1q/qh69LBZBPJREBD0WvXhswX5AG8pmO2nXbjZhdyOU0F/gxYMiXv1J3vw3btsctPXBwOO9GWbmBYng2rjut1NYW9/Y3Cpul3Z29/YPyodHLR2nimGTxSJWnYBqFFxi03AjsJMopFEgsB2M72Z++wmV5rF8MJME/YgOJQ85o8ZKjYt+ueJW3TnIKvFyUoEc9X75qzeIWRqhNExQrbuemxg/o8pwJnBa6qUaE8rGdIhdSyWNUPvZ/NApObPKgISxsiUNmau/JzIaaT2JAtsZUTPSy95M/M/rpia88TMuk9SgZItFYSqIicnsazLgCpkRE0soU9zeStiIKsqMzaZkQ/CWX14lrcuq51a9xlWldpvHUYQTOIVz8OAaanAPdWgCA4RneIU359F5cd6dj0VrwclnjuEPnM8fcAGMrg==</latexit>
Then
TL
Artur Boronat. 5th event Lowcomote Network. 14/4/2021
25. Model Repair
name = "Item"
1:Class
name = "product"
multiValued=false
2:Attribute
name = "Invoice"
4:Class
name = "date"
multiValued=false
3:Attribute
name = "items"
multiValued=true
5:Attribute
attr attr attr
name = "Item"
1:Class
name = "product"
multiValued=false
2:Attribute
name = "Order"
4:Class
name = "date"
multiValued=false
3:Attribute
name = "items"
multiValued=true
5:Attribute
attr attr attr
name = "Item"
1:Class
name = "product"
multiValued=false
2:Attribute
name = "Order"
4:Class
name = "date"
multiValued=false
3:Attribute
name = "items"
multiValued=true
5:Attribute
attr attr attr
name = "Item"
1:Class
name = "product"
multiValued=false
2:Attribute
name = "Order"
4:Class
name = "date"
multiValued=false
3:Attribute
name = "items"
multiValued=true
5:Attribute
attr attr attr
name = "Item"
1:Class
name = "product"
multiValued=false
2:Attribute
name = "Order"
4:Class
name = "date"
multiValued=false
3:Attribute
name = "items"
multiValued=true
5:Attribute
attr
attr attr
name = "Item"
1:Table
name = "product"
2:Column
name = "Invoice"
6:Table
name = "date"
3:Column
name = "pk_Invoice"
7:Column
col
col
col
name = "pk_Item"
4:Column
col
name = "fk_Item--items-->Invoice"
5:Column
col
name = "Item"
1:Table
name = "product"
2:Column
name = "Order"
6:Table
name = "date"
3:Column
name = "pk_Order"
7:Column
col
col
col
name = "pk_Item"
4:Column
col
name = "fk_Item--items-->Order"
5:Column
col
name = "Item"
1:Table
name = "product"
2:Column
name = "Order"
6:Table
name = "date"
3:Column
name = "pk_Order"
7:Column
col
col
col
name = "pk_Item"
4:Column
col
name = "fk_Item--items-->Order"
5:Column
col
name = "Item"
1:Table
name = "product"
2:Column
name = "Order"
6:Table
name = "date"
3:Column
name = "pk_Order"
7:Column
col
col
col
name = "pk_Item"
4:Column
col
name = "fk_Item--items-->Order"
5:Column
col
name = "Item"
1:Table
name = "product"
2:Column
name = "Order"
6:Table
name = "date"
3:Column
name = "pk_Order"
7:Column
col col
col
name = "pk_Item"
4:Column
col
name = "fk_Item--items-->Order"
5:Column
col
name = "Product"
6:Class name = "Product"
8:Table
name = "pk_Product"
9:Column
col
name = "amount"
multiValued=false
6:Attribute
attr
name = "amount"
8:Column
col
type
type
type
type
type
name = "String"
0:DataType
type
type
name = "String"
0:DataType
type
type
name = "String"
0:DataType
type
type
name = "String"
0:DataType
type
type
name = "String"
0:DataType
type
type
Propagation of delta a (case 4)
Propagation of delta b (case 1)
Propagation of delta c (case 9)
Propagation of delta d (case 10)
Propagation of delta e (case 11)
New root
object
New
inner
object
Delete
object
Move
object
TL
Artur Boronat. 5th event Lowcomote Network. 14/4/2021
26. Executing Model Transformations in YAMTL
val xform = new cd2db
xform.executionMode = ExecutionMode.INCREMENTAL
// PREPARE MODELS
xform.loadInputModels(#{'cd' -> inputModelPath})
// EXECUTE INITIAL TRAFO
xform.execute()
// EITHER LOADING EMF CHANGE DESCRIPTION
xform.loadDelta('cd', deltaName, forwardDeltaPath)
// OR RECORDING CHANGE
xform.recordDelta('cd', deltaName, [
c.name = 'Invoice’
])
// DELTA PROPAGATION: where c is initialized above
xform.propagateDelta('cd', deltaName)
// PERSISTING MODEL
xform.saveOutputModels(#{'db' -> outputModelPath})
incremental
execution
TL
Artur Boronat. 5th event Lowcomote Network. 14/4/2021
28. VIATRA CPS Benchmark
YAMTL solution:
1. Helper to determine receiving transitions (waitFor)
2. Build the structure of deployment model using rules with high priority
3. Initialize triggers with a transient rule (only updates)
4. Extract CPS traceability model from YAMTL’s internal traceability model
allocated AppInstance à
DeploymentApp on DeploymentHost
action triggers to be
set after behaviours
are instantiated
behaviours are
instantiated (copy)
traceability model
TL
Artur Boronat. 5th event Lowcomote Network. 14/4/2021
29. VIATRA CPS Benchmark
• Very large models (VLMs)
• Models up to 10.16M objects and 27.53M references (scenarios client-server and statistic-based)
• Model updates are sparse
• Adaptation
• Model generation with VIATRA CPS model generator
• Each experiment (size): 13 iterations - median of inner results (excluding 1st – warm up)
Boronat, A. (2020). Incremental execution of rule-based model transformation. STTT, 1433-2787.
TL
Artur Boronat. 5th event Lowcomote Network. 14/4/2021
30. • YAMTL brings declarative M2M transformations to the Xtend world
• Advanced model transformation constructs
• Support for VLMs with good performance
• Scalability with respect to model changes
• Publications
• Boronat, A. (2020). Incremental execution of rule-based model transformation. STTT, 1433-2787.
• Boronat, A. Offline Delta-Driven Model Transformation with Dependency Injection. FASE’19.
• Boronat, A. Expressive and Efficient Model Transformation with an Internal DSL of Xtend.
MODELS’18.
• Web: https://yamtl.github.io/
In summary
TL
Artur Boronat. 5th event Lowcomote Network. 14/4/2021