MelangeK3FSM Sequential example

[67]

1. Presentation

This example features an executable language using GEMOC Sequential Engine.

It illustrates the GEMOC animation framework on a Finite State Machine language.

While similar to the K3FSM example (cf. K3FSM Example), this example focuses on the separation of the base language: FSM and the executable sequential language: XSFSM by using language polymorphism.

FSM/XSFSM main relations.

Figure 42. FSM/XSFSM main relations.


The tree editor and graphic editor are defined on top of the FSM language. They are considered as if they were pre-existing (Ie. legacy).

Then, Melange is used to built the XSFSM executable language by inheriting from FSM. The animation layer is also built as an extensions of the graphical editor.

This allows to use the model polymorphism. Ie. it is possible to edit FSM models and then run them as XSFSM with the appropriate animation extensions.

More information and the sources of these projects are available online on Github.

2. Installation

Install the projects of this language:

  • File → new → Examples…​ → GEMOC MelangeK3FSM Language example (Sequential)

Create and start an eclipse runtime:

  • Run → Run Configurations…​ → Eclipse application > new

Install sample models for the language:

  • File → new → Examples…​ → GEMOC model example for MelangeK3FSM (Sequential)

3. Language structure overview

The following figure presents :

  • the base language fsm content;
  • how the aspects extends the base classes;
  • how the xsfsm language is built by inheriting from the fsm language and using the aspects.
Language relations, packages and classes view.

Figure 43. Language relations, packages and classes view.


Please note that for simplification of the diagram, the associations that doesn’t represent a containment, have been represented as attribute rather than links.

4. Organization of the code

Main eclipse plugins:

  • org.eclipse.gemoc.example.melangek3fsm.fsm contains the definition of the FSM language using the Melange language.
  • org.eclipse.gemoc.example.melangek3fsm.fsm.design contains the graphical concrete syntax of FSM, using Sirius. It defines only the layer for edition.
  • org.eclipse.gemoc.example.melangek3fsm.fsm.k3dsa contains the operational semantics of FSM (ie. the interpreter), using the Kermeta3 language.
  • org.eclipse.gemoc.example.melangek3fsm.fsm.model contains the metamodel of FSM, using the Ecore language.
  • org.eclipse.gemoc.example.melangek3fsm.fsm.model.edit contains EMF edition support. It is used to customize the various views in Sirius and in the simulator (for example by providing custom icons in the various views)
  • org.eclipse.gemoc.example.melangek3fsm.fsm.model.editor contains EMF basic tree editor for FSM models.
  • org.eclipse.gemoc.example.melangek3fsm.xsfsm contains the definition of the XSFSM language using the Melange language. Basically, it inherits from FSM language and add the aspects defined in the k3dsa project.
  • org.eclipse.gemoc.example.melangek3fsm.xsfsm.design contains the graphical concrete syntax of XSFSM, using Sirius. It extends fsm.design editor by adding the layers used by the debug/animation.
  • org.eclipse.gemoc.example.melangek3fsm.xsfsm.trace contains the trace metamodel automatically generated from the semantics. It is used by the omniscient debugger to support StepBack instruction and to display an interactive timeline of the execution.
  • org.eclipse.gemoc.example.melangek3fsm.xsfsm.xsfsm contains the language runtime generated by Melange for XSFSM, ie. a new Ecore model that contains both static elements (from org.eclipse.gemoc.example.melangek3fsm.fsm.model) and dynamic features (from org.eclipse.gemoc.example.melangek3fsm.fsm.k3dsa).

4.1. Relation between FSM and XSFSM languages (defined with Melange)

The figure Figure 43, “Language relations, packages and classes view.” presents an overview of the main artefacts in the projects:

  • the base language fsm is built by fsm.melange from the fsm.ecore. As it use the legacy modifier (ie. it doesn’t modifies the ecore definitions) the java classes from the ecore are directly reused as implementation for the fsm language;
  • the aspects in fsm.k3dsa extends the base classes;
  • the xsfsm.melange file defines the xsfsm language. It inherits from fsm and add the fsm.k3dsa aspects. This will generate the java implementation classes for the resulting xsfsm language.

5. DIY

By following these instructions, you’ll be able to reproduce this example from scratch.

Note

You may apply some of these steps in a different order. This is only an example of a valid scenario.

5.1. Create a legacy language for edition only (FSM)

