The Henshin transformation meta-model defines the concepts used for the specification of model transformations in Henshin.
Model transformations are specified in terms of modules that comprise a set of units, being either transformation rules - atomic units - or composite units that allow to define a control flow.
Basic building blocks: Rules
For conciseness, the graphical editor merges LHS and RHS into an integrated representation: Nodes and edges are annotated with a «preserve», «create», or «delete» tag depending on their containment in LHS or RHS graphs.
Dangling condition: A common beginner-level problem is that rules are deemed unexecutable by the Henshin interpreter despite looking correct at the surface. This behavior is often connected to the dangling condition: A rule execution may not leave behind dangling edges, being edges with a missing source or target. It is possible to turn off the gluing condition check using the checkDangling Boolean flag.
Injective matching: The injectiveMatching flag specifies whether the match-finder is supposed to find matches that assign two or more LHS nodes to the same model element. Per default, matching is set injective (that is, not supposed to assign nodes to the same model element).
Advanced concepts: Application conditions and rule nesting
Application conditions are graph patterns that restrict the LHS of a given rule. They may require the presence of additional elements or relationships not included in the LHS. In this case, they are referred to as positive application conditions (PACs). Furthermore, they may forbid the presence of elements or relationships. In this case, they are referred to as negative application conditions (NACs). Consequently, the graphical editor displays PAC elements with a «require» and NAC elements with a «forbid» tag. Application conditions can be arbitarily nested using the propositional operators Or, And, Xor, and Not. Whether an application condition graph represents a NAC or a PAC is determined by its containment in a Not formula. There is one important distinction between model elements in the LHS graph and in a PAC graph of a rule: Model elements in PACs are not considered part of the match. The same holds for model elements in NACs.
Examples: Bank Accounts, Ecore2RDB, Java2StateMachine, Ecore2Genmodel, Grid & Comb Pattern, Gossiping Girls, Probabilistic Broadcast, Movies
Rule-nesting is a powerful concept providing a for-each operator for rules. In nested rules, the outer rule is referred to as kernel rule and the inner rule as multi rule. During execution of a nested rule, the kernel rule is matched and executed once and used as a starting point to execute the multi rule as often as possible. Multi mappings allow to specify identity between kernel and multi-rule nodes. In the graphical editor, multi-rule nodes are indicated by a layered representation and an asterisk (*). Multiple layers of rule-nesting are allowed. The graphical editor shows the path constituted by the nested rules in the title bar of the respective nodes. An extensive example for multiple-layer rule-nesting is found in Ecore2RDB.
Examples: Bank Accounts, Ecore2RDB, Gossiping Girls, Probabilistic Broadcast
Control flow: Units
In Henshin, control flow is specified using units. Units have a fixed number of sub-units, allowing for arbitrary nesting. The following unit types are available:
Sequential units have an arbitrary number of sub-units that are executed in the given order. The Boolean flag strict determines the behavior if one of the sub-units cannot be executed: In strict mode, the execution stops, otherwise, the next sub-unit is executed. The Boolean flag rollback determines whether in the case of a stopped execution previous executions are reverted.
Examples: Ecore2RDB, Java2StateMachine, Ecore2Genmodel, Grid & Comb Pattern, Movies
Priority Units have an arbitrary number of sub-units that are checked in the given order for executability. One sub-unit - the first one found to be executable - is executed.
Independent Units have an arbitrary number of sub-units that are checked in nondeterministic order for executability. One sub-unit - the first one found to be executable - is executed.
Iterated Units have one sub-unit. The sub-unit is executed as often as specified in the iterations property.
Examples: Grid & Comb Pattern
ConditionalUnits have either two or three sub-units: if, then, (and else). If a match for the if unit can be found, the then unit is executed. Otherwise, if present, the else unit is executed. Note that any changes specified in the if unit are ignored; it is used for matching only.
Execution-time variability: Parametrization
Parameters allow to shape the behavior of units and rules with variable information that is typically not present before execution time. Parameters are defined in the parameter list of a unit. Once defined, they can be accessed by properties inside the unit - for instance, inside the iterations condition, attribute values, or attribute conditions. Parameters are accessed by name reference in String values. In the graphical editor, the parameter list is shown and edited in the title bar of a unit, following in brackets after the unit name.
At execution time, the variable information is passed in by setting the parameters. Parameters can be set externally using the API or the graphical interpreter wizard. Parameters values that have been set externally are used during matching. In turn, parameters not set externally before matching are set by the matchfinder to the values found in the respective objects. This can be used to propagate values between LHS and RHS elements.
Examples: Bank Accounts, Ecore2RDB, Ecore2Genmodel, Grid & Comb Pattern, Gossiping Girls, Probabilistic Broadcast
Parameter mappings: In order to pass parameter values from outer to inner units, it is required to define parameter mappings. A parameter mapping assigns a source parameter to a target parameter.
Examples: Ecore2RDB, Ecore2Genmodel, Grid & Comb Pattern