Let’s focus on the language semantics. Ie. what each models of the language means.
The GEMOC Studio currently supports two major ways to make a language executable :
- one will target a sequential engine
- the second will target a concurrent engine
Note
The underlying executionframework used by the GEMOC Studio can be extended to support other methodologies or engines. However, this isn’t the scope of this document to explain how to use this framework and build an alternate or dedicated engine.
The Domain-Specific Actions define the runtime state (Execution Data) of the model and the operations (Execution Functions) which modify the runtime state of the model. In the case of the sequential engine, this project will also define the (control flow) between the operations.
In the GEMOC Studio, the DSA are implemented using Kermeta 3. To create a new DSA Project, in the main menu of the GEMOC Studio, go to: File > New > Project… > K3 Project. In the wizard, create it as a Plug-in with EMF using the template of your choice. Then, connect the xDSML Project to the DSA by referencing them in the .melange file thanks to the keyword with. See Section 1.7, “Melange editor” for more informations about Melange keywords and the content assist.
Kermeta 3 is based on xTend. The Execution Data and Execution Functions are defined through aspects weaved onto the metaclasses of the Domain Model.
The Execution Data consist in attributes and references added to existing concepts (metaclasses) of the Abstract Syntax. They may also include new metaclasses which define the type of these new attributes and references.
The Execution Functions define how the Execution Data evolve during the execution of the model. Execution Functions can be implemented by defining the body of a method.
These methods must have the @Step annotation.
Whenever a method with an @Step annotation returns, the changes in the model will be applied (via a transaction) to the resource. This means that the changes will be visible from an animator.
The technology used be K3 with its @Step annotation allows nested call so that changes in the model will be applied when entering and leaving methods having this annotations.
Note
Any change to the model must be done by operations with the @Step annotation or that are called by an operation that have the annotation.
Defining the control flow between operation for the sequential engine is equivalent to write a Visitor where operations can call other operations. This is quite straightforward with K3 @Aspect annotation since the operations are directly weaved on the metaclasses and applied on the target model elements.
The sequential engines will use as entry point the methods having an @Main annotation. (see K3 documentation)
This annotation must be placed on operations applicable to the root model element.
Optionally, In the DSA, one of the method can be tagged with the @InitializeModel annotation. (see K3 documentation)
This method will be called before the engine starts and is typically used to fill the RunTime Data initial values using information provided by the user in the launch configuration.
The Domain-Specific Actions define the runtime state (Execution Data) of the model and the operations (Execution Functions) which modify the runtime state of the model.
In the GEMOC Studio, the DSA are implemented using Kermeta 3.
To create a new DSA Project, in the main menu of the GEMOC Studio, go to: File > New > Project… > K3 Project.
In the wizard, create it as a Plug-in with EMF using the template of your choice. Then, connect the xDSML Project to the DSA by referencing them in the .melange file thanks to the keyword with.
See Section 1.7, “Melange editor” for more informations about Melange keywords and the content assist.
Kermeta 3 is based on xTend. The Execution Data and Execution Functions are defined through aspects weaved onto the metaclasses of the Domain Model.
The Execution Data consist in attributes and references added to existing concepts (metaclasses) of the Abstract Syntax. They may also include new metaclasses which define the type of these new attributes and references.
The Execution Functions define how the Execution Data evolve during the execution of the model. Execution Functions can be implemented by defining the body of a method.
Note
For now, Execution Functions are considered as atomic, instantaneous and blocking. This means that any long computation will block the rest of the simulation, and concurrent Execution Functions are not executed in concurrence yet.
Warning
For technical reasons, the Domain Model (Ecore metamodel) must specify the signature of the Execution Functions as EOperations.
Optionally, in the DSA, one of the method can be tagged with the @InitializeModel annotation. (see K3 documentation) This method will be called before the engine starts and is typically used to fill the RunTime Data initial values using information provided by the user in the launch configuration.
It is possible to test the DSA (in particular the Execution Functions) by simply writing a simple program with a main function (using Java or Xtend/Kermeta3). Create or load a model conform to your Domain Model and call the Execution Functions in the right order to verify there are no runtime exceptions or domain issues.
In the GEMOC approach, the executability characterization for a given language is done through several steps that include: the description of the actions associated with the language concepts (i.e. the Executions Functions); the description of the data / attributes that capture the state of a model or its evolution (the Execution Data); the description of the underlying language model of concurrency (the MoCC constraints).
A Model of Concurrency and Communication (MoCC) represents the concurrency, synchronizations and the possibly timed causalities in the behavioral semantics of a language. It must represent the acceptable schedules of the atomic actions of the language, which represent both computation and communication.
In this part of the guide, we assume that achieving the first two points has already been done based on Section 2.1, “Defining the Domain-Specific Actions (DSA) Project for concurrent language”. In this part, we will mainly focus on the steps for the description and integration fo the model of concurrency in the language, once the EF and ED have been already taken into account and integrated to the language. The execution engine of the GEMOC Studio is based on an event-based semantics, which means that events are used to activate the EF actions that can change the state of a model.
To describe and integrate the model of concurrency, we must 1) have a description of the useful events allowing activation of the EF, 2) a mechanism to express the MoCC constraints that apply on these events.
To enable the automatic generation of the execution model of a given DSML model, the MoCC is weaved into the context of specific concepts from the abstract syntax of the DSML. This contextualization is defined by a mapping between the elements of the abstract syntax and the constraints of the MoCC (defined using MoCCML). Examples of mapping are shown below.
The mapping defined in MoCCML is based on the notion of event, inspired by ECL ECL Description, an extension of the Object Constraint Language OCL. The separation of the mapping from the MoCC makes the MoCC independent of the DSML so that it can be reused.
ECL models are created via files with the extension .ecl. The _xDSML environment enables the creation and / or opening of new ECL project Section 1, “xDSML project (TODO rename GEMOC Project)”.
In this section, we show an examplified way to use ECL. The required steps to go from a given language to the integration of its concurrency model are presented.
As shown in Listing ECL import example., an ECL file imports the extended language that contains the language metaclasses, the EF and ED. The ECL language defines the notion of import to import the extended metamodel (see import of dplExtended.ecore in Listing ECL import example.). The import is used to load all the concepts of language that are used to clarify: the EF activation events; static properties numeric or Boolean values, and constraints associated with concepts.
import "platform:/resource/org.eclipse.gemoc.model.dpl.dplextended/model/dplExtended.ecore"
The ECL model gives access to the concept of the language via the declaration of their package container. In the illustration below, the package container is dplextended. Every metaclass/ concept is declared as a context. In a given context, we define the mapping between events and actions and the MoCC constraints of the context. The illustration shows the definition and mapping of events associated with the concept of Philosopher. For the context Philosopher, the events are used to enable its actions ie eat() and think() actions. ECL syntax for declaring the mapping Event / Action is as follows:
-
Define the type of the event: def: think: Event
- When the event activate actions: the action associated to the event is accessed through the context via self.actionName() (e.g. in Listing ECL Context event declaration example. Philosopher self.think() and self.eat())
- When the event does not trigger an action i.e. used as internal control events : Its declaration does not mention any related action (e.g. getrightFork, getleftFork, putrightFork, putleftFork)
- Finally, we can define local attributes to capture the value of static properties that can be for instance integers or booleans (e.g. def: eatcycleMax: Integer = self.eatCycles) The above steps specify the declaration of events and attributes that are used to control the actions for each language concept. We can focus on the description of the model of concurrency defined using MoCCML.
ECL Context event declaration example.
package dplextended context Philosopher def: think : Event = self.think() def: getrightFork : Event = self def: getleftFork : Event = self def: eat : Event = self.eat() def: putrightFork : Event = self def: putleftFork : Event = self def: thinkcycleMax : Integer = self.thinkCycles def: eatcycleMax : Integer = self.eatCycles endpackage
The latter phase is done in two steps: the implementation of the execution control constraints with MoCCML; the use of these constraints in the context definition to specify how the events should be scheduled (determine their causalities).
This section presents the MoCCML editor that supports the edition of MoCC_s. To keep the defined models formal and to provide a solver for the _MoCC, an operational semantics and a solver based on this formal semantics were defined. For more information on the operational semantics the reader can refer to MoCCML Operational Semantics.
The MoCCML models are created via files with an .moccml extension. They are also natively created from the dashboard _xDSML, where you can create a MoCC project. The project defines an empty model _.moccml with just the name of the library to be created. For a graphical representation of the models, you have to right-click on the file (New Representation File) and run next until the creation of the _.aird representation. This procedure is described in the Sirius tutorial Sirius documentation and Sirius Specifier Manual to create new diagrams starting from a model whose graphical editor was made from Sirius.
MoCCML is a declarative meta-language specifying constraints between the events of a MoCC. At any moment during a run, an event that does not violate the constraints can occur. The constraints are grouped in libraries that specify MoCC specific constraints. The constraints are eventually instantiated to define the execution model of a specific model. The execution model is a symbolic representation of all the acceptable schedules for a particular model. MoCCML is based on the principle of defining constraints on events. There are two categories of constraint definitions: the Declarative Definitions and the Constraint Automata Definitions. Each constraint definition has an associated ConstraintDeclaration that defines the prototype of the constraint.
The concrete syntax of MoCCML is implemented as a combination of graphical and textual syntaxes to provide the most appropriate representation for each part of a MoCC model library. The graphical syntax can be divided into two levels of representation: one for the definition of the MoCC libraries (the declaration and definition of the automata constraints); another for the implementation of the constraints in the form of automata. For instance:
- The first level of representation contains elements as illustrated in Figure Figure 3, “Screenshot of the First graphical level of Edition in MoCCML.”. The represented model imports two CCSL libraries (kernel.ccslLib and CCSL.ccslLib). The imported libraries provide predefined types that are used to define formal parameters such as DiscreteClocks, Integers, etc. Each defined Relation Declaration is associated to a Automata constraint definition. The association is done through the Set Declaration Relation link.
- The second level of graphical representation defines the graphical syntax for the modeling of the Automata constraints.
- The overall MoCC models are serialized to a textual syntax, which means that the graphical models are transformed into their equivalent representation in a textual formal. Both representations (graphical or textual) can be used for edition of models. Moreover, we define the integration of an embedded textual editor in the graphical representation to focus on specific parts of the MoCC model that are better edited using a textual syntax (eg trigger, the guards and the actions on transitions). Embedded editors are called by double-clic, and are placed on specific graphical edition elements (Relation Declaration, Relation Definition, DeclarationBlock, Transition).
NB: MoCCML has multiple pallets to instantiate a library. The pallets are located on the right branch of the editor. The creation of new library is preceded by an import of the native CCSL libraries (kernel.ccslLib, CCSL.ccslLib) which provide primitives for the description of events and variables that are handled by the constraints in the MoCC library. We use the third pallet in Figure Figure 3, “Screenshot of the First graphical level of Edition in MoCCML.”to import such CCSL libraries.
As shown in Figure Figure 3, “Screenshot of the First graphical level of Edition in MoCCML.”, creating new MoCC libraries can be done by using the first two pallets on the right (Library Edition, New Library & Required Feature). In these pallets, the element (Library New Library + New Relationship and Relationship) can be used for the instantiation of a new MoCC library. The two are distinguished by the fact that the last mentioned will create a new library of MoCC, while adding a default Relation Declaration. In Figure Figure 3, “Screenshot of the First graphical level of Edition in MoCCML.” we create a new Library called RendezVous_Relations.
In a MoCC library, we define constraints and their declarations. The declarations identify events and parameters to be considered in the implementation of the constraint. In the editor, the declaration is made using the two above mentioned pallets, and using the elements in the pallets i.e.: New Relationship Declaration and New Relationship Declaration +. The two differ in that the latter creates a Relation Declaration with a default formal parameter declaration. In the Figure Figure 3, “Screenshot of the First graphical level of Edition in MoCCML.”, we create two relation declarations (ForkConstraintDecl and PhilosopherConstraintDecl). Listing ??? also shows the equivalent textual code generated for the PhilosopherConstraintDecl.
RelationDeclaration PhilosopherConstraintDcl( pthink : clock, grfork : clock, glfork : clock, peat : clock, prfork : clock, plfork : clock, thinkCyc:int, eatCyc:int )
The implementation of constraints can be specified textually or graphically. Graphically, the first two pallets are used to create new definitions of constraints associated with their declarations. Constraint definitions is done using the menu items (New Automata Definition and New Automata Definition +). In Figure Figure 3, “Screenshot of the First graphical level of Edition in MoCCML.”, the following constraints are specified: ForkConstraintDef, PhilosopherConstraintDef). At this stage, we toured the main notions that can be set on the first level of graphical description with MoCCML. To navigate in the second level of graphical description (Constraint implementation), one should right-click on a specified constraint definition using (Open Diagram / New Diagram). Open Diagram will navigate to an existing diagram; New Diagram will create a new diagram to edit. The MoCCML Editor offers 3 different pallets for: editing the automata, defining the local variables and editing the transitons (ie adding Trigger, Guard, Actions). Figure Figure 4, “Screenshot of the Second graphical level of Edition in MoCCML (Constraint Implementation).” shows a simple example with two control states. An additional Layer displays the details of the transitions (Trigger, Guard, Action) as shown in Figure Figure 4, “Screenshot of the Second graphical level of Edition in MoCCML (Constraint Implementation).”, see yellow boxes. Besides, editing DeclarationBlock boxes and details in Transitions can be done using embedded text editor by double-clicking on the related boxes. We can then edit the properties of transitions and local variables textually.
One can define the desired set of constraints on the concepts of language using the MoCCML editor. To see the text code corresponding to the serialization of the edited MoCC models, the user can open the _.moccml file. Editing can also be directly made from this file and all the changes will be reflected in the graphical editor. The use of constraints is shown in the next section.
Figure 4. Screenshot of the Second graphical level of Edition in MoCCML (Constraint Implementation).
The MoCC constraints models can be used in the ECL file on concepts which they are attached. To declare the constraint on the events, we re-declare the context of the concept then define an invariant inv, see Listing ???. In this listing we also import the MoCCML library that was defined previously (i.e. rendez_vous.moccml) For instance, the invariant related to the context Philosopher (PhilosopherConstraintInv) uses the PhilosopherConstraintDef via its PhilosopherConstraintDcl declaration? It takes as input the set of control events and static variables used to calculate the causality between events.
ECLimport "platform:/resource/org.eclipse.gemoc.dpl.xdsml.mocc.model/mocc/rendez_vous.moccml" ECLimport "platform:/plugin/fr.inria.aoste.timesquare.ccslkernel.model/ccsllibrary/kernel.ccslLib" ECLimport "platform:/plugin/fr.inria.aoste.timesquare.ccslkernel.model/ccsllibrary/CCSL.ccslLib" package dplextended context Philosopher def: think : Event = self.think() def: getrightFork : Event = self def: getleftFork : Event = self def: eat : Event = self.eat() def: putrightFork : Event = self def: putleftFork : Event = self def: thinkcycleMax : Integer = self.thinkCycles def: eatcycleMax : Integer = self.eatCycles context Philosopher inv PhilosopherConstraintInv: Relation PhilosopherConstraintDcl( self.think, self.getrightFork, self.getleftFork,self.eat, self.putrightFork, self.putleftFork, self.thinkcycleMax, self.eatcycleMax ) endpackage
[8] asciidoc source of this page: https://github.com/eclipse/gemoc-studio/tree/master/docs/org.eclipse.gemoc.studio.doc/src/main/asciidoc/userguide/lw_MakeLaguageExecutable_headContent.asciidoc.
[9] asciidoc source of this page: https://github.com/eclipse/gemoc-studio-modeldebugging/tree/master/java_execution/java_xdsml/plugins/org.eclipse.gemoc.execution.sequential.javaxdsml.ide.ui/docs/asciidoc/user_lw_MakeK3SequentialExecutableLanguage.asciidoc.
[10] asciidoc source of this page: https://github.com/eclipse/gemoc-studio/tree/master/docs/org.eclipse.gemoc.studio.externaltools.doc/src/main/asciidoc/ccsljavaxdsml/user_lw_MakeCCSLJavaConcurrentExecutableLanguage.asciidoc.