/
MDL

MDL

Downloads

MDL can be obtained presently from a git repository only. In future, we will provide pre-compiled eclipse extensions.

Anonymous read-only access (cloning via HTTP takes a while, so please be patient!):

git clone http://build.se.informatik.uni-kiel.de/de.cau.se.measure.definition.language.git

Read/write access:

git clone git@build.se.informatik.uni-kiel.de:de.cau.se.measure.definition.language

Basic Grammar Structure

The basic structure of the grammar can be divided in fifth sections. First, the obligatory grammar header which imports usual terminal symbols for numbers, identifiers, strings and comments, followed by the used or generated meta-models and the grammar top and import rules. Second, the type system for MDL. Third, the measure definition rules. Fourth, the heart of the expression syntax. And fifth, some additional terminal symbols.

 

  • languages/MDL/Grammar/Expressions
  • languages/MDL/Grammar/FileHeader
  • languages/MDL/Grammar/MeasureDefinition
  • languages/MDL/Grammar/Terminals
  • languages/MDL/Grammar/Typing

Expressions

Expressions in MDL are used to define queries to refine a scope specified by a class of the application meta-model? (AMM). They address the features #5 and #6.

The expression grammar can be divided in several parts. First, it provides boolean operations, compare operations, unary operations and operations for simple calculations, which form the basic structure of an expression. Second, it provides logical quantors and conditional expressions. Third, it provides rules to describe property and method selectors. And fourth, it provides auxiliary rules for built-in functions and nested expressions.

Rules for the Basic Structure of Expressions

Expression: AndExpression ( ({Expression.left=current} operator='||') right=Expression)? ; 
AndExpression returns Expression: RelationalExpression ( ({Expression.left=current} operator='&&') right=AndExpression)? ; 
RelationalExpression returns Expression: AdditiveExpression ( ({Expression.left=current} operator=OpCompare) right=AdditiveExpression)?; OpCompare: '>=' | '<=' | '>' | '<' | '==' | '!=' ; 
AdditiveExpression returns Expression: MultiplicativeExpression (({Expression.left=current} operator=OpAdd) right=AdditiveExpression)?; OpAdd: '+' | '-'; 
MultiplicativeExpression returns Expression: UnaryOperation (({Expression.left=current} operator=OpMulti) right=MultiplicativeExpression)?; OpMulti: '*' | '**' | '/' | '%'; 
UnaryOperation returns Expression: {UnaryOperation} operator=OpUnary operand=PrimaryExpression | PrimaryExpression; OpUnary: "!" | "-" | "+"; 
PrimaryExpression returns Expression: Literal | IfExpression | ForAllExpression | ExistsExpression | FunctionCall | ValueExpression | ParenthesizedExpression; 

Quantors and Conditional Expressions

The MDL scope expression language provides a conditional expression to control the evaluation of parts of an expression, and the forall and exists quantors used to conclude over sets and properties of their elements.

The semantic of the IfExpression is, that the condition is evaluated first. If it is true, the then-expression is evaluated. If it is false, the else-expression is evaluated.

Constraint: The expression for the condition must therefore be a boolean expression.

Constraint: The expressions for then and else must conform to the type context established by the outer scope of the expression.

IfExpression returns Expression: {IfExpression} 'if' '(' condition=Expression ')' then=Expression ('else' else=Expression); 

The behavior of the ForAllExpression is to return true if all elements of a collection are true, or, if specified, the given expression for each collection value is true. The collection is specified by a Collection rule.

Constraint: The expression to evaluate is optional. If such an expression is given, it must return a boolean value for each given collection member.

Constraint: If no expression is given, the collection must contain boolean values.

ForAllExpression returns Expression: {ForAllExpression} 'forall' '(' collection=Collection ('|' evaluate=Expression)? ')' ; 

The behavior for the ExistsExpression is to return true if at least one element of an collection is true, or, if specified, the given expression for one collection value is true. The collection is specified by a Collection rule.

Constraint: The expression to evaluate is optional. If such an expression is given, it must return a boolean value for each given collection member.

