Skip to main content

Notice: This Wiki is now read only and edits are no longer possible. Please see: for the plan.

Jump to: navigation, search


< VIATRA2‎ | UseCases
Revision as of 13:00, 19 March 2010 by Unnamed Poltroon (Talk) (format updates)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Transformation best practices in VIATRA2

Naming elements

In two words: NAME THEM! It might seem as trivial, but it is one of the most useful techniques for developing and debugging a complex transformation. Note that model elements are automatically named uniquely by the MT framework, but this name doesn't include any information on the actual role of the element. The rename(element,name) function can be used for giving a proper name.

ASM functions

ASM functions provide a non-persistent map to store values. Each ASM function needs to be declared prior to its first use. Initial values can also be set when defining an ASM function.

machine asmFuns {
asmfunction team / 2 {
// Initialization
 (1, "real") = "Casillas";
 (7, "real") = "Raul";
 // Any values are allowed to be used in the untyped version
 (7.1, 6) = 2;

asmfunction anotherFun / 1; // An ASM function without initialization

The values stored at a certain location of an ASM function can be updated using the update ASM construct: update fun(X) = Y: assigns a new value Y to variable X or ASM function location fun(X).

Usage Tips:

  • Use ASM functions and keys with an intuitive name in order to make it easier to update and reuse the stored values. For example, define a temp for storing temporal values used close to the definition and a global for storing values used throughout the MT. It is better to store frequently used elements instead of passing them along as rule parameters.
  • The number after the ASM function name defines how many parameters make up the key for a value.
  • Note that it is possible to use model elements both as keys and values in ASM functions.

GT-rules and ASM-rules

GT-rules where the tranformation is defined decleratively with pre and postconditions together with some actions is closer to the graph transformation formalism underlying model transformations. However, writing, debugging and reusing GT-rules is burdensome and the performance is lower than when using ASM rules. Still, those who are acquainted with declerative programming may find it easier to create tranformations using GT-rules. Furthermore, MTs built from GT-rules are more usable for intra model transformations if manipulation is more frequent than generation.

On the other hand ASM rules are closer to imperative programming where model manipulation is given as ASM sequences. We advise those who start using VIATRA and model transformations with a fair knowledge of imperative languages to use ASM rules for developing a transformation. Note that ASM rules are also more adventageous for writing inter model transformations as generation has more weight than manipulation.

Control structures

Control structures are used for creating the control flow graph of MT rules. In the following the most usual usecases of these structures are given:

  • The forall structure executes the specified actions on every matching graph pattern. The matches are collected first, thus new matches emerging due to execution are not processed. This structure is best used when the action executions doesn't depend on each other and every match is treated equally. If no match is found the structure is simply skipped, if one of the executions fail the next one is started.
  • The choose structure uses the first match of the pattern for the execution. However, this choice is non-deterministic although not random meaning that it is best used when only one execution is required but not suitable when a random match is required. If no matches are found the structure fails, therefore it should be used when this event means that the execution of the actual rule should be aborted.
  • The try choose structure extends choose by encapsulating it to catch the fail when no matches are found. The structure may have an optional else part which is executed when the choose fails. This structure is best used when the transformation can proceed even if no match is found.
  • The iterate choose structure extends choose by executing the defined action on one chosen match then repeating it again if a match can still be found. Note that if the execution doesn't fail or the match isn't modified during the action, the structure will stuck in an endless cycle. The fail command can be used to force the structure to end.
  • The if-else structure provides the usual conditional execution. The condition can be a simple value or existence check but it may also include pattern matching as well. However, every parameter of the called pattern must be bound already as this is only a check not a search.

Pattern Composition

Apart from the regular definition of a pattern, several composition techniques can be used for building more complex and better understandable patterns.

  • or composition: It is possible to define more than one body for any pattern. The or operator between pattern bodies can be used for this composition. Note that the order of the bodies have no impact on the pattern matching mechanism.
  • find/neg find: it is possible to embed matching to an other pattern in the pattern body. This can be used for matching and NAC as well. By using embedded matching, patterns can be defined to be reusable and to ease understanding.
  • recursive matching: Embedded matching can be used also to implement recursive pattern matching as the pattern itself can be called with different parameters (same parameters would mean an endless cycle). For example recursive matching can be used for navigating in the modelspace hierarchy to a special level.
  • check: makes it possible to specify desired attribute values in pattern bodies. For example, the name or value of a model element can be restricted with this structure.

Back to the top