<?xml version="1.0" encoding="UTF-8"?>
<TEI xml:space="preserve" xmlns="http://www.tei-c.org/ns/1.0" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://www.tei-c.org/ns/1.0 https://raw.githubusercontent.com/kermitt2/grobid/master/grobid-home/schemas/xsd/Grobid.xsd"
 xmlns:xlink="http://www.w3.org/1999/xlink">
	<teiHeader xml:lang="en">
		<fileDesc>
			<titleStmt>
				<title level="a" type="main">Analysing the hierarchical structure of Erlang applications</title>
			</titleStmt>
			<publicationStmt>
				<publisher/>
				<availability status="unknown"><licence/></availability>
			</publicationStmt>
			<sourceDesc>
				<biblStruct>
					<analytic>
						<author>
							<persName><forename type="first">István</forename><surname>Bozó</surname></persName>
							<email>bozoistvan@caesar.elte.hu</email>
							<affiliation key="aff0">
								<orgName type="institution">ELTE Eötvös Loránd University Faculty of Informatics Budapest</orgName>
								<address>
									<country key="HU">Hungary</country>
								</address>
							</affiliation>
						</author>
						<author>
							<persName><forename type="first">Melinda</forename><surname>Tóth</surname></persName>
							<email>tothmelinda@caesar.elte.hu</email>
							<affiliation key="aff0">
								<orgName type="institution">ELTE Eötvös Loránd University Faculty of Informatics Budapest</orgName>
								<address>
									<country key="HU">Hungary</country>
								</address>
							</affiliation>
						</author>
						<title level="a" type="main">Analysing the hierarchical structure of Erlang applications</title>
					</analytic>
					<monogr>
						<imprint>
							<date/>
						</imprint>
					</monogr>
					<idno type="MD5">860C87225E6E0F27E3C8359E4807E37F</idno>
				</biblStruct>
			</sourceDesc>
		</fileDesc>
		<encodingDesc>
			<appInfo>
				<application version="0.7.2" ident="GROBID" when="2023-03-24T00:24+0000">
					<desc>GROBID - A machine learning software for extracting information from scholarly documents</desc>
					<ref target="https://github.com/kermitt2/grobid"/>
				</application>
			</appInfo>
		</encodingDesc>
		<profileDesc>
			<abstract>