Constraint: If no expression is given, the collection must contain boolean values.

ExistsExpression returns Expression: {ExistsExpression} 'exists' '(' collection=Collection ('|' evaluate=Expression)? ')' ; 

The Collection rule is used for both quantors in the same way. It declares a name for the local scope of the expression. This name is then used in the evaluation-expression of the quantors to identify a single collection member.

Constraint: The collection must reference a value expression which resembles a collection of some kind.

Constraint: A collection must always contain objects of the same type. However, objects of subtyped classes are also allowed complying to OOP semantics.

Collection: name=ID 'in' collection=ValueExpression ; 

Property and Method Selectors

Scope expressions must be able to select properties and methods of the class specified to be the base for the scope. Furthermore, they must be able to navigate references to other classes of the application meta-model?. The ValueExpression realizes the chain of references in form of a tree. The left-side of each branch contains a reference, while the right side contains the next ValueExpression-node.

The scope for the base-reference are properties (ecore::EStructuredFeature) of the class referenced by the parent's ValueExpression base-reference. For the left most (or top most) reference the scope is defined by the ecore::EClassifier of the ModelType-node.

ValueExpression: base=ValueElement ('.' child=ValueExpression)? ; 

Select scope for properties

The above image shows the lookup chains for the left most reference, which context is the ecore::EClassifier of the ModelType-node. While the others use the type (and classifier) of previously resolved references.

Constraint: As the grammar does not distinguish between ecore::EReference and ecore::EAttribute, this must be done by a check, as attributes do not have an valid ecore::EClassifier.

Beside references, an value expression can use built-in methods to reflect on the type of a value. Furthermore, operations of the meta-model can be accessed. Therefore, the ValueExpression does not allow only References, but, through the following rule, also OperationCalls and ReflectionCalls.

ValueElement: Reference | OperationCall | ReflectionCall ; 

A Reference references an ecore::EStructuralFeature and uses the ID of that feature as lookup value. While references might point to collections, or collections of collections, the elements of an collection can be addressed by a selection expression.

Constraint: The Expression for the selection of one member of a collection must be a positive numerical value for simple collections or a key of the right type, if the collection is a map of some sort.

Reference: reference=[ecore::EStructuralFeature|ID] ('[' selections+=Expression ']')* ; 

An OperationCall is used to access operations provided by the meta-model for the type of the local typing context. The operation can have 0 or more parameters, which required suitable values.

Constraint: The validity of the operation parameters must be checked on the basis of the parameters provided by the ecore::EOperation instance. Therefore, the type of each parameter expression has to be determined.

OperationCall: operation=[ecore::EOperation|ID] '(' (parameterAssignments+=Expression (',' parameterAssignments+=Expression)*)? ')' ; 

MDL supports also methods to handle reflection on selector expressions. At present two methods are defined: isTypeOf and isKindOf. They provide the functionality of the reflection methods of OCL. Therefore, isKindOf returns true, if the instance has the given type, or the type of the instance is a subtype of the given type.

Constraint: The classifier should be part of the same meta-model as the reference written left of it. Otherwise it will always be false.

ReflectionCall: reflectionType=ReflectionType '(' type=[ecore::EClassifier|ID] ')' ; enum ReflectionType: IS_TYPE_OF = 'isTypeOf' | IS_KIND_OF = 'isKindOf' ; 

Auxiliary Rules for Expressions

ParenthesizedExpression returns Expression: '(' Expression ')' ; 
FunctionCall: function=FunctionName '(' (parameterAssignments+=Expression (',' parameterAssignments+=Expression)*)? ')' ; FunctionName: ABS = 'abs' | FLOOR = 'floor' | CEIL = 'ceil' | SIZE = 'size' ;

File Header

Grammar Preamble

The typical Xtext grammar header defines the grammar name and the include of the standard set of terminals for numbers, strings, identifies and comments. Furthermore, it states that the grammar has its own meta-model and imports Ecore for EMF structures. There are no SMM model elements present in the grammar. The SM is filled by a transformation.

