3.3.2. Complete behavioral specification of postcondition patterns

The behavior defined by a (flattened) postcondition pattern can be specified based upon (i) the model elements of the pattern body (ii) variable bindings, and (iii) containment constraints.

An effect set will contain elementary model manipulations prescribed by the postcondition of the GT rule. Furthermore, the check set contains additional constraints that need to be validated after executing the model manipulations steps prescribed by the postcondition pattern. If both sets are free of conflicts, then the GT rule has a valid result, otherwise a run-time exception is thrown.

As the first step, the manipulation of entities are handled in the following way:

// Handling of entities 
if (X is a parameter of the postcondition pattern bound to an entity) 
  if (myEntityType(X) appears in the pattern body) 
    add keep(X) to the effect set 
    add instanceOf(X, myEntityType) to the check set 
  else 
    add deleteEntity(X) to the effect set 
    // Delete all dangling incoming and outgoing relations 
    forall R with (R.from = X OR R.to = X) do 
       add deleteRelation(R) // move_content semantics: the children of X are preserved 
    // Delete all dangling relationships 
    forall Y with (supertypeOf(X,Y)) do 
       add 'deleteSupertypeOf(X, Y)' to the effect set 
    forall Y with (supertypeOf(Y,X)) do 
       add 'deleteSupertypeOf(Y, X)' to the effect set 
    forall Y with (instanceOf(X,Y)) do
       add 'deleteInstanceOf(X, Y)' to the effect set 
    forall Y with (instanceOf(Y,X)) do 
       add 'deleteInstanceOf(Y, X)' to the effect set 
else if (X is not a parameter of the postcondition pattern OR 
         X is a parameter of the postcondition but not ground) 
  if (myEntityType(X) appears in the pattern body) 
    parameter X becomes ground to a new unique name 
    add 'newEntity(X)' to the effect set 
    add 'newInstanceOf(X, myEntityType)' to the effect set 

As a second step, relations are resolved by iterating the following steps.

// Handling of relations 
if (R is a parameter of the postcondition pattern bound to a relation) 
  if (myRelationType(R, A, B) appears in the pattern body) 
    if (A and B are ground parameters) 
      add keep(R) to the effect set 
      if (A != R.from) add 'setFrom(R, A)' to the effect set 
      if (B != R.to) add 'setTo(R, B)' to the effect set 
      add 'instanceOf(R, myRelationType)' to the check set 
// The following lines handle aggregation relations 
    if (myRelationType is an aggregation AND both A and B are entities) 
      add 'move(B, A)' to the effect set // A becomes parent of B 
    else 
      RuntimeException: A/B is not ground to a valid model element 
  else 
    add 'deleteRelation(R)' to the effect set 
else if (R is not a parameter of the postcondition pattern OR 
         R is a parameter of the postcondition but not ground) 
  if (myRelationType(R, A, B) appears in the pattern body AND 
      both A and B are ground) 
    parameter R becomes ground to a new unique name 
    add 'newRelation(R, A, B)' to the effect set 
    add 'newInstanceOf(R, myRelationType)' to the effect set 
// The following lines handle aggregation relations 
    if (myRelationType is an aggregation AND both A and B are entities) 
      add 'move(B, A)' to the effect set // A becomes parent of B 
  else 
    RuntimeException: A/B is not ground to a valid model element 

Finally, entities are moved to appropriate parents in the containment hierarchy according to the containment constraints. It is worth pointing out that if the creation of an entity is prescribed by the rule, then there is only a single below containment constraint defined for this model element, then the new element is assigned like in case of an below containment constraint.

// Moving entities 
if (myEntityType(X) in M appears in the pattern body) 
  add 'move(X,M)' to the effect set 
if (myEntityType(X) below M appears in the pattern body) 
  if (there are no move operations in the effect set AND 
      there are no other below constraints defined for X AND 
      entity X is created by the rule) 
    add 'move(X,M)' to the effect set 
  else 
    add 'ancestorOf(X,M)' to the check set 

The GT engine first collects all the effects prescribed in the effect set for a certain matching, and executes them as a single atomic step. Within this atomic step, causalities of creations are respected, i.e. a relation can be created even if its source or target is created within the same step.

Relationship definitions (i.e. supertypeOf, subtypeOf, instanceOf, typeOf) can be checked by the postcondition, but they can only be manipulated explicitly in the action part. However, if a model element (entity or relation) is deleted then all incoming and outgoing relationships are implicitly removed as well to avoid dangling relationships leading out or into a non-existing model element. Furthermore, a new instanceOf relationship is created whenever creating a new model element corresponding to its type.

Remark.  Note that if two model elements appear in both the precondition and the postcondition with identical variable names, they are only identical, if both variables appear as parameters of the precondition and the postcondition pattern. Otherwise, a new model element is created.