<div xmlns="http://www.tei-c.org/ns/1.0"><p>Understanding and maintaining legacy software is a well-known problem. Static analysis tools aims to support developers in these tasks. We present a static analysis method for extracting the supervisor hierarchy of Erlang programs, which can support program comprehension and maintenance. Beside the algorithm we introduce two different views of the supervisor graph, a compact supervisor graph with only the essential information, and a more detailed full supervisor graph. We demonstrate the method on an example Erlang application and present the two different views of the supervisor hierarchy. The method has been implemented as an extension of the RefactorErl analyser framework.</p></div>
			</abstract>
		</profileDesc>
	</teiHeader>
	<text xml:lang="en">
		<body>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="1">Introduction</head><p>RefactorErl <ref type="bibr" target="#b0">[1,</ref><ref type="bibr" target="#b1">2]</ref> is a static source code analyser, comprehension and refactoring tool for Erlang <ref type="bibr" target="#b2">[3,</ref><ref type="bibr" target="#b3">4]</ref>. The aim of the tool is to support source code comprehension and maintenance. RefactorErl is an extensible framework that provides several analysis features <ref type="bibr" target="#b4">[5]</ref> and tools. The extracted information of the source code is stored in a Semantic Program Graph <ref type="bibr" target="#b5">[6]</ref> (SP G) which is available for users through a query language <ref type="bibr" target="#b6">[7]</ref>.</p><p>The tool provides several basic semantic analyses, like function call analysis, variable binding and reference analysis, data flow analysis, etc. There are several advanced analyses built on the basic semantic analyses, for example duplicate code analysis, dead code analysis, and dependency graphs, etc. However, the analysis of supervisors and applications <ref type="bibr" target="#b7">[8]</ref> of Erlang programs was not supported. Both concepts are fundamental in Erlang because they describe dependencies and connections between Erlang modules.</p><p>A supervisor is a process that monitors and manages other processes and handle errors based on the given strategies. A supervised process can be a worker or an other supervisor process. The hierarchically built structure of supervisor processes are called supervision trees. Using supervisors is a good programming practice to build fault-tolerant applications. Understanding the hierarchy of complex and concurrent or distributed applications is essential in maintenance and support phases.</p><p>In this paper we are going to extend the semantic layer of the SP G with information about supervisors. We provide formal definitions both for the extensions of the model of the semantic program graph and for the algorithms of the semantic analyses. In addition we define two new graphs, a compact view of the supervision hierarchy and a view of the full supervisor graph including detailed information.</p><p>Copyright c by the paper's authors. Copying permitted for private and academic purposes.</p><p>In: E. Vatai (ed.): Proceedings of the 11th Joint Conference on Mathematics and Computer Science, Eger, Hungary, 20th -22nd of May, 2016, published at http://ceur-ws.org</p><p>The paper is structured as follows. Section 2 describes the necessary background information for understanding the approach. Section 3 describes the formal extension of the used source code representation (SP G) and the algorithm of the analysis. Section 4 introduces two graphs/views with different granularity level. Section 5 demonstrates the presented algorithm and views on an example. Section 6 surveys the supervisor concept used in other programming languages. Finally, Section 7 summarises our results and presents our conclusions.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="2">Background</head><p>Before discussing the method in details, it is necessary to survey the Erlang supervisor and the RefactorErl framework used as a basis for the analysis.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="2.1">Erlang supervisors</head><p>The supervisor behaviour is a library module that contains generic code for process monitoring and managing. The specific code is implemented in the callback module. The only mandatory function in the callback module is the function init/1. This function defines the restart strategy, the maximum restart intensity and the child specifications of the supervisor process. The child specification describes the identifier of the child, the function to start the process, the restart option, the timeout of the shutdown, the type of child process (worker or supervisor) and its callback module.</p><p>The supervisor process can be started with the supervisor:start link/2,3 functions. These functions require the name of the supervisor (optional), the callback module and startup arguments. When the function is applied the init/1 function is invoked from the provided callback module with the specified arguments.</p><p>We must note here that besides the static initialising arguments, there are several supervisor manipulating functions such as adding, restarting, deleting a child process, or querying and checking child specifications, etc in runtime.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="2.2">RefactorErl</head><p>RefactorErl stores the analysed data in a special directed graph called semantic program graph (SP G). This graph includes all the information that can be statically extracted from the source code with different analyses. The SP G consists of three layers. The first is the lexical layer, the second is the syntactic layer and the third is the semantic layer.</p><p>The semantic layer is constructed by several analyses which can be divided into two groups. The first is the group of pre analyses which are executed when an Erlang source file is being loaded into RefactorErl, and the second is the group of post analyses which need to be run manually after the pre analysis phase.</p><p>The SP G is a directed graph that can be described as an ordered hextuple:</p><formula xml:id="formula_0">SP G = (V, A N , A V , l, E, e)</formula><p>The components of the hextuple are the following:</p><formula xml:id="formula_1">• V = (V lex ∪ V syn ∪ V sem ∪ V r ):</formula><p>The nodes of the SP G are the union of the lexical, syntactic and semantic nodes, extended with a special singleton set of the root node.</p><p>• A N : The set of attribute names of the nodes.</p><p>• A V : The set of possible attribute values.</p><formula xml:id="formula_2">• l : V × A N → A V :</formula><p>The node labelling partial function.</p><p>• E: The set of edge labels.</p><p>• e : V × E × N → V : The partial function that describes labelled, ordered edges between the graph nodes.</p><p>The SP G has several type of nodes with different attributes describing the properties of the nodes. The nodes of the SP G and their attributes that are important from the aspect of the supervisor analysis are as follows:</p><p>Root: A special singleton set that includes the root node of the SP G. Symbol: V r File: Set of syntactic nodes representing the files in the SP G. Symbol:</p><formula xml:id="formula_3">V f i ⊆ V syn</formula><p>Expr: Set of syntactic nodes representing the expressions in the SP G. The expression nodes have a type attribute which describes the type of the expression. The supervisor analysis uses expression nodes with type application, which means that the expression is a function invocation. Symbol: V e ⊆ V syn Module: Set of semantic nodes representing an Erlang module in the SP G. The module nodes have a name attribute which describes the name of the module. Symbol: V m ⊆ V sem Behaviour: Set of semantic nodes representing the behaviours in the SP G. A behaviour node is present in the SP G if the analysed module implements a behaviour. The type attribute of the node describes the name of the implemented behaviour. Symbol: V b ⊆ V sem Func: Set of semantic nodes representing the functions in the SP G. The functions are identified by the triple of the name of the defining module, and the name and arity of the function ((M,F,A)). Symbol:</p><formula xml:id="formula_4">V f ⊆ V sem</formula></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="3">Supervisor analysis</head><p>The analysis defined in this paper extends the SPG with the supervisor semantic node and new labelled links between semantic and syntactic nodes of the graph according to the semantics of the supervisor behaviour.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="3.1">SP G extension</head><p>We formally specify how do we extend the previously described set of semantic nodes with a set of Supervisor nodes (V sup ) and the directed edges between the nodes of the graph.</p><p>Attributes of the Supervisor node:</p><p>• name: The name of the supervisor. Type: atom() New edges from the Supervisor node:</p><formula xml:id="formula_5">•</formula><p>• sup cb module : V sup → V m : Points to the node of the callback module of the supervisor.</p><p>• sup start : V sup → V f : Points to the function nodes that apply the functions supervisor:start link/2,3 in their definition (potentially start the supervisor process).</p><p>• sup init : V sup → V f : Points to the function node init/1 in the callback module.</p><p>• sup worker : V sup → V sup : Points from a supervisor to its direct successor supervisor nodes (in the supervision tree).</p><p>• w def : V sup → V f : Points from a worker supervisor node to the function node that defines the worker.</p><p>• sup def : V sup → V sup : Points from a supervisor to its defining supervisor node.</p><p>• sup ref : V sup → V e : Points to the function calls (expressions) that can modify or query the supervisor in runtime.</p><p>New edges to the Supervisor node:</p><p>• beh sup : V b → V sup : This edge points from the behaviour node to the supervisor node if its type attribute is supervisor.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head>Formal extension of the SPG</head><p>Let SP G denote the extended semantic program graph:</p><formula xml:id="formula_6">SP G = (V , A N , A V , l , E , e )</formula><p>The set of semantic nodes (V sem ) is extended with the set of Supervisor nodes (V sup ):</p><formula xml:id="formula_7">V sem = V sem ∪ V sup V = V ∪ V sem</formula><p>The sets of attribute names (A N ) and values (A V ) are extended with the attributes and possible values of attributes of the Supervisor node:</p><formula xml:id="formula_8">A sup N = {name, type, registered name, data, strategy, start args} A sup V = {atom() ∪ [supervisor|worker] ∪ supRegN ame() ∪ supP ropList() ∪ supStrateg() ∪ [term()]} A N = A N ∪ A sup N A V = A V ∪ A sup V</formula><p>The set of edge labels (E) is extended with the new labels:</p><formula xml:id="formula_9">E sup = {sup def, sup cb module, sup start, sup init, sup worker, w def, sup ref, beh sup} E = E ∪ E sup</formula><p>The node labelling partial function l is extended with the following cases for an arbitrary x ∈ V sup node:</p><formula xml:id="formula_10">l : x × name → atom() l : x × type → [supervisor|worker] l : x × registered name → supRegN ame() l : x × data → supP ropList() l : x × strategy → supStrategy() l : x × start args → [term()]</formula><p>The partial function e is extended with the following cases for an arbitrary x ∈ V sup node and an arbitrary n ∈ N natural number:</p><formula xml:id="formula_11">e : x × sup cb module × n → y ∈ V m e : x × {sup start, sup init, w def } × n → y ∈ V f e : x × {sup worker, sup def } × n → y ∈ V sup e : x × sup ref × n → y ∈ V e</formula><p>For an arbitrary z ∈ V b node:</p><formula xml:id="formula_12">e : z × beh sup × n → y ∈ V sup</formula></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="3.2">The algorithm</head><p>The analysis is performed in two phases. The first step is the pre analysis which is performed during the basic semantic analysis. The second step is the post analysis, which extracts all the statically available information about the supervisors. We separated our analysis according to the asynchronous, incremental analyser framework of RefactorErl. The first phase of the analysis (pre analysis) is the syntax based node identification part that can be performed incrementally form by form asynchronously. In this phase we have only a partial view on the semantic layer. The second phase (post analysis) uses the information calculated by the first phase of the supervisor analysis and other semantic analyses performed on the full SP G in an interfunctional way (such as the data-flow reaching). The pseudo code of the analysis is presented in Algorithm 1.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head>Pre analysis</head><p>In the pre analysis phase a new Supervisor semantic node is created and inserted into the SP G if the module implements the supervisor behaviour. That is, the module contains the -behaviour(supervisor) attribute. This module is the callback module of the behaviour. A new edge with label sup cb module is inserted between the Supervisor node and the module and the name attribute of the Supervisor is set to the name of the callback module. Finally, a new edge with label beh sup is inserted between the corresponding behaviour node and the Supervisor node.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head>Post analysis</head><p>The pre analysis phase did the initialisation, new Supervisor nodes have been created, initialised and inserted to the SP G. The post phase of the algorithm extracts the most possible information about the supervisors. The algorithm determines the starting arguments, workers, hierarchy, etc. The post phase creates new semantic nodes and extends the semantic information available in the SP G. The Algorithm 1 shows the pseudo code of the post analysis phase for a given Supervisor node. First of all, the algorithm finds the init/1 callback function of the supervisor using the f ind init f un routine. Once the callback function node is found we insert an edge with label sup init between the examined Supervisor node and the function node.</p><p>The second step of the algorithm is to determine the functions that potentially start the supervisor process. The algorithm searches for supervisor:start link/2,3 function applications. For each function application we get its arguments with the get args routine, then we apply data-flow reaching by invoking the f low routine to determine the possible values of the arguments. The M odule variable contains the name of the callback module of the supervisor that is started with the examined application. We filter the result for the actual supervisor (Supervisor) and we update its registered name and args attributes. Finally, we create a link with label sup start between the Supervisor and the node of the function that applies the supervisor:start link/2,3 functions.</p><p>The third step of the algorithm is the analysis of restart strategies and child specifications of the Supervisor. This information can be found in the return value of the init/1 callback function or the supervisor:startchild/2 function. At first, we examine the return points of the init/1 callback function. The return points of the function are queried by the return points routine. For each return point we apply data-flow reaching to determine the possible strategies and child specifications. We update the attribute restart strategy with the newly found restart strategies (Strategies) and collect the child specifications in the set GoodChildSpecs. Next, we need to get the child specifications from the supervisor:start child/2 function applications. We query the function applications and for each function application we try to determine the values of its arguments with data-flow reaching. The gathered child specifications are inserted to the GoodChildSpec set if the set of registered names of the examined Supervisor and the set SupRef N ames has a non empty section. Next we create a new worker Supervisor node using the create worker routine for every child specification from the GoodChildSpec and create a link with label sup worker between every newly created worker and the examined Supervisor. Finally, based on the type of the worker process we use a sup def or w def edge to create a link between the worker and its definition.</p><p>The last step is to analyse the supervisor references. We examine the function from the supervisor module listed in variable F unsW ithArity. For each function we query the function applications, then with data-flow reaching we try to determine the referred supervisor from its arguments. If the function application refers the examined Supervisor, then a link with label sup ref is created between the function application and the Supervisor node.</p><p>Algorithm 1 analyse supervisor(Supervisor) (restart child, 2), (which children, 1), (count children, 1)} 41: for (F un, Arity) ∈ F unsW ithArity do In Section 3 we extended the SP G with additional semantic information about supervisors. It is possible to visualise the SP G, however it is too extensive and it is hard to find relevant information about supervisors. In this section we define a supervisor graph which is a view of the SP G that contains information only about the supervisors.</p><p>The introduced graphs contain explicit information about the supervisor structure that can be used for code comprehension, debugging or checking the hierarchy of the software.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="4.1">Definition of the supervisor graph</head><p>Let the supervisor graph G sup be an ordered pair. The first component of the pair is the set of nodes of the supervisor graph. The second component of the pair is the set of directed edges represented as ordered triples.</p><formula xml:id="formula_13">G sup = (V sup , E sup )</formula><p>The set of nodes is the union of supervisor nodes, worker nodes, function nodes and expression nodes, formally:</p><formula xml:id="formula_14">V sup = (V sup s ∪ V sup w ∪ V sup f ∪ V sup e )</formula><p>The set of edges is represented by ordered triples. The components of a triple are the head node, the tail node and the label of the edge:</p><formula xml:id="formula_15">E sup ⊆ V sup × V sup × LABEL sup</formula><p>The set of edge labels of the supervisor graph is: The Sup nodes are representing the supervisors in the supervisor graph. The Sup node has the following attributes:</p><formula xml:id="formula_16">LABEL sup = {start,</formula><p>name: The name of the supervisor. This will be the caption of the node in the supervisor graph.</p><p>strategy: The restart strategy of the supervisor.</p><p>registered name: If the supervisor is registered, this attribute contains the type of the registration along with the registered name.</p><p>start args: The arguments which are passed to the init/1 callback function.</p><p>• The definition of the worker node is the following:</p><p>SupW orker node = {name :: string(), data :: supP ropList()}</p><p>The SupW orker nodes are representing the workers in the supervisor graph. The SupW orker node has the following attributes:</p><p>name: The name of the worker. This name will be the caption of the node in the supervisor graph.</p><p>data: This attribute contains every information available about the worker, for example: the type of the worker.</p><p>• The definition of function node is the following:</p><p>SupF unction node = {name :: string()}</p><p>The function nodes represent the callback functions in the supervisor graph. The SupF unction node has the following attributes:</p><p>name: The name of the function. This will be the caption of the node in the supervisor graph.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head>COMPACT supervisor graph</head><p>We introduce two types of supervisor graphs. The full supervisor graph contains every available information about the supervisors and workers, like callback functions, supervisor references, worker definitions, etc. The COMPACT supervisor graph only contains information about the hierarchy of the supervisors and workers. We use the COMPACT flag to distinguish the COMPACT and full supervisor graphs in the rules.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head>Rules</head><p>In the followings we define the rules which are used to build the full and COMPACT supervisor graphs.</p><p>1. Supervisor node</p><formula xml:id="formula_17">x ∈ V sups x ∈ V sup s ∧ updateSup(x, x )</formula><p>If an x Supervisor node is present in the SP G then the x node which is synthesised from x using the updateSup function will be in the supervisor graph. This x will be a member of the Sup nodes of the supervisor graph.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="2.">Supervisor edge (COMPACT )</head><p>{x, y, z} ⊆ V sups ∧ sup worker ∈ edges(x, y) ∧ sup def ∈ edges(y, z)</p><formula xml:id="formula_18">∧ COM P ACT x ∈ V sup s ∧ z ∈ V sup s ∧ updateSup(x, x ) ∧ updateSup(z, z )∧ (x , z , supervisor) ∈ E sup</formula><p>Let the x, y and z be Supervisor nodes from SP G. If there is a sup worker edge between x and y and a sup def edge between y and z, then there will be a supervisor edge between the x and z synthesised Sup node nodes in the COMPACT supervisor graph. The not COMPACT (full) supervisor edge rule can be analogously defined.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="3.">Worker edge</head><p>x ∈ V sups ∧ y ∈ V supw ∧ sup worker ∈ edges(x, y) x ∈ V sup s ∧ y ∈ V sup w ∧ updateSup(x, x ) ∧ updateSupW orker(y, y )∧ (x , y , worker) ∈ E sup Let x and y be Supervisor nodes in the SP G and the type of y is worker. If there is a sup worker edge between x and y, then there will be a worker edge between the x and y synthesized Sup node nodes in the supervisor graph.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="4.">Supervisor init</head><formula xml:id="formula_19">x ∈ V sups ∧ f ∈ V f ∧ sup init ∈ edges(x, f ) ∧ ¬COM P ACT x ∈ V sup s ∧ f ∈ V sup f ∧ updateSup(x, x ) ∧ updateSupF unction(f, f )∧ (x , f , init) ∈ E sup</formula><p>If a Supervisor node is connected to a function node with a sup init edge in the SP G, then there will be an init edge between the synthesised x and f nodes in the supervisor graph (if the supervisor graph is not COMPACT ). This rule describes that the supervisor shall be connected to its init callback function.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="5.">Supervisor start</head><formula xml:id="formula_20">x ∈ V sups ∧ f ∈ V f ∧ sup start ∈ edges(x, f ) ∧ ¬COM P ACT x ∈ V sup s ∧ f ∈ V sup f ∧ updateSup(x, x ) ∧ updateSupF unction(f, f )∧ (x , f , start) ∈ E sup</formula><p>If a Supervisor node is linked to a function node with a sup start edge in the SP G, then there will be an start edge between the synthesised x and f nodes in the supervisor graph (if the supervisor graph is not COMPACT ). This rule describes that the supervisor shall be connected to the function that can start the supervisor with an application of the supervisor:start link/2,3 functions. If the x Supervisor node is linked to an expression node x with a sup ref edge in the SP G, then there will be a ref erence edge between the synthesised x and e nodes in the supervisor graph (if the supervisor graph is not COMPACT ).</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="6.">Supervisor reference</head><formula xml:id="formula_21">x ∈ V sups ∧ e ∈ V e ∧ sup ref ∈ edges(x, e) ∧ ¬COM P ACT x ∈ V sup s ∧ e ∈ V sup</formula></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="5">Demonstrating Example</head><p>In this section we illustrate the algorithm of the analysis with an example implementation of a supervisor. First we introduce the example implementation, then we discuss the algorithm step by step focusing mostly on the post analysis phase of the SPG extension. Finally we present the supervisor graph and the compact supervisor graph.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="5.1">Example Supervisor</head><p>The example supervisor can be seen in Figure <ref type="figure" target="#fig_4">1</ref>. This supervisor is a simplified model of a theatre. The theatre has a director, a technician, and a bandmaster. The bandmaster supervises the musicians as can be seen in Figure <ref type="figure" target="#fig_5">2</ref>.   </p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head>Pre analysis</head><p>The pre analysis phase looks for "-behaviour(supervisor)." attribute in each module. In this case both theatre (in line 2) and bandmaster module (in line 2) has such attribute. Two new Supervisor nodes will be inserted into the SP G. One for theatre module and one for bandmaster module, and two sup cb module links will be inserted between the Supervisor nodes and the module nodes. The name attribute of the Supervisor nodes will be equal to the names of the module which they are connected to. Also two beh sup links will be inserted between the Behaviour nodes and the Supervisor nodes.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head>Post analysis</head><p>We discuss only the analysis of the theatre supervisor since the analysis of the bandmaster can be executed analogously. The only difference will be the amount of extracted information about the restart strategy and maximal restart intensity as the information is passed as a parameter to function init/1. This additional information is not always trivially available statically, but the data-flow analysis can calculate the possible values of variables statically. The first step of the post analysis is to find the definition of the function init/1 from theatre callback module in the SP G. It can be found in the line 10 of Figure <ref type="figure" target="#fig_4">1</ref>. We insert a link sup init between the supervisor node and the function node.</p><p>The second step of the analysis is the examination of the supervisor:start link/2,3 function applications. We query the references of the function and we get two function applications, one application in the definition of function theatre:start link/1 (in line 8 in Figure <ref type="figure" target="#fig_4">1</ref>) and one other one in the definition of function bandmaster:start link/1 (in line 8 in Figure <ref type="figure" target="#fig_5">2</ref>). The next step is the filtering of the relevant applications. To do that we query the possible values of arguments for each application (using data flow analysis) and we look for the second argument which describes the started supervisor. We find that the function application from the theatre module refers to the theatre supervisor because the ?MODULE macro is substituted to the name of the containing module. We update the attributes of the theatre supervisor node with the gathered information. The attributes registered name and args are updated with the possible values of the first and the third arguments of the application. Finally we insert a link sup start between the node of the function theatre:start link/1 (in line 7 in Figure <ref type="figure" target="#fig_4">1</ref>) and the node of the supervisor theatre.</p><p>The third step is the analysis of restart strategies and child specifications. To find the child specifications we need the possible return values of the init/1 callback function. We query the possible return values and extract the information about the restart strategy and maximum intensity of restarts from the result. In our case it is the tuple {one for all, 3, 500} (in line 21 in Figure <ref type="figure" target="#fig_4">1</ref>). We update the strategy attribute of the theatre node with this information. Next we try to extract the child specifications from the return values using backward data-flow reaching. The Children variable (in line 11 in Figure <ref type="figure" target="#fig_4">1</ref>) contains the child specifications, and we need to determine the possible values of this variable using data-flow analysis. There are three different children of the theatre supervisor. For each children we create a new Supervisor node of type worker and update the data attributes with the information can be found about each supervisor. We link the theatre supervisor to the workers with sup worker edges. We insert worker def links between the workers and their function definition. The name of the worker function will be the second component of the child specification. For example, {director, start link, []} (in line 13 in Figure <ref type="figure" target="#fig_4">1</ref>) means, that the children will be started using the director:start link/0 function. We also examine the child specifications found in the applications of supervisor:start child/2 function, but in our case there is no information about them.</p><p>In the final step of the analysis we examine the supervisor references that potentially query or change the attributes of the theatre supervisor. There is a reference to our supervisor in the theatre:add crew/1 function (in line 23 in Figure <ref type="figure" target="#fig_4">1</ref>) . We insert a link sup ref between the supervisor node an the reference.</p><p>The post analysis of the bandmaster supervisor can be analogously executed. The only important difference is that the data flow analysis will have heavier impact on the data extracted, because the init/1 callback function of the bandmaster module have four clauses. Thus, the restart strategy and the maximal restart intensity can be given as parameters to the supervisor. For example the data-flow analysis will determine that the supervisor can have three different restart strategies (one for one, rest for one, one for all.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="5.2">Results</head><p>Using the rules defined in Section 4 the COMPACT and full supervisor graphs can be constructed from the SP G after the supervisor analysis is completed. We show the COMPACT and full supervisor graphs for our example supervisor implementation presented in subsection 5.1.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head>COMPACT supervisor graph</head><p>The Figure <ref type="figure" target="#fig_6">3</ref> shows the COMPACT supervisor graph for the theatre supervisor. The graph shows only the hierarchy of the supervisors and the workers. The green diamond nodes represent the supervisors and the blue oval nodes are the workers of the supervisors. The attributes of the nodes contains every information that can be extracted statically about the supervisors or the workers as it can be seen in the picture, we highlighted the attributes of three nodes. </p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head>Full supervisor graph</head><p>The Figure <ref type="figure" target="#fig_7">4</ref> shows the full supervisor graph for the theatre supervisor. We can see that the structure of this graph is more complex than in the case of the COMPACT supervisor graph. We can find additional information in the graph like the functions of the callback module, the function nodes of the worker definitions and the supervisor references. The orange hexagons represent the function nodes. The supervisor concept is present in other programming languages as well. In this section we examine some tools which are capable of analysing supervisors in Erlang and in other programming languages as well.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head>Percept2</head><p>Percept2 <ref type="bibr" target="#b8">[9]</ref> is a profiler tool for Erlang programs with focus on processes and process communication. Percept2 is a dynamic analyser tool which analyses the program in runtime. In comparison with our results Percept2 can detect the hierarchy of the supervisors correctly. However it does not know the supervisor specific information, for example restart strategy, child specifications, etc. In some cases Percept2 can provide more accurate results, because it can detect new children added to supervisors dynamically. Our tool is a static code analyser, and can detect only those children which specification is present in the source code. However our tool can detect child specifications that are not necessarily added to the supervisors in a certain runtime configurations. In conclusion, the two tools have slightly different focus, as Precept2 is a dynamic and RefactorErl is a static analyser tool. The tools should be used as complementary tools.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head>Akka</head><p>Akka <ref type="bibr" target="#b9">[10]</ref> is a library for Scala and Java programs. It supports the implementation of distributed concurrent and fault tolerant software using the Actor model. The Actor model takes care of the thread handling and resource locking, thus the developer can focus on the business logic of the software. Supervisors are present in Akka and it is very similar to the supervisors in Erlang. The processes are represented as actors and the supervisor can monitor these actors. Supervisors can start, stop and restart the monitored processes, and also halt them. Akka supports two restart strategies only. Currently there is no static code analyser support for supervisors in aid of Akka. Several IDE-s can provide dynamic information, like call stacks and class diagrams which can be used to get some information about the supervisors, but it is not nearly as accurate as our results for Erlang supervisors.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head>Cloud Haskell</head><p>Cloud Haskell <ref type="bibr" target="#b10">[11]</ref> is a library for Haskell programs. It supports the implementation of distributed and concurrent software mainly for clusters. In Cloud Haskell there is a package called distributed-process-supervisor <ref type="bibr" target="#b11">[12]</ref> which supports supervisors very similar to the supervisors used in Erlang. There is no static code analyser tool that support supervisor analysis in Cloud Haskell. The SourceGraph <ref type="bibr" target="#b12">[13]</ref> can be used to make function call graphs and detect module import hierarchy. From these graphs there are some information available about the supervisors, but our results for Erlang supervisors are more accurate and user friendly.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head n="7">Conclusions</head><p>In this paper we discussed a new method for extracting the relevant information from the source code written in Erlang implementing the supervisor behaviour. For the analysis we used the static analysis tool RefactorErl and the information available in its Semantic Program Graph. RefactorErl performs lexical, syntactic and different semantic analyses on the source code and stores the extracted results in the SP G. We presented the algorithm of the new analysis with its pseudocode and explained the steps in detail. We introduced the formal extension of the SP G with the new nodes and the way the new semantic information is embedded in the SP G. To make the supervisor hierarchy more explicit we defined a supervisor graph that is a view of the SP G that includes only information about supervisors. We defined two levels of granularity for supervisor graphs, that is a full and a compact view. We discussed the steps and rules how these graphs are generated from the SP G. Finally we demonstrated our approach on an example and showed the generated graphs, both a full and a compact view.</p><p>The presented method was examined on different open source Erlang applications, and the results seemed to be useful in software comprehension.</p></div><figure xmlns="http://www.tei-c.org/ns/1.0" xml:id="fig_0"><head></head><label></label><figDesc>type: The type of the supervisor. Type: [supervisor,worker] • registered name: This attribute contains the possible registered names of the supervisor. Type: supRegName() = [{[via], [Module :: atom()], [Name :: atom()]}], {[Scope :: atom()], [Name :: atom()]}. • data: If the supervisor is a worker then this attribute contains every information about the worker. Type: supPropList() = [{child id, [atom()]}, {restart, [atom()]}, {shutdown, [integer()]}, {modules, [atom()]}]. • strategy: The restart strategy of the supervisor. Type: supStrategy() = [{[Strategy :: strategy()], [MaxTime :: integer()], [MaxRestart :: integer()]}] where the strategy() is the type of restart strategies (one for all, one for one, restfor one, simple one for one), MaxTime and MaxRestart describe the maximum intensity of restarts within the given time period. • start args: Contains the last argument of the supervisor:start link/2,3 function calls which can start the actual supervisor. The last argument is passed to the init/1 callback function. Type: [term()]</figDesc></figure>