grammar de.cau.cs.se.measure.definition.language.MeasureDefinitionLanguage with org.eclipse.xtext.common.Terminals generate definition "http://se.cs.cau.de/languages/MeasureDefinitionLanguage" import "http://www.eclipse.org/xtext/common/JavaVMTypes" as types import "http://www.eclipse.org/emf/2002/Ecore" as ecore 

Grammar Service Structure

The main rule of the grammar, Model, aggregates all the necessary information. The library name should be compatible to the project structure in Eclipse where the MDL file is used. However, the tool does not force the name to be matched to the projects package structure.

The imports are not really useful at the moment. Their intention is to incorporate Java-types into the measure definition model when necessary. This would, however, exclude other target languages and suits no real purpose, because the type system is based on the EMF type system or any other type system introduced by included meta-models. These meta-models are introduced with the MetaModel rule. As SMM uses units together with classic types. This results in the problem that classic types cannot be used direct in MDL. Therefore, types must be imported which is done with MeasureType mappings. Finally, the Model rule allows the definition of measures.

Model: 'library' name=QualifiedName (imports+=Import)* (metamodels+=MetaModel)+ (types+=MeasureType)+ (measures+=Measure)+ ; 

Note The import rule might be removed in future.

Import: 'import' (importedType=[types::JvmType|QualifiedName] | importedNamespace=QualifiedNameWithWildcard) ; 

Meta-models are introduced to the measure definition with the MetaModel rule. The rule assigns meta-models, or to be precise, packages to an unique name.

MetaModel: 'model' name=ID package=[ecore::EPackage|STRING] ; 

Example

The following example is taken from the MENGES project. It includes two foreign meta-models. The ecore model is later used to define data-types and classifiers, while the types meta-model is the meta-model of later measured models.

library de.cau.cs.se.MengesMeasures

model ecore "http://www.eclipse.org/emf/2002/Ecore"
model types "http://se.informatik.uni-kiel.de/menges/types"

Declaration of Measures

The MDL provide four basic measures. The NamedMeasure is used to declare references to external measure sources. The CountingMeasure is an counting function, which could be replaced in future by functions in expressions. The MeasureExpression allows to define complex formulas over direct measures and is mapped to a wide range of BinaryMeasures of the SMM. And the CollectiveMeasure, which calculates accumulation expressions.

Measure: NamedMeasure | CountingMeasure | MeasureExpression | CollectiveMeasure ; 

A NamedMeasure is defined by an unique name, which references an external source of measurements. The resultType of a NamedMeasure defines the data type of that external source. The elementType describes, which meta-model elements the NamedMeasure can be used for. For example, the measure ExecutionTime is can be applied to a Java-method, but not to an enumeration. Therefore, it would be limited to Java-method by the elementType property.

NamedMeasure: 'measure' resultType=[MeasureType|ID] name=ID ':' elementType=ModelTypeReference ('(' parameter+=ParameterDeclaration (',' parameter+=ParameterDeclaration)* ')')? (scope=Scope)? ; 

The CountingMeasure is modeled after the SMM CountingMeasure. It returns 1, if selection is not empty and 0, if the selection is empty. Note: Either the naming should be changed to something more suitable to the specified semantics, or count should be able to return the number of found elements.

The CountingMeasure does not have a specifiable result type, as the type is unit-less 0 or 1.

CountingMeasure: 'count' name=ID ':' elementType=ModelType ('(' parameter+=ParameterDeclaration (',' parameter+=ParameterDeclaration)* ')')? 'select' selection=Expression (scope=Scope)? ; 

The MeasureExpression is the most complex measure construct. It is a facade to a wide range of measures, which are automatically generated through the specified expression. A MeasureExpression comprises of a unique name, a resultType to define, the allowed result type of the derived measure. An elementType to define which meta-model elements can be addressed by the MeasureExpression. And an expression to define the formula to derive values.

