Domain-specific languages (DSLs) are an important tool for effective system development. They provide concepts that are close to the problem domain and allow analysis as well as generation of full solution implementations. However, this comes at the cost of having to develop a new language for every new domain. To make their development efficient, we must be able to construct DSLs as much as possible from reusable building blocks. In this paper, we discuss how such building blocks can be constructed for the specification and analysis of a range of non-functional properties, such as, for example, throughput, response time, or reliability properties. We assume DSL semantics to be provided through a set of transformation rules, which enables a range of analyses based on model checking. We demonstrate new concepts for defining language modules for the specification of non-functional properties, show how these can be integrated with base DSL specifications, and provide a number of syntactic conditions that we prove maintain the semantics of the base DSL even in the presence of non-functional–property specifications.
Here we describe in detail the two ATL transformations that are part of our current prototype implementation (further details can be found in our paper On the Reusable Specification of Non-functional Properties in DSLs ). It is aimed at complementing the documentation already available within both ATL files. Consequently, the documentation presented here is better understood if the reader has taken a look at the code in both transformations.
As explained in the paper, these transformations aim to weave a DSL meta-model with an (o more than one) observer meta-model, and the behavioural semantics of the DSL (composed by a set of e-Motions  behavioural rules) with the behavioural semantics of observers (also composed by a set of behavioural rules). The general schema of both transformations is shown in Figure 1, it will be explained through this document.
In the remainder of this documentation, we illustre our approach by using the specific example presented in .
Figure 1 - Transformations schema
Weaving the meta-models
Let us start with the presentation of the meta-models to weave. The DSL meta-model is aimed at specifying production-line systems. It is shown in Figure 2. For observers, we are focusing here in response time, a generic non-functional property applicable to different domains. In the concrete DSL of our example, we will want to use that concept to calculate production time of machines. Its meta-model, shown in Figure 3, is a parametric model (i.e., a model template) where the concepts of Server, Queue, and Request and their inter-connections are parameters of the meta-model, and they are shaded in grey for illustration purposes. We use them to describe in which situations response time can be specified, and these concepts are then to be mapped to concrete concepts in a specific DSL. In our case, we map them to our production-line system.
Figure 2 - Production-line (DSL) meta-model
Figure 3 - Response time (observer) meta-model
Specifying correspondences among meta-models
In order to specify the correspondences between the two meta-models presented, we define them conforming to a Correspondences meta-model (Figure 4). It means that the correspondences between the meta-models are defined in a model (for this prototype, we create such model with the tree-view from Eclipse, although for future versions we plan to develop a graphical DSL for this purpose). For now, we focus on the left-hand side of the meta-model, where we define the bindings among DSL and observer meta-models, and we leave its right-hand side for when we explain the bindings among rules.
Figure 4 - Correspondences meta-model
We will have an object of type MMMatching for each pair of meta-models that we want to weave. In this case we are only weaving the production-line meta-model (Figure 2) with the ResponseTime meta-model (Figure 3), so we only need one object of this type. The attribute obMMName contains the name of the meta-model with the observer, whereas the DSLMMName attribute contains the name of the DSL meta-model.
The objects of type ClassMatching specify the correspondences between the classes in both meta-models. Attribute obName contains the name of the class (EClass according to the Ecore meta-model – see Appendix A) in the observer meta-model, whereas DSLName contains the name of the class in the DSL meta-model. We will have three objects of this type in our example, relating Server with Assemble, Queue with LimitedContainer, and Request with Part. Regarding the objects of type RefMatching, they contain the correspondences between references. Attributes obRefName and DSLRefName contain the names of the references (EReference according to the Ecore meta-model – see Appendix A) in the observer and DSL meta-models, respectively, that are to be woven. Attributes obClassName and DSLClassName store the name of the source classes for both references. In our example, we have three objects of this type, whose attributes are, in the same order as they appear in the LinkMatching class, [Server, in, Machine, in], [Server, out, Machine, out] and [Queue, reqsts, Container, parts].
Given the described correspondences among classes and references, the woven meta-model should be that of Figure 5 (notice that the added part has been shaded). The ATL transformation that generates such meta-model is explained next.
Figure 5 - Woven meta-model
The file WeaveMetaModels.atl contains the ATL transformation that weaves the DSL and observer meta-models. As mentioned above, in this prototype we have a production-line and a response time meta-models. The inputs of the transformation are the production-line meta-model (INDSLMM:DSLMM – MMDSL in Fig. 1), which conforms to Ecore; the GCS representation (concrete syntax) of the classes in the production-line (INDSLGCS:DSLGCS - GCSDSL in Fig. 1), which conforms to the GCS meta-model; the observer meta-model (INObsMM:ObsMM - MMObs in Fig. 1), conforming to Ecore; the GCS representation (concrete syntax) of the response time observer (INObsGCS:ObsGCS - GCSObs in Fig. 1), conforming to the GCS meta-model; and the model with the meta-models and rules binding (INCorresp:CorrespMM - BMM in Fig. 1), conforming to the meta-model shown in Figure 4.
As explained in detail in , in e-Motions the concrete syntax of the concepts of a meta-model (GCS file) points to the file containing the meta-model (Ecore file). For this reason, from this transformation we want to get the meta-model with the weave of the production-line and response time meta-models (OUTMM:WeaveMM), which conforms to Ecore, as well as its concrete syntax (OUTGCS:WeaveGCS), conforming to the GCS meta-model. These two files, consequently, are the outputs of the WeaveMetaModels.atl transformation (see Output 1 in Figure 1). This is the reason why we need as input in our transformation the GCS files with the concrete syntax of both input meta-models.
Before going through each part of the transformation, let us set its context. In the process of weaving the DSL and observer meta-models, we want to merge together those classes and references from both meta-models whose correspondences are specified in the correspondence model. Since all the concepts present in the observer meta-model represent parameters, except those describing the actual observers and their references, merging together both meta-models means that the concepts in the DSL meta-model will prevail over those parametric concepts in the observer meta-model. In our example, Assemble will prevail over Server, LimitedContainer over Queue, Part over Request¸ and the same for their references (as can be seen in Figure 5). Taking this into account and regarding the output woven meta-model, we could think of a transformation where the input DSL meta-model would act as well as output of the transformation, and we simply need to decorate that meta-model with those concepts in the observer meta-model representing observers. However, the input models of an ATL transformation are only readable, and the output models are only writable. It means that we cannot edit input models. Having this in mind, we explain the WeaveMetaModels.atl transformation by describing in detail each of its three parts:
1. Rules for copying the DSL meta-model. This first block of the transformation deals with the copy of the DSL input meta-model (INDSLMM:DSLMM) into the output meta-model (OUTMM:WeaveMM). It is done in order to decorate the output meta-model afterwards, concretely, in the third part of the transformation. We need to copy every concept in the Ecore meta-model: EClass, EAttribute, EReference, EDataType, EParameter, EOperation, etc.
2. Rules for copying both the DSL and observer GCS models. This block merges both the input GCSDSL model (INDSLGCS:DSLGCS) and input GCSObs model (INObsGCS:ObsGCS) into the output woven GCS model (OUTGCS:WeaveGCS). This part is composed of three rules. The first of them, CopyPackagesGCS, creates the package that will contain the output GCS model. It acquires its properties, such as its name, from the input GCSDSL model, since this one prevails over the GCSObs. The second rule, CopyClassesGDDSL, copies the DSL classGDs, which contain the information about the concrete syntax of the meta-model concepts as well as the references to the actual classes in the meta-model, in the output GCS model. The class attribute, which has to point to the class in the output meta-model (OUTMM:WeaveMM), is retrieved by the ATL engine by searching for it in the traceability links. The class it looks for should have been created before by the CopyClasses rule in the first block. The third and last rule, CopyClassesGDObs, copies the observer ClassGDs of those classes representing non-functional properties. To find those classes, it checks that the class name is not equal to any obName attribute in any ClassMatching class in the correspondence meta-model. To retrieve the class in the output meta-model to which the created ClassGD has to point, we make use of the CreateNonFunctionalClass lazy rule, explained in the third block of the transformation.
3. Rules for creating references, classes and attributes of non-functional properties. This part of the transformation looks for those classes, references and attributes in the observer meta-model which represent non-functional properties, and copies them in the output meta-model. The main rule, CreateObserverOnlyReference, creates, in the output meta-model, those EReferences that point to a non-functional class in the observer meta-model. In order to do it, the from part of the rule looks for those references in the observer meta-model that do not have a correspondence in the correspondence meta-model (they are not present in any object of type RefMatching) and creates an EReference in the output meta-model with the same properties except for two of them: the class to which the reference points, established by the eType attribute, and the source class of the reference. The former class is created by means of the CreateNonFunctionalClass unique lazy rule, since it can happen that two EReferences point to the same non-functional class in the observer meta-model, but the class has to be created only once in the output meta-model. To assign the source class of the reference, we cannot use the eContainingClass property of the EReference since it is non changeable, so we look in our global variable that contains all the classes created (thisModule.classes) for the appropriate one and assign the EReference created as one of its eStructuralFeatures (the reference between EReference and EClass with the endpoints eContainingClass and eStructuralFeatures in Ecore is bidirectional—see the Ecore meta-model in Appendix A). The unique lazy rule CreateNonFunctionalClass receives an EClass representing a non-functional property of the observer meta-model and creates that class in the output meta-model. The first call to this rule will create the class, and the remaining times it will return the class created the first time (this is the purpose of unique lazy rules in ATL). In order to assign the EAttributes of the class created, we get the eStructuralFeatures of the input class. The ATL engine will look in the traceability links for those structural features created in the CreateNonFunctionalAttribute rule from those of the input class. This last rule looks for EAttributes whose containing classes do not have a correspondence (so that the class is a class representing a non-functional property) and create the same attribute in the output meta-model. The containing classes for the created attributes will be those created by the CreateNonFunctionalClass unique lazy rule.
Input and Output Files
As detailed within the transformation, the input and output files for it are the following:
OUTMM : WeaveMM --> Meta-model resulting of the weave between INDSLMM:DSLMM and INObsMM:ObsMM. It conforms to Ecore. The Ecore meta-model is taken from the EMF registry and the resulting model is stored in WeaveModels/WeaveMetamodels/OUTWeaveMM.ecore
OUTGCS : WeaveGCS --> Meta-model resulting of the weave between INDSLGCS:DSLGCS and INObsGCS:ObsGCS. It conforms to the GCS meta-model. The GCS meta-model is in SLE12/Metamodels/GCS.ecore and the resulting model is stored in WeaveModels/WeaveMetamodels/OUTWeaveGCS.gcs
INDSLMM : DSLMM --> Meta-model of the DSL. It conforms to Ecore. The Ecore meta-model is taken from the EMF registry and the DSL meta-model is taken from PLS/Metamodel/DEVSMM.ecore
INDSLGCS : DSLGCS --> GCS model of the DSL. It conforms to the GCS meta-model. The GCS meta-model is in SLE12/Metamodels/GCS.ecore and the GCS model is taken from PLS/Behavior/DEVSgcs.gcs
INObsMM : ObsMM --> Meta-model of observers. It conforms to Ecore. The Ecore meta-model is taken from the EMF registry and the observers meta-model is taken from SLE12/Metamodels/RespTimeMM.ecore
INObsGCS : ObsGCS --> GCS model of the observers. It conforms to the GCS meta-model. The GCS meta-model is in SLE12/Metamodels/GCS.ecore and the observers GCS model is taken from SLE12/GCSs/RespTimeMM.gcs
INCorresp : CorrespMM --> Model with the correspondences. It conforms to the CorrespondencesMM meta-model. The CorrespondencesMM meta-model is at SLE12/Metamodels/CorrespondencesMM.ecore and the model is at SLE12/Models/PLSCorrespondences.xmi
Weaving the rules
Now we present how we weave DSL rules with observer rules. In our example, we have applied this weave to merge the Assemble rule (DSL rule, Figure 6) with the RespTime rule (observer rule, Figure 7). The Assemble rule shows how a new hammer is assembled. In the rule, a hammer generator a has an incoming tray of parts and is connected to an outgoing conveyor belt. Whenever there is a handle and a head available, and there is space in the conveyor for at least one part (specified by an OCL constraint in the LHS of the rule), the hammer generator can assemble them into a hammer. The new hammer is added to the parts set of the outgoing conveyor belt. The RespTime rule is an example of a transformation rule defining the semantics of the response time observer. It states that if there is a server with an in queue and an out queue and there is initially at least one request in the in queue, and the out queue contains some requests (at least 1) after the rule execution, the last response time should be recorder to have been equal to the time it took the rule to execute (in the range [a.pt – 3, a.pt + 3]). Similar rules need to be written to capture other situations in which response time needs to be measured, for example, when a request stays at a server for some time, or when a server does not have an explicit in or out queue. Note that this rule looks different from the Assemble rule. This is because the RespTime rule is actually a rule transformation, while Assemble rule is a transformation rule. The upper part of Figure 7 (shaded in grey for illustration purposes) is a pattern or query describing transformation rules that need to be extended to include response-time accounting. The lower part describes the extensions that are required. So, in addition to reading Fig. 7 as a “normal” transformation rule, we can also read it as a rule transformation stating: “Find all rules that match the shaded pattern and add ResponseTime objects to their left and right-hand sides as described”. In effect, observer models become higher-order transformations. In this prototype, however, we consider that the ResponseTime rule is defined as an e-Motions rule and the binding between the two rules are specified as explained in the next section.
Figure 6 - Assemble (DSL) rule
Figure 7 - RespTime (observer) rule
Specifying correspondences among rules
In order to specify the correspondences between rules, we define them conforming to the Correspondences meta-model shown in Figure 4. Now we focus on the right-hand side of this meta-model.
We will have an object of type RuleMatching for each pair of rules that we want to weave. Notice that we can weave the same observer rule with more than one DSL rules. In this prototype we are only weaving the Assemble rule (Figure 6) with the RespTime rule (Figure 7), so we only need one object of this type. It is given fresh variables, N and M, to the duration in the observer rule, so that in the weave N and M get instantiated with the duration of the DSL rule. The attribute obRuleName contains the name of the observer rule, whereas the DSLRuleName attribute contains the name of the DSL rule.
The objects of type ObjectMatching specify the correspondences between the objects in both rules (the elements that appear in the rules are of type Object conforming to the Behavior meta-model  – see Appendix B). Attribute obName contains the id of the object in the observer rule, whereas DSLName contains the id of the object in the DSL rule. Notice that an object of type RuleMatching may contain objects of type ObjectMatching according to two references, lhsObjs and rhsObjs. This is because we differentiate between the correspondences among the objects in the left-hand side and right-hand side of rules, what facilitates the definition of the ATL transformation presented later. Our object of type RuleMatching contains five objects with the reference lhsObjs and four of them with the reference rhsObjs. The former are [r,he], [r,ha], [i,t], [s,a] and [o,c]; while the latter are [i,t], [s,a], [o,c] and [r, ham].
Regarding the objects of type LinkMatching, they contain the correspondences between links (in the Behavior meta-model, the references among objects within the rules are of type Link, which are instances EReferences in the Ecore meta-model). We also differentiate between the correspondences between LHS and RHS of rules. Attributes obLinkName and DSLLinkName contain the names of the EReferences in the observer and DSL meta-models, respectively, that are to be woven (they are also the name of the Link objects in the Behavior model). Attributes obObjName and DSLObjName store the id of the source objects for both links. In our example, the object of type RuleMatching contains four objects with the reference lhsLinks and three of them with the reference rhsLinks. The former are [i, reqsts, t, parts], [i, reqsts, t, parts], [s, in, a, in] and [s, out, a, out]; while the latter are [s, in, a, in], [s, out, a out] and [o, reqsts, c, parts].
Given the described correspondences between classes and references, the weaving rule should be that of Figure 8.
Figure 8 - Woven rule
The file WeaveBeh.atl contains the ATL transformation that weaves DSL and observer rules. As mentioned above, in this prototype we have an Assemble and a RespTime rules that we want to weave (apart from the remaining DSL rules, which are also inputs of the transformation). The inputs of the transformation are the DSL and observer set of behavioural rules (INDSLBeh:DSLBeh and INObsBeh:ObsBeh – RlsDSL and RlsObs in Fig. 1 ), which conform to the Behavior meta-model (see Appendix B); the woven GCS model result of the WeaveMetaModels.atl transformation (INWeaveGCS:WeaveGCS), conforming to the GCS meta-model; the woven meta-model result of the WeaveMetaModels.atl transformation (INWeaveMM:WeaveMM), which conforms to the Ecore meta-model; and the model with the correspondences (InCorresp:CorrespMM, BRls in Fig. 1), conforming to the meta-model shown in Figure 4.
The output of the transformation, OUT:WeaveBeh, is a model, which conforms to the Behavior meta-model, containing a set of behavioural rules. That set of rules contains all those DSL rules that do not have any correspondence with any observer rule, plus the woven rules resulting from the merge of DSL and observer rules as specified by the correspondence model. In our prototype, the set of rules contains all those rules of the production-line system plus the woven Assemble-RespTime rule. The transformation is composed of three blocks that we explain below:
1. Rules for copying the behavioural rules of the DSL. As we did in the WeaveMetaModels.atl transformation, the first block here deals with the copy of all the DSL behavioural rules (and their contained elements) into the output behavioural model. This block also contains an entrypoint rule, where we establish the package that will contain the behavioural rules. Such package has a reference to the woven GCS model (INWeaveGCS:WeaveGCS), what makes that the objects in the rules created appear with their concrete syntax. Many elements are to be copied in this block, namely AtomicRule, OngoingRule, Helpers, Variables, Patterns, ActionExec, etc. When copying Objects, their reference to the class they belong, given by its attribute classGD, has to point to that class in the input woven GCS model. As for Links, they contain an attribute, ref, that has to point to the actual EReference in the input woven meta-model.
2. Rules for including observer objects and links in those rules having correspondences. This part aims to complete those rules created in the first block that need the inclusion of observers. In our example, it will decorate the rule in Figure 6 so that it becomes the rule in Figure 8. To do that, we need the information about the observer rule (Figure 7) and the correspondences between the rules in Figure 6 and 7. Rules CreateObserversLHS and CreateObserversRHS do basically the same, but the former decorates the LHS of a rule while the latter decorates its RHS. This distinction eases the organization of the transformation and allows us to consider those cases where an observer only needs to be added in one of the two patterns: if the observer object is only in the LHS, it means that it will disappear after the rule execution; if it is only in the RHS, it means that it did not exist before but it will be added to the system after the execution of the rule. Whenever the CreateObserversLHS rule is fired, it inserts in the LHS of the rule created from the DSL rule (rDSL in the transformation) an observer object and a link going from an existing object in the rule to the observer created. Regarding the link created, most of its properties are copied from the link in the observer rule that goes from a parametric object, which has a correspondence with a concrete object in the DSL rule, to the observer. Regarding the ref attribute, which points to the actual EReference in the meta-model, we look for the appropriate EReference in our woven input meta-model (INWeaveMM:WeaveMM). As for the object created, its classGD has to point to the corresponding class in the input GCS model. Objects, especially in the RHS of a rule, may contain slots. To create slots in the observers created, we use the ATL collect() operation to create slots from those slots of the observer in the observer rule. Lazy rule CreateSlot deals with the creation of such slots. An important consideration here is the creation of slots that have to refer to the time elapsed. As can be seen in Figure 7, those slots will be given the value time in observer rules. Then, in the woven rule and with the inclusion of the clock object (clk), the value of the slot has to be clk.time. We take that into account in our CreateSlot rule.
3. Rules for including clocks in the woven rules. Since the majority of the observers require using the time elapsed in the system, we add the clock object in all those woven rules where it was not already included.
Input and Output Files
As detailed within the transformation, the input and output files for it are the following:
OUT : WeaveBeh --> Behavior rules resulting of the weave between INDSLBeh:DSLBeh and INObsBeh:ObsBeh. It conforms to the Behavior meta-model, taken from SLE12/Metamodels/Behavior.ecore and the resulting model is stored in WeaveModels/WeaveBehavior/OUTWeaveBeh.behavior
INDSLBeh : DSLBeh --> Behavioral rules of the DSL. It conforms to the Behavior meta-model, which is taken from SLE12/Metamodels/Behavior.ecore and the DSL behavior is taken from PLS/Behavior/DEVSBehavior.behavior
INObsBeh : ObsBeh --> Behavioral rules of observers. It conforms to the Behavior meta-model, taken from SLE12/Metamodels/Behavior.ecore and the observe behavior is taken from SLE/Behaviors/RespTimeBeh.behavior
INWeaveGCS : WeaveGCS --> GCS model of the weave meta-model result of the WeaveMetaModels.atl transformation. It conforms to the GCS meta-model. The GCS meta-model is taken from SLE12/Metamodels/GCS.ecore and the GCS model is taken from WeaveModels/WeaveMetaModels/OUTWeaveGCS.gcs
INWeaveMM : WeaveMM --> Weave Meta-model result of the WeaveMetaModels.atl transformation. It conforms to Ecore. The Ecore meta-model is taken from the EMF registry and the woven meta-model is taken from WeaveModels/WeaveMetaModels/OUTWeaveMM.ecore
INCorresp : CorrespMM --> Model with the correspondences. It conforms to the CorrespondencesMM meta-model, which is taken from SLE12/Metamodels/CorrespondencesMM and the correspondences model is taken from SLE12/Models/PLSCorrespondences.xmi
The Eclipse project containing the transformations can be found here. Three different projects can be found within it:
- PLS. It contains the original implementation of the production-line system behavioural specification, without the use of observers. This project contains files that act as inputs for the transformations, such us the production-line metamodel (available in PLS/Metamodel/DEVSMM.ecore) or the model with the behavioural rules (PLS/Behavior/DEVSBehavior.behavior).
- SLE12. This project contains files created specifically for this work. It contains many files which are inputs for the transformations, such as the response time (observer) meta-model (SLE12/Metamodels/RespTimeMM.ecore), the response time behavioural model (SLE12/Behaviors/RespTimeBeh.behavior) or the correspondences meta-model and model (SLE12/Metmaodels/CorrespondencesMM.ecore and SLE12/Models/PLSCorrespondences.xmi).
- WeaveModels. It is an ATL project containing the two transformations as well as the outputs of such transformations. Within each transformation, the path of the input and output files is detailed.
Both transformations have been developed with Eclipse Indigo, so they must be executed with such Eclipse version. In order to visualize the GCS and Behavior files, both inputs and outputs in the transformations, we have to switch of Eclipse environment and open one containing the e-Motions pluggin (it has to be a Ganymede version). Documentation on how to download e-Motions can be found here.
 Durán, F., Zschaler, S., Troya, J.: On the Reusable Specification of Non-functional Properties in DSLs. Submitted (2012)
 Rivera, J.E.: On the Semantics of Real-Time Domain Specific Modeling Languages, PhD thesis, University of Malaga (2010)