<!DOCTYPE article PUBLIC "-//NLM//DTD JATS (Z39.96) Journal Archiving and Interchange DTD v1.0 20120330//EN" "JATS-archivearticle1.dtd">
<article xmlns:xlink="http://www.w3.org/1999/xlink">
  <front>
    <journal-meta />
    <article-meta>
      <title-group>
        <article-title>nite state machines</article-title>
      </title-group>
      <contrib-group>
        <contrib contrib-type="author">
          <string-name>Daniel Lukacs</string-name>
          <xref ref-type="aff" rid="aff0">0</xref>
        </contrib>
        <contrib contrib-type="author">
          <string-name>Melinda Toth</string-name>
          <xref ref-type="aff" rid="aff0">0</xref>
        </contrib>
        <contrib contrib-type="author">
          <string-name>Istvan Bozo dlukacs@caesar.elte.hu</string-name>
          <xref ref-type="aff" rid="aff0">0</xref>
        </contrib>
        <contrib contrib-type="author">
          <string-name>tothmelinda@caesar.elte.hu</string-name>
          <xref ref-type="aff" rid="aff0">0</xref>
        </contrib>
        <contrib contrib-type="author">
          <string-name>bozoistvan@caesar.elte.hu</string-name>
          <xref ref-type="aff" rid="aff0">0</xref>
        </contrib>
        <aff id="aff0">
          <label>0</label>
          <institution>ELTE Eotvos Lorand University Faculty of Informatics Budapest</institution>
          ,
          <country country="HU">Hungary</country>
        </aff>
      </contrib-group>
      <fpage>197</fpage>
      <lpage>218</lpage>
      <abstract>
        <p>Model driven development approaches help to alleviate the abstraction gap between high-level design and actual implementation, to aid design, development and maintenance of industrial scale software systems. To provide automatic, easily usable tools for stakeholders, model driven development essentially relies on e cient and expressive translations between the program source code and the model. We present a declarative, rule-based approach to deterministically transform Erlang program sources that satisfy a certain syntactical constraint, into valid UML models of state machines. The transformation relies only on static analysis techniques, and the produced model conforms to the state machine metamodel de ned in OMG UML 2.0.</p>
      </abstract>
    </article-meta>
  </front>
  <body>
    <sec id="sec-1">
      <title>Introduction</title>
      <p>
        Copyright c by the paper's authors. Copying permitted for private and academic purposes.
framework [
        <xref ref-type="bibr" rid="ref11 ref16 ref24">16, 11, 24</xref>
        ] to analyse the application source code, then it will transform and synthesise the program
representation resulting from the analysis, into an UML state machine model. We speci ed the transformation
by de ning an algorithm that utilises backtracking and graph pattern matching of certain sets of transformation
rules. To generalise the algorithm, we encapsulated all the RefactorErl speci c logic into the transformation
rules, thus separating the general operation principles of the method from the implementation speci c details.
This approach also makes it easier to extend the capability of the algorithm by adding more rules. To test
our design in practice we also created a reference implementation, and, as presented in Section 6, used this to
successfully transform several Erlang state machines selected from the source code of large, popular, open source
Erlang applications.
      </p>
      <p>The rest of this paper is structured as follows. At rst, Section 2 describes UML and Erlang state machines.
Sections 3 and 4 introduce the methodology and the transformation rules to generate UML state machines. In
Section 5 we explain the transformation starting from an example Erlang source code. Section 6 presents the
evaluation of our work on several open source projects. Finally, Sections 7 and 8 present related work and
conclude the paper.
2</p>
    </sec>
    <sec id="sec-2">
      <title>Background</title>
      <p>
        One way to represent the execution history of a computer program is to take snapshots of the state of the program
memory. State machines can be used to abstract away this low level representation. With state machines these
memory snapshots are taken upon the occurrence of certain events, and instead of storing the content of the
memory, we just store descriptive labels, called states. Therefore, a state describes a segment of the program
behaviour, while a state transition describes a change in such behaviours, usually triggered by an event [
        <xref ref-type="bibr" rid="ref21">21</xref>
        ].
2.1
      </p>
      <sec id="sec-2-1">
        <title>Our target metamodel: UML state machines</title>
        <p>
          Among many others, Uni ed Modeling Language (UML) [
          <xref ref-type="bibr" rid="ref7">7</xref>
          ] is one of the more accepted standards to represent
state machines. UML itself is a family of various languages (metamodels ) suitable to represent various aspects
of large software systems. The UML state machine language can be used to formally describe event-driven
systems, i.e. systems that wait for certain events, and upon the occurrence of these events, they change their
behaviour and wait for a possibly di erent set of events. The state machine metamodel of UML is a more
general representation of computation than the classical models of nite state machines, since it provides several
extensions to the classical model, like embedded state machines, assignable variables, branching states with
guards, etc.
        </p>
        <p>Figure 1 depicts the UML state machine language with a metamodel diagram. The root container object
is always an instance of the StateMachine class. The root object contains a Region object, which in turn
contains Vertex and Transition objects, that can be used to denote states and state transitions respectively.
Pseudostate vertices can be used to denote initial states and choice states, FinalState vertices to denote stop
states, and State vertices to denote ordinary states. The transitions can be assigned events (Trigger), guards
(Constraint) and actions (Behavior).
2.2</p>
      </sec>
      <sec id="sec-2-2">
        <title>State machines in the Erlang language</title>
        <p>
          Erlang [
          <xref ref-type="bibr" rid="ref12 ref14">12, 14</xref>
          ] is a general purpose, functional, dynamically typed, open source programming language, mostly
used to develop multithreaded, real time, fault tolerant applications, like telecommunication systems, web servers,
or distributed databases. The language provides various abstractions to support these applications. For example,
the event handler (gen event), thread monitor (supervisor), server (gen server), and state machine (gen fsm)
behaviours, provided by the built-in OTP library [
          <xref ref-type="bibr" rid="ref14 ref17">17, 14</xref>
          ]. Behaviours have similar roles to abstract classes in
the object oriented paradigm: to implement a behaviour, we have to implement certain functions, called callback
functions, speci ed by the behaviour semantics. The complex, behaviour speci c background logic connecting
these callbacks together is provided by Erlang. This way, we only have to implement the logic speci c to our
application, but not the logic speci c to the behaviour semantics. For example, the requirements of the gen fsm
behaviour are to implement a callback function, named init, and any number of transition functions. The
function init will designate, at a minimum, the initial state of the state machine. The transition functions will
designate, at a minimum, the next state the state machine will be in when it receives a speci c event, while in
a speci c state. All the logic necessary to handle multiple threads, messages, events, etc. will be handled by
Erlang in accordance to the gen fsm semantics [
          <xref ref-type="bibr" rid="ref14">14</xref>
          ].
        </p>
        <p>
          In our research, we use the RefactorErl static analysis framework [
          <xref ref-type="bibr" rid="ref11 ref24">11, 24</xref>
          ] to analyse Erlang source code. The
