About

ReFlO aims to provide a machine-assisted framework to support Design by Transformation, allowing domain-experts to encode domain knowledge about how programs are built in a particular domain, and for developers to synthesize efficient program architectures, using the knowledge provide by domain-experts.

It provides a GEF graphical editor, to allow users to specify models using a pipe-and-filter notation. Transformations, implemented using Epsilon, allows the users to create architectures, and incrementally refine and optimize them for specific platforms.

Users can also provide interpretations of architectures, in order to be able to automatically compute properties about the architectures (e.g., performance costs), at different stages of development.

ReFlO also allows users to attach documentation info to their models, and later export the models to HTML (similarly to Javadoc).

To see ReFlO in action, watch the following screencasts!

Downloads

ReFlO (v2.2.0) [~1.2 MB]

Eclipse (v3.6.2) + ReFlO (v2.2.0) [~475 MB]

Installation

Dependencies: the following Eclipse plugins need to be installed (click on the link to see how to install the plugins):

Installation steps:

  1. Unzip the downloaded file (it should contains folders dropins and xform).
  2. Copy the files contained on folder dropins to Eclipse's dropins folder.
  3. Launch Eclipse, and create a general project, named reflo.
  4. Copy folder xform to reflo project.
  5. Go to File > Import, choose General > Preferences, and then select file xform.epf from folder xform.

Not working? Download the full eclipse installation and you will just need to execute the last three installation steps.

Documentation

ReFlO Domain Models

A ReFlO Domain Model (RDM) encodes domain knowledge, i.e., interfaces of the domain and its implementations. To create a domain model, the user must create a diagram file, selecting File > New > Example... > Domainmodel Diagram, and then choose the name for the file.

After creating (and opening) the file, on the Pallete on the right, the user has available a list of objects and links he can use to build his models.

Layer
Container for domain models (allows to group subsets of the domain models, that can be enabled/disabled independently).
Interface
Models an operation of the domain. Defines the input ports, output ports, and additional parameters of the operation.
Primitive
Models a primitive implementation for an interface, that cannot be refined, but that has a direct code implementation.
Algorithm
Models an implementation for an interface as a pipe-and-filter graph. Besides defining the input ports, output ports, and additional parameters of the algorithm, it contains interfaces and connectors linking the interfaces, that define how operations shall be composed to provide the desired behavior.
Pattern
Special type of algorithm, that models a pipe-and-filter graph that can be abstracted to the interface it implements.
Input
Models an input port.
Output
Models an output port.
Connector
Connects the interfaces inside algorithms and patterns.
Implementation
Connects primitives, algorithms, and patterns with the interface they implement.

The user starts by creating layers, and them adds the different models that encode the domain operations, implementations and optimizations, effectively defining a set of rewrite rules, that will be available when synthesizing program architectures. It is recommended to model the interfaces first, and them the algorithms/patterns, as the user may automatically add any of the defined interfaces to an algorithm/pattern, selecting the algorithm/pattern box, right clicking, and selecting Wizards > Insert Interface (otherwise the user will have to manually add the interfaces, their ports, and set their attributes). The user will only have to set the values of the additional parameters of the interface, in case they exist.

The name of the objects (layers, boxes, ports) are specified in the attribute Name. The names must match the regular expression [a-zA-Z][a-zA-Z0-9_]*. Ports have the attribute Data Type to store its data type (optional).

The additional parameters are specified in the boxes' attribute Parameters, using the notation name1 : type1, name2 : type2, ..., or name1 = value1, name2 = value2, ... when the parameters' value also needs to be provided (this happens for boxes that appear inside algorithms). The parameters' types are optional.

ReFlO provides model validation, available in the menu Edit > Validate.

You can find a video here showing the creation of a RDM for databases.

Documenting an RDM

The different objects of RDM (boxes, ports, layers) have an attribute (doc), that should be used to put a description of the object. The user can select a RDM diagram file, right click, and select ReFlO > Export as HTML, to generate an HTML page that documents the RDM. This HTML page will list the contents of the RDM, showing their figures, and their descriptions.

Templates

ReFlO provides a mechanism to easily define several rewrite rules that have a common shape, reducing the modeling effort. Every rewrite rule can be used as a template. This is done setting the Template attribute of the interface being defined in the rewrite rule. The attribute should be null, in case the rewrite rule is not used as a template, or contain an string of format (template_box1, template_box2, ...) := (real_box1, real_box2, ...) | (real_box1', real_box2', ...), meaning that template_box1, template_box2, ... are parameterizable boxes, that can be instantiated with real_box1, real_box2, ..., or with real_box1', real_box2', .... That is, this attribute Template defines the valid instantiations for the template. The users can define as many instantiations as they need for a templatized rewrite rule.

Architectures

Architectures allow the user to specify programs and transform them. To create an architecture, the user must create a new diagram file, selecting File > New > Example... > Architecture Diagram, and then choose the name for the file.

After creating a architecture diagram file, the first thing to do is to associate a RDM to it. To do this, the user must select the architecture diagram file and a RDM diagram file, right click, and select ReFlO > Sync ReFlO Domain Model. If the user decides to update the RDM, he must repeat this process (he may also need to close and reopen the file, to be able for the changes to take effect).

