Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "VIATRA/DSE/UserGuide/API"

< VIATRA‎ | DSE
(Using the results)
Line 7: Line 7:
 
== API ==
 
== API ==
  
VIATRA-DSE depends on the Eclipse platform thus using it one should create a plugin project and add the '''org.eclipse.viatra.dse.base''' plugin as a dependency for the plugin project.
+
VIATRA-DSE depends on the Eclipse platform thus using it one should create a plug-in project and add the '''org.eclipse.viatra.dse.base''' plug-in as a dependency for the plug-in project.
 
To start using the framework type this line of code:
 
To start using the framework type this line of code:
  
Line 117: Line 117:
 
dse.setMaxNumberOfThreads(1);
 
dse.setMaxNumberOfThreads(1);
 
</source>
 
</source>
 +
 +
= Run configuration =
 +
 +
Running the DSE engine needs an Eclipse platform, thus it is recommended to use a '''JUnit plug-in test''' in headless mode. Here are some basic steps to configure it properly:
 +
 +
* Add the org.junit as a dependency.
 +
* Annotate the method with @Test annotation
 +
* Create a JUnit plug-in test run configuration with the corresponding class
 +
* Locate the Run configuration / Main tab and change the selection at "Run an application" to "[No Application] – Headless Mode".
 +
* On the Plug-ins tab select "plug-ins selected below only" from the drop down list and select the plugin which contains the class with the annotated method.
 +
* Hit "Add Required Plug-ins" 2-3 times.
  
 
= Examples =
 
= Examples =
  
 
Coming soon.
 
Coming soon.

Revision as of 15:23, 29 September 2014

Usage of the VIATRA-DSE API

This page presents the basic API of the VIATRA-DSE framework. After reading this you will be able to define a DSE problem including transformation rules and goals, run it with different built in strategies and use the solutions the exploration found.

It is highly recommended to get familiar with the EMF and EMF-IncQuery frameworks first as they are essential for using VIATRA-DSE.

API

VIATRA-DSE depends on the Eclipse platform thus using it one should create a plug-in project and add the org.eclipse.viatra.dse.base plug-in as a dependency for the plug-in project. To start using the framework type this line of code:

DesignSpaceExplorer dse = new DesignSpaceExplorer();

Defining the domain

The first thing required is a metamodel or ecore model created with EMF and an initial model. See the code below.

EObject root = createInitialModel();
dse.setStartingModel(root);
 
// You can also define the metamodel however it is not obligatory
dse.addMetaModel(MetamodelEPackage.eINSTANCE);

Transformation rules

Rules tell the engine how the initial model can be modified and treated as atomic steps. They consist of a left hand side (LHS or condition) and a right hand side (RHS) . The LHS is always an IncQuery pattern (or a model query) while the RHS is simple Java code. To define such a rule an instance of the TransformationRule class must be created.

Let's say a pattern named myPattern with two parameters is already available and can be used as a LHS.

TransformationRule<MyPatternMatch> rule = 
new TransformationRule<MyPatternMatch>(MyPatternQuerySpecification.instance(), new MyPatternMatchProcessor() {
    @Override
    public void process(ExampleEObject p1, ExampleEObject p2) {
        // RHS manipulates the EMF model
        p1.setFriend(p2);
    }
});
 
dse.addTransformation(rule);


Note 1: A rule can also have a name via the "setName(String)" method.

Note 2: It's forbidden to apply two rules with same LHS to be able to distinguish them based on the pattern. Using the IncQuery keyword find can avoid code duplication.

Note 3: It's a good practice to use static factory methods in a separate class for creating rules.

Goals

Goals are defined by IncQuery patterns and can be added to the problem with a simple method call:

dse.addGoalPattern(new PatternWithCardinality(MyGoalPatternQuerySpecifiaction.instance()));


The default behavior of the framework is checking all goals and if they are all fulfilled (have at least one match in the current model) the model state is marked as a solution state. To override this behavior please see the Strategies section of this wiki.

State coding

A state coder is also necessary for the engine to start the exploration. For any more detail about this please see the state coding section of this wiki.

ArrayList<EPackage> metaModelPackages = new ArrayList<EPackage>();
metaModelPackages.add(MetamodelEPackage.eINSTANCE);
dse.setSerializerFactory(new IncrementalGraphHasherFactory(metaModelPackages));

Starting the exploration

To start the exploration a strategy must also be defined. Static methods of the Strategies class can be used to create a built in strategy like depth first search. The exploration runs in separate threads hence there is a boolean parameter whether to wait for the exploration process.

boolean waitForTermination = true;
dse.startExploration(Strategies.createDFSStrategy(), waitForTermination);


The second parameter can also be an integer for timeout, which if elapses the exploration will stop as soon as possible.

Using the results

A solution of the exploration is a trajectory, a sequence of rules which if applied to the initial model, it satisfies the goals. It's important that the same goal state can be reached by different trajectories and this is also represented by the results: an instance of Solution class can have multiple SolutionTrajectory instances. A solution has at least one solution trajectory, but nothing more can be expected, as it is heavily depend on the traversal strategy and the actual traversal of the state space. The SolutionTrajectory can be used to transform the given model (should be the initial model) based on the trajectory.

Collection<Solution> solutions = dse.getAllSolutions();
if (!solutions.isEmpty()) {
    Solution solution = dse.getAllSolutions().iterator().next();
    SolutionTrajectory solutionTrajectory = solution.getArbitraryTrajectory();
    // Transform the model
    solutionTrajectory.setModel(theInitialModel);
    solutionTrajectory.doTransformation();
}

Other functions of the API

Global constraints

If there are any global constraints added they must be satisfied in all of the intermediate model state of trajectory. If a global constraint is not satisfied the engine won't allow the exploration to go further from that state. It can be useful to reduce the state space, but it can also be a goal of the problem. Defining a global constraint is very similar to defining a goal patter.

dse.addConstraint(new PatternWithCardinality(MyGlobalConstraintQuerySpecifiaction.instance()));

Parallel execution

The engine allows the traversal strategy to explore the state space with multiple threads. By default it allows a number of threads equal to the number of logical cores in the processor. It can be overridden with the following code:

dse.setMaxNumberOfThreads(1);

Run configuration

Running the DSE engine needs an Eclipse platform, thus it is recommended to use a JUnit plug-in test in headless mode. Here are some basic steps to configure it properly:

  • Add the org.junit as a dependency.
  • Annotate the method with @Test annotation
  • Create a JUnit plug-in test run configuration with the corresponding class
  • Locate the Run configuration / Main tab and change the selection at "Run an application" to "[No Application] – Headless Mode".
  • On the Plug-ins tab select "plug-ins selected below only" from the drop down list and select the plugin which contains the class with the annotated method.
  • Hit "Add Required Plug-ins" 2-3 times.

Examples

Coming soon.

Back to the top