19.11.2012 Views

Bachelor thesis by Oliver Rohe

Bachelor thesis by Oliver Rohe

Bachelor thesis by Oliver Rohe

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

Institute for Computer Science<br />

Software Engineering Group<br />

Warburger Straße 100<br />

33098 Paderborn<br />

Germany<br />

Model Transformation <strong>by</strong> Interpreting Triple<br />

Graph Grammars: Evaluation and Case Study.<br />

Thesis to receive the degree<br />

”<strong>Bachelor</strong> of Computer Science”<br />

within the integrated course of studies<br />

computer science.<br />

<strong>by</strong><br />

<strong>Oliver</strong> <strong>Rohe</strong><br />

Dringenberger Str.61<br />

33014 Bad Driburg<br />

submitted to<br />

Dr. Ekkart Kindler<br />

and<br />

Prof. Dr. Gerd Szwillus<br />

Paderborn, January 2, 2006


DECLARATION<br />

I here<strong>by</strong> declare that this submission is my own work and that, to the best of my knowledge and<br />

belief, it contains no material previously published or written <strong>by</strong> another person nor material<br />

which to a substantial extent has been accepted for the award of any other degree of a university<br />

or other institute of higher learning, except where due acknowledgement is made in the text.<br />

Paderborn, January 2, 2006<br />

<strong>Oliver</strong> <strong>Rohe</strong>


Contents<br />

1 Introduction 3<br />

1.1 Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3<br />

1.2 Goals and Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4<br />

1.3 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5<br />

2 Model Transformation 6<br />

2.1 Triple Graph Grammars . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6<br />

2.2 Interpreter Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8<br />

3 Case Study 28<br />

3.1 Fujaba- TGG Editor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29<br />

3.2 Eclipse/EMF TGG Editor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32<br />

3.3 Mapping both models . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35<br />

4 Realization 47<br />

4.1 Common Problems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47<br />

4.2 Problems and Solutions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47<br />

5 Conclusion 52<br />

List of figures 55<br />

Bibliography 56<br />

1


Chapter 1<br />

Introduction<br />

1.1 Motivation<br />

In software engineering the usage of formal methods provides all kinds of different techniques<br />

for the specification, design, verification, validation and development of a system, which are<br />

supported <strong>by</strong> a wide range of different, sometimes incompatible tools. Also, these formal<br />

methods very often make use of different underlying formalisms and notations, which makes<br />

them difficult to use because knowing them all in detail is difficult and keeping different<br />

formal models of the same system consistent even more.<br />

The model driven development (MDD) approach is addressing these problems <strong>by</strong> ensuring<br />

the use of standard notations and models, which are widely understood and which can be<br />

consistently shared and reused between different steps of the software design life cycle.<br />

This approach is captured <strong>by</strong> the Model Driven Architecture (MDA) [1], which is defined <strong>by</strong><br />

the Object Management Group (OMG) [2] and which is a set of standards and technologies<br />

to decouple models and to bridge them between different modeling languages and platforms.<br />

Therefore, it defines platform-independent models (PIM) and its automated transformation to<br />

one or more platform-specific models (PSMs).<br />

To adapt the MDD concepts, the most difficult part is to provide models and formalisms that<br />

can be related to each other across the software development life cycle and the tools to ensure<br />

a consistent transformation from one formalism into the other.<br />

The ComponentTools [3] project addresses these problems <strong>by</strong> providing an infrastructure to<br />

ease the application, integration and transformation of different formal models. Therefore, a<br />

model transformation mechanism has been developed as well as an application interface to<br />

integrate third party tools that can directly make use of the transformed models.<br />

In order to transform models with different formalisms and from different sources generally,<br />

a defined interface was implemented to interpret a formal model as graph and then perform a<br />

graph transformation with triple graph grammars.<br />

Transforming the structure of a model instance that has an object oriented meta model is<br />

very similar to a graph transformation, because its object instances and references can be<br />

interpreted as nodes and edges. Besides, objects may also contains properties like names or<br />

IDs, which can be transformed as well <strong>by</strong> using attributed graphs, where a node is assigned<br />

one or more properties.<br />

3


1.2. GOALS AND METHODS<br />

Therefore, the underlying graph model is all important for the model transformation, since<br />

it must contain all the information to be transformed. It must be very general and it must<br />

contain the most common concepts used in a variety of existing object- oriented models, so<br />

that different models can be transformed correctly.<br />

In the project group ComponentTools [3] , a first prototype of the TGG interpreter and<br />

its underlying TGG model has been developed. This version successfully transforms a<br />

ComponentLibrary [3] model into a PetriNetKernel [4] model as well as into a PetriNetMarkupLanguage<br />

[5] model.<br />

Although the concepts of the interpreter architecture is very general, the problem is to say<br />

whether it is always possible to transform any given model instance into another. This is due<br />

to the fact that models often times are very different in their structure and the information they<br />

keep and it is not clear whether both can always be mapped to the graph interface appropriately<br />

to perform a transformation into another model.<br />

The question is, wether there exists some model specific features or concepts that can not be<br />

interpreted generally and which would need to adjust the interpreter and the graph model in order<br />

to perform the transformation. However, doing so whenever a single model transformation<br />

can not be performed is not the desired behavior.<br />

1.2 Goals and Methods<br />

The subject of this <strong>thesis</strong> is to evaluate the existing interpreter architecture and its underlying<br />

TGG graph model <strong>by</strong> implementing yet another example model transformation. The goal is to<br />

get a better understanding which requirements and features are needed to describe and to perform<br />

a wide range of different model transformations. Especially, it should help to understand<br />

what a model instance and its meta model must look like in order to apply a transformation, or<br />

which properties may prevent a transformation to be successful.<br />

The results will then be used to extend the current interpreter architecture in order to get the<br />

example transformation to work, although it is very important not to make the architecture<br />

unnecessarily complex <strong>by</strong> adding useless features, but rather to keep its concepts very clear<br />

and general.<br />

The example transformation will be performed from the Fujaba TGG model to the ComponentTools<br />

TGG model. The speciality is that both models are different TGG models, whereas<br />

the latter one is also the underlying model for the transformation itself.<br />

Also, for the Fujaba TGG model, there exists already a very comfortable TGG rule modeling<br />

editor and now the goal is to use it indirectly for the ComponentTools TGG model as well,<br />

<strong>by</strong> transforming the created Fujaba TGG rules into the corresponding ComponentTools TGG<br />

rules and format. Thus, it replaces the painfull usage of the ComponentTools TGG rule editor,<br />

which, although was generated automatically <strong>by</strong> the EMF framework and hence gotten for<br />

free, is very difficult to use and therefore very error-prone.<br />

Another speciality is, that the example implementation will be done in a kind of bootstrapping<br />

manner. Therefore, the first rule set is going to be modeled with the ComponentTools editor<br />

4


1.3. OVERVIEW<br />

<strong>by</strong> hand and then after successfully doing a transformation, the Fujaba TGG editor can be used<br />

to remodel the rule set. The created Fujaba model will then be transformed and the result<br />

can be used again as a rule input for the interpreter, to transform a Fujaba TGG model into a<br />

ComponentTools TGG model.<br />

1.3 Overview<br />

Chapter two explains the idea of the model transformation. Therefore, triple graph grammars<br />

are introduced as well as the interpreter architecture and the matching algorithm. In chapter<br />

three, the example model transformation will be explained. Besides, both models are presented<br />

and the transformation details are illustrated. In chapter four the current implementation and<br />

its weaknesses will be evaluated, as well as the changes and enhancements being made during<br />

the work of this <strong>thesis</strong> in order to get the example transformation to work.<br />

The fourth chapter then gives an overview and provides ideas and strategies for future work<br />

and research.<br />

5


Chapter 2<br />

Model Transformation<br />

Transforming models is a very challenging problem. The existing approaches very often<br />

either lack performance or generality, which means that an efficient transformation usually is<br />

restricted to a certain class of models, whereas general approaches usually are only applicable<br />

for very small input models.<br />

The goal of ComponentTools [3] was to ease this drawback and to be general and performant<br />

at once. Therefore, the idea was to interpret any in- memory model [6] as a graph and then<br />

perform a graph transformation using triple graph grammar rules. The following chapter will<br />

give an idea how, the specification and the execution of a model transformation is done.<br />

2.1 Triple Graph Grammars<br />

Triple Graph Grammars are an extension of Graph Grammars. They consist of a set of Triple<br />

Graph Rules to formally describe a graph transformation. A TGG rule itself consist of three<br />

declarative graph rewriting rules (source-, correspondence- and target- rule), whereas each<br />

rule again is splitted into a condition graph (left side) and an action graph (right side).<br />

Additionally, the correspondence rule maps source- and target- rule elements onto each other<br />

and therefore allows a bidirectional n:m mapping of its elements. That makes the rule applicable<br />

in both direction, since the correspondence mappings between the model elements always<br />

allow a unique identification of the elements belonging together.<br />

This is very benefiting, since it allows a mapping between two structurally different graphs. In<br />

addition, it simplifies the handling of the rules, because the correspondence structure can store<br />

additional information, which might be necessary for the transformation.<br />

Therefore, a TGG rule is nothing more than a mapping bettween the rules of two different<br />

graph grammars, which means that for every existing rule and its defined structural graph<br />

rewriting in the first grammar, there exists a corresponding graph rewriting rule in the second<br />

graph grammar and vice versa. In other words, whenever the node structure of a source graph<br />

instance allows the fireing of one of the rules from the first graph grammar, there exists a<br />

corresponding node structure in the target graph instance that allows the fireing of the second<br />

graph grammar’s rule.<br />

Figure 2.1 shows a simple TGG rule that was used within the context of the ComponentTools<br />

[3] project. It transforms a Track into its corresponding PetriNet construct.<br />

6


2.1. TRIPLE GRAPH GRAMMARS<br />

R<br />

L<br />

:Track<br />

source<br />

:Project<br />

:Inport<br />

++<br />

:Outport<br />

2.1.1 Graph Transformation<br />

++<br />

++<br />

++<br />

++<br />

++<br />

++<br />

++<br />

++<br />

correspondence<br />

:Corresp<br />

:Corresp<br />

++<br />

:Corresp<br />

++<br />

:Corresp<br />

++<br />

++<br />

++<br />

++<br />

++<br />

++<br />

target<br />

:Petrinet<br />

++<br />

:Place<br />

++<br />

:Arc<br />

++<br />

++<br />

++<br />

:Transition<br />

Figure 2.1 : A simple triple graph grammar rule.<br />

A graph transformation between two different graph instances can be performed <strong>by</strong> applying<br />

TGG rules stepwise. Every rule defines one transformation step, which extends the transforming<br />

target graph instance according to its definition on the right side of the target grammar rule<br />

(When the rule is read from left to right. Otherwise the right side of the source graph grammar<br />

rule is considered).<br />

The left side of the TGG rule like in the figure 2.2 defines the precondition of the transformation<br />

step. It shows two nodes from the source and the target grammar, mapped <strong>by</strong> a correspondence<br />

node. The right part of the source side defines the structure that already exists in<br />

the source graph instance and that needs to be transformed into the corresponding target graph<br />

structure. For none- deleting rules, which are currently only supported <strong>by</strong> the interpreter, the<br />

elements on the left side are always also on the ride side, which means that the graph is always<br />

only extended, but never reduced. The difficulties of handling deleting rules will be discussed<br />

in the chapter 5.<br />

R<br />

L<br />

:Track<br />

source correspondence target<br />

:Project<br />

:Inport<br />

:Outport<br />

:Corresp<br />

Figure 2.2 : Left side pre condition.<br />

:Petrinet<br />

When both, the rule’s left side and the source’s right side (L Form) can be successfully mapped<br />

within the graph instances, the rule can be fully applied and the target graph instance can be<br />

extended, as defined on the right side of the target graph grammar rule 2.3 .<br />

7<br />

++<br />

++


2.2. INTERPRETER ARCHITECTURE<br />

L+R<br />

R<br />

:Track<br />

source correspondence target<br />

:Project :Corresp<br />

:Inport<br />

:Outport<br />

++<br />

++<br />

++<br />

:Corresp<br />

++<br />

:Corresp<br />

++<br />

:Corresp<br />

++<br />

++<br />

++<br />

++<br />

++<br />

++<br />

:Petrinet<br />

++<br />

:Place<br />

++<br />

:Arc<br />

++<br />

++<br />

++<br />

:Transition<br />

Figure 2.3 : Target right side, that needs to be created.<br />

Since the rule is applicable in both direction, the same principle holds, when the rule is read<br />

from right to left. In this case, the source graph instance is extended according to the definition<br />

on the right side of the source graph grammar rule.<br />

2.2 Interpreter Architecture<br />

The first prototype of the interpreter was developed during the project group ComponentTools<br />

[3] to support the model driven development <strong>by</strong> providing a tool that performs a well defined<br />

transformation of different formal models. The goal was to do the transformation generally<br />

and efficiently, without ever modifying the interpreter and its algorithm when a new model<br />

transformation has to be performed. Therefore, a graph interface was developed to allow the<br />

interpretation of a model instance as graph and then perform a graph transformation via triple<br />

graph grammars.<br />

The interpreter architecture that is shown in figure 2.4 is separated into four main components.<br />

In-<br />

Memory<br />

Model<br />

(Instance)<br />

Model<br />

Adapter<br />

Graph-<br />

Type<br />

Model<br />

TGG<br />

Interpreter<br />

TGG<br />

Rules<br />

Model<br />

Adapter<br />

Figure 2.4 : The interpreter architecture.<br />

8<br />

++<br />

++<br />

In-<br />

Memory<br />

Model<br />

(Instance)


2.2. INTERPRETER ARCHITECTURE<br />

1. The graph type models are referenced <strong>by</strong> the triple graph grammar rules and represent<br />

the meta model type definitions of the in- memory model instances.<br />

2. The model adapters are used as a graph interface <strong>by</strong> the interpreter to navigate on the<br />

in- memory model instances and its types.<br />

3. The TGG rule graphs describe the single transformation steps.<br />

4. The interpreter performes the transformation of two graphs <strong>by</strong> stepwise applying the<br />

TGG rules.<br />

Each of these components will be explained more in detail in the following sections.<br />

2.2.1 Graph Type Model<br />

The goal of the interpreter is to be independent from any model instance that has to be transformed.<br />

Therefore, the structure and the types of the models are hidden behind a graph interface.<br />

The interpreter then simply uses a model adapter (see Section 2.2.2) to virtually translate<br />

the model instance as graph. In order to hide the element types of a model, the interpreter uses<br />

a defined type interface called a graph type model. Each graph type model is equivalent to the<br />

actual meta model of the model instance.<br />

A graph type model contains node-, edge- and property- types, which are shown in figure 2.5 .<br />

*<br />

GraphElementType<br />

EdgeType<br />

GraphType<br />

+ description: String<br />

*<br />

graphTypes<br />

graphElementTypes<br />

NodeType<br />

+ role: String + name: String<br />

in<br />

*<br />

out<br />

*<br />

1<br />

source<br />