In the following step, we’ll create a language with usual EMF technologies: Ecore + Sirius

It will be considered as a "legacy" language (ie. as if it was developped by a third party).

5.1.1. Create the Domain concepts

Create an Ecore project:

  • Menu File → New → Ecore Modeling Project

    • name it org.eclipse.gemoc.example.melangek3fsm.fsm.model
  • Edit the ecore file and add the concepts corresponding to the syntaxic domain (ie. reproduce concepts of Figure 41, “FSM Syntaxic domain.”).
FSM Syntaxic domain.

Figure 44. FSM Syntaxic domain.


  • In the org.eclipse.gemoc.example.k3fsm project, open the genmodel file,

    • change the Base Package for the model to org.eclipse.gemoc.example.melangek3fsm (on the package: Fsm → Fsm → section All)
    • Right click on the root element then Generate model code.

5.1.2. add a tree editor

  • In the org.eclipse.gemoc.example.melangek3fsm.fsm.model project, open the genmodel file,

    • Right click on the root element then Generate model code; Generate edit code; Generate editor code.

You’ll obtain the following projects: org.eclipse.gemoc.example.melangek3fsm.fsm.model.edit and org.eclipse.gemoc.example.melangek3fsm.fsm.model.editor

5.1.3. add a graphical editor

  • Create a project for the graphical editor: File → New → Viewpoint Specification Project . name it: org.eclipse.gemoc.example.melangek3fsm.fsm.design
  • Create a representation for edition

    • Change viewpoint name to "MelangeK3FSMViewPoint", label "K3FSM"
    • New Diagram representation; set the ID to "FSM", add the k3fsm.ecore to the list of metamodels; set the domain class to the FSM class. In Advanced, set the title expression to "feature:name"
    • in the Default layer; New Diagram ElementContainer; ID = "StateContainer"; Domain class = "State"; Semantic candidate expression = [self.ownedStates/]

      • on the StateContainer; New StyleGradient
      • on the StateContainer; New Contitional style; Predicate expression = [self.eContainer().oclAsType(FSM).initialState = self/]; create another gradient in it and set a border size to 4.
    • in the Default layer; New Diagram ElementElement Based Edge; ID = "TranditionEdge"; Domain class = "Transition"; Source mapping = "StateContainer"; source finder expression = [self.source/]; target Mapping = "StateContainer"; Target Finder Expression = [self.target/]

      • On TranditionEdge/ Edge Style solid, verify the decorators, No decoration for source arrow, and InputArrow for Target Arrow
      • On TranditionEdge/ Edge Style solid / Center Label Style 8; Label Expression = aql:self.getLabel()
    • Open the file org.eclipse.gemoc.example.melangek3fsm.design.Services; add a method: (use Eclipse quick fix to add the import to import org.eclipse.gemoc.example.k3fsm.Transition; )
public String getLabel(Transition transition) {
	final StringBuilder res = new StringBuilder();

	res.append(transition.getName());
	res.append("\n");
	res.append("");
	res.append(transition.getInput());
	res.append(" / ");
	res.append(transition.getOutput());
	return res.toString();
}

5.2. Transform the legacy projects into a GEMOC language

The following actions allow to declare a language for both GEMOC and Melange using the ecore defined previously.

5.2.1. Create the Language project (base language: FSM)

  • Menu File → New → Project…​ → Melange Project
  • Next ; Name it org.eclipse.gemoc.example.melangek3fsm.fsm ; → Next
  • Check the Create a plug-in using one of the templates box and select Simple GEMOC Melange Sequential project
  • Next Fill the wizard with the following:
Label Value

Package name

org.eclipse.gemoc.example.melangek3fsm

Language name

FSM

Melange file name

FSM

Ecore file location

browse to find org.eclipse.gemoc.example.melangek3fsm.fsm.model/model/fsm.ecore

  • Finish
  • Edit the file /org.eclipse.gemoc.example.melangek3fsm.fsm/src/org/eclipse/gemoc/example/melangek3fsm/fsm/FSM.melange
  • add external keywork to the language definition
external language FSM {
	syntax "platform:/resource/org.eclipse.gemoc.example.melangek3fsm.fsm.model/model/fsm.ecore"
}
  • Right click on the FSM.melange file → MelangeGenerate All
  • Right click on the org.eclipse.gemoc.example.melangek3fsm.fsm project → ConfigureAdd GEMOC Language Project Nature
  • Create a new file /org.eclipse.gemoc.example.melangek3fsm.fsm/src/org/eclipse/gemoc/example/melangek3fsm/fsm/FSM.dsl * with the following content:
