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!
ReFlO (v3.0.0) [~1.2 MB; for Eclipse 4.3]
ReFlO (v2.2.0) [~1.2 MB; for Eclipse 3.6]
Eclipse (v4.3.2) + ReFlO (v3.0.0) [~355 MB; for Windows]
Dependencies: the following Eclipse plugins need to be installed (click on the link to see how to install the plugins):
dropinsto Eclipse's dropins folder.
Not working? Download the full eclipse installation, which already contains everything you need to use ReFlO.
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.
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
The names must match the regular expression
Ports have the attribute
Data Type to store its data type (optional).
The additional parameters are specified in the boxes' attribute
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.
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
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_box2, ... are parameterizable boxes, that can be instantiated with
real_box2, ..., or with
That is, this attribute
Template defines the valid instantiations for the
The users can define as many instantiations as they need for a templatized rewrite rule.
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.
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:
You can find a video here showing the derivation of an architecture.
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.
Interpretations are specified in Java, extending class
AbstractInterpretation (this class is provided by jar file
Architecture.exec_*.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
The class provides methods to get and set the properties of box and its ports, when
Properties may be objects of any type, and are associated with a key of type
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 (
These attributes are essential to allow ReFlO to locate the classes specifying the
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
AbstractInit, and defining method
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
As for RDM, architectures also have attributes
Tf Path and
Tf Package to specify where classes are located.
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.
~ is used before the name of an interpretation to specify that
it is a backward interpretation.
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
need to disallow the refinement of
SORT with the
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
AbstractInterpretation also provides method
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