1 target<br />

1<br />

*<br />

PropertyType<br />

+ name: String<br />

+ type: String<br />

nodeType<br />

propertyTypes<br />

Figure 2.5 : A graph type and its node-, edge- and property- types.<br />

The figure 2.6 shows a graph type model that copies the meta model given as UML class<br />

diagram.<br />

Car<br />

color:String<br />

0..1<br />

1<br />

0..1<br />

0..*<br />

Engine<br />

Tire<br />

p1:PropertyType<br />

name=“color“<br />

type=“String“<br />

n1:NodeType<br />

name=“Car“<br />

e1:EdgeType<br />

role=“car2engine“<br />

n2:NodeType<br />

name=“Engine“<br />

e2:EdgeType<br />

role=“car2tire“<br />

n3:NodeType<br />

name=“Tire“<br />

Figure 2.6 : An UML class diagram and its corresponding graph type model instance.<br />

9


2.2. INTERPRETER ARCHITECTURE<br />

2.2.2 Model Adapter<br />

The main focus of the interpreter architecture is to be usable for every possible in- memory<br />

model and format [6]. Therefore, an adapter interface was developed to allow the interpretation<br />

of a model instance as a graph. That allows the interpreter to work directly on the model<br />

instances, but simply uses the model adapters to virtually interpret its objects and references as<br />

nodes and edges. That makes it independent from its input, but still allows to manipulate any<br />

model instance <strong>by</strong> just calling graph interface methods declared in the model adapters shown<br />

in the figure 2.7 .<br />

public interface RealModelAdapter<br />

{<br />

public RealModelAdapter(GraphType graphType, Object realModelInstance);<br />

}<br />

public abstract Object getRootElement();<br />

public abstract NodeType getNodeType(Object object) ;<br />

public abstract Collection getNeighbors(Object source, EdgeType edgeType);<br />

public abstract Collection getAllNeighbors(Object source);<br />

public abstract void deleteNode(Object object);<br />

public abstract void deleteEdge(EdgeType edgeType, Object source, Object target);<br />

public abstract void getPropertyValue(Object object, String property);<br />

public abstract void setPropertyValue(Object object, String property, Object value);<br />

public abstract Object createNode(NodeType nodeType, Hashtable propertyValues) ;<br />

public abstract void createEdge(EdgeType edgeType, Object source, Object target);<br />

Figure 2.7 : The model adapter interface.<br />

In figure 2.7 the adapter interface methods are shown. As an example, the last method<br />

createEdge is used to create a new reference from an object source to an object target.<br />

During the method call the interpreter passes an edge type to the model adapter to let it know<br />

what kind of reference has to be created. The last but one method createNode creates a new<br />

object based on the node type parameter passed <strong>by</strong> the interpreter. An example for the usage of<br />

the model adapter is given in the method countNeighbors presented below 2.8 . This method<br />

simply counts the number of neighbor objects.<br />

10


2.2. INTERPRETER ARCHITECTURE<br />

Integer countNeighbors(Object source, RealModelAdapter adapter)<br />

1: nodeType ← adapter.getNodeType(source)<br />

2: outgoingEdgeTypes ← nodeType.getOutgoingEdges(source)<br />

3: counter ← 0<br />

4: while (outgoingEdgeTypes.hasNext()) do<br />

5: edgeType ← outgoingEdgeType.next()<br />

6: neighbors ← adapter.getNeighbors(edgeType)<br />

7: counter ← counter + neighbors.size()<br />

8: end while<br />

9: return counter<br />

Figure 2.8 : Example, how the interpreter interacts with the model adapter.<br />

Figure 2.9 shows the routine of the model adapter that returns the node type, depending<br />

on the objects real type. The node types are defined in the graph type meta model and will<br />

be loaded together with the initialization of the adapter. Below there is an extract of the method.<br />

NodeType getNodeType(Object object)<br />

1: if (object instanceof UMLProject ) then<br />

2: return umlprojectNodeType<br />

3: else if (object instanceof UMLClassDiagram ) then<br />

4: return umlclassdiagramNodeType<br />

...<br />

5: end if<br />

Figure 2.9 : Example implementation of the getNodeType routine.<br />

2.2.3 TGG Rule Graphs<br />

TGG rule graphs consists of nodes, edges and properties and they resemble object diagrams<br />

to clone object structures, the same as might occur in the real model instances. A TGG rule<br />

graph consists of three graph rewriting rules, where each rule defines the rewriting step how<br />

the corresponding model is to be extended.<br />

Additionaly, the graph elements reference the graph type models (see Figure 2.10 ). These types<br />

are the same as those that are used <strong>by</strong> the model adapter to translate the in- memory models for<br />

the interpreter. Therefore, the structure and the used object types of a TGG graph rule can be<br />

directly matched with the in- memory model instances to perform the transformation.<br />

11


2.2. INTERPRETER ARCHITECTURE<br />

Edge<br />

Graph<br />

+ description: String<br />

*<br />

*<br />

GraphElement<br />

edge<br />

graph<br />

graphElement<br />

Node<br />

in * * 1 1 target<br />

out<br />

source<br />

*<br />

GraphElementType<br />

EdgeType<br />

GraphType<br />

+ description: String<br />

*<br />

graphTypes<br />

graphElementTypes<br />

node nodetype<br />

edgetype<br />

1<br />

1<br />

1 node<br />

*<br />

Property<br />

+ name: String<br />

+ type: String<br />

properties<br />

NodeType<br />

+ role: String + name: String<br />

in<br />

*<br />

out<br />

*<br />

1<br />

source<br />

property propertytype<br />

1 target<br />

Figure 2.10 : The graph- and graph type- meta model.<br />

1<br />

1<br />

*<br />

PropertyType<br />

+ name: String<br />

+ type: String<br />

nodeType<br />

propertyTypes<br />

Figure 2.11 shows how the interpreter architecture interacts together. The interpreter transforms<br />

the model source instance. Therefore, it matches the source graph rule within the object<br />

structure of the source model. However, since the interpreter is supposed to be independend<br />

from the model instances, it must not know its structure, and its types, and therefore, the model<br />

adapters are used to hide both of them. The interpreter can then compare the elements of the<br />

rule directly with the model object instances <strong>by</strong> comparing its types.<br />

Real model source instance<br />

c1:Car eng1:Engine<br />

color=“Silver“<br />

t1:Tire t2:Tire t3:Tire t4:Tire<br />

TGG source graph rule<br />

p1:Property<br />

value=“Silver“<br />

n1:Node<br />

name=“Manta“<br />

e1:Edge<br />

++<br />

++<br />

n2:Node<br />

name=“Continental“<br />

interpreter:Interpreter<br />

source:RealModelAdapter<br />

(c1,n1)<br />

(eng1,n2)<br />

(t1,n3)<br />

(t2,n3)<br />

(t3,n3)<br />

(t4,n3)<br />

Source graph model type definition<br />

p1:PropertyType<br />

name=“color“<br />

type=“String“<br />

n1:NodeType<br />

name=“Car“<br />

e1:EdgeType<br />

role=“car2engine“<br />

n2:NodeType<br />

name=“Engine“<br />

Figure 2.11 : A graph and the referenced model type definition.<br />

12<br />

Represents a relation.<br />

e2:EdgeType<br />

role=“car2tire“<br />

n3:NodeType<br />

name=“Tire“


2.2. INTERPRETER ARCHITECTURE<br />

2.2.4 Interpreter<br />

The interpreter finally performs the model transformation <strong>by</strong> applying the TGG rules stepwise.<br />

Therefore, it tries to match the condition part of the TGG rule within the object structures of the<br />

source, target and correspondence graph. This matching is similar to the (sub) graph matching<br />

problem, where a smaller subgraph is searched within a bigger main graph. Before explaining<br />

the interpreter algorithm, firstly a short recapitulation of graph theory is given to get familiar<br />

with the notion again.<br />

2.2.4.1 (Sub-) Graph Matching<br />

Graphs<br />

A graph is defined as a tuple G = (V, E), whereas V is a set of nodes and E is a set of edges<br />

(see Figure 2.12 ).<br />

V ={v1, v2, v3}, E ={{v1, v2}, {v2, v3}, {v1, v3}}<br />

Directed-/Undirected Graph<br />

v 1<br />

v 2<br />

Figure 2.12 : A simple graph.<br />

Depending on the application domain a graph can be directed or undirected. Former means<br />

that an edge between two nodes has an explicit direction. Therefore the set of edges is defined<br />

as tuples of sorted nodes E ={(u, v) | u, v ∈ V }. Undirected graphs have unsorted pairs of<br />

nodes (see Figure 2.13 ).<br />

V ={v1, v2, v3}, E ={(v1, v2), (v2, v3), (v3, v1)}<br />

Labeled-/Attributed Graph<br />

v 1<br />

v 2<br />

Figure 2.13 : A directed graph.<br />

A graph can be labeled or attributed. That means all of its nodes and edges are labeled<br />

differently (but arbitrarily), so that they can be distinguished. To label the nodes and edges, a<br />

13<br />

v 3<br />

v 3


2.2. INTERPRETER ARCHITECTURE<br />

graph must have a labeling function which assigns every node or edge an unique id, name or<br />

index (see Figure 2.14 ).<br />

Here is an example for a graph with a node and edge labeling function.<br />

E = (V, E, µ, η), V ={v1, v2, v3} E ={(v1, v2), (v2, v3), (v3, v1)}<br />

µ : v → Lv η : e → Le<br />

Sub Graphs<br />

v 1<br />

A<br />

v 2<br />

C<br />

B<br />

Figure 2.14 : An attributed graph.<br />

A subgraph, as part of a main graph, is usually defined as a subset of the nodes and edges of<br />

the original graph. More formally, a graph G ′<br />

= (V ′<br />

, E ′<br />

, µ ′<br />

, η ′<br />

), is a subgraph of a graph<br />

G = (V, E, µ, η) short G ′<br />

⊆ G iff, V ′<br />

⊆ V and E ′<br />

⊆ E ∪ (V ′<br />

× V ′<br />

). Additional, the labeling<br />

functions must be identical.<br />

Morphisms between graphs<br />

µ(v) ′<br />

� ′<br />

µ(v) if v ∈ V<br />

=<br />

undefined otherwise<br />

A relationship between two graphs is defined as a Morphism from one graph G ′<br />

to another<br />

graph G.<br />

When considering the edge relation in a graph as a binary relation, then a morphism is defined<br />

as a mapping function f : G ′<br />

→ G such that f(u ∗ v) = f(u)αf(v), where ∗ is the relation<br />

on G ′<br />

and α is the relation on G. That means that when there exist two nodes u, v in the<br />

source graph, being related <strong>by</strong> ∗, then the node images f(u), f(v) must be related <strong>by</strong> the target<br />

relation α as well.<br />

In graph theory a morphism is called a Homomorphism.<br />

Homomorphism<br />

Given two graphs,<br />

G ′<br />

= (V ′<br />

, E ′<br />

), V ′<br />

= {A, B, C}, E ′<br />

= {(A, B), (B, C), (C, A)}<br />

G = (V, E), V = {D, E, F, G, H},<br />

14<br />

v 3


2.2. INTERPRETER ARCHITECTURE<br />

E = {(D, E), (E, F ), (F, D), (F, G), (G, H), (H, F )}<br />

a homomorphism f between the two graphs is defined as.<br />

f : V ′<br />

→ V such that (u, v) ∈ E ′<br />