name = org.eclipse.gemoc.example.melangek3fsm.fsm.FSM
ecore = platform:/resource/org.eclipse.gemoc.example.melangek3fsm.fsm.model/model/fsm.ecore
metaprog = org.eclipse.gemoc.metaprog.ecore 1

1

Indicates that this dsl definition is only providing ecore content but no behavior

5.3. Create an executable language by extension of the legacy language

5.3.1. Create Semantics operations

  • Menu File → New → Project…​ → K3 Project
  • name it : org.eclipse.gemoc.example.melangek3fsm.fsm.k3dsa ; → Next
  • Check the Create a plug-in using one of the templates box and select User Ecore Basic Aspects
  • Next

Fill the wizard with the following:

Label Value

Aspect package prefix

org.eclipse.gemoc.example.melangek3fsm

Aspect package sufffix

.aspects

Aspect file name

FSMAspects

Aspect classes suffix

Aspect

Ecore base package name

org.eclipse.gemoc.example.melangek3fsm

Ecore file path

browse to find org.eclipse.gemoc.example.melangek3fsm.fsm.model/model/fsm.ecore

  • Finish
  • Open the /org.eclipse.gemoc.example.melangek3fsm.fsm.k3dsa/src/org/eclipse/gemoc/example/melangek3fsm/fsm/aspects/fsmAspects.xtend file and add the following methods in the aspects:
package org.eclipse.gemoc.example.melangek3fsm.fsm.k3dsa

import fr.inria.diverse.k3.al.annotationprocessor.Aspect
import fr.inria.diverse.k3.al.annotationprocessor.InitializeModel
import fr.inria.diverse.k3.al.annotationprocessor.Main
import fr.inria.diverse.k3.al.annotationprocessor.Step

import org.eclipse.gemoc.example.melangek3fsm.fsm.State
import org.eclipse.gemoc.example.melangek3fsm.fsm.StateMachine
import org.eclipse.gemoc.example.melangek3fsm.fsm.Transition

import static extension org.eclipse.gemoc.example.melangek3fsm.fsm.k3dsa.StateAspect.*
import static extension org.eclipse.gemoc.example.melangek3fsm.fsm.k3dsa.StateMachineAspect.*
import static extension org.eclipse.gemoc.example.melangek3fsm.fsm.k3dsa.TransitionAspect.*
import org.eclipse.emf.common.util.EList

@Aspect(className=StateMachine)
class StateMachineAspect {

	public State currentState

	public String unprocessedString
	public String consummedString
	public String producedString

	@Step
	@Main
    def void main() {
    	try{
    		while (!_self.unprocessedString.isEmpty) {
    			_self.currentState.step(_self.unprocessedString)
    		}
		} /* catch (NoTransition nt){
			println("Stopped due to NoTransition"+nt.message)
		} catch (NonDeterminism nt){
			println("Stopped due to NonDeterminism"+nt.message)
		} */ catch (Exception nt){
			println("Stopped due to "+nt.message)
		}
		println("unprocessed string: "+_self.unprocessedString)
		println("processed string: "+_self.consummedString)
		println("produced string: "+_self.producedString)
	}


    @Step
	@InitializeModel
	def void initializeModel(EList<String> args){
		_self.currentState = _self.initialState;
		_self.unprocessedString = args.get(0)
		_self.consummedString = ""
		_self.producedString = ""
	}


}


@Aspect(className=State)
class StateAspect {
	@Step
	def void step(String inputString) {
		// Get the valid transitions
		val validTransitions =  _self.outgoingTransitions.filter[t | inputString.startsWith(t.input)]
		if(validTransitions.empty) {
			//throw new NoTransition()
			throw new Exception("No Transition")
		}
		if(validTransitions.size > 1) {
			//throw new NonDeterminism()
			throw new Exception("Non Determinism")

		}
		// Fire transition
		validTransitions.get(0).fire
	}
}

@Aspect(className=Transition)
class TransitionAspect {
	@Step
	def void fire() {
		println("Firing " + _self.name + " and entering " + _self.target.name)
		val fsm = _self.source.owningFSM
		fsm.currentState = _self.target
		fsm.producedString = fsm.producedString + _self.output
		fsm.consummedString = fsm.consummedString + _self.input
		fsm.unprocessedString = fsm.unprocessedString.substring(_self.input.length)
	}
}
/* need to be enabled when feature request  */
class NoTransition extends Exception{

}
class NonDeterminism extends Exception{

}

