Skip to content

Configuration Language

Daniel Varro edited this page May 16, 2018 · 6 revisions

Structure of configuration files

Basic Structure

A ConfigurationScript in a .vsconfig file follows the consists of an import section (Import), then declares one or more variables (Declaration), and specifies one or more commands (Command):

<ConfigurationScript>:= <Import>* (<Declaration> | <Command>)*

Import section

The import section refers to existing modeling artefacts to be included to the analysis. Currently ECore EPackages (.ecore) and VIATRA Query (.vql) files can be referred:

<Import>:= <EPackageImport> | <ViatraImport>;
<EPackageImport>:= "import" "epackage" <STRING>;
<ViatraImport>:= "import" "viatra" <STRING>;

Files an be imported in two ways: by their simbolic name (available in Eclipse plug-in mode, the referred files needs to be in the classpath), or by a path (Eclipse plug-in and Standalone Java application). For simbolic names, an EPackages are referred by its NS URI (nsURI attribute), and Pattern Models by their package name (constructed by their package name and "Patterns"). For example:

import epackage	"http://www.inf.mit.bme.hu/viatrasolver/example/fam"
import viatra	"hu.bme.mit.inf.dslreasoner.domains.transima.fam.FamPatterns"

Use content assist to list files on the classpath.

Additionally, files can be referred by their path:

import epackage	"/inputs/FamMetamodel.ecore"
import viatra	"/inputs/FamPatterns.vql"

In this case, content assist cannot help.

Declarations

The configuration file identifies elements by names. Valid identifiers are specified as follows:

