• Nem Talált Eredményt

• As mentioned before, a (transaction-oriented)notification APIprovides synchronous feedback on elementary model manipulation operations using delegates or call-back methods. These notification objects can be collected by listeners for further analysis when a transaction commit point has been reached.

• In interactive environments (such as EMF-based editors), a command stack API may also be available, which provides services for listening to commands (objects that represent user-originated operations) that get applied to the model. Such command objects can be directly queried for elementary operation analysis.

The Viatra2 framework provides high level support for both techniques, and the prototype imple-mentation relies mostly on the notification API. However, the concepts and techniques outlined in this work can be adapted to other modeling environments where such facilities are available.

Live recomputation Live transformation execution requires the continuous maintenance of the execution contextto avoid the necessity of model merging in target models. In our approach, this context contains:

• global variables, which are persisted to enable the transformation engine to store (global) cached values.

• pattern variables, which are maintained by the incremental pattern matching engine after each atomic model manipulation operation. This means that the matches stored in a given pattern variable are always updated and the match set of any pattern can be retrieved in constant time.

As a result, the computation required to initialize and execute the incremental transformation sequence after a change is fast, since pattern matching, the most cost-intensive phase of the trans-formation, is executed in linear time with respect to the size of the match set.

5.3. GRAPH TRIGGERS: AN EVENT-DRIVEN TRANSFORMATION LANGUAGE 99

1 @ T r i g g e r(s e n s i t i v i t y=rise, e x e c u t i o n=c h o o s e) 2 g t r u l e f i r e A s L o n g A s P o s s i b l e () =

3 {

4 p r e c o n d i t i o n f i n d f i r e a b l e ( Tr ) 5 a c t i o n {

6 c a l l f i r e t r a n s i t i o n ( Tr );

7 }

8 }

Figure 5.7: Simple trigger example

Annotation modifiers @Trigger annotations accept the following parameters (key-value pairs) that are written in a Java 5-like syntax. Thesemodifiersaffect the semantics and thus the behaviour of event-driven graph transformation rules.

• Sensitivity(rise|fall|both): Risetriggers are activated whenever a new match (of the precon-dition pattern) is encountered;falltriggers are activated when a previously existing match is lost;bothtriggers activate on rises and falls as well.

• Priority(integer): Defines a precedence relation on multiple active triggers. From those trig-gers that are activated at the same time, the one with the highest priority value will run first.

• Mode(always|once ): Defines whether a trigger is continuously scheduled for execution, or it is executed only once and then it becomes disabled forever. By default, all triggers are assigned to run inalwaysmode.

• Execution(choose|iterate|forall): the distinction between theseexecution modescorresponds to the various invocation modes of traditional graph transformation rules discussed in Sec-tion 4.1.4.3. In thechoosemode, a single (randomly picked) match (among the newly found, or lost matches) will be picked for execution, initeratemode, all such matches will be processed one after another, while inforallmode, this processing will be done a pseudo-parallel manner (see Section 5.2.2.4 for more details).

5.3.1 Execution context

The system tracks changes changes in the match sets of patterns and executes the action sequences in a persistently maintainedexecution context. This context consists ofpattern variables(continuously maintained by the RETE network) andpersistent variables(ASM functionsSection 4.1.4.1). These can be used to persist information between transformation execution sequences (transactions) and thus carrytraceability informationalong the execution path.

Sincepattern variables(T rin Figure 5.7) are also part of the maintained context, their values are instantly available for processing during the execution of an event-drive rule. Hence, the execution of such rules inincremental, since the underlying RETE-based pattern matcher maintains the matches for the precondition pattern (fireable) incrementally and no model traversal is necessary for the computation of events and the evaluation of conditions.

Using ASM functions in the execution context An example usage of ASM functions in the exe-cution context is shown in Figure 5.8. We extended the previous example of Figure 5.7 to include a simple termination conditions where each transition is only allowed to fire at most once. In this

example, we use thefired/1ASM function to store already fired transitions to ensure that no Tran-sitionwill be fired more than once. In theactionpart, an if-check is added to query (usingfired/1) whether the fireable transitionT rhas been fired before, and the call to thefiretransition()rule is extended with an update of the corresponding slot offired/1.

1 // s t o r e w h e t h e r a t r a n s i t i o n has b e e n a l r e a d y f i r e d 2 // T r a n s i t i o n - > B o o l e a n

3 a s m f u n c t i o n f i r e d /1;

4

5 @ T r i g g e r(s e n s i t i v i t y=rise, e x e c u t i o n=c h o o s e) 6 g t r u l e f i r e A s L o n g A s P o s s i b l e () =

7 {

8 p r e c o n d i t i o n f i n d f i r e a b l e ( Tr ) 9 a c t i o n {

10 if ( f i r e d ( Tr )==f a l s e) seq { 11 c a l l f i r e t r a n s i t i o n ( Tr );

12 u p d a t e f i r e d ( Tr ) = t r u e;

13 }

14 } 15 }

Figure 5.8: Triggers and ASM functions

The contents offired/1 are preserved in-between executions of this rule, which ensures that the execution will terminate after all transitions that have become fireable at some point have been fired once.

5.3.2 Complex change detection

To detect complex model changes, the transformation developer can make use of the riseandfall triggers andwhen clauses, that define operational conditions on the sequence of elementary model changes that constitute thenet changecorresponding to the newly found (or lost) match.

5.3.2.1 Creation