runtime data added via aspect

a method with @InitializeModel annotation in order to use the launch configuration parameters to set up the runtime data when the model execution starts.

a method with @Main annotation that will be used to start the execution.

a method with the @Step annotation that will be observable (ie. the debugger can do a pause when a object instance of this class call this method).

another method with the @Step annotation that will be observable

5.3.2. Create the extended Language project (executable language: XSFSM)

  • Menu File → New → Project…​ → Melange Project
  • Next ; Name it org.eclipse.gemoc.example.melangek3fsm.xsfsm ; → Next
  • Check the Create a plug-in using one of the templates box and select GEMOC Melange based sequential project (extended languages)
  • Next Fill the wizard with the following:
Label Value

Package name

org.eclipse.gemoc.example.melangek3fsm.xsfsm

Language name

XSFSM

Melange file name

XSFSM

Base language name

FSM

Ecore file location

browse to find org.eclipse.gemoc.example.melangek3fsm.fsm.model/model/fsm.ecore

K3 DSA Project name

browse to find org.eclipse.gemoc.example.melangek3fsm.fsm.k3dsa

  • Finish
  • open the /org.eclipse.gemoc.example.melangek3fsm.xsfsm/META-INF/MANIFEST.MF file, add a dependency to the org.eclipse.gemoc.example.melangek3fsm.fsm project.

check the XSFSM.melange file so that it correctly finds the inherited dsl.

package org.eclipse.gemoc.example.melangek3fsm.xsfsm
import-dsl org.inria.gemoc.example.melangek3fsm.fsm.FSM
language XSFSM inherits org.eclipse.gemoc.example.melangek3fsm.fsm.FSM {

	with org.eclipse.gemoc.example.melangek3fsm.fsm.k3dsa.StateAspect
	with org.eclipse.gemoc.example.melangek3fsm.fsm.k3dsa.StateMachineAspect
	with org.eclipse.gemoc.example.melangek3fsm.fsm.k3dsa.TransitionAspect
}
  • Right click on the XSFSM.melange file → MelangeGenerate All

This generates a new GEMOC language project: org.eclipse.gemoc.example.melangek3fsm.xsfsm.xsfsm

5.4. Add Animation and Debug capabilities to the graphical editor

Debug capabilities (breakpoint support, basic highlighting, …​)

  • Right click on the org.eclipse.gemoc.example.melangek3fsm.xsfsm.xsfsm project → GEMOC LanguageCreate animator project for languageExtends an existing diagram description → Next → select FSM (ie. the name of the representation in org.eclipse.gemoc.example.melangek3fsm.fsm.design) → Next

Fill the wizard with the following:

Label Value

Project name

org.eclipse.gemoc.example.melangek3fsm.xsfsm.design

Viewpoint Specification Model name

org.eclipse.gemoc.example.melangek3fsm.xsfsm.XSFSM.odesign

Viewpoint name

MelangeK3FSM_XSFSMViewpoint

Diagram name

org.eclipse.gemoc.example.melangek3fsm.xsfsm.XSFSM

-> Finish

Domain specific animation

This is similar to <<K3FSM-example>> (see section Domain specific animation <<K3FSM-example-debug-animation>>).
It has some specificities:
As the fsm.design is based on fsm.ecore but the executed model is actually based on xsfsm.ecore,
the typing must use as much as possible the lazy typing of AQL (Sirius query language).
Ie. write `State` instead of `fsm.State`
Additionally, the java service classes should handle both case: edition and running
so the service methods defined in _/org.eclipse.gemoc.example.melangek3fsm.fsm.design/src/org/eclipse/gemoc/example/melangek3fsm/fsm/design/services/FSMServices.java_
 that were dedicated to FSM must be duplicated and adapted to work with XSFSM in
 _/org.eclipse.gemoc.example.melangek3fsm.xsfsm.design/src/org/eclipse/gemoc/example/melangek3fsm/xsfsm/design/services/XFSMServices.java_

6. Additional resources

The following online resources are related to this examples.

Note

as these resources have been written with a previous version of the GEMOC Studio,
their content may need some adaptations to 100% work with the latest version.