Then the user can open the architecture diagram file, and on the Pallete on the right, he will see the list of objects and links he can use to build his architectures.

Architecture
Models program architectures. Defines the input ports, output ports, and additional parameters of the program. Additionally, it contains a pipe-and-filter graph that defines operations may be composed to produce the behavior of the program being modeled.
Interface
Models an operation of the domain. They are used to specify the behavior of architectures.
Input
Models an input port.
Output
Models an output port.
Connector
Connects the boxes inside architectures.

These allow the user to specify an initial architecture, to later transform. The interfaces used to specify the initial architecture must be present in the RDM associated with this architecture diagram file. The interface may be created manually (creating the interfaces, the ports, and setting its attributes), or the user may select the architecture box, right click, and select Wizards > Insert Interface, that will insert the interface, according to its definition in the RDM (and the user will only have to set the values of the additional parameters of the box, in case they exist).

Given an architecture, users may apply transformations to it, in order to derive architectures with desired properties (such as availability or efficiency). To apply a transformation, users should select the model elements to transform, and then right click, and select Wizards and the desired transformation.

The following transformations are available:

Refine
Refines the selected interface, replacing it with an algorithm, primitive, or another interface.
Flatten
Removes the modular boundaries of the selected algorithm. (There is also the Flatten Below transformation, that removes the modular boundaries of all algorithms contained inside the selected algorithm or architecture.)
Abstract
Replaces the selected subgraph with the interface it implements.
Optimize
Replaces the selected subgraph with an equivalent implementation (this transformation applies the transformations abstract, refine, and flatten in a row).
Find Pattern
Identifies opportunities for optimizations in the selected architecture. Adds a label to the boxes that can be optimized (the transformation Clear can be used to remove the labels).

You can find a video here showing the derivation of an architecture.

Interpretations

Interpretations allow users to associate behavior with boxes, and execute architectures. This behavior can specify the computation the box represents, in which case executing the architecture would result in a interpretor, but may also capture other properties of the boxes. A typical example, is to use interpretations to associates to estimate performance costs for architectures.

An interpretation for a box is a function that compute properties about its outputs (or about the box itself) based on properties about its inputs (or about the box). Given an architecture, ReFlO can execute it, running these functions according to the topological order of boxes. Ports connected share properties, which means that when executing the architecture, the properties are propagated as usual when running a dataflow architecture. We noticed that some properties are easier to compute when inverting the order of execution of boxes, thus we provide backward interpretations.

Interpretations may be composed, that is, several interpretations may be executed in sequence, and an interpretation has access to properties set by previous interpretations. This allow users to specify interpretations in a modular way, and reuse an interpretation in different scenarios.

Specification of Interpretations

Interpretations are specified in Java, extending class AbstractInterpretation (this class is provided by jar file Architecture.exec_2.2.0.jar, that you installed in your Eclipse). An interpretation is defined creating a Java package (the name of the package is the name of the interpretation), and for each box existing in the domain models, a Java class shall be created (with the name of the box). The behavior is defined implementing method compute. The class provides methods to get and set the properties of box and its ports, when defining the compute method. Properties may be objects of any type, and are associated with a key of type String.

In the RDM, there is an attribute (Tf Path) where the user should specify the base path of the classes, and a package that is the root of the packages specifying the different interpretations (Tf Package). These attributes are essential to allow ReFlO to locate the classes specifying the interpretations.

In architectures, the users may also define interpretations for architectures' boxes, and define the properties of inputs of the architecture (or properties of outputs, for backward interpretations), that will be propagated through the architecture when executing interpretations.

Architectures' interpretations are defined similarly to interpretations for other boxes. The specification of the architectures' inputs properties is done using a Java class that extends class AbstractInit, and defining method init. This class must be part of a package with the name of the interpretation that needs the property being initialized. Methods to set the properties are provided by class AbstractInit.

As for RDM, architectures also have attributes Tf Path and Tf Package to specify where classes are located.

Executing Interpretations

Interpretations can be executed simply selecting an architecture, right clicking, and selecting Wizards > Run Interpretations. Then, he must introduce a comma separated list of interpretations to run. The character ~ is used before the name of an interpretation to specify that it is a backward interpretation.

Pre- and Postconditions

Interpretations may also be used to define conditions that must be met, in order to a box produce the desired behavior. This allow user to validate architectures. More than that, this is useful to define implementations for interfaces that are only valid for specific inputs.

For example, a SORT operation (that sorts a stream) may be implemented by an algorithm that just outputs its inputs (i.e., an Identity function), provided that the input stream is already sorted. If we just defined the Identity as an implementation of SORT, we need to disallow the refinement of SORT with the Identity whenever we do not know whether the stream is sorted or not. This is accomplished defining an interpretation that computes a property (say IsSorted), that specify how each operation affects the order of a stream. This will be a postcondition of the boxes (operations). Additionally, an interpretation must be defined to check if if property IsSorted is defined whenever we try to refine SORT with Identity. Class AbstractInterpretation also provides method addError, that must be called by the interpretation whenever the precondition is not met (to tell ReFlO that a transformation is not valid in the current context, and thus it must be disallowed).