RefactorErl tool rst analyses the source code, and then stores the discovered lexical, syntactic and semantic
information in a database. This information can be accessed through various user interfaces, and the framework
provides several feature to run refactorings on the source code, to perform further analyses { like data ow, and
dynamic function call analysis {, to execute various queries, to calculate certain metrics, and many other features.
To transform Erlang state machines to UML state machines, we based our de nition of the transformation on
the data structure RefactorErl uses to represent the lexical, syntactic and semantic information it gathers. This
data structure will be described in more detail in Section 3.
3
        </p>
      </sec>
    </sec>
    <sec id="sec-3">
      <title>Methodology</title>
      <p>In this section we rst describe the main entities and their related notations involved in the transformation
of Erlang state machines (i.e. Erlang modules implementing the gen fsm behaviour), and then we give the
algorithm that realises this transformation.
3.1</p>
      <sec id="sec-3-1">
        <title>Internal program representation of RefactorErl</title>
        <p>
          The RefactorErl analysis framework stores all information it gathers about Erlang programs via static analysis
in a special data structure, called semantic program graph (SPG ) [
          <xref ref-type="bibr" rid="ref11">11</xref>
          ]. In this paper, we show how the SPG
can be transformed into a state machine, which corresponds to the original state machine described by the
original Erlang source code. As the SPG is based on a syntax tree and extended with various semantic elements,
it represents the lexical, syntactic and semantic structure of one or more Erlang applications. Syntactic and
semantic elements of a program are mapped to nodes in this graph, while their relationships are mapped to
edges between the corresponding nodes. In the following sections the set of all nodes in a speci c SPG instance
will be denoted as VSP G, while set of all edges will be denoted as ESP G.
        </p>
        <p>A small Erlang program and a segment of its SPG can be observed in Figure 3 and Figure 4 in Section
5. Apart from the special node called root, all nodes in the SPG correspond to lexical, syntactic, or semantic
elements in the Erlang source code. The root node is the only node without incoming edges, and serves as the
common ancestor for all nodes of the SPG. Edges of the SPG are ordered.</p>
        <p>
          RefactorErl supplies various tools for discovering and analysing the SPG, such as a user friendly query
language, and several useful library functions that can be used in more complex programmed queries [
          <xref ref-type="bibr" rid="ref26">26</xref>
          ].
RefactorErl also performs special prede ned semantic analyses on the SPG. One of these is the zeroth and rst order
data ow analysis that discovers how data can ow between the syntactical elements of an Erlang program and
marks these data ow relations as edges between the corresponding SPG nodes [
          <xref ref-type="bibr" rid="ref11 ref25">25, 11</xref>
          ]. Another one is dynamic
function call analysis that discovers the functions called by dynamic function calls, and represents this
relationship with an edge in the SPG between the corresponding function node and the node of the dynamic caller
expression [
          <xref ref-type="bibr" rid="ref15">15</xref>
          ].
3.2
        </p>
      </sec>
      <sec id="sec-3-2">
        <title>A simpler metamodel for describing abstract state machines</title>
        <p>
          In this section we will describe a simple state machine metamodel, depicted by Figure 2, with which we represent
the target state machines of the transformation. We showed in [
          <xref ref-type="bibr" rid="ref19">19</xref>
          ] that this metamodel (and its instances)
can be mapped onto the UML state machine metamodel (and its instances). This intermediate state machine
language explicitly highlights the elements we utilise from UML. Later in this section we will introduce a notation
for these elements. For implementation purposes, the intermediate state machine can be omitted altogether, by
substituting the UML state machine element descriptions for the corresponding elements in our notation.
        </p>
        <p>The target state machines will basically consist of states (AnyState) and transition (Transition) elements
between those states. There are four kinds of states: ordinary states (State), the initial state (InitState), stop
states (StopState), and choice states (ChoiceState). Every transition may have exactly one source and one
target state. States may have arbitrary number of incoming and outgoing edges, including zero. Transitions
may have trigger and guard attributes, depending on whether their source state is an ordinary state or a choice
state, respectively. In this paper, triggers and guards will be represented as simple strings constructed from
events and guard expressions in the Erlang source code. In order to make the target state machines executable,
further research could extend this approach to include a more sophisticated representation for trigger and guard
elements. In the following sections the set of all states in a speci c state machine instance will be denoted as
VF SMG, while the set of all transitions will be denoted as EF SMG.
Let Init be the following set of gen fsm callback functions:</p>
        <p>Init d=ef finit/1; handle event/3; handle sync event/4; handle info/3; code change/4g
As per the speci cation of the gen fsm behaviour, the functions in Init, when triggered, can put the state
machine in any arbitrary state, independently of the actual state. If we only consider the behaviour of an
Erlang state machine in terms of states and transitions, but do not consider the memory changes (side e ects)
accumulated during the execution, then it can be said that these functions e ectively restart the state machine.
Therefore, it makes sense to model these as initial states, i.e. states from which the state machine execution can
be started.</p>
        <p>
          To describe the transformation rules we will use a textual notation to denote a mapping from nodes in the
SPG and states in the state machine, and also its inverse, a mapping from states to nodes. Since we previously
distinguished four types of states, we will use a di erent function for every type: each of these maps a node to
a state with the associated state-type. All these functions can be de ned to be invertible.
state 2 VSP G ! VF SMG maps nodes to ordinary states. The nodes mapped to ordinary states will precisely
be the semantic nodes representing transition functions, i.e. the user de ned callback functions of the gen
fsm behaviour, bearing the name of a state. We chose these nodes, since they have a 1:1 correspondence
with the states of the state machine implemented by the analysed Erlang module.
choice 2 VSP G ! VF SMG maps nodes to choice states. The nodes mapped to choice states are either
representing functions with multiple clauses, or they are representing branching expressions. For brevity,
in this paper we only touch upon the latter { and simpler { case: branching expressions. We presented
handling of the former case in [
          <xref ref-type="bibr" rid="ref18">18</xref>
          ].
stop 2 VSP G ! VF SMG maps nodes to stop states. Following the speci cation of the gen fsm behaviour, the
nodes mapped to stop states will precisely be those representing tuple expressions, that are return points of
a transition function, and have the stop atom as their rst element.
init 2 VSP G ! VF SMG maps nodes to initial states. Following the speci cation of the gen fsm behaviour
and our previous remark, the nodes mapped to initial states will precisely be those representing the functions
in Init.
        </p>
        <p>After applying the transformation, every state in the target state machine will correspond to a node in the
SPG, and every transition in the target state machine will correspond to an edge sequence in the SPG. In Section
4 where we describe the transformation rules we will denote this state-node correspondence relation with the
function node : VF SMG ! VSP G. The node function is de ned as the inverse of the node-state mapping described
earlier. Thus, if we regard the earlier functions as relations, i.e. sets of ordered pairs, then
node d=ef (state [ choice [ stop [ init) 1
Since the range of these functions are pairwise disjoint, and all four functions were invertible, node always exists.</p>
        <p>In the de nition of the transformation rules, we also use a textual notation to denote the trigger and guard
labels of the transitions. As mentioned earlier, we represent these as simple human or machine-readable strings.
The set of all strings will be denoted by S.</p>
        <p>trigger 2 VSP G ! S maps nodes representing the rst parameter pattern of a transition function to a string.
For example, the string may consist entirely of the Erlang term denoting this parameter.
guardbranch, guardif , guardtry, guardcatch,guardafter and guardclause 2 VSnP G ! S functions map nodes
representing the pattern and guard expressions of the clauses of the various branching expressions can be
found in the Erlang programming language. Since it may be necessary to use more patterns and guard
expression to uniquely identify a state machine guard, we assume these functions can handle more parameters.
The exact value of n depends only on the guard function it describes.
3.3</p>
      </sec>
      <sec id="sec-3-3">
        <title>An algorithm for transforming program graphs to state machines</title>
        <p>In this section we present an algorithm, that { with the help of a prede ned set of transformation rules {
transforms the semantic program graph of any Erlang state machine adhering to the speci cation of the gen fsm
behaviour, to a state machine model described in UML or the simple state machine language we introduced in
Section 3. Since most of the application speci c logic (the logic related to the RefactorErl semantic program
graph) of the transformation are encoded in the transformation rules, the algorithm itself is relatively simple.
Basically it is an extended depth rst search, that selects the neighbouring nodes to discover, based on prede ned
rules.</p>
        <p>This approach has several advantages. To extend the transformation for currently unhandled cases, we do
not have to modify the procedural algorithm, we only have to add more rules to the transformation sets. For
example, UML o ers several state machine features (e.g. embedded state machines, variables, e ects) that could
be utilised by the transformation, after the rule set were to be appropriately extended to handle these cases.
Also, the rule sets encapsulate the RefactorErl speci c logic, which means we could use the same algorithm with
other static analysis frameworks too. We just have to swap the RefactorErl speci c rule sets to the rule sets
speci c to the other static analysis framework. It is worth noting though that devising a rule set, in general, is
not a trivial task. Finally, this approach opens up the possibility to execute rules in parallel, to achieve better
runtime performance.</p>
        <p>
          Informally, our transformation algorithm, together with the rules presented in Section 4, will perform the
following tasks:
1. Starting with the transition functions in Init, the algorithm analyses the return point of each transition
function it visits.
2. If during the analysis, it discovers an branching expression or a function with multiple clauses, denoted as b,
the corresponding choice(b) choice state will be added to the state machine. Then the algorithm continues
by analysing the return points of each clause of the b branching expression or function.
3. If during the analysis a t tuple is discovered, it will further analysed t to decide whether it indicates a stop
state, or an ordinary state. In the former case, the corresponding stop(t) stop state will be added to the
state machine, and the algorithm backtracks. In the latter case, it will analyse the appropriate element of
t (see the gen fsm speci cation [
          <xref ref-type="bibr" rid="ref14">14</xref>
          ]), to nd out the f name of the target state of the currently analysed
transition function. If found, the algorithm will continue to analyse the transition function with name f .
4. For any other node type, the algorithm will proceed in way speci c to this node type. In most cases it
will utilise the data ow analysis provided by the RefactorErl tool [
          <xref ref-type="bibr" rid="ref11 ref25">25, 11</xref>
          ]. Since the data ow analysis may
abstract away information necessary to analyse gen fsm modules, we require node type speci c analysis in
some cases.
5. When the algorithm adds an s state to the state machine, it will also have to add an appropriate transition
between s and the old state o, which corresponds to the transition function named o, that was analysed as
s was discovered.
        </p>
        <p>More speci cally, our algorithm will perform these generic tasks in three separate stages: an analysis stage, a
transformation stage, and a synthesis stage. In the analysis stage, our goal is to discover precisely those nodes
and edges in the SPG that will be mapped to state machine elements in later stages. The result is a ltered
SPG, called the analysed SPG, consisting only these nodes and edges. The edges are relabelled with semantic
information about their role in the future state machine. The transformation stage eliminates nodes and edges
from this analysed SPG, so as to obtain a reduced SPG that can be mapped to a state machine instance with
relative ease. The synthesis stage will map the reduced SPG to a state machine instance, producing the nal
result of the transformation.</p>
        <p>The general algorithm with the three stages is denoted on Figure 1. All three stages will start a depth rst
algorithm from the function nodes in the Init set or, in the case of the synthesis stage, init(Init), the set of the
initial states corresponding to the nodes in Init. For certain edges we will not continue the analysis, i.e. will not
extend the target nodes of these edges. The types of these edges are listed in the Exclude1 set.</p>
        <p>Later in this paper we will de ne separate rule sets for each of these stages. Rule sets R1 and R2 {
corresponding to the analysis and synthesis stage respectively { are side-e ect free. By matching the left hand side
of the rules to a graph, their right hand side can be used to construct another graph. Rules in rule set R3 {
Algorithm 1 DiscoverF SM G(SP G; R1; R2; R3)
1: Init finit=1; handle event=3; handle inf o=3;</p>
        <p>handle sync event=4; code change=4g
2: Exclude1 ftri;gger; co;nd ; fsm;guardg
3: RelationGraph discover(Init; R1; Exclude1; SP G)
4: T RelationGraph transf orm(Init; R2; RelationGraph)
5: F SM G discover(init(Init); R3; ?; T RelationGraph)</p>
      </sec>
      <sec id="sec-3-4">
        <title>6: return F SM G</title>
        <p>corresponding to the transformation stage { are not side-e ect free. By matching their left hand side in a graph,
their right hand side can be used to modify this same graph.</p>
        <p>The analysis stage and the synthesis stage will make use of the same backtracking algorithm, that tries to
pattern match every rule to an environment of the current node, and determines the next neighboring nodes to
visit using the matching rules. The transformation stage makes use of a slightly modi ed backtracking algorithm.
This one will try to apply a rule to a node as many times as possible, before moving on the next node. After
it visited every node, it will proceed to repeat this procedure with the next rule. The stage ends when the last
rule was applied as many times as possible to every node in the graph.
4</p>
      </sec>
    </sec>
    <sec id="sec-4">
      <title>Speci cation of the transformation rules</title>
      <p>
        As mentioned earlier, the transformation is realised by two backtracking algorithms, that are performing pattern
matching on their respective input graphs with the left hand side (LHS) of certain set of rules, and then apply
the right hand side (RHS) of the matching rules to construct an output graph, or { in case of the transformation
stage { to modify the input graph. This section describes the algorithms referenced by Figure 1 and outlines
the rule sets utilised by the analysis, transformation and synthesis stages. The keep the discussion concise, we
only selected a few rules to present here, and these can only be used to transform small, simple state machines,
like the one demonstrated in Section 5. We presented more elaborate rule sets capable of transforming large,
complex state machines, in the appendices of [
        <xref ref-type="bibr" rid="ref18">18</xref>
        ]. Our reference implementation is also based on these larger
rule sets, and, as described in Section 6, it was successfully tested on state machines, selected from the sources
of large, open source, widely used Erlang applications.
      </p>
      <p>First, we introduce a notation that will be used to denote these rules. The LHS of the rules will consist of edge
patterns and logical expressions, featuring relations between nodes of the input graph. In these rules, x always
denotes the node that the pattern matching must start on, while other variable names are arbitrary. For example,
if a rule has the pattern x de!f y 2 SP GE as its LHS, then the rule matches on some x0 node of the input graph if
and only if there is an edge, between the nodes x0 and some arbitrary y0, with the label def. We use a shorthand
notation for connecting relations: we write x ! y ! z SP GE instead of x ! y 2 SP GE ^ y ! z 2 SP GE .
Edges in the semantic program graph are ordered: we denote restrictions on the sequence number of an edge
by denoting the number after the edge label. E.g. a rule with x clause=!2 y 2 SP GE in its LHS matches on
x0 only if there is an edge with the label clause and the sequence number 2 between x0 and some other node.
Unnumbered edges in the patterns may match edges of the input graph with arbitrary sequence numbers. Nodes
in the semantic program graph can also possess various properties: we denote restrictions on a property of a node
with an equality expression between braces after the node. E.g. x[type = tuple] elem=!1 y 2 SP GE matches on
some node x0 only if the pattern x elem=!1 y 2 SP GE matches and the type property of x0 is of the value tuple.
Pattern nodes without property restrictions may match nodes with arbitrary values on their properties.
4.1</p>
      <sec id="sec-4-1">
        <title>Analysis stage</title>
        <p>In the analysis stage we traverse part of the semantic program graph of RefactorErl to identify all the nodes used
by the following stages, and to attach transformation-speci c semantic information to the edges by relabelling
them. This traversal is done by the backtracking algorithm described in Figure 2, utilising the rules collected in
Table 1.</p>
        <p>The backtracking algorithm in Figure 2 starts by visiting and expanding the nodes in the Init set. To expand
a node x0, it iterates over all the rules in Table 1, and tries to pattern match these rules on x0. For any matching
rules, it adds the RHS of the matching rule to the node in the output graph, corresponding to x0, and puts the
Algorithm 2 discover(Init; Rules; Exclude; G)
1: V Init
2: E ?
3: V isited ?
4: S stack(Init)
5: while S 6= ? do
6: v S:pop()
7: if v 62 V isited then
8: V isited:add(v)
9: N Edges ?
10: for r 2 Rules do
11: N Edges:add(r:match(G; v))
12: end for
13: for e 2 N Edges do
14: E:add(e)
15: V:add(endpoint(e))
16: if e:edgetype() 62 Exclude then
17: S:add(endpoint(e))
18: end if
19: end for
20: end if
21: end while
22: return (V; E)
endpoint, denoted in the rules by y, in the stack to expand later. If the type of the edge in the RHS of the
matching rule is featured in Exclude, then the y endpoint will not be expanded. As both the input graph and
the rule sets are nite, the backtracking algorithm is guaranteed to terminate, and operates in polynomial time.</p>
        <p>Apart from identifying the neighbouring nodes to be visited by the backtracking algorithm, the rules in Table
1 describe how certain edge sequences encountered in the semantic program graph will be labelled in the analysed
semantic program graph. These labels indicate the semantic roles of the endpoints of their respective edges, and
these roles will determine how each node will be treated in the subsequent stages. Labels ;s0 and ; denote a
s
transition function node at their source, nam;eof connects an atom with a function with the same name as the
value of that atom, and the edges with tri;gger and co;nd labels point to nodes that will be used to construct
trigger and guard labels in the nal state machine. The fs;m0 label is a special label that needs to substituted
to other labels as speci ed by Table 2. This substitution only serves to make our de nition more compact: it
can be eliminated in design time by adding new rules by combining the conditions of the rules in Table 1 and
Table 2. Because of this, the substitution step does not need to appear in the algorithm either. As for the labels
appearing in Table 2, ;c denotes a branching expression at its source, ;a0 and ;a denote ordinary functions, ;e
points to a tuple that will be mapped to a stop state, and ;t points to a tuple which contains the name of a state
in the state machine. The label ;0 does not convey any speci c semantic meaning, it is only used to specify the
next nodes to be visited by the backtracking algorithm.</p>
        <p>In later stages, transition functions will be mapped to states, and each function clause will correspond to a
state transition leading out of that state, with a trigger label constructed from the rst parameter (the event)
of the clause. Since the gen fsm speci cation allows for multiple clauses to have the same event, this mapping
could results in non-deterministic state machines. To avoid this, we introduce a choice state for every group
of clauses with the same event. This way there will be only one transition for each event between the original
state and the choice state, and we will use guard labels on the transitions leading out from the choice states to
distinguish between clauses in the same group. Ordinary functions with multiple clauses, similar to branching
expressions, will be mapped to choice states, while those with single clauses do not have to be denoted in the
resulting state machine.</p>
        <p>In Table 2, the predicate multiclause(x) is true i the node x is a node in the semantic program graph,
representing a function with multiple clauses. Let s denote a relation between function clauses, and let c1 s c2
be true for c1; c2 of a function i their rst parameter patterns are identical. As s is an equivalence relation,
it partitions the clauses of a function into equivalence classes. In Table 1 the predicate multiclausegroup(x) is
true i the node x represents a transition function with multiple clauses and there is at least one class of s with
at least two elements, i.e. the function has at least two clauses with identical rst parameter patterns. If x is an
atom, f ind(x) denotes the set of all functions with the same name as the value of x.</p>
        <p>LHS
x de!f y 2 SPGE ^ : multiclausegroup(y)
x de!f y fclause=!i cl pattern=!1 patt SPGE
x[type=atom] 2 SPGV ^ y 2 find(x)
x[type=funcjfun expr] fclause=!i clause cre!t y SPGE
type(x) 2 fif exprjcase exprjtry exprjreceive exprg ^</p>
        <p>x (exprcljcatchcljaftercl)=!i cl cre!t y 2 SPGE
type(x) 2 fcase exprjtry exprjreceive exprg ^</p>
        <p>x exprcl=!i cl pattern=!1 patt SPGE
x[type=case exprjtry expr] exprc!l cl1 2 SPGE ^</p>
        <p>x headcl=!i cl2 cre!t y SPGE
x trig;ger=i patt
x nam;eof y
x fsm;0=i y
x condb;ranch=i patt
x cond;head=i y</p>
        <p>x fs;m0 y</p>
        <p>Condition (x; y)
type(y) = if exprjcase exprjtry exprjreceive expr
type(y) = f uncjf un expr ^ : multiclause(y)
type(y) = f uncjf un expr ^ multiclause(y)
type(y) = atom</p>
        <p>type(y) = tuple ^
y elem=!1 z 2 SP GE ^
In the transformation state we reduce the analysed semantic program graph to acquire a graph that can be easily
mapped to a state machine. For this stage we slightly modi ed the backtracking algorithm. This algorithm
iterates over all the rules in a predetermined order, and in each iteration it visits the nodes of the analysed
semantic program graph to apply the actual rule as many times as possible. Since the matching rules speci ed
in Table 3 always eliminate some of the edges from their LHS, the algorithm is guaranteed to terminate. Since
eliminated nodes will not be visited again, this algorithm also operates in polynomial time.
Algorithm 3 transf orm(Init; Rules; G)
Require: Rules is ordered according to the transformation rule set
1: for r 2 Rules do
2: V isited Init
3: S stack(Init)
4: while S 6= ? do
5: v S:pop()
6: if v 62 V isited then
7: V isited:add(v)
8: do
9: success r:execute(G; v)
10: while success
11: S:add(G:children(v))
12: end if
13: end while
14: end for</p>
        <p>
          We used a procedural approach to describe the rules for this stage: the RHS of these rules contains simple
statements that are inserting or removing edges to or from the input graph. If the LHS of a rule matches, the
modi cations speci ed in the RHS are performed on the input graph. As mentioned previously, we only included
in this paper those rules that are necessary to demonstrate the transformation of a small example state machine,
and a more elaborate extended rule set capable of transforming any Erlang state machines is presented in the
appendices of [
          <xref ref-type="bibr" rid="ref18">18</xref>
          ]. While the rules presented here could have been expressed with a declarative approach, it
would have been more di cult to express declaratively those in the extended transformation rule set. The rule
x11 contracts nam;eof edges, while x12 contracts ;s0 edges. The rule x13 contracts ;t and ;0 edges in a way that
the new edge inherits the edge sequence number of the contracted edge. With the exception of the placeholder
0
;, all these edges can be used to eliminate unnecessary or unwanted segments from the analysed program
graph. For example, branches that would be mapped to a choice state with only one outgoing transitions, or for
example dead ends, i.e. paths that would be mapped to transitions without a target state. We also described
these eliminations in [
          <xref ref-type="bibr" rid="ref18">18</xref>
          ].
        </p>
        <p>)
9i1; :::; in (n</p>
        <p>1) :</p>
        <p>R 2 ft; 0g ^
S 2 fa; c; e; sg ^</p>
        <p>x R;=i y ;S z
x14
x15
x16
x11
x12
x13
8k 2 fi1; :::; ing (insert(x e;=k z)) ;
8k 2 fi1; :::; ing (</p>
        <p>remove(x e;=k yk nam;eof z)
8k 2 fi1; :::; ing (
insert(x S;=k zk) ;
remove(y S;=k zk)
) ;
remove(x ;s0 y)
insert(x S;=i z) ;
remove(x R;=i y ;S z)
4.3</p>
      </sec>
      <sec id="sec-4-2">
        <title>Synthesis stage</title>
        <p>In the last stage we map the reduced analysed semantic program graph to a state machine. The purpose of the
previous transformation stage was to make the rules in the synthesis stage simpler. As shown in Figure 1, this
stage reuses the backtracking algorithm in Figure 2 with the rules speci ed in Table 4. This time the algorithm
expands states instead of program graph nodes. In the analysis stage, the LHS of the rules were pattern matched
to the input semantic program graph, and the news edges identi ed by the RHS were added to the output
analysed program graph. In the synthesis state, the input graph is the reduced analysed program graph and
output graph is a state machine, thus the LHS pattern matching is performed on the reduced analysed graph,
while the new edges in the RHS are transitions, which are added to the state machine. Similar to the fs;m0 label
of the rst stage, the la!b labels in the RHS of the rules in Table 4 can be substituted according to Table 5.
Again, this label substitution is only required to keep the description concise, and it can be accomplished during
design time by adding new rules that combine the corresponding conditions and rules of the two tables.</p>
        <p>LHS
node(v) ;e y[type6=tuple]
node(v) ;e y[type=tuple]
node(v) ;c branch
v la!b stop(y)
v la!b choice(branch)
node(v) fsm;0=i node(u) ^</p>
        <p>condb;ranch=i patt1 ^
node(v) con;dhead hd</p>
        <p>trigger(patt)
guardbranch(hd; patt1)
5</p>
      </sec>
    </sec>
    <sec id="sec-5">
      <title>Demonstration of the state machine transformation</title>
      <p>In this section we demonstrate the transformation method previously introduced, by presenting the intermediate
results of the transformation of a small Erlang state machine. Although we intentionally selected a simple
state machine for this example, an implementation of the transformation was also successfully tested on large
state machines selected from open source Erlang applications. The code of the example state machine shown in
Figure 3 describes the language of identi ers: words starting with letters and proceeding with letters, numbers
or underscores. We omitted from the source code some of the callbacks required by the gen fsm speci cation,
and also those functions that can be used to interact with the state machines to initialise the state machine,
and to send events to it. In this example events could be letters read from some input word. The state machine
accepts identi ers ending with the line ending character ($nn), and rejects every other words. The initial state
of this state machine is pos1, where it transitions to a rejecting state upon receiving a non-letter character, and
transitions to posOther state upon receiving a letter. In posOther, it transitions to an accepting state upon
receiving a line ending character, stays in posOther upon receiving alphanumeric characters or underscores, and
transitions to a rejecting state upon receiving any other event.
E
r
o
t
c
a
f
e</p>
      <sec id="sec-5-1">
        <title>Demonstration of the analysis stage</title>
        <p>The rst stage of the transformation applies the algorithm in Figure 2 to the semantic program graph. The
result of this analysis stage is shown in Figure 5. This stage identi es all the nodes used by the following stages
and attaches transformation-speci c semantic information to the edges by relabelling them.</p>
        <p>The rst node to analyse is the init/1 function node, since init/1 is element of the Init set. This function
has only one clause, thus the rst rules that match are x2 and x3. At this point the resulting graph consists of
the edges ;s0 and trig;ger=1, and their nodes. Since trig;ger=1 is a member of Exclude1, we will not expand the
target node of this edge. The next node to expand, as speci ed by x2, is the form node. The rule x5 matches,
thus we add an fs;m0 edge to the result graph. We may choose to do the substitution of fs;m0 right now, based on
Table 2, swapping it to ;t. The left hand side of x9 matches the tuple node, thus after substituting fs;m0, we add
an ;e edge to the result. Finally x4 matches on the atom node, thus we add to results a nam;eof edge, pointing
to the semantic node of the pos1/3 function. At this point the analysis of the init/1 function concludes, since
we found the name of the rst state, and the next function to analyse.</p>
        <p>On the pos1/3 function node we can match x2 and x3 again, since all the clauses of pos1/3 have di erent
events. Now, we can match x5 on two branches, one for each clause. The rst tuple represents a stop state, thus
we have to substitute fs;m0 by ;e. There are no rules matching on this branch, thus the algorithm backtracks to
the other branch. In the other branch fs;m0 is substituted to ;c. We can match x6, x7, and x8 on the case expr
node and its clauses. Again, con;dhead, and cond;branch are in Exlcude1, thus their target nodes { used in later
stages to construct guards for the state machine { will not be expanded. In the left branch that matched x6, we
substitute fs;m0 by ;t, and then continue the analysis of this branch by matching x10 on the tuple, and swap fs;m0
with ;e. Finally, we nd the posOther/3 function node by matching x4. The analysis of posOther/3 is almost
identical, except that the last matching of x4 will result in a nam;eof edge pointing back to the posOther/3 itself.
With this the analysis stage concludes.</p>
      </sec>
      <sec id="sec-5-2">
        <title>Demonstration of the transformation stage</title>
        <p>In the transformation stage we start with the analysed program graph, resulting from the analysis stage, shown
in Figure 5, and reduce it to graph, that can be mapped to a state machine model relatively easily. The result
of the transformation stage is depicted by Figure 6.</p>
        <p>
          Since in this example the state machine we transform is small, we only have to use a few reductions. To reduce
the analysed semantic program graph of larger state machines may require more kinds of reduction rules, which
are described in the appendix of [
          <xref ref-type="bibr" rid="ref18">18</xref>
          ]. The rst step is to contract every ;e, nam;eof edge pairs into an ;e edge by
applying x11. Next we contract the ;s0 edges by applying x12. While the ;s edges highlight transition functions
with multiple clauses, each having the same event parameter, this small program did not have these kinds of
functions, therefore the analysed program graph features only ;s0 edges. We could use the ;t edges to recognise
and eliminate branches that violate the syntactic convention about tuples in function return points, containing
the atom with the name of the next state, speci ed in the gen fsm speci cation. The example program graph
follows the speci cation, therefore these edges are not needed anymore, and can be contracted, by applying x13.
As a result we get the reduced analysed program graph shown in Figure 6.
        </p>
      </sec>
      <sec id="sec-5-3">
        <title>Demonstration of the synthesis stage</title>
        <p>
          In this stage we map the reduced analysed program graph, shown in Figure 6, unto a state machine model,
depicted by Figure 7. First, we add init(init=1) (the initial state created from the function node of init/1)
to the state machine, since init/1 is the only element of Init in this example. The rule x14 matches the node
corresponding this state (i.e. init/1) with the function node of pos1/3, thus we add state(pos1=3), and a
transition to the state machine. We may choose to do the substitution of la!b right now based on Table 5,
swapping it to trigger label constructed from the joker pattern pointed by the trig;ger=1 edge. Next, we can match
both x15 and x16 on the pos1/3 node. The former results in adding a stop state to the state machine, while
the latter results in adding a choice state. To substitute la!b for a trigger, as speci ed by the substitution rule,
we have utilise the edge numbering to select the pattern nodes corresponding to each transitions: the pattern
pointed by trig;ger=1 will be used to label the transition of the stop state corresponding to the tuple node pointed
by e;=1, and trig;ger=2 for the choice state corresponding to the branching expression pointed by e;=2. Next, x14
and x15 matches on the node of the choice state. This time, la!b is substituted to a guard, constructed with
the appropriate expressions pointed by the con;dhead and cond;branch edges. With the match of x14, we added
state(posOther=3) to the state machine. The corresponding posOther/3 node can be analysed similarly to
pos1/3. Finally, we get the result of the transformation, a complete state machine, as shown in Figure 7.
To test and measure the previously presented transformation method during actual physical execution, we also
created a reference implementation in Erlang. Instead of creating an application that communicates with a
RefactorErl instance via some remote communication protocol, we realised the implementation by extending
the source code of the open source RefactorErl framework to eliminate the need of creating a bridge, and to
minimise the number of dependencies. To implement the matching rules, we were able to make use of the function
clause pattern matching in the Erlang language, and used memoisation technique to avoid repetitive evaluation
of functions called from multiple places in the source code. We also implemented a few small extension not
mentioned in this paper. For example, initialising special states to stand in place of undiscoverable states, or the
recognition of a state machine based on the functions calls that start that state machine. We also used Erlang
to generate the XMI les storing the resulting UML state machines, and used txtUML [
          <xref ref-type="bibr" rid="ref13">13</xref>
          ], also developed at
the Eotvos Lorand University (ELTE) to generate graphical diagrams from these UML state machine models.
        </p>
        <p>
          We executed the implemented algorithm on Erlang state machines found in large, popular, open source Erlang
applications. Our sample state machines are from the sources of the Ejabberd communication server [
          <xref ref-type="bibr" rid="ref6">6</xref>
          ], the
Riak distributed NoSQL database [
          <xref ref-type="bibr" rid="ref9">9</xref>
          ], and the Erlang OTP library [
          <xref ref-type="bibr" rid="ref14">14</xref>
          ]. Unfortunately, the more general state
machines are less commonly used than the more specialised behaviours, like gen server, and gen event, which
means we had to test on a smaller sample. Still, the selected sample of state machines seems to have a nice
enough variety both in length and complexity.
        </p>
        <p>Our results are summarised in Table 6, containing, for each Erlang state machine module the number of
lines of code in the module, the number of discovered states and transitions in the resulting state machine,
and the runtime of the transformation (minimum, maximum, average, median runtimes in microseconds). To
measure runtime, we repeated every measurement 500 times for each le, thus creating a 500 element sample for
each Erlang state machine. The runtime data does not include the time needed to load the respective Erlang
applications in the RefactorErl databases, since this operation only has to be performed once for every software
application, and in general, the size of the complete application source code is expected to be independent from
the size of the individual Erlang state machines the application contains. Since the resulting state machines
usually contain choice states, the measured number of states and edges are expected to be higher than the
(ordinary) states explicitly de ned by the Erlang state machines.</p>
        <p>File name
ejabberd c2s
ejabberd http bind
ejabberd http ws
ejabberd odbc
ejabberd s2s in
ejabberd s2s out
ejabberd service</p>
        <p>eldap
mod irc connection</p>
        <p>mod muc room
mod proxy65 stream
mod sip proxy
riak kv 2i aae
riak kv get fsm
riak kv put fsm
riak kv mrc sink
ssh connection handler
tls connection</p>
        <p>Taking our use case into account, fast runtimes are not of critical importance to the success of the
transformation. However, even the slowest execution time, measured with tls connection module in Erlang OTP, is quite
small with 3 seconds. We have to remind the reader though, that we used memoisation in the implementation
to optimise the runtime: without the elimination of repetitive SPG branch evaluations, the algorithm would be
noticeably slower.</p>
        <p>According to Figure 8 (after eliminating the outlier tls connection), the number of lines positively correlates
with time needed to execute the transformation. This phenomenon can be explained by the fact, that the
algorithm needs more time to analyse deeper function return points, and the depth of these return points
are likely correlated with the length of the source code of the module. Although not shown here, the same
connection can be observed between the states in the resulting state machines and the transformation execution
time. Since we mapped branching expressions to choice states, and deeper function return points are more
likely to contain such branching expressions, it is also more likely that we will create more choice states for
those state machines with deeper return points and longer transformation execution times. Figure 9 also shows
a positive, although less de nite correlation between the number of lines and the number of states. Using the
same reasoning, we conjecture that deeper function return points will have more lines, and are also more likely to
contain branching expressions. Conversely, Erlang state machines with more states, and therefore more transition
function de nitions, are also more likely to contain more lines of code. Still, because of the low number of state
machine modules in the samples, these assertions probably require more thorough research with a bigger sample
size, and perhaps with the use of more advanced metrics.
7</p>
      </sec>
    </sec>
    <sec id="sec-6">
      <title>Related work</title>
      <p>
        While most CASE tools support source code generation from UML models, the inverse operation, generation of
UML models from source code (code-model transformation) is less prevalent. This is probably explained by that
code-model transformation requires complex static and/or dynamic analysis tools. For the most popular
objectoriented languages, industrial tools suitable for this task usually support the discovery of UML class diagrams
and sequence diagrams from the program sources. Such tool are for example ObjectAid [
        <xref ref-type="bibr" rid="ref8">8</xref>
        ] and Eclipse MoDisco
[
        <xref ref-type="bibr" rid="ref5">5</xref>
        ] for Java, Microsoft Visio [
        <xref ref-type="bibr" rid="ref3">3</xref>
        ] and Altova UModel [
        <xref ref-type="bibr" rid="ref1">1</xref>
        ] for C# s Visual Basic, Visio and Doxygen [
        <xref ref-type="bibr" rid="ref2">2</xref>
        ] for C++.
Another interesting approach makes use of static and dynamic analysis techniques to detect design patterns in
object-oriented source code [
        <xref ref-type="bibr" rid="ref23">23</xref>
        ].
      </p>
      <p>
        Model transformations, a recent, but well researched area can also be of interest concerning state machine
transformations. While this methodology is mostly used to specify and execute transformations between models,
it can be extended to also handle entities not usually considered to be models, such as syntax trees. Closely
related to the topic of our current paper, we presented a procedure to map a subgraph of the SPG of RefactorErl
to an SPG model by utilising triple graph grammars [
        <xref ref-type="bibr" rid="ref22">22</xref>
        ] to transform this SPG model to a valid UML state
machine model [
        <xref ref-type="bibr" rid="ref19">19</xref>
        ]. By employing a formal mathematical theory, this approach provably obtained advantageous
properties concerning among others the correctness and completeness of its results and the e ciency of its
execution. On the other hand, since it utilises high level model transformation concepts, implementations of
that procedure are expected to be a magnitude slower than the directly implementable approach presented in
our current paper.
      </p>
      <p>
        Similarly to the tool introduced in the present paper, Erlesy [
        <xref ref-type="bibr" rid="ref4">4</xref>
        ] is another tool that can be used to visualise
Erlang state machines. Instead of utilising a powerful, but complex static analysis framework, Erlesy uses
standard Erlang tools to parse state machine source code. Erlesy does not include choice states and guards in its
output, thus the results will possibly represent non-deterministic state machines. Unlike our approach, Erlesy
uses loop edges to model the handle callbacks of the gen fsm speci cation: an advantage of this approach is that
it follows gen fsm semantics more closely, a disadvantage is that it inevitably clutters the resulting state machine
graphs with loop edges. Erlesy is a readily usable, lightweight solution to visualize Erlang state machines in
various output formats, like Graphviz, PlantUML or D3.js.
      </p>
      <p>
        There is also a mature methodology for discovering deterministic nite state machines using dynamic code
analysis, called state machine induction and behavioural inference. Procedures applying this methodology
execute the analysed program based on speci c use case scenarios (e.g. a sequence of function calls), and collect
information to generate a state machine model. This task requires the elimination of non-deterministic
transitions, and transitions featuring recurring execution traces. Such state machine reducing methods are the k-tail
algorithm, and the QSM algorithm. QSM o ers the user various valid reductions, and proceeds to perform the
reductions chosen by the user. Later methods can eliminate the need for these user dialogues by utilising static
source code analysis to nd good answers automatically and with high precision [
        <xref ref-type="bibr" rid="ref27">27</xref>
        ]. The Erlang language is
also well suited for this task due to its statelessness and advanced program execution tracing facilities [
        <xref ref-type="bibr" rid="ref10">10</xref>
        ].
      </p>
      <p>
        While the dynamic approach to state machine discovery enjoys bene ts from the well de ned methodology,
the requirement for use case scenarios hinders its usability for large systems. With static analysis, it is possible
to discover the complete state machine, relying only on the source code. One of the di culties arising from
using static analysis is identifying the relation between the implementation level programming patterns and high
level state machine concepts. And even if we solve this problem, in some special cases it is still impossible for
pure static analysis to lter out components (e.g. states, transitions) that can be never reached during program
executing (e.g. because of conditions that can only be evaluated to false). Thus, it can be stated that both
the dynamic and static analysis approaches have their advantages and disadvantages, therefore the choice is
dependent upon the goals and requirements of the task at hand. Our approach strongly relies on static analysis,
since the requirements of the gen fsm behaviour [
        <xref ref-type="bibr" rid="ref14">14</xref>
        ] makes it easier to identify and analyse the programming
constructs relevant to state machines, and the RefactorErl framework provides the means to perform deep and
comprehensive static analysis on Erlang source code.
8
      </p>
    </sec>
    <sec id="sec-7">
      <title>Conclusions</title>
      <p>In this paper, we introduced a method to transform Erlang state machines, implementing the gen fsm behaviour,
to state machines described by UML, or similar state machine languages. To analyse Erlang programs, we used
the RefactorErl static analysis framework. We also de ned an UML-compatible state machine representation
to denote the target state machines of the transformations. The presented method consists of three stages: an
analysis stage, a transformation stage, and a synthesis stage. In each stage, a backtracking algorithm is executed
on the output of the last stage (or, in the case of the rst stage, the RefactorErl Semantic Program Graph),
and each stage utilises a separate set of transformation rules by means of pattern matching. The algorithms
themself are general enough not to depend on any static analysis framework, only the presented transformation
rules depend on the structural details of the RefactorErl Semantic Program Graph. By separating the algorithm
and the rules, we made it more easier to the extend of the transformation: one just has to add more rules to
the rule sets. By specifying the bulk of the transformation logic by rules, we also made it possible to parallelise
the algorithm to optimise it for environments with multiple processing units. We demonstrated the execution
and the results of each stage by a small example. We were able to realise a relatively fast implementation
of the algorithm. After testing our implementation on state machines selected from the source code of large,
popular, open source Erlang applications, we concluded that the time needed to perform the transformation on
an Erlang state machine is positively correlated with the number of lines of code in the program code of the state
machine. We also found similar correlation between the transformation execution time and the states created by
the transformation. We explained both phenomenon by conjecturing that deeper return point expressions need
more time to be analysed, probably have more lines of code, and contain more branching expressions.</p>
      <p>The evaluation of our implementation evidences that the method presented in this paper can be used to
construct UML state machine models, even from large and complex Erlang state machines. Still, several
opportunity remains for improvement, for example by extending the analysis with more elaborate RefactorErl queries
to discover even more state machine elements, or by targeting an even larger subset of all the features provided
by the UML state machine language, or even by preparing the method to generate executable state machines.</p>
    </sec>
  </body>
  <back>
    <ref-list>
      <ref id="ref1">
        <mixed-citation>
          [1]
          <string-name>
            <surname>Altova</surname>
            <given-names>UModel</given-names>
          </string-name>
          <year>2016</year>
          . http://www.altova.com/umodel.html. Accessed:
          <fpage>2016</fpage>
          -06-30.
        </mixed-citation>
      </ref>
      <ref id="ref2">
        <mixed-citation>
          <article-title>[2] Doxygen - Generate documentation from source code</article-title>
          . http://www.stack.nl/~dimitri/doxygen/. Accessed:
          <fpage>2016</fpage>
          -06-30.
        </mixed-citation>
      </ref>
      <ref id="ref3">
        <mixed-citation>
          [3]
          <string-name>
            <given-names>Microsoft</given-names>
            <surname>Visio</surname>
          </string-name>
          . http://visio.microsoft.com/. Accessed:
          <fpage>2016</fpage>
          -06-30.
        </mixed-citation>
      </ref>
      <ref id="ref4">
        <mixed-citation>
          <article-title>[4] Visualising Erlang development</article-title>
          . https://github.com/haljin/erlesy. Accessed:
          <fpage>2016</fpage>
          -06-30.
        </mixed-citation>
      </ref>
      <ref id="ref5">
        <mixed-citation>
          [5]
          <string-name>
            <given-names>Eclipse</given-names>
            <surname>MoDisco</surname>
          </string-name>
          . http://www.eclipse.org/MoDisco/. Accessed:
          <fpage>2016</fpage>
          -06-30.
        </mixed-citation>
      </ref>
      <ref id="ref6">
        <mixed-citation>
          <article-title>[6] Ejabberd, robust scalable and extensibe XMPP Server</article-title>
          . https://www.ejabberd.im/. Accessed:
          <fpage>2016</fpage>
          -06-30.
        </mixed-citation>
      </ref>
      <ref id="ref7">
        <mixed-citation>
          [7]
          <string-name>
            <given-names>Object</given-names>
            <surname>Management</surname>
          </string-name>
          <article-title>Group</article-title>
          . OMG Uni ed Modeling Language Superstructure. www.omg.org/spec/UML/. Accessed:
          <fpage>2016</fpage>
          -06-30.
        </mixed-citation>
      </ref>
      <ref id="ref8">
        <mixed-citation>
          [8] ObjectAid. http://www.objectaid.com/home. Accessed:
          <fpage>2016</fpage>
          -06-30.
        </mixed-citation>
      </ref>
      <ref id="ref9">
        <mixed-citation>
          [9]
          <string-name>
            <surname>Riak</surname>
            <given-names>KV</given-names>
          </string-name>
          ,
          <article-title>distributed NoSQL database</article-title>
          . http://basho.com/products/riak-kv/. Accessed:
          <fpage>2016</fpage>
          -06-30.
        </mixed-citation>
      </ref>
      <ref id="ref10">
        <mixed-citation>
          [10]
          <string-name>
            <given-names>Thomas</given-names>
            <surname>Arts</surname>
          </string-name>
          and
          <article-title>Cecilia Holmqvist. In the need of a design... reverse engineering Erlang software</article-title>
          .
          <source>10th International Erlang User Conference, EUC</source>
          .
          <year>2004</year>
          .
          <volume>10</volume>
          .
        </mixed-citation>
      </ref>
      <ref id="ref11">
        <mixed-citation>
          [11]
          <string-name>
            <surname>Istvan</surname>
            <given-names>Bozo</given-names>
          </string-name>
          , Daniel Horpacsi, Zoltan Horvath, Robert Kitlei,
          <article-title>Judit K}oszegi</article-title>
          , Mate Tejfel, and Melinda Toth. RefactorErl,
          <article-title>Source Code Analysis and Refactoring in Erlang</article-title>
          .
          <source>In Proceeding of the 12th Symposium on Programming Languages and Software Tools</source>
          , Tallin, Estonia,
          <year>2011</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref12">
        <mixed-citation>
          [12]
          <string-name>
            <given-names>Francesco</given-names>
            <surname>Cesarini</surname>
          </string-name>
          and
          <string-name>
            <given-names>Simon Thompson. Erlang</given-names>
            <surname>Programming. O'Reilly Media</surname>
          </string-name>
          ,
          <year>2009</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref13">
        <mixed-citation>
          [13]
          <string-name>
            <surname>Gergely</surname>
            <given-names>Devai</given-names>
          </string-name>
          , Gabor Ferenc Kovacs, and
          <string-name>
            <given-names>Adam</given-names>
            <surname>Ancsin</surname>
          </string-name>
          . Textual, executable,
          <source>translatable UML. Proceedings of 14th International Workshop on OCL and Textual Modeling co-located with 17th International Conference on Model Driven Engineering Languages and Systems (MODELS</source>
          <year>2014</year>
          )
          <article-title>Valencia</article-title>
          , Spain,
          <year>September 30</year>
          ,
          <year>2014</year>
          ., pages
          <fpage>3</fpage>
          -
          <lpage>12</lpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref14">
        <mixed-citation>
          [14]
          <string-name>
            <surname>Ericsson</surname>
            <given-names>AB</given-names>
          </string-name>
          .
          <article-title>Erlang Reference Manual</article-title>
          . http://www.erlang.org/doc/reference_manual/part_frame.html.
        </mixed-citation>
      </ref>
      <ref id="ref15">
        <mixed-citation>
          [15]
          <string-name>
            <given-names>Daniel</given-names>
            <surname>Horpacsi</surname>
          </string-name>
          and
          <article-title>Judit K}oszegi</article-title>
          .
          <article-title>Static analysis of function calls in erlang</article-title>
          . e-Informatica
          <source>Software Engineering Journal</source>
          ,
          <volume>7</volume>
          :
          <fpage>65</fpage>
          {
          <fpage>76</fpage>
          ,
          <year>2013</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref16">
        <mixed-citation>
          [16]
          <string-name>
            <surname>Zoltan</surname>
            <given-names>Horvath</given-names>
          </string-name>
          , Laszo Lovei, Tamas Kozsik, Robert Kitlei, Aniko Nagyne V g, Tamas Nagy, Melinda Toth, and
          <string-name>
            <given-names>Roland</given-names>
            <surname>Kiraly</surname>
          </string-name>
          .
          <article-title>Modeling semantic knowledge in Erlang for refactoring</article-title>
          .
          <source>In Knowledge Engineering: Principles and Techniques, Proceedings of the International Conference on Knowledge Engineering</source>
          , Principles and Techniques,
          <string-name>
            <surname>KEPT</surname>
          </string-name>
          <year>2009</year>
          , volume
          <volume>54</volume>
          (
          <year>2009</year>
          )
          <article-title>Sp</article-title>
          . Issue of Studia Universitatis Babe-Bolyai, Series Informatica, pages
          <volume>7</volume>
          {
          <fpage>16</fpage>
          ,
          <string-name>
            <surname>Cluj-Napoca</surname>
          </string-name>
          , Romania,
          <year>Jul 2009</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref17">
        <mixed-citation>
          [17]
          <string-name>
            <surname>Martin</surname>
            <given-names>Logan</given-names>
          </string-name>
          , Eric Merritt, and Richard Carlsson. Erlang and OTP in Action. Manning Publications Co.,
          <string-name>
            <surname>Greenwich</surname>
            ,
            <given-names>CT</given-names>
          </string-name>
          , USA, 1st edition,
          <year>2010</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref18">
        <mixed-citation>
          [18]
          <string-name>
            <given-names>Daniel</given-names>
            <surname>Lukacs</surname>
          </string-name>
          .
          <article-title>Erlang allapotgepek elemzese es transzformalasa UML-re</article-title>
          . Scienti c Students' Associations Conference, ELTE, Budapest, Hungary,
          <year>2016</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref19">
        <mixed-citation>
          [19]
          <string-name>
            <given-names>Daniel</given-names>
            <surname>Lukacs</surname>
          </string-name>
          .
          <article-title>Erlang allapotgepek modell alapu es transzformacioja UML-re</article-title>
          . Scienti c Students' Associations Conference, ELTE, Budapest, Hungary,
          <year>2016</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref20">
        <mixed-citation>
          [20]
          <string-name>
            <given-names>Chris</given-names>
            <surname>Raistrick</surname>
          </string-name>
          , Paul Francis,
          <string-name>
            <given-names>and John</given-names>
            <surname>Wright</surname>
          </string-name>
          .
          <article-title>Model Driven Architecture with Executable UML(TM)</article-title>
          . Cambridge University Press, New York, NY, USA,
          <year>2004</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref21">
        <mixed-citation>
          [21]
          <string-name>
            <given-names>Miro</given-names>
            <surname>Samek</surname>
          </string-name>
          . Practical UML Statecharts in C/C++:
          <article-title>Event-Driven Programming for Embedded Systems</article-title>
          . Electronics &amp; Electrical. Taylor &amp; Francis,
          <year>2009</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref22">
        <mixed-citation>
          [22]
          <string-name>
            <given-names>Andy</given-names>
            <surname>Schu</surname>
          </string-name>
          <article-title>rr. Speci cation of graph translators with triple graph grammars</article-title>
          , pages
          <volume>151</volume>
          {
          <fpage>163</fpage>
          . Springer Berlin Heidelberg, Berlin, Heidelberg,
          <year>1995</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref23">
        <mixed-citation>
          [23]
          <string-name>
            <given-names>Nija</given-names>
            <surname>Shi</surname>
          </string-name>
          and
          <string-name>
            <given-names>Ronald A.</given-names>
            <surname>Olsson</surname>
          </string-name>
          .
          <article-title>Reverse Engineering of Design Patterns from Java Source Code</article-title>
          .
          <source>In 21st IEEE/ACM International Conference on Automated Software Engineering (ASE'06)</source>
          , pages
          <fpage>123</fpage>
          {
          <fpage>134</fpage>
          ,
          <string-name>
            <surname>Sept</surname>
          </string-name>
          <year>2006</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref24">
        <mixed-citation>
          [24]
          <string-name>
            <given-names>Melinda</given-names>
            <surname>Toth</surname>
          </string-name>
          and
          <string-name>
            <given-names>Istvan</given-names>
            <surname>Bozo</surname>
          </string-name>
          .
          <source>Static Analysis of Complex Software Systems Implemented in Erlang. In Central European Functional Programming School</source>
          , volume
          <volume>7241</volume>
          of Lecture Notes in Computer Science, pages
          <volume>440</volume>
          {
          <fpage>498</fpage>
          . Springer,
          <year>2012</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref25">
        <mixed-citation>
          [25]
          <string-name>
            <surname>Melinda</surname>
            <given-names>Toth</given-names>
          </string-name>
          , Istvan Bozo, Zoltan Horvath, and
          <string-name>
            <given-names>Mate</given-names>
            <surname>Tejfel</surname>
          </string-name>
          .
          <article-title>First order ow analysis for Erlang</article-title>
          .
          <source>In Proceedings of the 8th Joint Conference on Mathematics and Computer Science (MACS)</source>
          ,
          <source>ISBN:978-963- 9056-38-1</source>
          ,
          <year>2010</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref26">
        <mixed-citation>
          [26]
          <string-name>
            <surname>Melinda</surname>
            <given-names>Toth</given-names>
          </string-name>
          , Istvan Bozo,
          <article-title>Judit K}oszegi</article-title>
          , and Zoltan Horvath.
          <article-title>Static Analysis Based Support for Program Comprehension in Erlang</article-title>
          .
          <source>In Acta Electrotechnica et Informatica</source>
          , Volume
          <volume>11</volume>
          ,
          <string-name>
            <surname>Number</surname>
            <given-names>03</given-names>
          </string-name>
          ,
          <year>October 2011</year>
          . Publisher: Versita, Warsaw, ISSN 1335-8243 (
          <issue>print</issue>
          ),
          <source>ISSN 1338-3957 (online)</source>
          , pages
          <fpage>3</fpage>
          -
          <lpage>10</lpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref27">
        <mixed-citation>
          [27]
          <string-name>
            <surname>Niel</surname>
            <given-names>Walkinshaw</given-names>
          </string-name>
          , Kirill Bogdanov, Mike Holcombe, and
          <string-name>
            <given-names>Sarah</given-names>
            <surname>Salahuddin</surname>
          </string-name>
          .
          <article-title>Reverse Engineering State Machines by Interactive Grammar Inference</article-title>
          .
          <source>In 14th Working Conference on Reverse Engineering (WCRE</source>
          <year>2007</year>
          ), pages
          <fpage>209</fpage>
          {
          <fpage>218</fpage>
          ,
          <string-name>
            <surname>Oct</surname>
          </string-name>
          <year>2007</year>
          .
        </mixed-citation>
      </ref>
    </ref-list>
  </back>
</article>