ATL

AtlanMod Transformation Language

Naomod team

IMT Atlantique, LS2N

Context of this work

The present courseware has been elaborated in the context of the MODELWARE European  IST FP6 project (http://www.modelware-ist.org/).

Co-funded by the European Commission, the MODELWARE project involves 19 partners from 8 European countries. MODELWARE aims to improve software productivity by capitalizing on techniques known as Model-Driven Development (MDD).

To achieve the goal of large-scale adoption of these MDD techniques, MODELWARE promotes the idea of a collaborative development of courseware dedicated to this domain. 

The MDD courseware provided here with the status of open source software is produced under the EPL 1.0 license. 

Prerequisites

To be able to understand this lecture, a reader should be familiar with the following concepts, languages, and standards:
  • Model Driven Engineering (MDE)

  • The role of model transformations in MDE

  • UML

  • OCL

  • MOF

  • Basic programming concepts

Contents

  • Introduction

  • Description of ATL

  • Example: Class to Relational

  • Additional considerations

  • Conclusion

Contents

  • Introduction

    • Definitions

    • Operational context

  • Description of ATL

  • Example: Class to Relational

  • Additional considerations

  • Conclusion

Definitions (1/2)

A model transformation is the automatic creation of target models from source models.

Definitions (2/2)

Model transformation is not only about M1 to M1 transformations:
  • M1 to M2: promotion,

  • M2 to M1: demotion,

  • M3 to M1, M3 to M2, etc.

three levels

Operational Context: Small Theory

operational context

Operational Context of ATL

atl context

Contents

  • Introduction

  • Description of ATL

    • Overview

    • Source pattern

    • Target pattern

    • Execution order

  • Example: Class to Relational

  • Additional considerations

  • Conclusion

ATL Overview

Source models and target models are distinct:
  • Source models are read-only (they can only be navigated, not modified),

  • Target models are write-only (they cannot be navigated).

readonly writeonly

Model Transformation

  • In ATL, transformations are organized in modules.

  • A module contains 4 parts:

    1. A header.

    2. An optional import section.

    3. A set of helpers.

    4. A set of rules.

Module Header

module RedGreen2PinkBlue;
create OUT : PinkBlue from IN : RedGreen;
  • By convention, the module name follows the format source-language2target-language.

  • Source and target models are typed: here PinkBlue and RedGreen.

  • Models must respect their types (languages/metamodels).

Import Section

uses strings; -- imports the strings library
  • The optional import section enables to declare which ATL libraries are imported.

Helpers

helper context Integer def : double() : Integer = self * 2;

helper def : sqrt(x: Real): Real = x ∗ x;
  • Helpers are auxiliary functions.

  • A helper is composed of: - a name, a context (type), a return type, and an optional set of parameters, identified by pairs name/type.

  • a body, in the form of an ATL expression that represents the code of the ATL helper.

Rules

  • There are two kinds of rules: called or matched.

  • Called rules are equivalent to procedures in imperative programming, they are called by other rules.

  • Matched rules are declarative, they are automatically executed by ATL.

Called Rules (1/2)

rule newGreen (name: String) {
	to
		p : RedGreen!Green (
			name <- name
		)
}
  • Unlike helpers, called rules create elements in the target model.

Called Rules (2/2)

rule newGreen (name: String) {
    to
        p : RedGreen!Green (
            name <- name
        )
}
In short, a called rule is imperative, i.e., basically a procedure:
  • It is called by its name,

  • It may take arguments,

  • It can contain:

    • A declarative target pattern,

    • An action block (i.e. a sequence of statements),

    • Both.

Matched Rules

rule red2blue {
	from
		red : RedGreen!Red
	to
		blue : BluePink!Blue (
			name <- red.name
		)
}
  • Matched rules are the core of ATL transformations.

  • They allow to specify:

    1. for which kinds of source elements target elements must be generated,

    2. the way the generated target elements have to be initialized.

Matched Rules

rule red2blue {
    from
        red : RedGreen!Red
    to
        blue : BluePink!Blue (
            name <- red.name
        )
}
In short, a matched rule is declarative and specifies:
  • a source pattern to be matched in the source models,

  • a target pattern to be created in the target models for each match during rule application.

Kinds of Matched Rules

There are three kinds of matched rules:
Standard

rules that are applied once for each match: a given set of elements may only be matched by one standard rule,

Lazy

rules that are applied as many times for each match as it is referred to from other rules (possibly never for some matches)

Unique

lazy rules that are applied at most once for each match and only if it is referred to from other rules.

Matched Rules: Source Pattern

rule red2blue {
    from
        red : RedGreen!Red(red.name->size() > 0)
    -- (...)
  • The source pattern is composed of:

    • A labeled set of types coming from the source metamodels,

    • A guard (Boolean expression) used to filter matches.

  • A match corresponds to a set of elements coming from the source models that:

    • Are of the types specified in the source pattern (one element for each type),

    • Satisfy the guard.

Matched Rules: Target Pattern

rule red2blue {
    -- (...)
    to
        blue : BluePink!Blue (
            name <- red.name
        )
The target pattern is composed of:
  • A labeled set of types coming from the target metamodels,

  • For each element of this set, a set of bindings.

  • A binding specifies the initialization of a property of a target element using an expression.

Matched Rules: Target Pattern

rule red2blue {
    -- (...)
	to
		blue : BluePink!Blue (
			name <- red.name
		)
For each match, the target pattern is applied:
  • Elements are created in the target models (one for each type of the target pattern),

  • Target elements are initialized by executing the bindings:

    • First evaluating their value,

    • Then assigning this value to the corresponding property.

Execution Order

Declarative ATL frees the developer from specifying execution order:
  • The order in which rules are matched and applied is not specified.

    • Remark: the match of a lazy or unique lazy rules must be referred to before the rule is applied.

  • The order in which bindings are applied is not specified.

Execution Order (continued)

  • The execution of declarative rules can however be kept deterministic:

    • The execution of a rule cannot change source models

      • It cannot change a match,

    • Target elements are not navigable

      • The execution of a binding cannot change the value of another.

Contents

  • Introduction

  • Description of ATL

  • Example: Class to Relational

    • Overview

    • Source metamodel

    • Target metamodel

    • Rule Class2Table

    • Rule SingleValuedAttribute2Column

    • Rule MultiValuedAttribute2Column

  • Additional considerations

  • Conclusion

Example: Class to Relational, Overview

  • The source metamodel Class is a simplification of class diagrams.

  • The target metamodel Relational is a simplification of the relational model.

  • ATL declaration of the transformation:

module Class2Relational;

create Mout : Relational from Min : Class;

Source: the Class Metamodel

class metamodel

The Class Metamodel in Xcore

package Class

abstract class NamedElt {
	String name
}

abstract class Classifier extends NamedElt {
}

class DataType extends Classifier {
}

class ^Class extends Classifier {
	refers ^Class[] ^super
	contains Attribute[] attributes opposite owner
	boolean isAbstract
}

class Attribute extends NamedElt {
	boolean multiValued
	refers Classifier ^type
	container ^Class owner opposite attributes
}

The Relational Metamodel

relational metamodel

The Relational Metamodel in Xcore

package Relational

abstract class Named {
	String name
}

class Table extends Named {
	contains Column[] col opposite owner
	refers Column[]  ^keys opposite keyOf
}

class Column extends Named {
	container Table owner opposite col
	refers Table[0..1] keyOf opposite ^keys
	refers Type ^type
}

class Type extends Named {
}

Transformation Overview

Informal description of main rules
  • Class2Table:

    • A table is created from each class,

    • The columns of the table correspond to the single-valued attributes of the class,

    • A column corresponding to the key of the table is created.

Transformation Overview (Continued)

Auxiliary rules:
  • SingleValuedAttribute2Column:

    • A column is created from each single-valued attribute.

  • MultiValuedAttribute2Column:

    • A table with two columns is created from each multi-valued attribute,

    • One column refers to the key of the table created from the owner class of the attribute,

    • The second column contains the value of the attribute.

Class2Table Rule

  • A Table is created for each Class:

rule Class2Table {
  from -- source pattern
    c : Class!Class
  to -- target pattern
    t : Relational!Table
}

Class2Table Rule

  • The name of the Table is the name of the Class:

rule Class2Table {
  from
    c : Class!Class
  to
    t : Relational!Table (
      name <- c.name -- a simple binding
      )
}

Class2Table Rule

  • The columns of the table correspond to the single-valued attributes of the class:

rule Class2Table {
  from
    c : Class!Class
  to
    t : Relational!Table (
        name <- c.name,
        col <- c.attr->select(e | -- a binding
           not e.multiValued)-- using complex navigation
        )
}
  • Remark: attributes are automatically resolved into columns by automatic traceability support.

Class2Table Rule

  • Each Table owns a key containing a unique identifier:

rule Class2Table {
  from
    c : Class!Class
  to
    t : Relational!Table (
  name <- c.name,
    col <- c.attr->select(e |
    not e.multiValued
    )->union(Sequence {key}),
      key <- Set {key}
      ),
    key : Relational!Column ( -- another target
    name <- ‘Id’-- pattern element
  ) -- for the key
}

SingleValuedAttribute2Column Rule

  • A Column is created for each single-valued Attribute:

rule SingleValuedAttribute2Column {
  from -- the guard is used for selection
    a : Class!Attribute (not a.multiValued)
  to
    c : Relational!Column (
      name <- a.name
      )
}

MultiValuedAttribute2Column Rule

  • A Table is created for each multi-valued Attribute, which contains two columns:

    • The identifier of the table created from the class owner of the Attribute

    • The value.

rule MultiValuedAttribute2Column {
  from
    a : Class!Attribute (a.multiValued)
  to
    t : Relational!Table (
      name <- a.owner.name + ‘_’ + a.name,
      col <- Sequence {id, value}
    ),
    id : Relational!Column (
      name <- ‘Id’
    ),
    value : Relational!Column (
      name <- a.name
    )
}

Contents

  • Introduction

  • Description of ATL

  • Example: Class to Relational

  • Additional considerations

    • Other ATL features

    • ATL in use

  • Conclusion

Other ATL Features: Rule Inheritance

  • Rule inheritance, to help structure transformations and reuse rules and patterns:

    • A child rule matches a subset of what its parent rule matches,

      • All the bindings of the parent still make sense for the child,

    • A child rule specializes target elements of its parent rule:

      • Initialization of existing elements may be improved or changed,

      • New elements may be created.

Rule Inheritance Syntax

abstract rule R1 {
  -- ...
}

rule R2 extends R1 {
  -- ...
}

Queries

query <query_name> = <atl_exp>;
  • In short, a query is a model to primitive type value transformation.

  • A query is composed of:

    • A name.

    • A type.

    • A ATL expression that expresses the calculated value.

Refining Mode

Refining mode for transformations that need to modify only a small part of a model:
  • Since source models are read-only target models must be created from scratch,

  • This can be done by writing copy rules for each elements that are not transformed,

    • This is not very elegant.

Refining Model

  • In refining mode, the ATL engine automatically copies unmatched elements.

  • The developer only specifies what changes.

  • ATL semantics is respected: source models are still read-only.

    • An (optimized) engine may modify source models in-place but only commit the changes in the end.

  • Syntax: replace from by refining

module A2A; create OUT : MMA refining IN : MMA;

ATL in Use

  • ATL has been used in a large number of application domains.

  • A library of transformations is available at

  • About 100 sites use ATL for various purpose:

    • Teaching,

    • Research,

    • Industrial development,

    • Etc.

ATL in Use

  • ATL tools and documentation are available at:  https://eclipse.org/atl/

  • Execution engine:

    • Virtual machine,

    • ATL to bytecode compiler,

  • Integrated Development Environment (IDE) for:

    • Editor with syntax highlighting and outline,

    • Execution support with launch configurations,

    • Source-level debugger.

  • Documentation:

    • Starter’s guide, User manual, Installation guide, etc.

ATL Development Tools: Perspective, Editor and Outline

atl perspective

ATL Development Tools: Launch Configuration

launch configuration

ATL Development Tools: Source-level Debugger

atl debugger

Contents

  • Introduction

  • Description of ATL

  • Example: Class to Relational

  • Additional considerations

  • Conclusion

Conclusion

  • ATL has a simple declarative syntax:

    • Simple problems are generally solved simply.

  • ATL supports advanced features:

    • Complex OCL navigation, lazy rules, refining mode, rule inheritance, etc.

    • Many complex problems can be handled declaratively.

  • ATL has an imperative part:

    • Any problem can be handled.

Thank You!

  • Questions?

  • Comments?

License