In order to detect that a model element (or a certain configuration of multiple model elements) has been added to the model space, arisesensitive trigger is defined with the corresponding precondition pattern. As a pattern may refer to multiple model elements,when(create()) clauses(used in theaction part) allow the transformation designer to impose creation conditions on each model element (iden-tified by a pattern variable) to distinguish between various model manipulation operation sequences that caused the activation of the trigger.

An example of this technique is illustrated in Figure 5.9. Here, we use thePetriNetPlace(PN,P) pattern as the precondition to define a simple event-driven transformation rule that prints a log message whenever a newPlaceis added to the model. The trigger will be activated whenever a new match of thePetriNetPlacepattern is observed; however, as such a new match can be the result of many different elementary operation sequences (e.g. if a previously existingPlaceis assigned to a newNet), we impose a further condition to only print the log message if the atomic eventcreate(P) (corresponding to the creation of a new model element that is mapped to the pattern variableP) was indeed part of the sequence that caused the activation of the trigger.

5.3. GRAPH TRIGGERS: AN EVENT-DRIVEN TRANSFORMATION LANGUAGE 101

1 p a t t e r n P e t r i N e t P l a c e ( PN , P ) = { 2 Net ( PN );

3 P l a c e ( P );

4 Net . n o d e s ( _ , PN , P );

5 } 6

7 @ T r i g g e r(s e n s i t i v i t y=rise, e x e c u t i o n=i t e r a t e) 8 g t r u l e n e w P l a c e () =

9 {

10 p r e c o n d i t i o n f i n d P e t r i N e t P l a c e ( PN , P ) 11 a c t i o n {

12 w h e n(c r e a t e( P )) seq {

13 log(" A new p l a c e "+ P +" has b e e n created , in P e t r i net "+ PN );

14 }

15 } 16 }

Figure 5.9: Trigger creation

5.3.2.2 Deletions

Analogously to the technique presented for creations, thedeletionof model elements (or disappear-ance of model element configurations) can be used as activation conditions offallsensitive triggers.

1 @ T r i g g e r(s e n s i t i v i t y=fall, e x e c u t i o n=i t e r a t e) 2 g t r u l e l o s t T o k e n () =

3 {

4 p r e c o n d i t i o n f i n d P e t r i N e t P l a c e ( PN , P ) 5 a c t i o n {

6 w h e n(d e l e t e( P )) seq {

7 log(" A p l a c e "+ P +" has b e e n deleted , f r o m P e t r i net "+ PN );

8 }

9 }

10 }

Figure 5.10: Trigger deletion

Figure 5.10 illustrates an example of this technique. In this case, we defined an alternative version of the example of Figure 5.9: this trigger will fire after a previously existing match ofPetriNetPlace has been lost, and this loss was due to the deletion of aPlace(expressed by the when(delete(P)) condition).

5.3.2.3 Attribute updates

The language also supports the event-driven detection of attribute value changes (in Viatra2, at-tribute values are stored by thevalueVPM core function, see Def. 12). Again, the key technique is the usage of thewhen(update()) clause, which defines a condition that corresponds to an update operation on a model element (name or value change) identified by a pattern variable.

In Figure 5.11, we reuse the capacity constraint example inFigure 4.4 of Section 4.1.2.3 to define a simple event-driven rule similar to the previous introductory examples. Thewhen(update(CC)) clause is used to identify those cases where the change (ofbothsensitivity) the matching set of the CapacityConstraintpattern was caused by a change of theCapacityConstraintelement. In such cases, the:oldand:newdiscriminators may be used to refer to the values of thevalueVPM function

1 @ T r i g g e r(s e n s i t i v i t y=both, e x e c u t i o n=i t e r a t e) 2 g t r u l e c a p a c i t y C h a n g e d () = {

3 p r e c o n d i t i o n p a t t e r n C a p a c i t y C o n s t r a i n t () = { 4 P l a c e ( P );

5 C a p a c i t y C o n s t r a i n t ( CC );

6 P l a c e . c a p a c i t y ( _ , P , CC );

7 }

8 a c t i o n {

9 w h e n(u p d a t e( CC )) seq {

10 if ( v a l u e ( CC ):old > v a l u e ( CC ):new) seq {

11 log(" P l a c e "+ P +" ’ s c a p a c i t y has b e e n d e c r e a s e d . ");

12 }

13 }

14 } 15 }

Figure 5.11: Trigger update

beforeandafterthe model has been manipulated; in this case, this information is used to detect and report that the capacity constraint ofP has been increased.

5.3.3 Trigger lifecycle management

Triggers, as shown in Figure 5.6, have a simple life-cycle consisting of two states (ACTIVEand INAC-TIVE). This lifecycle can be managed using from VTCL using native rules (Section 4.1.4.4) and queried using a native function as follows:

• Controlling statescan be achieved by two native rules:

– A trigger can be started (moved from INACTIVE to ACTIVE state) by passing its identi-fied to thestartTriggernative ASM rule, any time. The state transition will occur after the execution has reached the IDLE state.

– A trigger can be stopped (moved from ACTIVE to INACTIVE state) by passing its identi-fied to thestopTriggernative ASM rule, any time. The state transition will occur after the execution has reached the IDLE state.

• Querying the current state of a trigger: thegetTriggerStatenative function can be used for this purpose, which returns a symbolic constantACTIVEorINACTIVEdepending on the actual state of the trigger.

The usage of the language facilities above is illustrated in a small example in Figure 5.12.