MeasureExpression: 'def' resultType=[MeasureType|ID] name=ID ':' elementType=ModelTypeReference ('(' parameter+=ParameterDeclaration (',' parameter+=ParameterDeclaration)* ')')? expression=AdditiveExpression (scope=Scope)? ; 

A CollectiveMeasure summarizes results from a nested measure. The Accumulator defines the method of this collection. And the referencedMeasure specifies the measure which provides the data to be accumulated. Depending on the type of the referenced measure and the accumulation method the result type must be specified.

Note: The CollectiveMeasure is not yet complete, as it does not support periodic measures.

CollectiveMeasure: 'collect' resultType=[MeasureType|ID] name=ID ':' elementType=ModelTypeReference ('(' parameter+=ParameterDeclaration (',' parameter+=ParameterDeclaration)* ')')? accumulator=Accumulator ref=[Measure|ID] (scope=Scope)? ; enum Accumulator: SUM = 'sum' | AVERAGE = 'average' | STANDARD_DEVIATION = 'standard-deviation' | STANDARD_DEVIATION = 'sd' ; 

The previously described measures have some common features, which require the following two common rules. First, the ParameterDeclaration allows to declare parameter for measures. As the reference rule for the parameter type TypeReference is used to limit probable types to types with units or base types.

ParameterDeclaration: type=TypeReference name=ID ; 

Second, the Scope rule is used to refine the scope of a measure. While elementType limits the measure to one meta-model class, the scope can go further and add limits based on complex Boolean expressions. For example, elementType limits the use of a measure to Java-methods and the scope can limit that to methods with the name run if the class is a Runnable.

Scope:{Scope} 'scope' '{' (scopes+=Expression)+ '}' ;

Terminals

terminal BOOLEAN returns ecore::EBooleanObject : "true" | "false"; QualifiedName: ID (=>'.' ID)*; QualifiedNameWithWildcard: QualifiedName '.' '*' ; SpecialName: ID | STRING ; 

Typing

SMM defines the result type of a measure by a data type and a unit of measurement. Therefore, all result types are user defined types, based on base types, such as Integer or Float, which are enriched by a unit. MDL supports this by introducing a rule to declare types with typedef. Each declared type must be based on a base type, even though the rules might allow to derive types from other MeasureTypes. The base type is then followed by the specification of a unit. The unit can either defined by a string, which can hold any character sequence, or an SI-like unit specification. The latter was introduced to help to unify unit declarations.

MeasureType: 'typedef' baseType=TypeReference unit=Unit name=ID ; Unit: UnitFormula | FreeUnit ; FreeUnit: unit=STRING ; 

FreeUnit can be any arbitrary string and therefore does not provide a way to check if types are compatible or can result out of other types. Therefore, the type check can only be applied on the basis of the base type and a warning can be issued when two types with different free units are combined. A better way is provided by the UnitFormula which is, right now, based on SI-units and the metric system. It allows to define complex unit structures, which can then be used to verify if a given expression really returns the given type. For example, an constant acceleration (a) can measured and its unit is m/s². And the velocity (v, m/s) can be determined by also measuring the time (t) s with the formula v=a * t. By interpreting the formula and the units used in the formula, it can be checked if the unit m/s can be produced from m/s² multiplied by s.

UnitFormula: UnitCombination (({UnitFormula.numerator=current} '/') denominator=UnitCombination )? ; UnitCombination: SIUnit | '(' units+=UnitCombination+ ')' ; 

An SIUnit is a combination of three elements. First, a prefix to define the scale, which can be omitted. Second, the base unit. And third, the dimension. the dimension can also be omitted, which will imply an dimension of 1. Negative dimension values are not allowed.

SIUnit:
	(prefix=Prefix)? kind=Kind (dimension=INT)?
;

MDL supports the following prefixes for units:

enum Prefix: PICO = 'pico' | NANO = 'nano' | MICRO = 'micro' | MILLI = 'milli' | CENTI = 'centi' | DECI = 'deci' | KILO = 'kilo' | MEGA = 'mega' | GIGA = 'giga' | TERA = 'tera' | PETA = 'peta' ; 