⇒ ((f(u), f(v)) ∈ E<br />

The figure 2.15 shows one possible homomorphism between the two graphs.<br />

Isomorphism<br />

A<br />

C<br />

B<br />

The arrow shows a possible node mapping.<br />

Figure 2.15 : A possible homomorphism f(A) = G,f(B) = H,f(C) = F<br />

[The word ”isomorphism” applies when two complex structures can be mapped<br />

onto each other, in such a way that to each part of one structure there is a corresponding<br />

part in the other structure...(Gdel, Escher, Bach) [7]]<br />

An isomorphism is a bijective (surjective and injective) mapping f between two graphs. It<br />

usually indicates that they are identical and that every element in the source graph can be<br />

mapped to an equal node in the target graph and vice versa. The definition for a sub graph<br />

isomorphism is given in the same way, except that a certain part of the target graph is ignored.<br />

It is exactly the part that doesn’t exists in the target graph. This definition for a sub graph<br />

isomorphism is usually very helpfull, since often times, the target graph has much more nodes<br />

than the source graph and one is looking for subgraphs to be identical only to a certain subpart<br />

of the target graph (sub graph isomorphism). Figure 2.16 shows the the four cases for different<br />

mapping functions.<br />

15<br />

D<br />

G<br />

F<br />

E<br />

H


2.2. INTERPRETER ARCHITECTURE<br />

1<br />

3<br />

1<br />

2<br />

2<br />

3<br />

4<br />

2.2.4.2 Graph Matching Algorithm<br />

a<br />

c<br />

a<br />

b<br />

c<br />

b<br />

(a) Bijective (injective and surjective) (b) Injective, not surjective<br />

1<br />

3<br />

1<br />

2<br />

2<br />

3<br />

4<br />

(c) Surjective, not injective (d) Not surjective, not injective<br />

Figure 2.16 : Mapping functions between two graphs.<br />

The graph isomorphism problem is very difficult to solve and not yet proven to be in either of<br />

the sets P or NP -Complete. However the sub graph isomorphism problem is proven to be in<br />

NP-Complete [8].<br />

For every matching algorithm, it is almost unavoidable to try every node mapping combination<br />

between the two graphs. Unfortunately, this leads very quickly to a search space explosion,<br />

since trying every combination for two graphs G ′<br />

= (V ′<br />

, E ′<br />

) and G = (V, E) with |V ′<br />

| = m<br />

and |V | = n nodes causes the algorithm in worst case to try m × n! different combinations<br />

and therefore it runs exponentially long.<br />

That is <strong>by</strong> far too long for an efficient application. However, in most of the cases enough<br />

information exists to reduce the search space, which then results in an acceptable, quadratic<br />

time. These will be discussed in the following sections.<br />

Example<br />

Figure 2.17 shows an example of how to systematically try every node mapping combination.<br />

Starting with the first node v ′ ′<br />

1 ∈ V of the source graph G ′<br />

, |V | possibilities are left to match<br />

the node with a node vi ∈ V of graph G. When the node was matched successfully, the next<br />

node v ′<br />

2 has |V | − 1 possibilities, to be matched and so on.<br />

16<br />

a<br />

b<br />

c<br />

a<br />

b<br />

d<br />

c<br />

d


2.2. INTERPRETER ARCHITECTURE<br />

n<br />

Node Mapping<br />

v' 1<br />

v' 2<br />

v' 3<br />

v' 4<br />

v' 5<br />

v' 5<br />

v' 4<br />

v 4<br />

v' 1<br />

v' 3<br />

v' 2<br />

v 5<br />

G' G<br />

v 3<br />

f(v' 1 )=v 1<br />

v 5<br />

v 4<br />

v 4<br />

v 2<br />

v 3<br />

v 4<br />

(1) (2)<br />

v 5<br />

v 4<br />

v 3<br />

v 1<br />

Figure 2.17 : Searchtree<br />

When a node n ′<br />

from graph G ‘ does can be mapped to another node n from a graph G ?<br />

Depending on the underlying graph model and its graph properties there can exists many<br />

different criteria for equalness. However, the structure is the main property to be checked<br />

when two graphs are compared for equality. Therefore, the answer of the question above can<br />

be directly derived from the definition of a graph homomorphism in the section 2.2.4.1. It<br />

says, whenever there exists an edge e ′<br />

between two nodes (n ′<br />

1 , n′ 2 ) in graph G′ , their node<br />

images f(n ′<br />

1 ) = n1, f(n ′<br />

2 ) = n2 must be connected <strong>by</strong> an edge e in G as well.<br />

That means whenever the algorithm tries to match two nodes, it must check whether they have<br />

the same outgoing edges and hence the same neighbors.<br />

The following pseudocode will explain the simplified checkoutgoingEdges routine that is a<br />

part of the interpreter algorithm and which checks the homomorphism condition.<br />

As input there are two nodes n ′<br />

∈ G ′<br />

to be a subset of G<br />

...<br />

v 4<br />

v 1<br />

v 2<br />

v 4<br />

= (V ′<br />

, E ′<br />

) and n ∈ G = (V, E) whereas G ′<br />

is supposed<br />

17<br />

v 5<br />

v 3<br />

n<br />

n-1<br />

n-2<br />

n-3<br />

1<br />

n!


2.2. INTERPRETER ARCHITECTURE<br />

boolean checkoutgoingEdges(Node n ′<br />

1 , Node n1)<br />

1: if (n ′<br />

1 .getOutgoingEdges().size() > n1.getOutgoingEdges().size()) then<br />

2: return false<br />

3: end if<br />

4: while (n ′<br />

5:<br />

.getOutgoingEdges().hasNext()) do<br />

(e ′<br />

← n ′<br />

.getOutgoingEdges().next()<br />

6: if (isMapped(e ′<br />

.getTargetNode())) then<br />

7: n2 ← getMappingPartner(e ′<br />

.getTargetNode())<br />

8: found ← false<br />

9: while (n1.getOutgoingEdges().hasNext() & !found) do<br />

10: e ← n1.getOutgoingEdges().next()<br />

11: if (e.getTargetNode().equals(n2)) then<br />

12: found ← true<br />

13: end if<br />

14: end while<br />

15: if (not found) then<br />

16: return false<br />

17: end if<br />

18: end if<br />

19: end while<br />

20: return true<br />

The checkoutgoingEdges routine simply iterates over all outgoing edges of the first node<br />

n ′<br />

1 ∈ G′ and checks if the target node is already mapped to a node n2 ∈ G. In that case, the<br />

node n2 must be a neighbor node of the node n1, for which n ′<br />

1 is supposed to be the mapping<br />

partner.<br />

Backtracking<br />

The backtracking step is a systematic approach to handle dead ends while running through<br />

the search space to find a solution for a given problem. During the matching application<br />

the algorithm traverses through both graphs G ′<br />

= (V ′<br />

, E ′<br />

), G = (V, E), and tries every<br />

node mapping combination between their nodes. Whenever it ends up in a dead solution, it<br />

discards the last node mapping, makes one step back and proceeds with the next possible node<br />

mapping pair. Programmatically, a backtracking step usually is implemented as recursion.<br />

One backtracking step means going up one recursion step.<br />

Depth First Search vs. Breath First Search<br />

Both, Depth First- and Breath First- Search can be used to traverse a graph systematically.<br />

The advantage of BFS is guaranteed to find the shortest solution path first. That means using<br />

BFS allows the algorithm to find the smallest subgraph first, because the breadth-first strategy<br />

always expands all the nodes at one level of the graph before expanding any of their neighbor.<br />

This property is important when graphs again are subgraphs of other graphs and hence the<br />

interpreter could match them at once. This feature will be explained more in detail in chapter<br />

5.<br />

The default search algorithm used within the interpreter is BFS, but only a few lines of code<br />

would need to be changed in order let it use DFS instead.<br />

18


2.2. INTERPRETER ARCHITECTURE<br />

The difficulty of the matching algorithm is that it performes a BFS search on two graphs simultaneously.<br />

Therefore a recursive nested routine is implemented to systematicaly try every node<br />

matching possibility.<br />

The routine matchGraphs 2.19 tries to perform a graph matching between the two given<br />

graphs G ′<br />

= (V ′<br />

, E ′<br />

) and G = (V, E). Therefore, it initiates the breath-first search for the<br />

root node mapping and then explores recursively the neighbor nodes.<br />

Vector matchGraphs(Graph G ′<br />

, Graph G)<br />

1: while (V ′<br />

.hasNext()) do<br />

2: n ′ ′<br />

1 ← V .next()<br />

3: while (V .hasNext()) do<br />

4: n1 ← V .next()<br />

5: if (matchNodes(n ′<br />

1 ,n1)) then<br />

6: nodeMapping ← new NodeMapping(n ′<br />

1 ,n1)<br />

7: mappings.add(nodeMapping)<br />

8: edgesCopy ← n ′<br />

1 .getOutgoingEdges()<br />

9: success ← exploreEdges(nodeMapping,edgesCopy,mappings,emptyVector)<br />

10: if (success) then<br />

11: return mappings<br />

12: else<br />

13: mappings.clear<br />

14: end if<br />

15: end if<br />

16: end while<br />

17: end while<br />

Figure 2.18 : This routine checks if a graph is subgraph of another graph.<br />

boolean matchNodes(Node n ′<br />

1 ,Node n1)<br />

1: success ← checkoutgoingEdges(n ′<br />

1 ,n1)<br />

2: return success<br />

Figure 2.19 : This routine is used to match two nodes with each other.<br />

19


2.2. INTERPRETER ARCHITECTURE<br />

boolean exploreEdges(NodeMapping nodeMapping, Vector edgesCopy, Vector mappings,Vector<br />

levelMappings)<br />

1: source ← nodeMapping.getSourceNode()<br />

2: target ← nodeMapping.getTargetNode()<br />

3: if (!edgesCopy.isEmpty()) then<br />

4: e ′<br />

← edgesCopy.next()<br />

i<br />

5: n ′<br />

i<br />

← e′<br />

i .getTargetNode()<br />

6: while (target.getOutgoingEdges().hasNext()) do<br />

7: ei ← target.getOutgoingEdges().next()<br />

8: ni ← ei.getTargetNode()<br />

9: if ( isMapped(ni) & isMapped(n ′<br />

i )) then<br />

10: oldMapping ← node2nodeMapping.get(nu) {}//node2nodeMapping is global<br />

map<br />

11: oldMapping2 ← node2nodeMapping.get(n ′<br />

u)<br />

12: if (oldMapping.equals(oldMapping2)) then<br />

13: newMapping ← oldMapping<br />

14: end if<br />

15: else if (matchNodes(n ′<br />

i ,ni)) then<br />

16: newMapping ← new NodeMapping(n ′<br />

i ,ni)<br />

17: end if<br />

18: if (newMapping != null) then<br />

19: levelMappings.add(newMapping)<br />

20: mappings.add(newMapping)<br />

21: edgesCopy.remove(e ′<br />

i )<br />

22: success ← exploreEdges(nodeMapping,edgesCopy,mappings,levelMappings)<br />

23: if (success) then<br />

24: return true<br />

25: else<br />

26: levelMappings.remove(newMapping)<br />

27: mappings.remove(newMapping)<br />

28: end if<br />

29: end if<br />

30: end while<br />

31: return false<br />

32: else<br />

33: while (levelMappings.hasNext()) do<br />

34: tmpMapping ← levelMappings.next()<br />

35: newEdgesCopy ← tmpMapping.getSourceNode().getOutgoingEdges()<br />

36: success ← exploreEdges(tmpMapping,edgesCopy,mappings,emptyVector)<br />

37: if (!success) then<br />

38: return false<br />

39: end if<br />

40: end while<br />

41: end if<br />

Figure 2.20 : This routine explores all outgoing edges of a node.<br />

The routine exploreEdges shown in the figure 2.20 simply tries to match all nodes at a given<br />

level <strong>by</strong> running through the outgoing edges of the actual parent node mapping’s source node<br />

20


2.2. INTERPRETER ARCHITECTURE<br />

and then recursively tries to find a mapping partner within the neighbor nodes of the parent<br />

node mapping’s target node. Once all nodes at a certain level are mapped, for each of these<br />

level node mappings, the routine is recursively called again.<br />

Graph- Rewriting/Production<br />

A graph may be produced <strong>by</strong> a graph grammar. Besides, its graph rewriting rules stepwise<br />

extends the graph according to its definition of the right side (as explained in Chapter 2.1 ).<br />

Therefore, the left side can be considered as a precondition subgraph, that needs to be matched<br />

within the existing graph in order to extend it. The matchGraph algorithm can be used to<br />

stepwise apply the graph rewriting rules and therefore extend the graph.<br />

Graph- Parsing/Derivation<br />

A graph that was produced <strong>by</strong> a graph grammar has been stepwise extended <strong>by</strong> the graph grammar<br />

rules. By deriving a produced graph back, its rule application order can be reconstructed.<br />

Besides, the graph rewriting rules will be virtually reapplied on the existing graph. During this<br />

reaplication, the graph and its elements are categorized into an already produced part and a<br />

virtually none- existing part.<br />

A rule can be successfully reaplied, whenever its precondition subgraph on the left side can<br />

be successfully matched within the already produced part of the graph and its right side can<br />

be matched within the virtually none existing part of the graph. Figure 2.21 shows a possible<br />

model instance and its produced elements.<br />

in01:Inport<br />

out01:Outport<br />

p1:Project<br />

t01:Track s01:Signal<br />

c01:Con<br />

in02:Inport<br />

out02:Outport<br />

Already produced<br />

Figure 2.21 : Nodes were already successfully reproduced<br />

The following rule shown in the figure 2.22 could be successfully reaplied, since its left precondition<br />

side can be matched within the already produced part of the graph. Therefore,<br />

the left side of the rule must be matched within the produced part of the model and the<br />

right side must be matched within the not yet produced part. A possible matching would<br />

be (r1,p1),(r2,in01),(r3,t01),(r4,out01).<br />

21


2.2. INTERPRETER ARCHITECTURE<br />

R<br />

L<br />

++<br />

++<br />

r3:Track<br />

++<br />

source<br />

r1:Project<br />

++<br />

r2:Inport<br />

++<br />

r4:Outport<br />

Figure 2.22 : The graph rewriting rule that could be reaplied next.<br />

The following algorithm derives a graph back <strong>by</strong> stepwise reapplying the TGG rules on the<br />

graph as long as it has still not yet produced elements e.g. whenever there exists produced<br />

elements, that still have not yet produced neighbors. This set is called the front (see Figure<br />

2.23 ), since these elements mark the border between the left and the right side of a graph<br />

grammar rule. It is also used as starting context for possible node mappings and therefore<br />

helps to reduce the search space. This is because, whenever a rule is going to be matched,<br />

at least one of its elements on the left side must be a matching partner for at least one of the<br />

nodes in the front. Every time a rule is successfully matched, the front needs to be updated<br />

and elements get removed when they no longer have not yet produced neighbors.<br />

The Front<br />

in01:Inport<br />

out01:Outport<br />

p1:Project<br />

t01:Track s01:Signal<br />

c01:Con<br />

in02:Inport<br />

++<br />

out02:Outport<br />

Already produced<br />

Figure 2.23 : The front that marks the border for the graph grammar rule’s left and right side.<br />

The following algorithm assumes at least one start element to be in the front.<br />

22


2.2. INTERPRETER ARCHITECTURE<br />

Vector deriveGraph(Vector ruleGraphs,Graph G)<br />

1: while (!theFront.hasNext()) //theFront is a global list do<br />

2: frontELement ← theFront.next()<br />

3: while (ruleGraphs.hasNext()) do<br />

4: ruleGraph ← ruleGraphs.next()<br />

5: nodeList ← ruleGraph.getNodes()<br />

6: while (nodeList.hasNext()) do<br />

7: node ← nodeList.next()<br />

8: success ← matchNodes(node,frontElement)<br />

9: if (success) then<br />

10: nodeMapping ← new NodeMapping(node,frontElement)<br />

11: mappings.add(nodeMapping)<br />

12: edgesCopy ← node.outgoingEdges<br />

13: success ← exploreEdges(nodeMapping,edgesCopy,mappings,emptyVector)<br />

14: if (success) then<br />

15: while (nodeMappings.hasNext()) do<br />

16: nodeMapping ← nodeMappings.next()<br />

17: theFront.add(nodeMapping.getSourceNode())<br />

18: produced.add(nodeMapping.getSourceNode())<br />

19: updateTheFront()<br />

20: deriveOrder.add(ruleGraph)<br />

21: end while<br />

22: else<br />

23: mappings.clear<br />

24: end if<br />

25: end if<br />

26: end while<br />

27: end while<br />

28: end while<br />

29: return deriveOrder<br />

Figure 2.24 : This routine parses a graph.<br />

boolean updateTheFront()<br />

1: while (theFront.hasNext()) do<br />

2: node ← theFront.next()<br />

3: outgoingEdges ← node.getOutgoingEdges()<br />

4: stayInFront ← false<br />

5: while (outgoingEdges.hasNext() & !stayInFront) do<br />

6: neighbor ← outgoingEdges.next()<br />

7: if (!isProduced(neighbor)) then<br />

8: stayInFront ← true<br />

9: end if<br />

10: end while<br />

11: if (!stayInFront) then<br />

12: theFront.remove(node)<br />

13: end if<br />

14: end while<br />

Figure 2.25 : This routine updates the front.<br />

23


2.2. INTERPRETER ARCHITECTURE<br />

In order to use the algorithm exploreEdges from above, the matchNodes routine needs to be<br />

changed, such that two nodes can only be matched when the first node is on the left side and<br />

the second node is already produced, or when the first node is only on the right side, but then<br />

the second node must not be produced yet.<br />

boolean matchNodes(Node n ′<br />

1 ,Node n1)<br />

1: success ← (((n ′<br />

1 .isLeft() & isAlreadyProduced(n1)) or (!n ′<br />

1 .isLeft() &<br />

!isAlreadyProduced(n1))) ( & checkoutgoingEdges(n ′<br />

1 ,n1))<br />

2: return success<br />

Search space reduction<br />

Figure 2.26 : This routine matches two nodes.<br />

In order to optimize the graph matching application, the underlying graph model is very<br />

important. As already mentioned, the structure is one property to be checked, but there could<br />

be many more. For example, labled nodes and edges could be compared as well. Therefore,<br />

the matchNodes routine can be changed such that whenever two nodes are going to be matched<br />

its labels are checked first.<br />

success ← ((n ′<br />

i .label == ni.label) & (checkoutgoingEdges(n ′<br />

i ,ni))<br />

Since the checkoutgoingEdges check is more expensive, the label check should be done first.<br />

At this point, many different properties can be checked. The more properties and the more<br />

restrictive the equalness of two graphs is defined, the earlier a dead end is recognized.<br />

Briefing<br />

In the above section, several graph algorithms were introduced that are almost all used within<br />

the interpreter algorithm that will be explained in the next chapter 2.2.4.3. The checkoutgoingEdges<br />

routine assures that the homomorphism condition (structure preserving) is not violated.<br />

The exploreEdges routine together with the matchGraph routine can be used to perform<br />

a graph rewriting application. The exploreEdges routine together with the deriveGraph routine<br />

can be used to parse a graph and reproduce its rule application order.<br />

2.2.4.3 Interpreter Algorithm<br />

The interpreter transforms two models into each other <strong>by</strong> performing a graph transformation<br />

with triple graph grammars. Therefore, it tries iteratively to apply the TGG rules in order to<br />

build up the corresponding target model.<br />

A TGG rule can be applied whenever its precondition can be successfully matched within<br />

the existing elements of the source, correspondence and target models. Depending on<br />

the reading direction, the precondition of the TGG rule is composed of the source graph<br />

grammar rule’s left and right side, the correspondence left side and the target graph grammar<br />

rules left side. This structure altogether is sometimes also called the L structure. The<br />

24


2.2. INTERPRETER ARCHITECTURE<br />

matching and the creation of the new target model elements can be divided into five main steps:<br />

1. Matching the source graph rewriting rule.<br />

2. Matching the correspondence.<br />

3. Matching the target graph rewriting rule’s precondition side.<br />

4. Extending the target model.<br />

5. Extending the correspondence between both models.<br />

R<br />

L<br />

++<br />

++<br />

:Track<br />

++<br />

source correspondence target<br />

:Project<br />

++<br />

1<br />

:Inport<br />

++<br />

:Outport<br />

++<br />

++<br />

++<br />

++<br />

2 3<br />

:Corresp<br />

:Corresp<br />

5<br />

++<br />

:Corresp<br />

++<br />

:Corresp<br />

++<br />

++<br />

++<br />

++<br />

++<br />

++<br />

:Petrinet<br />

++<br />

:Place<br />

++<br />

:Arc<br />

++<br />

4<br />

++<br />

++<br />

:Transition<br />

Figure 2.27 : The five steps of the interpreter algorithm.<br />

For the first step, the deriveGraph method can be used. The only difference is that, instead<br />

of getting a graph as input, the source in- memory model is used. However, this can be<br />

interpreted as a graph using the model adapter. After the interpreter has successfully matched<br />

the source graph grammar rule, it just needs to call the matchCorrespondence routine in step<br />

two, in order to go on with the TGG rule matching.<br />

In the second step, the correspondence between the source elements and the target elements<br />

needs to be checked. Therefore, the matchCorrespondence routine simply tries to map the<br />

correspondence nodes from the TGG rule within the real correspondence nodes between the<br />

source and target in- memory model that has been newly created during the transformation.<br />

This correspondence matching is not like a real graph matching, but rather an operation on<br />

data structures. Therefore, it stepwise retrieves the real correspondence nodes for all, in<br />

the first step, mapped source model object instances and tries to match these with the rule<br />

correspondence nodes.<br />

When a rule correspondence node could be found, the real correspondence nodes outgoing<br />

edges are checked within the source mappings, to make sure it is the right correspondence<br />

node, so far. In the next step its target outgoing edges must be mapped within the left side of<br />

the target graph grammar rule of the TGG rule.<br />

Therefore, in the third step, the matchCorrespondence runs through the outgoing edges of the<br />

currently treated real correspondence node and checks if their neighbor nodes (these are the<br />

25<br />

++<br />

++


2.2. INTERPRETER ARCHITECTURE<br />

objects of the target in- memory model) can be matched within the left precondition structure<br />

of the target graph rewriting rule. For every successfull matching, a node mapping is created,<br />

which maps the rule node with the target in- memory model object.<br />

After the L structure was successfully matched, the TGG rule can be fully applied. Therefore,<br />

the routine doTransfomationStep runs through the nodes of the target graph grammar rule and<br />

creates a new object for every node that is only on the right side of the TGG rule.<br />

Thereafter, new edges are created <strong>by</strong> running through the same nodes to check if there exists<br />

edges that are only on the right side. When it does, for every of these edges, a new reference is<br />

created <strong>by</strong> using the nodes (mapping) partner (objects of the target model instance) as source<br />

object and the neighbor nodes (mapping) partner is used as target object.<br />

Then the interpreter can just call the model adapter method createEdge to create a new reference.<br />

In the last step, the newly created target elements must be mapped to its corresponding<br />

source elements. Therefore, the interpreter runs through the correspondence graph rewriting<br />

rule and creates a new node, for every rule rule node only on the right side. Additionally,<br />

it runs through the outgoing edges of the rule correspondence node and then retrieves the<br />

mapping partner object of the edge’s neighbor node, <strong>by</strong> using the global maintained map<br />

node2nodeMappings, which stores the current node mapping for every mapped rule node.<br />

Thereafter, the mapping partner (the model instance object) is stored in the newly created list,<br />

which will be assigned to the newly created correspondence node, using the global maintained<br />

map realCorrespondenceNodes2modelInstanceElements.<br />

Changing the Transformation Direction<br />

The transformation direction can be changed <strong>by</strong> calling the interpreter routine switchDirection(String<br />

direction). The method simply exchanges all currently maintained data structures,<br />

as well as the side of the model adapters, without loosing any information about the current<br />

transformation status. Switching the direction during the transformation is necessary when<br />

performing incremental transformation steps from any side of the in- memory model instances.<br />

Incremental Transformation<br />

The interpreter also supports incremental transformation steps. Although, this feature is still<br />

in development, it can be used for simple model changes. For this purpose, the interpreter can<br />

register itself as observer to the source and target model adapters and then listen for model<br />

changes. The adapter can send the following event types:<br />

• PROPERTY CHANGED<br />

• NEW NODE<br />

• NODE DELETED<br />

• EDGE DELETED<br />

The property changed event is send, when a property value was changed.<br />

The new node event is send, when a new object was created outside of the interpreter<br />

environment. Besides, the interpreter receives the newly created objects from the adapter, puts<br />

26


2.2. INTERPRETER ARCHITECTURE<br />

them in the front, switches the transformation direction when necessary, and simply triggers<br />

the transformation routine again. However, the interpreter does not restart the complete model<br />

transformation, but rather transforms only the newly created objects.<br />

The delete node event is send, when an object was deleted outside of the interpreter environment.<br />

Besides, the interpreter receives the deleted object from the adapter and then revokes<br />

the TGG rule that created this object. Therefore, it maintaines a list that stores all objects and<br />

references that were created within the same transformation step and maps each list entry to<br />

the list itself. The interpreter then deletes all objects and references using the model adapter<br />

method deleteNode(Object source) and deleteEdge(EdgeType edgeType, Object source, Object<br />

target) respectively, and then updates all its data structures that had a reference to the deleted<br />

objects and references. However, the interpreter does not check the consistency of the models,<br />

after having revoked a TGG rule. Very often the model is getting inconsistent afterwards, and<br />

other TGG rules would need to be revoked as well. However, this feature is not yet supported,<br />

but the interpreter could also maintain a tree like hierarchy of applied TGG rules. Therefore,<br />

the interpreter could trace back affected objects and revoke its TGG rules as well.<br />

The delete edge event is handled exactly in the same way than the delete node event.<br />

Restriction<br />

The interpreter algorithm is not restricted to context free graph grammars, where every lefthand<br />

side consists of a single node but rather supports also context- sensitive graph grammars<br />

in which both left- and right-hand side of a production are graphs. The only restriction is that<br />

all nodes of the graph grammar needs to be reachable from at least one node on the left-hand<br />

side.<br />

27


Chapter 3<br />

Case Study<br />

This case study is meant to improve the current interpreter architecture and to help understanding<br />

which requirements and features are needed to perform a wide range of different<br />

model transformations. Therefore, an example transformation from the Fujaba TGG model<br />

to the ComponentTools TGG model has been developed. During the implementation the<br />

interpreter architecture was evaluated and the results were then used to enhance the architecture<br />

in order to get the transformation done. These enhancements will be described in chapter 4.<br />

Additionally, this example transformation will help to ease the modelling of a ComponentTools<br />

TGG model, because from this work on the Fujaba editor can be used to create any TGG model<br />

that ought to be the input for the interpreter and then ues the interpreter itself to transform<br />

this model into the corresponding ComponentTools format. This avoids the painful usage of<br />

the very user unfriendly ComponentTools editor, which was generated automatically <strong>by</strong> the<br />

Eclipse Modeling Framework (EMF) (see Section 3.2).<br />

The special on this transformation is that both models are triple graph grammar models,<br />

whereas the ComponentTools TGG model also serves as the underlying graph model for the<br />

interpreter. The implementation of the example transformation was done in a kind of bootstrapping<br />

manner. Therefore, the first TGG rules and graph type models were modeled with<br />

the ComponentTools TGG- editor, which could be then used to transform a small part of the<br />

Fujaba model into the ComponentTools model. The results were then again used as TGG ruleand<br />

graph type model- input for the interpreter, in order transform an even bigger part of the<br />

Fujaba model. This step was repeated until the whole Fujaba model could be sucessfully transformed.<br />

Figure 3.1 shows the bootstrapping process during the implementation of the example<br />

transformation.<br />

28


3.1. FUJABA- TGG EDITOR<br />

EMF Editor<br />

Fujaba Editor<br />

Modeling<br />

ComponentTools TGGModel<br />

FujabaTGG2ComponentToolsTGG'<br />

Fujaba TGGModel<br />

FujabaTGG2ComponentToolsTGG<br />

Rule- Catalog & Type Models<br />

Modeling Input<br />

Result<br />

TGG Interpreter<br />

Figure 3.1 : Bootstrapping the ComponentTools TGG model.<br />

new input<br />

ComponentTools TGGModel<br />

FujabaTGG2ComponentToolsTGG''<br />

In the following sections both TGG models and its elements will be introduced. Besides, the<br />

two model editors are explained and how both models were mapped onto each other.<br />

3.1 Fujaba- TGG Editor<br />

The Fujaba Tool Suite [9] is an UML [10] development environment that features among other<br />

things, the modelling of software systems and the code generation out of it. It was developed<br />

at the University of Paderborn and it supports the most common UML diagrams like class- and<br />

activity diagrams and statecharts.<br />

Additionally, Fujaba provides a plugin mechanism that was used to extend the Fujaba- model<br />

and the editor to support the modeling of TGG rules. Figure 3.2 shows the extended part of the<br />

Fujaba model.<br />

29


3.1. FUJABA- TGG EDITOR<br />

UMLIncrement<br />

UMLDiagramitem<br />

UMLConnection<br />

UMLLink<br />

+ modifier: Integer<br />

+ name: String<br />

+ type: Integer<br />

ASGElement<br />

+ name: String<br />

UMLObject<br />

+ modifier: Integer<br />

+ name: String<br />

+ type: Integer<br />

ASGDiagram<br />

UMLDiagram<br />

UMLObjectDiagram<br />

TGGDiagram 0..*<br />

diagram2element<br />

0..*<br />

diagram2element<br />

0..*<br />

TGGObject<br />

+ side: Integer<br />

outlink2source<br />

0..1<br />

inlink2target 0..*<br />

0..*<br />

0..1 0..*<br />

TGGLink<br />

Figure 3.2 : The extended part of the Fujaba model<br />

3.1.1 Creating a Fujaba TGG Model<br />

A Fujaba TGG model can be created <strong>by</strong> specifying three different class diagrams that represent<br />

the meta type definition of the source-, correspondence- and target- models. Each element in a<br />

class diagram represents a certain type for one of the elements found in the three in- memory<br />

model instances.<br />

The TGG model also contains TGG rules (TGG diagrams) that describe the single transformation<br />

steps. A TGG diagram is an object diagram using the types defined in the class diagrams.<br />

These object structures define the three graph rewriting rules and every element in the TGG<br />

diagram references one type of the above defined graph type models.<br />

3.1.2 TGG Rule Specification in Fujaba<br />

A TGG model can easily be created <strong>by</strong> using the Fujaba editor to model the class diagrams and<br />

the TGG rules. The figure 3.3 shows the Fujaba editor and a TGG diagram that describes the<br />

transformation step of a Fujaba TGG diagram object into the corresponding ComponentTools<br />

Graph object.<br />

30


3.1. FUJABA- TGG EDITOR<br />

Figure 3.3 : The Fujaba editor showing a TGG diagram.<br />

TGG objects can be edited in a dialog (see figure 3.4 ) that allows to set important properties<br />

listed below.<br />

• The objects name.<br />

• The type of the object, which references one of the class diagram’s elements.<br />

• The side, which sets one of the three graph rewriting rules (source, correspondence or<br />

target).<br />

• The modifier ’left’ or ’right’, which defines the actual rule side of the element (in Fujaba<br />

they are called ’None’ and ’Create’)<br />

• The constraint that defines whether the node should be treated as normal, or as condition<br />

node.<br />

31


3.2. ECLIPSE/EMF TGG EDITOR<br />

3.1.3 Fujaba Graph Type Model<br />

Figure 3.4 : The part of the Fujaba graph type model.<br />

The Fujaba model provides the very basic UML elements like classes, associations and others,<br />

in order to model UML diagrams. Since the current interpreter architecture does not support<br />

abstraction (see Chapter 5) the graph type in figure 3.5 was modeled without it.<br />

UMLProject<br />

0..1<br />

project2diagram<br />

0..*<br />

UMLClassDiagram<br />

+ name: String<br />

0..*<br />

diagram2element<br />

UMLClass<br />

+ name: String<br />

0..1<br />

class2attr<br />

0..*<br />

UMLAttr<br />

+ name: String<br />

+ type: String<br />

0..*<br />

0..1<br />

0..1<br />

0..1<br />

0..1<br />

0..*<br />

0..1<br />

project2diagram<br />

project2typelist<br />

0..*<br />

typelist2type<br />

role2targetclass<br />

0..*<br />

assoc2rightrole<br />

0..1<br />

0..1<br />

0..1<br />

UMLRole<br />

+ adornment: Integer<br />

UMLTypeList<br />

0..1<br />

0..*<br />

UMLAssoc<br />

+ name: String<br />

attrexpr2attr<br />

TGGDiagram<br />

+ name: String<br />

diagram2element<br />

0..*<br />

0..1<br />

assoc2leftrole<br />

0..1<br />

0..*<br />

0..*<br />

diagram2element<br />

0..*<br />

TGGObject<br />

+ modifier: Integer<br />

+ name: String<br />

+ side: Integer<br />

+ type: Integer<br />

0..1<br />

object2class<br />

object2attrexpr<br />

UMLAtrrExprPair<br />

+ expression: Integer<br />

+ operator: Integer<br />

diagram2element<br />

outlink2source<br />

inlink2target<br />

0..1 0..*<br />

link2assoc<br />

Figure 3.5 : The Fujaba graph type model as a UML class diagram.<br />

3.2 Eclipse/EMF TGG Editor<br />

0..1<br />

0..1<br />

0..*<br />

0..1<br />

0..*<br />

1<br />

0..*<br />

TGGLink<br />

0..*<br />

+ modifier: Integer<br />

expr2assignedexpr<br />

The ComponentTools infrastructure was developed <strong>by</strong> a project group at the University of<br />

Paderborn. The tool allows to easily apply formal methods in the development cycle of<br />

a system. Therefore, an application interface was developed as well as a transformation<br />

32<br />

0..1<br />

0..*


3.2. ECLIPSE/EMF TGG EDITOR<br />

mechanism to allow third party tools to be integrated, <strong>by</strong> transforming formal models into<br />

each other and then allow different tools to work on one and the same model. Therefore,<br />

ComponentTools has developed a triple graph grammar model that is used to model the rules<br />

and the type definitions (see Chapter 2.4 ) that are necessary for the transformation.<br />

The ComponentTools TGG model, generated <strong>by</strong> the Eclipse Modeling Framework (EMF) [11].<br />

EMF is a modeling framework and code generation facility for building tools and other applications.<br />

From a model specification described in XMI, EMF provides tools and runtime support<br />

to produce a set of Java classes implementing the model, a set of adapter classes that enable<br />

viewing and command-based editing of the model, and a basic editor.<br />

3.2.1 Creating a ComponentTools TGG Model<br />

A ComponentTools TGG model consists of three graph types, which define the meta type<br />

definition of the three in- memory models, in the same way the class diagrams do in a Fujaba<br />

TGG model. A graph type model consists of node-, edge- and property- types, whereas each<br />

of these elements represent a type for one of the elements in the in- memory model instances.<br />

Furthermore, the TGG model contains TGG rule graphs and each rule again defines the three<br />

graph rewriting rules for the triple graph grammar application. A TGG rule graph consists<br />

of nodes, edges and properties and resembles object diagrams, in the same way as the TGG<br />

diagrams do in Fujaba.<br />

3.2.2 TGG Rule Specification in ComponentTools<br />

A ComponentTools TGG model can be created <strong>by</strong> using the tree based XMI editor, which was<br />

generated <strong>by</strong> the EMF framework. Figure 3.6 shows the ComponentTools editor modeling a<br />

TGG rule that transforms a TGG diagram into the corresponding ComponentTools graph.<br />

33


3.2. ECLIPSE/EMF TGG EDITOR<br />

Figure 3.6 : The ComponentTools Editor modeling a TGG rule graph.<br />

The elements can be edited <strong>by</strong> using the property cell editor, which can be seen in the lower<br />

part of figure 3.6 .<br />

3.2.3 ComponentTools Meta Model<br />

A graph type may contain element types like node- and edge- types, whereas the first one<br />

can have multiple property types that represents certain class attributes. A TGG rule graph<br />

contains elements like nodes and edges. Nodes can have properties that again have a reference<br />

to an element type. Figure 3.7 shows the underlying graph model of the interpreter architecture<br />

as an EMF class diagram.<br />

34


3.3. MAPPING BOTH MODELS<br />

Figure 3.7 : The ComponentTools graph type model as EMF class diagram.<br />

3.3 Mapping both models<br />

As seen above, the Fujaba- and the ComponentTools- models are very similar to each other.<br />

They almost have the same structure and they provide the same information that is necessary<br />

for a transformation with triple graph grammars. Therefore, the Fujaba model could have been<br />

easily used as underlying graph model for the interpreter too.<br />

However, modelling a new graph model with EMF was the first choice, because Fujaba<br />

contains some elements and features that are useless for the interpreter architecture and hence<br />

would have made it unnecessarily complex. EMF also provides comfortable ways to map<br />

other models to its internal Ecore model representation, which is used for the model code- and<br />

editor generation. Nevertheless, Fujaba would have been a good choice as well, since some of<br />

the enhancement being made to the interpreter are actually adapted from the Fujaba model.<br />

The following two sections show an example TGG rule in both, the Fujaba as well as the<br />

CoamponentTools notation. Both diagrams are modeled as UML object diagram whereas the<br />

related elements are drawn in the same color. Both models only show the part of the model<br />

that is necessary for defining the TGG rule that transforms a Fujaba TGG diagram into the<br />

corresponding ComponentTools graph.<br />

35


3.3. MAPPING BOTH MODELS<br />

3.3.1 Representation in ComponentTools<br />

The TGGCatalog of the ComponentTools model represents the root element of the project.<br />

This object references the GraphTypes and the TGG rule Graphs. The GraphTypes, source<br />

(blue color), correspondence (orange color) and target (green color), define the element types<br />

of the three in- memory models. The Graphs and its elements define the object structure of the<br />

three graph rewriting rules (source, correspondence and target). Each of these object structures<br />

and its elements reference elements of one of the GraphTypes.<br />

nt1:NodeType<br />

name:=”UMLProject”<br />

n1:Node<br />

name:=”project”<br />

left:=true<br />

source:=true<br />

et1:EdgeType<br />

role:=”project2diagram”<br />

et2:EdgeType<br />

role:=”diagram2project”<br />

e1:Edge<br />

left:=false<br />

map:=true<br />

gt1:GraphType<br />

description:=”source”<br />

e2:Edge<br />

left:=false<br />

map:=true<br />

nt2:NodeType<br />

name:=”TGGDiagram”<br />

pt1:PropertyType<br />

name:=”name”<br />

type:=”String”<br />

n2:Node<br />

name:=”tggdiagram”<br />

left:=false<br />

source:=true<br />

t1:TGGCatalog<br />

p1:Property<br />

operator:=ASSIGN<br />

et3:EdgeType<br />

gt2:GraphType<br />

description:=”correspondence”<br />

corres1:NodeType<br />

name:=”project2catalog”<br />

role:=”p2t2p” et4:EdgeType<br />

et6:EdgeType<br />

role:=”t2g2t”<br />

e3:Edge<br />

left:=true<br />

map:=true<br />

3.3.2 Representation in Fujaba<br />

corres2:NodeType<br />

name:=”tggdiag2graph”<br />

cor1:Node<br />

name:=”project2catalog”<br />

left:=true<br />

map:=true<br />

g1:Graph<br />

role:=”p2t2t”<br />

descr:=”TGGDiagram2Graph”<br />

et7:EdgeType<br />

role:=”t2g2g”<br />

gl1:GraphElementTypes<br />

e4:Edge<br />

left:=true<br />

map:=true<br />

cor2:Node<br />

e7:Edge e8:Edge<br />

left:=false<br />

name:=”tggdiag2graph”<br />

left:=false<br />

left:=false<br />

map:=true<br />

map:=true<br />

map:=true<br />

nt3:NodeType<br />

name:=”TGGCatalog”<br />

et5:EdgeType<br />

role:=”tggcatalog2graph”<br />

n3:Node<br />

name:=”tggcatalog”<br />

side:=”right”<br />

modifier:=”none”<br />

Figure 3.8 : ComponentTools TGG model at runtime.<br />

et5:EdgeType<br />

role:=”tggcatalog2graph”<br />

gt3:GraphType<br />

description:=”target”<br />

nt4:NodeType<br />

name:=”Graph”<br />

e5:Edge<br />

left:=false<br />

target:=true<br />

e6:Edge<br />

left:=false<br />

target:=true<br />

pt2:PropertyType<br />

name:=”name”<br />

type:=”String”<br />

n4:Node<br />

name:=”graph”<br />

side:=”right”<br />

modifier:=”create”<br />

p1:Property<br />

operator:=ASSIGN<br />

The Fujaba notation is very similar (see Figure 3.9 ). The root element is an object of type<br />

UMLProject, which references the UMLClassDiagram objects source (blue color), correspondence<br />

(orange color) and target (green color). These again define the element types of the<br />

three in- memory models. The UMLProject object also has a reference to the TGGDiagram<br />

object (purple object td1). The TGG diagram and its references define the object structure<br />

of the three graph rewriting rules (source, correspondence and target). Each of these object<br />

structures and its elements reference elements of one of the class diagram.<br />

36


3.3. MAPPING BOTH MODELS<br />

c1:UMLClass<br />

name:=”UMLProject”<br />

adornment:=0<br />

cd1:UMLClassDiagram<br />

name:=”source”<br />

a1:UMLAssoc<br />

name:=”project2diagram”<br />

r1:UMLRole r2:UMLRole<br />

o1:TGGObject<br />

name:=”project”<br />

side:=”left”<br />

modifier:=”none”<br />

adornment:=0<br />

t1:TGGLink<br />

modifier:=”create”<br />

t2:TGGLink<br />

c2:UMLClass<br />

name:=”TGGDiagram”<br />

a1:UMLAttr<br />

name:=”name”<br />

type:=”String”<br />

o2:TGGObject<br />

name:=”tggdiagram”<br />

side:=”left”<br />

modifier:=”create”<br />

p1:UMLProject<br />

t6:TGGLink<br />

modifier:=”none”<br />

td1:TGGDiagram<br />

r5:UMLRole<br />

adornment:=0<br />

r6:UMLRole<br />

adornment:=3<br />

name:=”TGGDiagram2Graph”<br />

r9:UMLRole<br />

adornment:=0<br />

r10:UMLRole<br />

adornment:=3<br />

cd2:UMLClassDiagram<br />

name:=”correspondence”<br />

c5:UMLClass<br />

name:=”project2catalog”<br />

a3:UMLAssoc<br />

name:=”p2t2p”<br />

a3:UMLAssoc<br />

name:=”t2g2t”<br />

cor1:TGGObject<br />

name:=”project2catalog”<br />

side:=”map”<br />

modifier:=”none”<br />

c6:UMLClass<br />

name:=”tggdiag2graph”<br />

a4:UMLAssoc<br />

name:=”p2t2t”<br />

a5:UMLAssoc<br />

name:=”t2g2g”<br />

tl1:UMLTypeList<br />

r7:UMLRole<br />

adornment:=0<br />

r8:UMLRole<br />

adornment:=3<br />

r11:UMLRole<br />

adornment:=0<br />

r12:UMLRole<br />

adornment:=3<br />

t5:TGGLink<br />

modifier:=”none”<br />

c3:UMLClass<br />

name:=”TGGCatalog”<br />

a2:UMLAssoc<br />

cd3:UMLClassDiagram<br />

name:=”target”<br />

name:=”tggcatalog2graph”<br />

adornment:=0<br />

c4:UMLClass<br />

name:=”Graph”<br />

r3:UMLRole r4:UMLRole<br />

o3:TGGObject<br />

name:=”tggcatalog”<br />

side:=”right”<br />

modifier:=”none”<br />

adornment:=0<br />

t3:TGGLink<br />

modifier:=”create”<br />

t4:TGGLink<br />

a2:UMLAttr<br />

name:=”name”<br />

type:=”String”<br />

o4:TGGObject<br />

name:=”graph”<br />

side:=”right”<br />

modifier:=”create”<br />

modifier:=”create”<br />

t2:UMLAttrExprPair<br />

t7:TGGLink<br />

modifier:=”create”<br />

cor2:TGGObject<br />

name:=”tggdiag2graph”<br />

t8:TGGLink<br />

modifier:=”create”<br />

modifier:=”create”<br />

expression:=”name:=o4.getName()”<br />

side:=”map”<br />

modifier:=”create”<br />

t2:UMLAttrExprPair<br />

expression:=”name:=o2.getName()”<br />

3.3.3 Mapping The Elements<br />

Figure 3.9 : Fujaba TGG model at runtime.<br />

In this section, the elements of both models are mapped onto each other. Therefore, in the<br />

following sections, the TGG rules are introduced that are needed for the transformation. For<br />

a better understanding of a correct model transformation, the creation of bidirectional references<br />

have been explicitly modeled <strong>by</strong> using two references in both direction. However, both<br />

the Fujaba and the ComponentTools model allow to maintain the consistency of bidirectional<br />

references within the model, and therefore, would not make it necessary to explicitly set both<br />

directions.<br />

3.3.3.1 UMLProject2TGGCatalog<br />

The UMLProject- and TGGCatalog- objects represent the root elements of their models and<br />

therefore must be transformed manually <strong>by</strong> hand . That means, whenever a Fujaba model<br />

is to be transformed into a ComponentTools model, its UMLProject object is transformed <strong>by</strong><br />

creating a new TGGCatalog object <strong>by</strong> hand. This is also called the axiom, since there exists no<br />

precondition for this rule.<br />

3.3.3.2 UMLClassDiagram2GraphType<br />

The UMLClassDiagram- and the GraphType- objects represent the root object for the element<br />

types. The first one references UMLClass-, UMLAssoc- (associations) and UMLAttr-<br />

37


3.3. MAPPING BOTH MODELS<br />

(attributes) objects, whereas the latter one references Node-, Edge- and Property type objects.<br />

This rule creates a new GraphType object as well as references in both directions to the TG-<br />

GCatalog object for every UMLClassDiagram object referenced <strong>by</strong> an UMLProject object.<br />

Vice versa, it creates a new UMLClassDiagram object and references in both directions to the<br />

UMLProject object for every GraphType object referenced <strong>by</strong> a TGGCatalog object (see Figure<br />

3.10 ).<br />

p1:UMProject<br />

project2diagram<br />

++<br />

++<br />

cd1:UMLClassDiagram<br />

(a)<br />

diagram2project<br />

++<br />

t1:TGGCatalog<br />

catalog2graphtype graphtype2catalog<br />

++ ++<br />

++<br />

gt1:GraphType<br />

Figure 3.10 : Transforms an UMLClassDiagram object into a GraphType object.<br />

3.3.3.3 TGGDiagram2Graph<br />

The TGGDiagram- and the Graph- object represents the root element for the TGG rule<br />

object structures. The first one references TGGObject- (objects), TGGLink- (references) and<br />

UMLAttrPairExpr- (attribute instances) objects, whereas the latter one references Nodes,<br />

Edges and Properties.<br />

This rule creates a new Graph object as well as new references in both directions to the TG-<br />

GCatalog object for every TGGDiagram object referenced <strong>by</strong> the UMLProject object. Vice<br />

versa, it creates a new TGGDiagram object and references in both directions to the UMLProject<br />

object for every Graph object referenced <strong>by</strong> the TGGCatalog object (see Figure 3.11 ).<br />

p1:UMProject<br />

++ diagram2project<br />

++<br />

project2diagram<br />

td1:TGGDiagram<br />

(a)<br />

(b)<br />

t1:TGGCatalog<br />

catalog2graph<br />

graph2catalog ++<br />

++<br />

++ ++<br />

g1:Graph<br />

Figure 3.11 : Transforms an TGGDiagram object into a Graph object.<br />

3.3.3.4 UMLTypeList2GraphElementTypes<br />

The UMLTypeList- and the GraphElementTypes- object represents a type list. The first one<br />

contains UMLClass objects only, whereas the latter one contains all Node- and Edge- Type<br />

objects. The GraphElementTypes element was introduced to allow Node- and Edge- Types to<br />

be referenced <strong>by</strong> multiple GraphTypes (see Chapter 4).<br />

38<br />

(b)


3.3. MAPPING BOTH MODELS<br />

This rule creates a new GraphElementTypes object as well as a new reference for the TGGCatalog<br />

object for the one UMLTypeList object that is referenced <strong>by</strong> the UMLProject object. Vice<br />

versa, it creates a new UMLTypeList object and a new reference for the UMLProject object for<br />

the one GraphElementTypes object that is referenced <strong>by</strong> the TGGCatalog object (see Figure<br />

3.12 ).<br />

p1:UMProject<br />

typelist2project<br />

++<br />

project2typelist<br />

++<br />

++<br />

list:UMLTypeList<br />

(a)<br />

t1:TGGCatalog<br />

catalog2elementtypelist<br />

++<br />

++<br />

elementtypelist2catalog<br />

glist:GraphElementTypes<br />

Figure 3.12 : Transforms an UMLTypeList object into a GraphElementTypes object.<br />

3.3.3.5 UMLClass2NodeType<br />

The UMLClass- and the NodeType- object represent an element type. The first one may be<br />

referenced as type <strong>by</strong> the TGGObject objects and can be connected to other UMLClass objects<br />

using UMLAssoc objects. The latter one is referenced as type <strong>by</strong> a Node object and can be<br />

connected to other NodeType objects using EdgeType objects.<br />

This rule creates a new NodeType object as well as new references in both directions to the<br />

GraphElementTypes object for every UMLClass referenced <strong>by</strong> the UMLTypeList object. Vice<br />

versa, it creates a new UMLClass object and references in both directions to the UMLTypeList<br />

object for every NodeType object referenced <strong>by</strong> the GraphElementTypes object (see Figure<br />

3.13 ).<br />

list:UMLTypeList<br />

c1:UMLClass<br />

(a)<br />

(b)<br />

glist:GraphElementTypes<br />

++<br />

type2typelist typelist2type elementtypelist2elementtype<br />

elementtype2elementtypelist ++<br />

++ ++<br />

n1:NodeType<br />

Figure 3.13 : Transforms an UMLClass object into a NodeType object.<br />

3.3.3.6 UMLClass2NodeType-Correspondence<br />

This rule creates new references in both directions between a GraphType object and a Node-<br />

Type object for every reference found between an UMLClassDiagram object and an UMLClass<br />

object. Vice versa, it creates new references in both directions between an UMLClassDiagram<br />

object and an UMLClass object for every reference found between a GraphType object and a<br />

NodeType object (see Figure 3.14 ).<br />

39<br />

(b)


3.3. MAPPING BOTH MODELS<br />

cd:UMLClassDiagram<br />

element2diagram diagram2element<br />

c1:UMLClass<br />

3.3.3.7 UMLAssoc2EdgeType<br />

++ ++<br />

(a)<br />

gt:GraphType<br />

++ graphtype2elementtype<br />

elementtype2graphtype ++<br />

n1:NodeType<br />

Figure 3.14 : This rule only transforms a reference.<br />

An UMLAssoc (association) object in Fujaba represents the connection type between two<br />

UMLClass objects (see Figure 3.15 ). Therefore, it references a left and a right UMLRole<br />

object, which again references the source and the target class objects. Additionally, the role<br />

has a field called ’adornment’, which defines the association kind between the two classes. The<br />

adornment can be set to the following values:<br />

• NONE - The roles target class gets a reference of the partner class.<br />

• REFERENCE - The roles target class won’t get a reference of the partner class.<br />

• AGGREGATION, COMPOSIION, QUALIFIED - All three are not supported <strong>by</strong> the<br />

ComponentTools model.<br />

When both, the left and right UMLRole ist set to NONE, the association is bidirectional. When<br />

one of the roles is set to REFERENCE, the association is unidirectional.<br />

UMLClass<br />

+ name: String<br />

0..1<br />

role2targetclass<br />

assoc2rightrole<br />

0..*<br />

0..1<br />

UMLRole<br />

+ adornment: Integer<br />

UMLAssoc<br />

0..1 + name: String<br />

assoc2leftrole<br />

Figure 3.15 : The UMLAssoc part of the Fujaba model.<br />

The difficulty in transforming UMLAssocs is that there are many different kinds and each of<br />

it needs to be transformed differently. In ComponentTools, a connection type is defined as<br />

directed EdgeType between two NodeTypes.<br />

In the following, the TGG rules will be explained that are needed to get the transformation of<br />

the different UMLAssocs done.<br />

UMLAssoc2EdgeType-Bidirectional<br />

This rule creates two different EdgeType objects and new references in both directions to<br />

the GraphElementTypes object for every bidirectional UMLAssoc object referenced <strong>by</strong> an<br />

UMLClassDiagram object. Vice versa, it creates a new bidirectional UMLAssoc object (and a<br />

new left and right UMLRole object which are both set to NONE) and new references in both<br />

40<br />

0..1<br />

0..1<br />

(b)


3.3. MAPPING BOTH MODELS<br />

directions to the UMLClassDiagram object for every pair of EdgeType objects cross referencing<br />

the same source and target NodeType objects and referenced <strong>by</strong> the GraphElementTypes<br />

object (see Figure 3.16 ).<br />

++<br />

++<br />

targetclass2role<br />

left:UMLRole<br />

adornment:=”NONE”<br />

right:UMLRole<br />

adornment:=”NONE”<br />

targetclass2role<br />

++ ++<br />

role2targetclass<br />

++<br />

role2targetclass<br />

rightassoc2rightrole<br />

++<br />

rightrole2rightassoc<br />

++<br />

++<br />

c2:UMLClass<br />

c1:UMLClass<br />

++<br />

leftrole2leftassoc<br />

++<br />

leftassoc2leftrole<br />

(a)<br />

a1:UMLAssoc<br />

++<br />

diagram2element<br />

++<br />

++<br />

element2diagram<br />

cd:UMLClassDiagram<br />

n1:NodeType n2:NodeType<br />

++<br />

outedge2source<br />

inedge2target ++<br />

++<br />

++<br />

source2outedge<br />

++<br />

++<br />

++<br />

inedge2target<br />

e1:EdgeType<br />

e2:EdgeType<br />

++<br />

elementTypes2type<br />

++<br />

elementTypes2type<br />

graphtype2elementtype<br />

++<br />

list:GraphElementTypes<br />

g1:GraphType<br />

(b)<br />

++<br />

source2outedge ++<br />

outedge2source<br />

++<br />

graphtype2elementtype<br />

Figure 3.16 : Transforms a bidirectional UMLAssoc object into two EdgeType objects.<br />

UMLAssoc2EdgeType-Unidirectional-1<br />

This rule does the same as the rule UMLAssoc2EdgeType-Bidirectional, except that it only creates<br />

one new EdgeType object and new references in both directions to the GraphElementTypes<br />

object for every unidirectional UMLAssoc (left UMLRole is set to NONE, right UMLRole is<br />

set to REFERENCE) object referenced <strong>by</strong> an UMLClassDiagram object and vice versa creates<br />

an unidirectional UMLAssoc object for every EdgeType object that is referenced <strong>by</strong> the<br />

GraphElementTypes object and that has no corresponding EdgeType object showing in the<br />

other direction.<br />

++<br />

++<br />

targetclass2role<br />

left:UMLRole<br />

adornment:=”NONE”<br />

right:UMLRole<br />

adornment:=”REF”<br />

++<br />

role2targetclass<br />

rightrole2rightassoc<br />

++ ++<br />

++<br />

rightassoc2rightrole<br />

++ targetclass2role<br />

role2targetclass ++<br />

c2:UMLClass<br />

c1:UMLClass<br />

leftrole2leftassoc<br />

++<br />

(a)<br />

++<br />

leftassoc2leftrole<br />

++<br />

a1:UMLAssoc<br />

diagram2element element2diagram<br />

++ ++<br />

cd:UMLClassDiagram<br />

nt1:NodeType nt2:NodeType<br />

outedge2source inedge2target<br />

source2outedge target2inedge<br />

++<br />

++<br />

++<br />

++<br />

++<br />

et1:EdgeType<br />

++<br />

elementTypes2type<br />

++<br />

type2elementTypes<br />

list:GraphElementTypes<br />

gt1:GraphType<br />

(b)<br />

++<br />

graphtype2elementtype<br />

Figure 3.17 : Transforms an unidirectional UMLAssoc object into one EdgeType object.<br />

41


3.3. MAPPING BOTH MODELS<br />

UMLAssoc2EdgeType-Unidirectional-2<br />

This rule does the same as the rule UMLAssoc2EdgeType-Unidirectional-1, except that it<br />

creates a new EdgeType object that references the source and the target NodeType object in<br />

the opposite direction.<br />

++<br />

++<br />

targetclass2role<br />

left:UMLRole<br />

adornment:=”REF”<br />

++<br />

role2targetclass<br />

rightrole2rightassoc<br />

++ ++<br />

++<br />

rightassoc2rightrole<br />

right:UMLRole<br />

adornment:=”NONE”<br />

++ targetclass2role<br />

role2targetclass ++<br />

c2:UMLClass<br />

c1:UMLClass<br />

leftrole2leftassoc<br />

++<br />

(a)<br />

++<br />

leftassoc2leftrole<br />

++<br />

a1:UMLAssoc<br />

diagram2element element2diagram<br />

++ ++<br />

cd:UMLClassDiagram<br />

nt1:NodeType nt2:NodeType<br />

inedge2target outedge2source<br />

target2inedge ++<br />

++ source2outedge<br />

++<br />

++<br />

++<br />

et1:EdgeType<br />

++<br />

elementTypes2type<br />

++<br />

type2elementTypes<br />

list:GraphElementTypes<br />

gt1:GraphType<br />

(b)<br />

++<br />

graphtype2elementtype<br />

Figure 3.18 : Transforms an unidirectional UMLAssoc object into one EdgeType object.<br />

UMLAssoc2EdgeType-Bidirectional-SelfAssociation<br />

This rule does the same as the rule UMLAssoc2EdgeType-Bidirectional, except that the left<br />

and the right UMLRole object of the UMLAssoc object references the same target UMLClass<br />

object (see Figure 3.19 ).<br />

++<br />

++<br />

target2role<br />

++<br />

role2target<br />

c1:UMLClass<br />

left:UMLRole right:UMLRole<br />

adornment:=”NONE” adornment:=”NONE”<br />

leftrole2leftassoc<br />

++<br />

++<br />

a1:UMLAssoc<br />

++<br />

diagram2element<br />

c1:UMLClassDiagram<br />

(a)<br />

role2target<br />

rightrole2rightassoc<br />

++<br />

++<br />

target2role<br />

++<br />

leftassoc2leftrole rightassoc2rightrole<br />

++<br />

++<br />

++<br />

++<br />

element2diagram<br />

++<br />

outedge2source<br />

++<br />

++<br />

graphtype2elementtype<br />

n1:NodeType<br />

++<br />

++<br />

++<br />

source2outedge target2inedge inedge2target<br />

++<br />

++<br />

++ outedge2source<br />

inedge2target target2inedge<br />

++<br />

e1:EdgeType e2:EdgeType<br />

++<br />

elementTypes2type<br />

++<br />

elementTypes2type<br />

list:GraphElementTypes<br />

g1:GraphType<br />

(b)<br />

++<br />

outedge2source<br />

++<br />

graphtype2elementtype<br />

Figure 3.19 : Transforms a bidirectional self UMLAssoc object into two EdgeType objects.<br />

UMLAssoc2EdgeType-Reference<br />

42


3.3. MAPPING BOTH MODELS<br />

This rule only creates new references between a GraphType object and an EdgeType object for<br />

every reference found between an UMLClassDiagram object and an UMLAssoc object. Vice<br />

versa, it creates new references in both directions between an UMLClassDiagram object and<br />

an UMLAssoc object for every reference found between a GraphType object and a EdgeType<br />

object.<br />

UMLAssoc2EdgeType-Unidirectional-1-SelfAssociation<br />

This rule does the same as the rule UMLAssoc2EdgeType-Unidirectional-1, except that it handles<br />

the self association (see Figure 3.20 ).<br />

++<br />

targetclass2role<br />

++<br />

role2targetclass<br />

++ ++<br />

c1:UMLClass<br />

left:UMLRole right:UMLRole<br />

adornment:=”NONE” adornment:=”REF”<br />

++<br />

leftrole2leftassoc<br />

++<br />

diagram2element<br />

a1:UMLAssoc<br />

cd:UMLClassDiagram<br />

(a)<br />

++<br />

targetclass2role<br />

++<br />

role2targetclass<br />

++<br />

rightassoc2rightrole<br />

leftassoc2leftrole ++<br />

++<br />

element2diagram<br />

++<br />

rightrole2rightassoc<br />

nt1:NodeType<br />

++ ++<br />

source2outedge<br />

target2inedge<br />

outedge2source inedge2target<br />

++ ++<br />

++<br />

et1:EdgeType<br />

++<br />

elementTypes2type<br />

++<br />

type2elementtypes<br />

list:GraphElementTypes<br />

gt1:GraphType<br />

(b)<br />

++<br />

graphtype2elementtype<br />

Figure 3.20 : Transforms an unidirectional UMLAssoc object into one EdgeType object.<br />

3.3.3.8 UMLAttr2PropertyType<br />

The UMLAttr- and the PropertyType- object represents a property definition. The first one is<br />

referenced <strong>by</strong> UMLClass objects and the latter one <strong>by</strong> NodeType objects.<br />

This rule creates a new PropertyType object and a new reference in both directions to the<br />

NodeType object for every UMLAttr (attribute) object that is referenced <strong>by</strong> an UMLClass<br />

object. Vice versa, it creates a new UMLAttr object and a new reference in both direction to<br />

the UMLClass object for every PropertyType object that is referenced <strong>by</strong> a NodeType object<br />

(see figure 3.21 ).<br />

++<br />

c1:UMLClass<br />

nt1:NodeType<br />

class2attr<br />

++<br />

propertyType2nodeType<br />

++<br />

attr2class<br />

++<br />

nodeType2propertyType<br />

++<br />

a1:UMLAttr<br />

(a)<br />

pt1:PropertyType<br />

Figure 3.21 : Transforms an UMLAttr object into a PropertyType object.<br />

43<br />

(b)<br />

++


3.3. MAPPING BOTH MODELS<br />

3.3.3.9 UMLAttrExprPair2Property<br />

The UMLAttrExprPair- and the Property- object represents an instance of a property. The<br />

first one is referenced <strong>by</strong> UMLObject objects and itself has a reference to an UMLAttr object,<br />

which defines its type. The latter one is referenced <strong>by</strong> Node objects an itself has a reference to<br />

a PropertyType object, which defines its type.<br />

This rule creates a new Property object and references in both directions to the Node object as<br />

well as a reference to the PropertyType object for every UMLAttrExprPair object referenced<br />

<strong>by</strong> an UMLObject object. Vice versa, it creates a new UMLAttrExprPair object and references<br />

in both direction to the Node object as well as a reference to the UMLAttr object for every<br />

Property object referenced <strong>by</strong> a Node object (see Figure 3.21 ).<br />

a1:UMLAttr<br />

attr2attrexpr<br />

++<br />

o1:UMLObject<br />

p1:UMLAttrExprPair<br />

n1:Node<br />

object2attrexpr<br />

node2property<br />

++<br />

++ ++<br />

attrexpr2object<br />

++<br />

attrexpr2attr<br />

property2node<br />

++ ++<br />

pt1:Property<br />

(a) (b)<br />

pt1:PropertyType<br />

++<br />

property2propertytype<br />

Figure 3.22 : Transforms an UMLAttrExprPair object into a Property object.<br />

3.3.3.10 UMLAttrExprPairAssigned2PropertyAssigned<br />

The class UMLAttrExprPair object in Fujaba represents an instance of the UMLAttr class. It<br />

defines a field of type String called expression that either stores a simle value or a complex<br />

object returned back <strong>by</strong> a method call. Additionally, it defines a field called operator to define<br />

how the expression is going to be evaluated.<br />

In the ComponentTools model a Property object represents an instance of the PropertyType<br />

class. The Property object can be assigned a simple value or another Property instance.<br />

The rule creates a reference from the Property object to the assigned Property object for every<br />

UMLAttrExprPair object that references another UMLAttrExprPair object through its expression<br />

field. Vice versa, it sets the expression property of the two UMLAttrExprPair objects for<br />

every Property object referencing another Property object (see Figure 3.23 ).<br />

o1:UMLObject<br />

p2:UMLAttrExprPair<br />

expression:=”o2.getText()”<br />

operator:=”:=”<br />

object2attrexpr<br />

only existing in the GraphType model<br />

o2:UMLObject<br />

object2attrexpr<br />

p1:UMLAttrExprPair<br />

expression:=”o1.getName()”<br />

operator:=”:=”<br />

n1:Node<br />

node2property<br />

p1:Property<br />

(a) (b)<br />

++<br />

n2:Node<br />

node2property<br />

property2assignedProperty<br />

p2:Property<br />

Figure 3.23 : Transforms the expression field into an assigned property.<br />

44


3.3. MAPPING BOTH MODELS<br />

3.3.3.11 TGGObject2Node<br />

The TGGObject- and Node- objects represent an element instance in both models and are both<br />

contained in a TGG rule object diagram. The first one is referenced <strong>by</strong> a TGGDiagram object<br />

and can be connected to other TGGObject- objects using UMLLink objects. Additionally,<br />

it references a UMLClass object, which defines its type. The latter one is referenced <strong>by</strong> a<br />

Graph object and can be connected to other Node objects using Edge objects. Additionally, it<br />

references a NodeType object, which defines its type.<br />

This rule creates a new Node object and references in both directions to the Graph object for<br />

every TGGObject object referenced <strong>by</strong> a TGGDiagram object. Vice versa, it creates a new<br />

TGGObject and references in both directions to the TGGDiagram object for every Node object<br />

referenced <strong>by</strong> a Graph object (see Figure 3.24 ).<br />

c1:UMLClass<br />

++<br />

class2object<br />

object2class<br />

++<br />

td1:TGGDiagram<br />

diagram2element<br />

++<br />

++<br />

element2diagram<br />

o1:TGGObject<br />

(a)<br />

++<br />

g1:Graph<br />

graph2node<br />

++ ++<br />

node2graph<br />

++<br />

n1:Node<br />

(b)<br />

nt1:NodeType<br />

node2nodetype<br />

++<br />

nodetype2node<br />

++<br />

Figure 3.24 : Transforms an UMLObject object into a Node object.<br />

3.3.3.12 TGGLink2Edge<br />

The TGGLink- and Edge object represent a connection instance in both models. The first is<br />

referenced <strong>by</strong> a TGGDiagram object and connects two TGGObject objects with each other.<br />

Additionally, it references an UMLAssoc object which defines its type. The latter one is<br />

referenced <strong>by</strong> a Graph object and connects two Node objects with each other. Additionally, it<br />

references an Edge object, which defines its type. The following rules transform the different<br />

TGGLink objects into an Edge objects.<br />

TGGLink2Edge-Forth<br />

This rule creates a new Edge object and references in both directions to the source Node object,<br />

to the target Node object and to the Graph object, respectively and a reference to the<br />

EdgeType object for every TGGLink object that has a reference to an UMLAssoc object and<br />

that is referenced <strong>by</strong> a TGGDiagram an (see Figure 3.25 ).<br />

45


3.3. MAPPING BOTH MODELS<br />

source:UMLClass<br />

role2target<br />

left:UMLRole<br />

adornment:=”NONE”<br />

leftrole2leftassoc<br />

a1:UMLAssoc<br />

TGGLink2Edge-Back<br />

object2class<br />

td1:TGGDiagram<br />

source:TGGObject<br />

assoc2link ++<br />

++<br />

link2assoc<br />

l1:TGGLink<br />

target:TGGObject<br />

(a)<br />

diagram2element<br />

++<br />

link2source source2link<br />

++ ++ ++<br />

link2target target2link<br />

++<br />

++<br />

++<br />

element2diagram<br />

source:Node<br />

edge2source<br />

source2edge<br />

++ ++<br />

++<br />

e1:Edge<br />

node2type<br />

target:Node<br />

edge2type<br />

source:NodeType<br />

graph2element<br />

edge2target<br />

++ ++<br />

++<br />

element2graph<br />

target2edge ++<br />

++<br />

(b)<br />

outedge2source<br />

e2:EdgeType<br />

g1:Graph<br />

Figure 3.25 : Transforms an UMLLink object into an Edge object.<br />

This rule does the same as the TGGLink2Edge-Forth, except that it creates an Edge that is<br />

directed in the other direction (see Figure 3.26 ).<br />

target:UMLClass<br />

role2target<br />

right:UMLRole<br />

adornment:=”NONE”<br />

rightrole2rightassoc<br />

a1:UMLAssoc<br />

object2class<br />

source:TGGObject<br />

assoc2link ++<br />

++<br />

link2assoc<br />

td1:TGGDiagram<br />

l1:TGGLink<br />

diagram2element<br />

++<br />

link2source source2link<br />

++ ++ ++<br />

link2target target2link<br />

++<br />

++<br />

target:TGGObject<br />

(a)<br />

++<br />

element2diagram<br />

source:Node<br />

edge2source<br />

source2edge<br />

++ ++<br />

++<br />

e1:Edge<br />

node2type<br />

target:Node<br />

edge2type<br />

target:NodeType<br />

graph2element<br />

edge2target<br />

++ ++<br />

++<br />

element2graph<br />

target2edge ++<br />

++<br />

(b)<br />

outedge2source<br />

e2:EdgeType<br />

g1:Graph<br />

Figure 3.26 : Transforms an UMLLink object into an Edge object (other direction).<br />

46


Chapter 4<br />

Realization<br />

This chapter discusses the problems that occurred during the implementation of the example<br />

transformation and it explains the enhancements beeing made to the interpreter and the underlying<br />

graph model in order to get the transformation to work.<br />

4.1 Common Problems<br />

Creating the TGG rules is the most difficult part, since the developer need to know both models<br />

in detail. However, once the rules are created the model transformation is just a push on the<br />

button.<br />

During the evaluation of the interpreter and the example implementation many errors have been<br />

corrected and improvements were made. The localization of errors was very difficult because<br />

the algorithm trace had to be analyzed in order to understand why the error occurred and where<br />

to find it. Therefore, in most cases the complete matching process had to be debugged. Due<br />

to the many recursions this very difficult. Below are the most common reasons for errors that<br />

caused the interpreter to produce strange results.<br />

• The modeled TGG rules and graph type definitions contained errors. (e.g. a modeling<br />

error, like a forgotten property setting).<br />

• The interpreter algorithm contained errors. (e.g. data structures were not maintained<br />

correctly).<br />

• The adapter implementation contained errors. (e.g. the implementation did not match<br />

the rule and the graph type definition)<br />

4.2 Problems and Solutions<br />

4.2.1 TGG Rules only creating References/Edges.<br />

During the transformation the problem occurred that UMLDiagramItems (UML-<br />

Classes,UMLAssocs...) can be contained <strong>by</strong> multiple ASGDiagrams (UMLClassDiagram,<br />

TGGDiagram...). Therefore, an UMLClass object can be referenced <strong>by</strong> multiple UMLClass-<br />

Diagram objects, but only at least one reference was transformed correctly. This was because<br />

other diagrams that had a reference on this element were thrown out of the front too early.<br />

Therefore, the front was extended and an EdgeMapping was introduced in order to track all<br />

the produced references so far.<br />

47


4.2. PROBLEMS AND SOLUTIONS<br />

4.2.1.1 EdgeMapping<br />

By transforming two models into each other, the source model needs to be parsed in order to<br />

reconstruct its structure and stepwise build up the target model. Therefore, the source graph<br />

rewriting rule of the TGG rules must be virtually reapplied on the source model.<br />

When a TGG rule could be applied successfully, elements matched with rule nodes only on<br />

the right side will be marked as produced. Additionaly, they will be marked as front elements,<br />

when they still have not yet produced neighbors. This border defines the TGG rules left and<br />

right side.<br />

In the first prototype version of the TGG interpreter elements have been thrown out of the<br />

front whenever all of its neighbors were reproduced. But to fully transform a model, it is also<br />

important to check whether all its references and hence all outgoing edges of a node can be<br />

reproduced.<br />

In the new version, an object is thrown out of the front only if all of its references and hence its<br />

outgoing edges have been successfully reproduced.<br />

An edge mapping will be created, when its reference was mapped with an edge of a TGG<br />

rule only on the right side. It contains the source- and target objects which are mapped with<br />

the source- and target nodes of the edge. Additionally, the edge type is stored to identify the<br />

mapped reference.<br />

public class EdgeMapping<br />

{<br />

private Object sourceObject;<br />

private Object targetObject;<br />

private EdgeType edgeType;<br />

}<br />

public EdgeMapping(Object sourceObject,EdgeType edgeType,Object targetObject)<br />

{<br />

this.sourceObject=sourceObject;<br />

this.edgeType=edgeType;<br />

this.targetObject=targetObject;<br />

}<br />

Figure 4.1 : The class EdgeMapping of the interpreter.<br />

The above enhancement allows to have rules that only creates references (see. 4.2 ).<br />

source<br />

correspondence<br />

:UMLClassDiagram :Corresp<br />

element2diagram<br />

++ ++<br />

diagram2element<br />

assoc:UMLAssoc<br />

:Corresp<br />

target<br />

:GraphType<br />

++<br />

graphtype2edgetype<br />

back:EdgeType<br />

Figure 4.2 : A rule that only creates a reference.<br />

48


4.2. PROBLEMS AND SOLUTIONS<br />

4.2.2 TGG Rules only creating or changing Properties.<br />

4.2.2.1 PropertyMapping<br />

The above modification can be extended, such that a model is fully transformed only, whenever<br />

all its objects, references and properties are transformed. That allows to have TGG rules, only<br />

change or create properties of a an object. Although, this was possible before <strong>by</strong> using the<br />

structure of the TGG rules and define an own NodeType for this property, i.e. HeightNodeType,<br />

it is much easier and efficient <strong>by</strong> extending the front, such that objects are thrown out of it only<br />

if all its properties have been reproduced. However, this again has the disadvantage that the<br />

front might be getting polluted of objects, which properties can not be changed. Although, the<br />

transformation would be correct nevertheless, at the end of the transformation, the front would<br />

not be empty. Therefore the feature is currently not enabled.<br />

public class PropertyMapping<br />

{<br />

private Object sourceObject;<br />

private PropertyType propertyType;<br />

}<br />

public PropertyMapping(Object sourceObject,PropertyType propertyType)<br />

{<br />

this.sourceObject=sourceObject;<br />

this.propertyType=propertyType;<br />

}<br />

Figure 4.3 : PropertyMapping to trace the already produced properties.<br />

4.2.3 TGG rule condition.<br />

4.2.3.1 Property Operators<br />

In the ComponentTools model a Node object can reference multiple Properties. A Property<br />

has a certain value assigned, which can be evaluated through the interpreter at runtime <strong>by</strong><br />

comparing its values with the properties defined <strong>by</strong> the in- memory model objects.<br />

The new version now supports multiple operators for the evaluation. Therefore, the Property<br />

element in the ComponentTools model had to be extended <strong>by</strong> an operator that has one of the<br />

following values:<br />

• Equal (==)<br />

• Greater Equal (>=)<br />

• Greater (>)<br />

• Less Equal (


4.2. PROBLEMS AND SOLUTIONS<br />

The interpreter can now evaluate the rule node property value with the in- memory model object<br />

property value <strong>by</strong> using the rule nodes property operator.<br />

The following simplified rule transforms a bidirectional UML association into two EdgeTypes<br />

with different directions, depending on the adornment property of the UMLRole object. When<br />

both the left and right UMLRole object is set to ’NONE’ a bidirectional association has been<br />

found and two EdgeTypes will be created in the ComponentTools model.<br />

left:UMLRole<br />

adornment==0<br />

source:UMLClass<br />

target:UMLClass<br />

source<br />

:UMLClassDiagram<br />

assoc:UMLAssoc<br />

name:=forth.getName()<br />

right:UMLRole<br />

adornment==0<br />

correspondence<br />

:Corresp<br />

:Corresp<br />

:Corresp<br />

:Corresp<br />

target<br />

:GraphType<br />

back:EdgeType<br />

name:=assoc.getName()<br />

out2source<br />

source:NodeType<br />

:GraphElementTypes<br />

forth:EdgeType<br />

name:=assoc.getName()<br />

in2target<br />

in2target out2source<br />

target:NodeType<br />

Figure 4.4 : Transforms a bidirectional UMLAssoc into two EdgeTypes.<br />

4.2.3.2 Comparing Properties with each other.<br />

Mapping properties were used during the creation of the target model objects. Therefore, a<br />

correspondence node could define a mapping property that consisted of the source- and target<br />

node properties. Whenever the target object was created, its attributes were initialized with the<br />

values from the mapping properties source property.<br />

In the new version of the interpreter architecture, mapping properties were removed out of the<br />

graph model. Instead, properties can now be assigned and compared with arbitrary properties<br />

from other nodes, using the operators from section 4.2.3.1. That allows to compare the fields of<br />

arbitrary objects, from both, the source, and the target in- memory model. The only restriction<br />

is that node properties can only be compared with properties from other nodes when they are<br />

connected <strong>by</strong> an edge or <strong>by</strong> a correspondence node. That guarantees that the target node, when<br />

not already happend, can always be matched directly within the in- memory model objects to<br />

retrieve the actual property value.<br />

4.2.3.3 EMF Containment References<br />

In the old version of the ComponentTools model, GraphElementTypes like Node- and Edge-<br />

Types could only be contained <strong>by</strong> one GraphType. Although this is the usual case, sometimes<br />

it happens that different GraphTypes reference each other, or may be composed of several<br />

other GraphTypes. The problem occurred during the transformation of UMLClass objects,<br />

since they can be referenced <strong>by</strong> multiple UMLClassDiagrams objects and therefore caused the<br />

transformation to produce wrong results, because NodeTypes were only added to at most one<br />

GraphType. Though, the lost references were no problem during the transformation from left<br />

to right (Fujaba2ComponentTools), the model was not transformed correctly and therefore,<br />

50


4.2. PROBLEMS AND SOLUTIONS<br />

could not be transformed back into the original Fujaba model.<br />

Therefore, a new element called GraphElementTypes was added to the ComponentTools model<br />

to store all the defined element types as containment reference and then allow other GraphTypes<br />

to just reference these.<br />

4.2.3.4 Online evaluation of cardinalities.<br />

In the new version of the interpreter cardinalities are evaluated at runtime to improve the efficiency.<br />

Therefore, whenever a NodeMapping and its outgoing Edges are explored (using the<br />

exploreEdges method), the edges are sorted depending on the size of the in- memory model<br />

neighbors that are returned <strong>by</strong> the RealModelAdapter’s method getNeighbors(EdgeType edgeType,<br />

Object source).<br />

4.2.3.5 Optional- /Negative edges<br />

Negative- and optional edges can be used to express that certain object references must not, or<br />

must not necessarily exist, in order to fully apply the TGG rule. For example, an Object a can<br />

only be transformed if it has no reference to a neighbor object of type B, or an Object a can<br />

always be transformed, regardless whether it has a reference to a neighbor object of type B<br />

or not. Therefore, the underlying graph model was changed, such that an Edge has a Property<br />

called KIND, which can be set to the following values.<br />

• NORMAL - The default setting to treat an Edge as normal.<br />

• OPTIONAL - The Edge must not necessarily be matched within the in- memory model<br />

instances.<br />

• NEGATIVE - The Edge must not be matchable within the in- memory model instances<br />

in order to apply the TGG rule.<br />

The interpreter handles negative edges in the way that it returns false in the current transformation<br />

step, whenever it can map a negative edge within the references of an in- memory model<br />

object. In the case of optional edges, it continuous with the transformation anyway, even when<br />

it can not match an optional Edge within the references of an in- memory model object, and<br />

there is no other reference left to try.<br />

Although, this feature is supported <strong>by</strong> the interpreter, it was not yet needed in any of the TGG<br />

rules and might get thrown out again, when it turns out to be a problem while trying to prove<br />

the correctness of a transformation (see Chapter 5). It was just added to try different modeling<br />

techniques.<br />

Sometimes negative edges can be avoided <strong>by</strong> splitting up a transformation step into two separate<br />

rules and then refining each rules using a more restrictive context around the transforming<br />

object.<br />

51


Chapter 5<br />

Conclusion<br />

The implemented example transformation and the enhancements being made during the<br />

work of this <strong>thesis</strong> helped to improve the current interpreter architecture and to get a better<br />

understanding about the assets and drawbacks of a model transformation with triple graph<br />

grammars. Additionally, the implemented example now helps to ease the modeling of the<br />

ComponentTools- TGG rule’s set and the GraphType definition models needed for a transformation,<br />

<strong>by</strong> using the Fujaba editor, instead of the very user unfriendly ComponentTools<br />

EMF editor. Therefore, a created Fujaba TGG model can be transformed into the necessary<br />

ComponentTools format.<br />

As a result it turned out that the underlying interpreter graph model is all important for being<br />

compatible to perform a wide range of different model transformation. The difficulty is that the<br />

interpreter has to be as general and efficient as possible but may not make any assumption about<br />

the models to be transformed, other than all must underly an object oriented meta model, in<br />

order to interpret them as a a graph. Therefore, the ComponentTools GraphModel must contain<br />

the most common concepts used in a variaty of object oriented meta models. The following list<br />

shows the ones known so far:<br />

• Object oriented<br />

• Type and instance level<br />

• Abstract data types (types, operations, variables, conditions)<br />

• Primitive types<br />

• Abstraction (not yet supported)<br />

Although it is nice to have a clean Graph Grammar model as underlying model for the<br />

interpreter, it is not necessarily needed, because the required information could be also<br />

provided <strong>by</strong> using the Adaptable pattern [12] to extend an existing model, i.e. to store the<br />

triple graph grammar informations. That makes it is very easy to replace the underlying<br />

ComponentTools model with any object oriented model, i.e. Java or EMF. Therefore, it would<br />

be possible for the future to make the interpreter even more independent from its own model to<br />

support the usage of different underlying models. However, that would make it also necessary<br />

to let it make use of some sort of strategy interface (strategy pattern [12]) to always support all<br />

features that are used in any underlying model.<br />

One strategy could be for example the already mentioned Abstraction concept used in many<br />

object oriented meta models that would allow to have only one TGG rule for very simmilar ob-<br />

52


ject structures, which could then make use of the super type hierarchies defined in a GraphType<br />

model definition.<br />

Another result is that although the interpreter works very efficient and reliable working with it<br />

is very difficult. This is because very often the complete algorithm trace needs to be debugged,<br />

in order to understand why certain results are produced. Therefore, it would be very helpfull<br />

for the future to have a visual debug interface that allows to follow the interpreter algorithms<br />

matching process in order to track the errors.<br />

One more problem is the uniqueness of TGG rules. Sometimes it happens that different rules<br />

can be applied at the same time to one and the same object structure. This is very often, when<br />

rules are a subset of other rules. In the example transformation, the rule UMLAssoc2EdgeType-<br />

Unidirectional-Ref1 is a subset of the rule UMLAssoc2EdgeType-Unidirectional-Bidirectional.<br />

The problem occurs, when the rule is applied from the target- to the source side, because then<br />

the interpreter can not decide, whether a single found EdgeType object has to be transformed<br />

into a bidirectional, or into an unidirection UMLAssoc object. Although sometimes, it is possible<br />

to avoid these conflicts, <strong>by</strong> splitting up the transformation step, in order to make the rules<br />

unique again, very often it is not. In this case the interpreter needs to have a priority in which<br />

order to apply the rules. For example, the problem with the UMLAssocs could be solved,<br />

<strong>by</strong> ordering the TGG rules (preprocessing), such that the bigger one (UMLAssoc2EdgeType-<br />

Unidirectional-Bidirectional) is always tried to be applied first.<br />

Another feature to be implemented in the future is the matching of multiple TGG rules at<br />

the same time. That would allow the interpreter to decompose the TGG rules into common<br />

subgraphs and then match them at once. Figure 5.1 shows an example where two graphs are<br />

matched at the same time.<br />

r 3<br />

r 2<br />

C<br />

E A<br />

v 1, r 1<br />

v 2, r 2<br />

v 3, r 3<br />

v 4<br />

v 5<br />

r 1<br />

w 4<br />

w 8<br />

w 9<br />

D<br />

B<br />

r 4<br />

r 5<br />

v 3<br />

v 2<br />

C<br />

E A<br />

v 1<br />

w 5 w6<br />

r 4<br />

r 5<br />

w 2<br />

w 3<br />

w 4<br />

w 7<br />

K<br />

L<br />

w 1<br />

v 4<br />

v 5<br />

w 7<br />

w 8<br />

w 5<br />

K<br />

B<br />

C A<br />

Figure 5.1 : Decomposing TGG rules and match them at the same time.<br />

53<br />

B<br />

w 9<br />

L<br />

E<br />

w 1<br />

w 2<br />

w 4<br />

D<br />

w 3<br />

C w6


List of Figures<br />

2.1 A simple triple graph grammar rule. . . . . . . . . . . . . . . . . . . . . . . . 7<br />

2.2 Left side pre condition. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7<br />

2.3 Target right side, that needs to be created. . . . . . . . . . . . . . . . . . . . . 8<br />

2.4 The interpreter architecture. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8<br />

2.5 A graph type and its node-, edge- and property- types. . . . . . . . . . . . . . . 9<br />

2.6 An UML class diagram and its corresponding graph type model instance. . . . 9<br />

2.7 The model adapter interface. . . . . . . . . . . . . . . . . . . . . . . . . . . . 10<br />

2.8 Example, how the interpreter interacts with the model adapter. . . . . . . . . . 11<br />

2.9 Example implementation of the getNodeType routine. . . . . . . . . . . . . . . 11<br />

2.10 The graph- and graph type- meta model. . . . . . . . . . . . . . . . . . . . . . 12<br />

2.11 A graph and the referenced model type definition. . . . . . . . . . . . . . . . . 12<br />

2.12 A simple graph. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13<br />

2.13 A directed graph. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13<br />

2.14 An attributed graph. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14<br />

2.15 A possible homomorphism f(A) = G,f(B) = H,f(C) = F . . . . . . . . . . 15<br />

2.16 Mapping functions between two graphs. . . . . . . . . . . . . . . . . . . . . . 16<br />

2.17 Searchtree . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17<br />

2.18 This routine checks if a graph is subgraph of another graph. . . . . . . . . . . . 19<br />

2.19 This routine is used to match two nodes with each other. . . . . . . . . . . . . 19<br />

2.20 This routine explores all outgoing edges of a node. . . . . . . . . . . . . . . . 20<br />

2.21 Nodes were already successfully reproduced . . . . . . . . . . . . . . . . . . . 21<br />

2.22 The graph rewriting rule that could be reaplied next. . . . . . . . . . . . . . . . 22<br />

2.23 The front that marks the border for the graph grammar rule’s left and right side. 22<br />

2.24 This routine parses a graph. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23<br />

2.25 This routine updates the front. . . . . . . . . . . . . . . . . . . . . . . . . . . 23<br />

2.26 This routine matches two nodes. . . . . . . . . . . . . . . . . . . . . . . . . . 24<br />

2.27 The five steps of the interpreter algorithm. . . . . . . . . . . . . . . . . . . . . 25<br />

3.1 Bootstrapping the ComponentTools TGG model. . . . . . . . . . . . . . . . . 29<br />

3.2 The extended part of the Fujaba model . . . . . . . . . . . . . . . . . . . . . . 30<br />

3.3 The Fujaba editor showing a TGG diagram. . . . . . . . . . . . . . . . . . . . 31<br />

3.4 The part of the Fujaba graph type model. . . . . . . . . . . . . . . . . . . . . . 32<br />

3.5 The Fujaba graph type model as a UML class diagram. . . . . . . . . . . . . . 32<br />

3.6 The ComponentTools Editor modeling a TGG rule graph. . . . . . . . . . . . . 34<br />

3.7 The ComponentTools graph type model as EMF class diagram. . . . . . . . . . 35<br />

3.8 ComponentTools TGG model at runtime. . . . . . . . . . . . . . . . . . . . . 36<br />

3.9 Fujaba TGG model at runtime. . . . . . . . . . . . . . . . . . . . . . . . . . . 37<br />

3.10 Transforms an UMLClassDiagram object into a GraphType object. . . . . . . . 38<br />

3.11 Transforms an TGGDiagram object into a Graph object. . . . . . . . . . . . . 38<br />

54


3.12 Transforms an UMLTypeList object into a GraphElementTypes object. . . . . . 39<br />

3.13 Transforms an UMLClass object into a NodeType object. . . . . . . . . . . . . 39<br />

3.14 This rule only transforms a reference. . . . . . . . . . . . . . . . . . . . . . . 40<br />

3.15 The UMLAssoc part of the Fujaba model. . . . . . . . . . . . . . . . . . . . . 40<br />

3.16 Transforms a bidirectional UMLAssoc object into two EdgeType objects. . . . 41<br />

3.17 Transforms an unidirectional UMLAssoc object into one EdgeType object. . . . 41<br />

3.18 Transforms an unidirectional UMLAssoc object into one EdgeType object. . . . 42<br />

3.19 Transforms a bidirectional self UMLAssoc object into two EdgeType objects. . 42<br />

3.20 Transforms an unidirectional UMLAssoc object into one EdgeType object. . . . 43<br />

3.21 Transforms an UMLAttr object into a PropertyType object. . . . . . . . . . . . 43<br />

3.22 Transforms an UMLAttrExprPair object into a Property object. . . . . . . . . . 44<br />

3.23 Transforms the expression field into an assigned property. . . . . . . . . . . . . 44<br />

3.24 Transforms an UMLObject object into a Node object. . . . . . . . . . . . . . . 45<br />

3.25 Transforms an UMLLink object into an Edge object. . . . . . . . . . . . . . . 46<br />

3.26 Transforms an UMLLink object into an Edge object (other direction). . . . . . 46<br />

4.1 The class EdgeMapping of the interpreter. . . . . . . . . . . . . . . . . . . . . 48<br />

4.2 A rule that only creates a reference. . . . . . . . . . . . . . . . . . . . . . . . 48<br />

4.3 PropertyMapping to trace the already produced properties. . . . . . . . . . . . 49<br />

4.4 Transforms a bidirectional UMLAssoc into two EdgeTypes. . . . . . . . . . . 50<br />

5.1 Decomposing TGG rules and match them at the same time. . . . . . . . . . . . 53<br />

55


Bibliography<br />

[1] Online source. 2006. Information about MDA. URL: http://www.omg.org/mda.<br />

[2] Online source. 2006. OMG homepage. URL: http://www.omg.org.<br />

[3] A. Gepting, J. Greenyer, Ekkart Kindler, A. Maas, S. Munkelt, C. Pales, T. Pivl, O. <strong>Rohe</strong>,<br />

Vladimir Rubin, M. Sanders, A. Scholand, C. Wagner, and Robert Wagner. Component<br />

Tools: A vision of a tool. In Proc. of the 11th Workshop on Algorithms and Tools for<br />

Petri Nets (AWPN2004), Paderborn, Germany, September 30 - October 1, pages 37–42,<br />

September 2004.<br />

[4] M. Weber and E. Kindler. The petri net kernel, 2002.<br />

[5] M. Jungel, E. Kindler, and M. Weber. The petri net markup language.<br />

[6] Ekkart Kindler, Vladimir Rubin, and Robert Wagner. An Adaptable TGG Interpreter for<br />

In-Memory Model Transformation. In Andy Schürr and Albert Zündorf, editors, Proc.<br />

of the 2nd International Fujaba Days 2004, Darmstadt, Germany, volume tr-ri-04-253 of<br />

Technical Report, pages 35–38. University of Paderborn, September 2004.<br />

[7] Douglas R. Hofstadter. Godel Escher Bach: An Eternal Golden Braid. Basic Books, Inc.,<br />

1999.<br />

[8] Online source. 2004. Entry from Wikipedia URL: http://en.wikipedia.org/<br />

wiki/NP-Complete.<br />

[9] Online source. 2006. Fujaba homepage. URL: http://www.fujaba.de.<br />

[10] Online source. 2006. UML homepage. URL: http://www.uml.org.<br />

[11] Online source. 2006. Information about EMF. URL: http://www.eclipse.org/<br />

emf.<br />

[12] Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides. Design patterns:<br />

Abstraction and reuse of object-oriented design. Lecture Notes in Computer Science,<br />

707:406–431, 1993.<br />

56

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!