<ID>:= '^'?('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'_'|'0'..'9')*
<QualifiedID>:= <ID> ('.' <ID>)*

The configuration language supports the declaration of macros for an identifier. Currently the following declaration types are supported:

<Declaration>:= <FileDeclaration>
	      | <MetamodelDeclaration>
	      | <PartialModelDeclaration>
	      | <GraphPatternDeclaration>
	      | <ConfigDeclaration>
	      | <ScopeDeclaration>

In general, a declaration introduces a variable with a name (ID) for a value, which can be refer instead of writing the value multiple times:

<Declaration>:= "type" <ID> "=" <Value>
<Use>:= <ID> | <Value>

For example, the following declaration introduces a file variable LogFile:

file LogFile = "/outputs/log.txt"

From now on, file "/outputs/log.txt" can be referred from any part of the document as LogFile.

Metamodels

Relevant elements from EPackages can be collected to a metamodel specification, which can be used to configure the generator. A metamodel element is referred as follows:

<MetamodelElement>:= (<QualifiedID> "::")? <ID> ('.' <ID>)?

The first (optional) qualified identifier selects the target EPackage by its name. The other one or two identifier select the target metamodel element.

  • EClass: First ID is the name of the EClass, second ID is empty.
  • EReference: First ID is the name of the container EClass, second ID is the name of the EReference.
  • EAttribute: First ID is the name of the container EClass, second ID is the name of the EAttribute.
  • EEnum: First ID is the name of the EEnum, second ID is empty.
  • EEnumLiteral: First ID is the name of the EEnum, second ID is the name of the EEnumLiteral.

The selected EPackage needs to be in one of the imported packages. If the EPackage is specified, then the first ID must be the name of a classifier from the package, otherwise the first ID needs to be a classifier in any of the imported packages. The second ID needs to be a name of an EReference, EAttribute, EEnumLiteral in the classifier specified by the first ID

Alternatively, one can refer to all of the elements in an EPackage:

<AllPackageElement>:= "package" <QualifiedID> ("excluding" '{' <MetamodelElement> (',' <MetamodelElement>)*'}')?;

With the excluding keyword, a list of metamodel elements can be excluded from a package element. Only elements that are in the EPackage can be excluded referred in the excluding section.

Finally, a metamodel specification consists of a list of MetamodelEntry:

<MetamodelSpecification>: '{' (<MetamodelEntry>) (',' <MetamodelEntry>)* '}';
<MetamodelEntry>: <MetamodelElement> | <AllPackageElement>;

An example metamodel specification is illustrated below:

import epackage	"http://www.inf.mit.bme.hu/viatrasolver/example/fam"
metamodel SimpleFAM { FunctionalElement, Function, Function.subElements }

In summary, a metamodel specification select a list of elements from the imported packages.

  • Each element have to be selected at most once
  • If an EClass is selected, then all supertype EClasses also have to be selected.
  • If an EReference is selected, the source and target EClasses also have to be selected.
  • If an EAttribute is selected, then the source EClass also have to be selected.
  • If an EEnum type EAttribute is selected, then the type also have to be selected.
  • Only EBoolean, EInt, EString, EDouble, and EEnum attributes are supported.
  • If a, EEnumLiteral is selected, then the containing EEnum also have to be selected.

Constraints

The list of relevant patterns also need can be selected. A single graph pattern is referred in the following way:

<PatternElement>:= (<QualifiedID>'::')? <ID>;

The first optional QualifiedID refers to an imported VIATRA package, and ID is the name of a pattern in the selected package. If no package is specified, ID refers to a pattern available in any of the imported VIATRA packages.. All patterns can be selected from a package, optionally by excluding some unwanted patterns with the following construct:

<AllPatternElement>: 'package' <QualifiedID> ('excluding' '{' <PatternElement> (',' <PatternElement>)* '}')?

A constraint specification consists of a list of pattern and package references:

<PatternSpecification>:= '{' <PatternEntry> (',' <PatternEntry>)* '}';
<PatternEntry>:= <PatternElement> | <AllPatternElement>;

The analysis translates all patterns specified in a PatternSpecification. If there are patterns that are not included into the specification, but referred by patterns that are (via find keyword), they are automatically included to the analysis. Patterns annotated with @Constraint are interpreted as ill-formedness constraints (i.e. they have to capture when the constraint is violated), and patterns with @QueryBasedFeature act as the definition for EAttributes and EReferences marked as '''derived'''. Patterns that are not included to the specification, but automatically added because of a reference, will not act as well-formedness constraints and derived features.

Models and Partial Models

Optionally, existing instance models can be included into the model generation process as partial snapshots. A partial snapshot defines an initial model structure that have to be contained in all generated models. A single model referred as a file (and a file referred as a path):

<ModelElement>:= <File>

Additionally, multiple files in a folder can be referred:

FolderElement:= "folder" <File> ("excluding" "{" <ModelElement> ("," <ModelElement>)* "}")?

Finally, a model specification consists of a list of file and folders

<ModelSpecification>:= '{' <ModelEntry> (',' <ModelEntry>)? '}';
<ModelEntry>:= <ModelEntry> | <FolderEntry>;

Scopes

Scope defines the required size of the models with respect to the number of objects and different attribute values. There are three kind of scopes in VIATRA Solver:

  • first, a TypeScope specifies the number of instanceos of an EClass,
  • an ObjectScope specifies the number of all EObjects,
  • and finally, IntegerTypeScope, RealTypeScope and StringTypeScope specifies the range of different primitive values in the model.

The range of elements is specified in multiple way:

  • An ExactNumber specifies the exact number of elements. Value * means undefined.
<ExactNumber>:= <INT> | '*'
  • An IntervallNumber specifies that the number of elements have to be in an interval defined in min...max form. Again, * means undefined.
<IntervallNumber>: <INT> '..' (<INT> | '*')
  • Finally, one can explicitly define the range of possible values for attributes. Not all attribute have to be used in an instance model.
<IntEnumberation>: '{' (<INT> (',' <INT>)*)?'}';
<RealEnumeration>: '{' (<INT> (',' <INT>)*)?'}';
<StringEnumeration>:  '{' (<STRING> (',' <STRING>)*)?'}';

The range can specify either the elements in the graph, or, if there is a partial snapshot, just the newly created elements:

  • Type = Range: The range specifies the size of the complete model.
  • Type += Range: The range specifies the size of the models without the partial model.

Therefore, scopes are defined in the following way:

<TypeScope>:= '#' '<' <MetamodelElement> '>' ('+=' | '=') ( <ExactNumber> |  <IntervallNumber>)
<ObjectScope>:= # 'node' ('+=' | '=') ( <ExactNumber> |  <IntervallNumber>)
<IntegerScope>:= '#' 'int'  ('+=' | '=') ( <ExactNumber> | <IntervallNumber> | <IntEnumberation>)
<RealTypeScope>:= '#' 'real' ('+=' | '=') ( <ExactNumber> | <IntervallNumber> | <RealEnumberation>)
<StringTypeScope>:= '#' 'string' ('+=' | '=') ( <ExactNumber> | <IntervallNumber> | <StringEnumberation>)

Finally, a scope specification consists of a list of scopes:

<ScopeSpecification>=: '{' (<Scope> (',' <Scope>)*)? '}'
<Scope>:= <TypeScope> | <ObjectScope> | <IntegerScope> | <RealScope> | <StringScope>

Solvers and Configuration

Currently, there are three underlying solvers: := "SMTSolver" | "AlloySolver" | "ViatraSolver";

Additionally, there is a way to configure multiple parameters of the selected solver:

  • A maximal runtime limit can be defined in milliseconds:
<RuntimeEntry>:= "runtime" "=" <INT>
  • A maximal memory limit can be defined in megabytes:
<MemoryEntry>:= "memory" "=" <INT>
  • The log-level of the translation and solver logging level:
<LogEntry>:= "log-level" "=" ("none" | "normal" | "full")
  • Or any other parameter can be be forwarded to the solver by using custom key-value pairs:
<CustomEntry>:= <STRING> "=" <STRING>

A solver is configured with the list of those entries:

<ConfigSpecification>:= '{'(<ConfigEntry> ("," <ConfigEntry>)*)?'}'
<ConfigEntry>: <DocumentationEntry> | <RuntimeEntry> | <MemoryEntry> | <CustomEntry>

## Generation Task

Currently, model generation is the only command that are supported in VIATRA Solver:
```java
<Command>:= <GenerationTask>

A generation task defines a command to create a set of instance models. The command has several parameters:

  • metamodel (Mandatory): Defines the target metamodel.
  • partial-model(Optional, default: no partial model): Defines an initial instance model.
  • constraints (Optional, default: no constraints): Defines the well-formedness constraints.
  • scope (Optional, default: *): Defines the size of the target model.
  • number (Optional, default: 1): Defines the number of different models need to be generated.
  • runs (Optional, default: 1): Defines the number of separete runs of the generation.
  • solver (Mandatory): Defines the target solver.
  • config (Optional, default: no limits, default config for the solver): Defines a configuration for the target solver.
  • debug (Optional, default: no folder): Defines a folder where the solver can write additional information.
  • log: (Optional, default: no file): Defines a file where the solver can write log data.
  • statistics (Optional, default: no file): Defines a file wher the solver can write statistics about the model generator.
  • output (Optional, default: no folder): Defines a folder where the newly generated models are saved.

A generation command is specified in the following format:

<GenerationTask>:  'generate' '{'(
	('metamodel' '=' <MetamodelSpecification>) |
	('partial-model'  '=' <ModelSpecification>) |
	('constraints'  '=' <ConstraintSpecification>) |
	('scope' '=' <ScopeSpecification>) |
	('number' '=' <INT>) |
	('runs' '=' <INT>) |
	('solver' '=' <Solver>) |
	('config' '=' <ConfigSpecification>) |
	('debug' '=' <FileSpecification>) |
	('log' '=' <FileSpecification>) |
	('statistics' '=' <FileSpecification>) |
	('output' '=' <FileSpecification>) |
)*'}'