Chapter 8. Behaviour

8.1.  Expected behaviour for this tutorial

Adding a behaviour to the FSM meta-model consists in to make a simulation of execution with operations and an execution context represented by the current state of the FSM. That's why you need to add a currentState reference and three operation :

  1. run() for FSM class,

  2. step(String): String for State class,

  3. and fire(): String for Transition class

Adding behavior to this meta model look like change the meta model according the following schema :

FSM metamodel with behavior

Figure 8.1.  FSM metamodel with behavior


The old way to add behavior in Kermeta was transform the ecore meta model into a Kermeta file and add the code for the methods. This tutorial presents the new approach, use aspect to add this new operations. With aspect, you can add new elements and new operations to a fixed meta-model. You can also combine several aspects. This section show you how to add behaviour with aspect into a metamodel. Have a look on the file fsm_Operationnal_Semantics.kmt from fr.irisa.triskell.samples.fsm.demo/kermeta/semantics which contains the fsm 's behaviour operations.

8.2.  Structuration of this behavior with aspects

So, this part presents the use of aspects to implement behavior. An aspect into a KerMeta file can be created simply with :

require kermeta
     require "http://www.kermeta.org/fsm"
       1
       
     using fsm
       2 
     using kermeta::standard
      
      aspect class Transition 
      3
	{	
	// Fire the transition
	operation fire() : String is do
	4
	  [...]
	end
	}
      
     
     }
    

1

You need to load the meta model where you will weave aspects.

2

The key word using fsm permits to simplify the writing of the elements from the fsm meta model like an import in the Java language.

3

The key word aspect is used to add attribute or operation to an existing metaclass (in this case Transition) of the loaded meta model.

4

Now, you can add attribute or operation like in a classical Kermeta file.

Example 8.1.  Aspect in Kermeta


[Warning]

None of the elements added by aspect take part of the ecore meta model, so these elements are transient that’s why it cannot be serialized by this way. If you want to serialize a new element to the meta model you need to add it into.

Have a look on the Kermeta file fsm_Operationnal_Semantics.kmt in the folder kermeta/semantics of fr.irisa.triskell.kermeta.samples.fsm.demo. You can add several aspects in the same file. So, this code is structured like this :

 
     package fsm;

	require kermeta
	require "http://www.kermeta.org/fsm"
	using fsm
	using kermeta::standard
	using kermeta::persistence
	using kermeta::exceptions

 
 
	aspect class FSM 
	{
	reference currentState : State
	 1
	 
	  
	// Operational semantic
	operation run() :  Void raises FSMException is do 
	2
    // [...]
     end 
     
     /** Initialize a new automaton from an existing one 
	 *  param :
	 *    p_state : the initial state
	 *    isInitComb
	 */
	operation initialize(p_state : State, isInitComb : Boolean) is do
     // [...]
     end
     
  } 
   3
  
  aspect class State {
  
  // Go to the next state
	operation step(c : String) : String raises FSMException
	//[...]
	end
	
  } 
  
  aspect class Transition 
{	
	
	// Fire the transition
	operation fire() : String is do
	//[...]
	end
	}
     

1

The reference currentState is added by aspect into the fsm meta model.

2

The key word raises declare an exception that an operation can throw.

3

Don't forget to close the brace at the and of an aspect definition.

Example 8.2.  Structuration of the fsm_Operationnal_Semantics.kmt file


The next section presents the differents algorithms in details.

8.3.  Behavior algorithms

Now, we will present in details the algorithm for the operations run(), step(String) and fire (String).

  • The run operation is used as a user interface. Thanks to this operation, we are going to display information about the finite state machine, read user input and process steps.

  • The step operation is used to go to an other state depending on the user's input and the transitions available from the current state.

  • The fire operation is used to change the current state and to get the produced string.

Let us see the behavior of these three operations.

8.3.1.  Run algorithm

Behavior :

1 – initialize current state

2 – loop until the user's input equal to "quit"

print the current state

read a string

process a step

catch exceptions if there are some and exit the program displaying the error.

Here is the code of the operation :

operation run() :  Void raises FSMException is do  
		// reset if there is no current state
		if self.currentState == void then self.currentState := self.initialState end
		self
		from var str : String init "init"
		until str == "quit"
		loop
			stdio.writeln("Current state : " + self.currentState.name)
			str := stdio.read("give me a letter : ")
			if str == "quit" then
				stdio.writeln("")
				stdio.writeln("quitting ...")
			else 
				if str == "print" then
					stdio.writeln("")
				else	
					stdio.writeln(str)			
					stdio.writeln("stepping...")
					do
						var textRes : String
						textRes := self.currentState.step(str)
						if( textRes == void or textRes == "" )
						then
							textRes := "NC"
						end
						
						stdio.writeln("string produced : " + textRes)
					
						rescue (err : ConstraintViolatedPre)
		            		stdio.writeln(err.toString)
		            		stdio.writeln(err.message)
		            		str := "quit"
		            	rescue (err : ConstraintViolatedPost)
	            			stdio.writeln(err.toString)
	            			stdio.writeln(err.message)
	            			str := "quit"
	            		
						rescue(err : NonDeterminism)
							stdio.writeln(err.toString)
							str := "quit"	
						rescue(err : NoTransition)
							stdio.writeln(err.toString)
							str := "quit"
	            	end
				end
			end
		end
	end

8.3.2.  Step algorithm

In this operation, there are pre and post conditions. These are conditions checked each time the operation is called. If they are evaluated to false an exception is raised. You can choose to check them or not. The following chapter presents how to run configurations.

Behavior :

1 – Select the possible transitions.

2 – If there is none raise a NoTransition exception.

If there is more than one raise a NonDeterminism exception.

3 – If there is only one transition, call its fire operation and return its result.

// Go to the next state
	operation step(c : String) : String raises FSMException
	is do
		// Get the valid transitions
		var validTransitions : Collection<Transition> 
		validTransitions :=	outgoingTransition.select { t | t.input.equals(c) }
		// Check if there is one and only one valid transition
		if validTransitions.empty then raise NoTransition.new end
		if validTransitions.size > 1 then raise NonDeterminism.new end
		
		// Fire the transition
		result := validTransitions.one.fire
	end

8.3.3.  Fire algorithm

Behavior :

1 – change the current state of the FSM

2 – return the produced string

// Fire the transition
	operation fire() : String is do
		// update FSM current state
		source.owningFSM.currentState := target
		result := output
	end

8.4.  Run an fsm example of behaviour

In this example we execute a step into the fsm behaviour algorithm with the file samplerun.fsm stored into fr.irisa.triskell.kermeta.samples.fsm.demo/models/samplerun.fsm. The following image presents the file samplerun.fsm.

In this example, you use the transition c to go to s1 to s2 and produce the string v . the behaviour can be produced thanks to the operations run(), step() and fire() defined in the last section. To run this behaviour right click on FSM Aspect Behaviour -> Run as -> FSM Aspect Behaviour.

You should obtain the following trace :

Example of behaviour execution

Figure 8.2.  Example of behaviour execution


You can continue the behaviour of finite state machine if you want. This section has presented how to add a behaviour on the meta model. The next section present how to use model transformation.