Known units of MDL are:

enum Kind: METER = 'meter' | SECOND = 'second' | GRAM = 'gram' | LITER = 'liter' ; 

These unit types should be extended in future to cover all base and derived unit types declared in the SI systems.

The following two rules, are used to model references to types. The first, is used to reference data types, meaning base types, and already composed measure types. While the second, is used to reference classifiers in Ecore-models.

TypeReference: metamodel=[MetaModel|ID] '::' dataType=[ecore::EDataType|ID] | measureType=[MeasureType|ID] ; ModelTypeReference: metamodel=[MetaModel|ID] '::' classifier=[ecore::EClassifier] ;

Requirements

A use-case scenario for the MDL is, measuring an application at runtime, which requires some sort of instrumentation, mapping of the instrumentation to measures, and the means to evaluated the measurements. To apply measures to a specific application model (AM), measures need to be contraint to an SMM:Scope refering to the application meta-model (AMM). Such meta-models can be meta-models of DSLs?, the  Knowledge Discovery Metamoodel (KDM), or any other meta-model. For the selection of only specific instances in that scope, SMM allows to specify a recognizer, which can be parametrized. Together they allow to select application model elements (AME) of an AMM.

The concrete instantiation of the measures is realized through an SMM:ObservedMeasure' in an SMM:Observation' by configuring them so they suit a specific AM and a specific measuring project. As the MDL is a language built without a specific AMM in mind, but with SMM as its basis for the MAMBA execution engine, it has some constraints to follow. Furthermore, the MDL should be easy to use and not too different from the MQL.

R01: Selection of model elements

To select model elements, the MDL has to be able to specify elements of an AM and transform all these selections in an proper SMM:Scope and SMM:Operation for the scopes recognizer. For the user, this should be strait forward.

  • #5 Simple selection expression to select single instances in the AM
  • #6 Selection method for multiple instances in the AM

R02: Referencing an application model

For the tooling and proper references in the measure specification, the language has to provide the means to specify an AM for an observation and the AMM for the measures in general.

  • #7 Specification of an application meta model reference for the measures
  • #8 Specification of an application model reference for the observation

R03: Multiple observations

There might be multiple identical observations with the same measure library. Therefore the measure library should be re-useable over those different observations. Furthermore, the same AM can be observed with the same observation setup more than once resulting in multiple identical observation setups with different results. Therefore an observation setup should be able to be specified separately and instantiated by a tool for a concrete observation. And different observation setups should be able to use the same measure library. This results in the following features:

  • #9 Separate description of measure library from the observation setup
  • #10 Separate description of the observation setup
  • #11 Mechanism to include a measure library into an observation setup

Generation of SMM Models

The MDL is a language to describe SMM models, or to be more precise to describe SMM model libraries. On this page we describe the composition of the generator.

Basic Compsition

The MDL can be divided in four major aspects (beside terminals), measure definition, expressions of measures, scope declarations and unit modeling. The generator follows this distinction and comprises four Xtend-classes implementing these four aspects. It can be found in

  • Project de.cau.cs.se.measure.definition.language
    • Package de.cau.cs.se.measure.definition.language.generator

The generator uses the Xtext-builder and -generator framework. For now the generated SMM model is placed alongside its MDL counterpart with the extension smm. The builder is triggered, as usual for Xtext-based editors, every time the content is saved.

The main class of the generator is MeasureDefinitionLanguageGenerator with its central doGenerate method. The three other aspects are handled in:

  • MeasureExpressionGenerator to generate binary measures based on the measure expression
  • ScopeExpressionGenerator to generate SMM Scope and Operation objects containing OCL expressions derived from MDL scope expressions
  • UnitExpressionGenerator to generate correct unit strings for SMM

Limitations

  • Parameter are not supported in the moment, because the SMM specification is not concrete enough to just implement it. There is some space for interpretation how parameters could be achieved. Before implementing this, it has to be found a solution in MAMBA.
  • Periodic Measures are not supported
  • Switch between MAMBA collective measures and SMM collective measure is missing