<figure xmlns="http://www.tei-c.org/ns/1.0" xml:id="fig_1"><head>F</head><label></label><figDesc>unCalls ← get f un calls(supervisor, F un, Arity) 43: for F unCall ∈ F unCalls do 44: (SupRef N ames, ) ← f low(get args(F unApp)) 45: if Supervisor registered name ∩ SupRef N ames = ∅ then 46:create link(Supervisor, F unCall, sup ref )</figDesc></figure>
<figure xmlns="http://www.tei-c.org/ns/1.0" xml:id="fig_2"><head></head><label></label><figDesc>init, supervisor, worker, sup def, worker def, ref erence} Nodes of the supervisor graph • The definition of the supervisor node is the following: Sup node = {name :: string(), strategy :: supStrategy(), registered name :: [term()], start args = [term()]}</figDesc></figure>
<figure xmlns="http://www.tei-c.org/ns/1.0" xml:id="fig_3"><head>e∧</head><label></label><figDesc>updateSup(x, x ) ∧ updateSupExpression(e, e )∧ (x , e , ref erence) ∈ E sup</figDesc></figure>
<figure xmlns="http://www.tei-c.org/ns/1.0" xml:id="fig_4"><head>Figure 1 :</head><label>1</label><figDesc>Figure 1: Theatre supervisor 1 −module( t h e a t r e ) . 2 −b e h a v i o u r ( s u p e r v i s o r ) .3 4 −export ( [ s t a r t l i n k / 1 , add crew /1 ] ) . 5 −export ( [ i n i t /1 ] ) . 6 7 s t a r t l i n k ( Args ) −&gt; 8 s u p e r v i s o r : s t a r t l i n k ( { l o c a l , ?MODULE} , ?MODULE, Args ) . 9 10 i n i t ( Args ) −&gt; 11 C h i l d r e n = [ 12 { d i r e c t o r , 13 { d i r e c t o r , s t a r t l i n k , [ ] } , 14 t r a n s i e n t , 1 0 0 , worker , [ d i r e c t o r ] } , 15 { tech , 16 { tech , s t a r t l i n k , [ ] } , 17 t r a n s i e n t , 1 0 0 , worker , [ t e c h ] } , 18 {bandmaster , 19 {bandmaster , s t a r t l i n k , [ Args ] } , 20 t r a n s i e n t , 1 0 0 , s u p e r v i s o r , [ bandmaster ] } ] , 21 {ok , {{ o n e f o r a l l , 3 , 500} , C h i l d r e n }} . 22 23 add crew ( C h i l d S p e c ) −&gt; 24 s u p e r v i s o r : s t a r t c h i l d ( { l o c a l , ?MODULE} , C h i l d S p e c ) .</figDesc></figure>
<figure xmlns="http://www.tei-c.org/ns/1.0" xml:id="fig_5"><head>Figure 2 :</head><label>2</label><figDesc>Figure 2: Bandmaster supervisor</figDesc></figure>
<figure xmlns="http://www.tei-c.org/ns/1.0" xml:id="fig_6"><head>Figure 3 :</head><label>3</label><figDesc>Figure 3: COMPACT supervisor graph</figDesc><graphic coords="12,126.84,536.92,361.92,119.34" type="bitmap" /></figure>
<figure xmlns="http://www.tei-c.org/ns/1.0" xml:id="fig_7"><head>Figure 4 :</head><label>4</label><figDesc>Figure 4: Full supervisor graph</figDesc><graphic coords="13,86.40,105.18,442.80,128.70" type="bitmap" /></figure>
<figure xmlns="http://www.tei-c.org/ns/1.0" type="table" xml:id="tab_0"><head>1 :</head><label>1</label><figDesc>InitF un ← f ind init f un(Supervisor) 2: create link(Supervisor, InitF un, sup init) 3: %% Analyse supervisor : start link/2, 3 f unctions %% 4: StartF unCalls ← get f un calls(supervisor, start link, {2, 3}) 5: for F unCall ∈ StartF unCalls do (SupN ame, M odule, Args) ← f low(get args(F unCall)) Supervisor registered name ← Supervisor registered names ∪ SupN ame Supervisor args ← Supervisor args ∪ Args %% Analyse child specif ications %% 14: RetP oints ← return points(InitF un) 15: GoodChildSpecs ← ∅ 16: for RetP oint ∈ RetP oints do Supervisor strategy ← Supervisor strategy ∪ Strategies GoodChildSpecs ← GoodChildSpecs ∪ ChildSpecs 20: end for 21: StartChildF unCalls ← get f un calls(supervisor, start child, 2) 22: for F unCall ∈ StartChildF unCalls do Supervisor registered name ∩ SupRef N ames = ∅ then %% Analyse supervisor ref erences %% 39: F unsW ithArity ← {(start child, 2), (terminate child, 2), (delete child, 2),</figDesc><table><row><cell>6:</cell><cell></cell></row><row><cell>7:</cell><cell cols="2">if Supervisor name ∩ M odule = ∅ then</cell></row><row><cell>8:</cell><cell></cell></row><row><cell>9:</cell><cell></cell></row><row><cell>10:</cell><cell></cell><cell>create link(Supervisor, get f un(F unCall), sup start)</cell></row><row><cell>11:</cell><cell cols="2">end if</cell></row><row><cell cols="3">12: end for</cell></row><row><cell>13: 17:</cell><cell cols="2">(ok, (Strategies, ChildSpecs)) ← f low(RetP oint)</cell></row><row><cell>18:</cell><cell></cell></row><row><cell>19:</cell><cell></cell></row><row><cell>23:</cell><cell cols="2">(SupRef N ames, ChildSpecs) ← f low(get args(F unCall))</cell></row><row><cell cols="2">24: if 25:</cell><cell>GoodChildSpecs ← GoodChildSpecs ∪ ChildSpecs</cell></row><row><cell>26:</cell><cell cols="2">end if</cell></row><row><cell cols="3">27: end for</cell></row><row><cell cols="3">28: for ChildSpec ∈ GoodChildSpecs do</cell></row><row><cell>29:</cell><cell cols="2">N ewW orker ← create worker(ChildSpec)</cell></row><row><cell>30:</cell><cell cols="2">W orkerDef ← get worker def (ChildSpec)</cell></row><row><cell>31:</cell><cell cols="2">create link(Supervisor, N ewW orker, sup worker)</cell></row><row><cell>32:</cell><cell cols="2">if supervisor ∈ N ewW orker type then</cell></row><row><cell>33:</cell><cell></cell><cell>create link(N ewW orker, W orkerDef, sup def )</cell></row><row><cell>34:</cell><cell cols="2">else if worker ∈ N ewW orker type then</cell></row><row><cell>35:</cell><cell></cell><cell>create link(N ewW orker, W orkerDef, w def )</cell></row><row><cell>36:</cell><cell cols="2">end if</cell></row><row><cell cols="3">37: end for</cell></row><row><cell>38: 40:</cell><cell></cell></row></table></figure>
		</body>
		<back>
			<div type="annex">
<div xmlns="http://www.tei-c.org/ns/1.0"><p>• The definition of the expression node is the following: SupExpression node = {name :: string(), f unc :: {module(), f un(), arity()}, args : [term()]}</p><p>The expression nodes represent the supervisor references in the supervisor graph. Supervisor references are function applications, which might modify or query the supervisor arguments during runtime. The SupExpression node has the following attributes:</p><p>name: The text of the expression node which will be the caption of the node in the supervisor graph.</p><p>func: A module, function and arity triple ({M,F,A}) that identifies the function which is referred by the application expression.</p><p>args: The arguments of the function application.</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head>Notations</head><p>In the previous section we introduced the V sup set of Supervisor semantic nodes in the SP G. In this section we use the V sup notation for the set of supervisor nodes in the new supervisor graph. We define two subsets of set V sup :</p><p>• V sups ⊆ V sup -set of supervisor nodes which type is supervisor. Formally:</p><p>supervisor nodes which type is worker. Formally:</p></div>
<div xmlns="http://www.tei-c.org/ns/1.0"><head>Auxiliary functions</head><p>We introduce some auxiliary functions to shorten the supervisor graph building rules:</p><p>• edges(x, y): The function takes two nodes from the SP G and returns the set of labels of directed edges with head x and tail y.</p><p>• updateSup(Sup, Sup ): The rule says that the Sup node (type of Sup node) shall have the same name, strategy, registered name and start arguments as the Sup Supervisor node from the SP G.</p><p>• updateSupW orker(Sup, W orker):</p><p>The rule says that the W orker node (type of SupW orker node) shall have the same name and the same data as the Sup Supervisor node (which type is worker) from the SP G.</p><p>• updateSupF unction(F un, F un ): The function updates the name attribute of F un node (type of set SupF unction node) with the (M,F,A) of the Func node from the SP G.</p><p>• updateSupExpression(Expr, Expr ): The function updates the attributes of Expr node (type of SupExpression node). The name attribute shall be the string created from (M,F,A) of the function that contains the SP G expression Expr. The args attribute contains the arguments of the function application which information is gathered from. Finally, the func attribute contains the ordered triple {M,F,A} of the function which the supervisor reference refer. E.g.: {supervisor,start child,2}.</p></div>			</div>
			<div type="references">

				<listBibl>

<biblStruct xml:id="b0">
	<monogr>
		<ptr target="http://plc.inf.elte.hu/erlang" />
		<title level="m">RefactorErl -Refactoring Erlang Programs</title>
				<imprint>
			<date type="published" when="2015">2015. 2016-06-30</date>
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b1">
	<analytic>
		<title level="a" type="main">RefactorErl, Source Code Analysis and Refactoring in Erlang</title>
		<author>
			<persName><forename type="first">István</forename><surname>Bozó</surname></persName>
		</author>
		<author>
			<persName><forename type="first">Dániel</forename><surname>Horpácsi</surname></persName>
		</author>
		<author>
			<persName><forename type="first">Zoltán</forename><surname>Horváth</surname></persName>
		</author>
		<author>
			<persName><forename type="first">Róbert</forename><surname>Kitlei</surname></persName>
		</author>
		<author>
			<persName><forename type="first">Judit</forename><surname>Kőszegi</surname></persName>
		</author>
		<author>
			<persName><forename type="first">Máté</forename><surname>Tejfel</surname></persName>
		</author>
		<author>
			<persName><forename type="first">Melinda</forename><surname>Tóth</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="m">Proceeding of the 12th Symposium on Programming Languages and Software Tools</title>
				<meeting>eeding of the 12th Symposium on Programming Languages and Software Tools<address><addrLine>Tallin, Estonia</addrLine></address></meeting>
		<imprint>
			<date type="published" when="2011">2011</date>
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b2">
	<monogr>
		<title level="m" type="main">Erlang Programming Language</title>
		<ptr target="http://www.erlang.org" />
		<imprint>
			<date type="published" when="2016-06-30">2016-06-30</date>
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b3">
	<monogr>
		<title level="m" type="main">Erlang Programming</title>
		<author>
			<persName><forename type="first">Francesco</forename><surname>Cesarini</surname></persName>
		</author>
		<author>
			<persName><forename type="first">Simon</forename><surname>Thompson</surname></persName>
		</author>
		<imprint>
			<date type="published" when="2009">2009</date>
			<publisher>O&apos;Reilly Media</publisher>
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b4">
	<analytic>
		<title level="a" type="main">Static Analysis of Complex Software Systems Implemented in Erlang</title>
		<author>
			<persName><forename type="first">Melinda</forename><surname>Tóth</surname></persName>
		</author>
		<author>
			<persName><forename type="first">István</forename><surname>Bozó</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="m">Central European Functional Programming School</title>
		<title level="s">Lecture Notes in Computer Science</title>
		<imprint>
			<publisher>Springer</publisher>
			<date type="published" when="2012">2012</date>
			<biblScope unit="volume">7241</biblScope>
			<biblScope unit="page" from="440" to="498" />
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b5">
	<analytic>
		<title level="a" type="main">Modeling Semantic Knowledge in Erlang for Refactoring</title>
		<author>
			<persName><forename type="first">Zoltán</forename><surname>Horváth</surname></persName>
		</author>
		<author>
			<persName><forename type="first">László</forename><surname>Lövei</surname></persName>
		</author>
		<author>
			<persName><forename type="first">Tamás</forename><surname>Kozsik</surname></persName>
		</author>
		<author>
			<persName><forename type="first">Róbert</forename><surname>Kitlei</surname></persName>
		</author>
		<author>
			<persName><forename type="first">István</forename><surname>Bozó</surname></persName>
		</author>
		<author>
			<persName><forename type="first">Melinda</forename><surname>Tóth</surname></persName>
		</author>
		<author>
			<persName><forename type="first">Roland</forename><surname>Király</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="m">International Conference on Knowledge Engineering, Principles and Techniques</title>
				<meeting><address><addrLine>KEPT</addrLine></address></meeting>
		<imprint>
			<date type="published" when="2009">2009. 2009</date>
			<biblScope unit="page" from="38" to="53" />
		</imprint>
	</monogr>
	<note>Selected papers</note>
</biblStruct>

<biblStruct xml:id="b6">
	<analytic>
		<title level="a" type="main">Applying the Query Language to Support Program Comprehension</title>
		<author>
			<persName><forename type="first">M</forename><surname>Tóth</surname></persName>
		</author>
		<author>
			<persName><forename type="first">I</forename><surname>Bozó</surname></persName>
		</author>
		<author>
			<persName><forename type="first">Z</forename><surname>Horváth</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="m">Proceeding of International Scientific Conference on Computer Science and Engineering</title>
				<meeting>eeding of International Scientific Conference on Computer Science and Engineering<address><addrLine>Stara Lubovna, Slovakia</addrLine></address></meeting>
		<imprint>
			<date type="published" when="2010-09">September 2010</date>
			<biblScope unit="page" from="52" to="59" />
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b7">
	<monogr>
		<title level="m" type="main">Erlang and OTP in Action</title>
		<author>
			<persName><forename type="first">Martin</forename><surname>Logan</surname></persName>
		</author>
		<author>
			<persName><forename type="first">Eric</forename><surname>Merritt</surname></persName>
		</author>
		<author>
			<persName><forename type="first">Richard</forename><surname>Carlsson</surname></persName>
		</author>
		<imprint>
			<date type="published" when="2010">2010</date>
			<publisher>Manning Publications Co</publisher>
			<pubPlace>Greenwich, CT, USA</pubPlace>
		</imprint>
	</monogr>
	<note>1st edition</note>
</biblStruct>

<biblStruct xml:id="b8">
	<analytic>
		<title level="a" type="main">Multicore profiling for erlang programs using percept2</title>
		<author>
			<persName><forename type="first">Huiqing</forename><surname>Li</surname></persName>
		</author>
		<author>
			<persName><forename type="first">Simon</forename><surname>Thompson</surname></persName>
		</author>
	</analytic>
	<monogr>
		<title level="m">Proceedings of the Twelfth ACM SIGPLAN Workshop on Erlang, Erlang &apos;13</title>
				<meeting>the Twelfth ACM SIGPLAN Workshop on Erlang, Erlang &apos;13<address><addrLine>New York, NY, USA</addrLine></address></meeting>
		<imprint>
			<publisher>ACM</publisher>
			<date type="published" when="2013">2013</date>
			<biblScope unit="page" from="33" to="42" />
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b9">
	<monogr>
		<title/>
		<author>
			<persName><surname>Akka</surname></persName>
		</author>
		<ptr target="http://akka.io" />
		<imprint>
			<date type="published" when="2016-06-30">2016-06-30</date>
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b10">
	<analytic>
		<title level="a" type="main">Towards haskell in the cloud</title>
		<author>
			<persName><forename type="first">Jeff</forename><surname>Epstein</surname></persName>
		</author>
		<author>
			<persName><forename type="first">Andrew</forename><forename type="middle">P</forename><surname>Black</surname></persName>
		</author>
		<author>
			<persName><forename type="first">Simon</forename><surname>Peyton</surname></persName>
		</author>
		<author>
			<persName><forename type="first">-Jones</forename></persName>
		</author>
	</analytic>
	<monogr>
		<title level="m">Proceedings of the 4th ACM Symposium on Haskell, Haskell &apos;11</title>
				<meeting>the 4th ACM Symposium on Haskell, Haskell &apos;11<address><addrLine>New York, NY, USA</addrLine></address></meeting>
		<imprint>
			<publisher>ACM</publisher>
			<date type="published" when="2011">2011</date>
			<biblScope unit="page" from="118" to="129" />
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b11">
	<monogr>
		<ptr target="https://hackage.haskell.org/package/distributed-process-supervisor" />
		<title level="m">Supervisors for The Cloud Haskell Application Platform</title>
				<imprint>
			<date type="published" when="2016-06-30">2016-06-30</date>
		</imprint>
	</monogr>
</biblStruct>

<biblStruct xml:id="b12">
	<monogr>
		<ptr target="https://hackage.haskell.org/package/SourceGraph" />
		<title level="m">SourceGraph: Static code analysis using graph-theoretic techniques</title>
				<imprint>
			<date type="published" when="2016-06-30">2016-06-30</date>
		</imprint>
	</monogr>
</biblStruct>

				</listBibl>
			</div>
		</back>
	</text>
</TEI>
