EgoCoder: Intelligent Program Synthesis with Hierarchical Sequential Neural Network Model
Programming has been an important skill for researchers and practitioners in computer science and other related areas. To learn basic programing skills, a long-time systematic training is usually required for beginners. According to a recent market report, the computer software market is expected to continue expanding at an accelerating speed, but the market supply of qualified software developers can hardly meet such a huge demand. In recent years, the surge of text generation research works provides the opportunities to address such a dilemma through automatic program synthesis. In this paper, we propose to make our try to solve the program synthesis problem from a data mining perspective. To address the problem, a novel generative model, namely EgoCoder, will be introduced in this paper. EgoCoder effectively parses program code into abstract syntax trees (ASTs), where the tree nodes will contain the program code/comment content and the tree structure can capture the program logic flows. Based on a new unit model called Hsu, EgoCoder can effectively capture both the hierarchical and sequential patterns in the program ASTs. Extensive experiments will be done to compare EgoCoder with the state-of-the-art text generation methods, and the experimental results have demonstrated the effectiveness of EgoCoder in addressing the program synthesis problem.
Formally, programing denotes the process of developing and implementing computer instructions to enable a computer to perform certain tasks. These instructions are usually written in one or several programing languages, and a sequence of computer instructions (implementing the pre-specified functions) will be called a computer program, which helps the computer to operate smoothly. To learn necessary programing skills, a long-time systematic training is usually required for beginners. Generally, to be a qualified programmer, people may need to master knowledge from various areas, including programing language, discrete mathematics, data structure and algorithm, etc.
Computer programing continues to be a necessary and important skill for both academic researchers and industry practitioners as the Internet and AI applications continue to expand. As introduced in (grow, ), the computer software market is expanding at an accelerating speed and is estimated to grow from Billion USD in 2014 to more than Billion USD in 2022. Meanwhile, according to the latest market analysis report (market, ), there exists a huge gap between the market supply and demand of software developers. For instance, from January 2016 to February 2017, more than job postings requesting for qualified software engineers have been posted in each month, but the average monthly hire number is merely . Such a huge demand-supply gap also motivates many large IT companies to seek for other ways to address such a problem.
For effective program code storage and maintenance, inside all the well-known big IT and related technology companies, they are maintaining a company-internal program codebase for storing all the developed program code of company systems, web services, software products and research projects. The program code in these codebases is normally of a tremendous amount. A recent report (codebase, ) releases the lines of code used in several companies and software systems, among which Google ranks the top with more than 2 billion lines of code (google, ) used in all its Internet services. These company codebase repositories cover very diverse yet high-quality code, which are also the most valuable intellectual property of companies, but fail to be effectively exploited.
Programing has been long-time treated as one of the most challenging skills mastered by a very small number of people from some untrained eyes. In this paper, we will make our try to attack this holy-grail pride of software engineers by training a model to write programs automatically. The automatic program synthesis problem is a fundamental problem from the technology, business and society development perspectives. Successfully addressing the problem will effectively bridge the market supply&demand gap for qualified practitioners, greatly stimulate the development of IT and other related areas, intelligently recycle the company internal codebase for secondary-development, and promisingly free human from the tedious coding positions to other more challenging jobs.
In recent years, due to the surge of deep learning developments (GBC16, ), many text generation research works and models have been proposed, which introduce many novel yet interesting research problems. Meanwhile, slightly different from the unstructured sentences written in natural languages, the program code written in programing languages is highly structured, which can be precisely parsed into a hierarchical structure according to the specific programming language grammar. For instance, for the program written in an advanced programing language, Python, its code will consist of hierarchical structures like class, function, statements and expressions, etc. Therefore, instead of handling the program characters by characters (like the existing text generation research works (SMH11, )), new techniques that can handle the program according to its own structure will be necessary.
The automatic program synthesis problem is extremely challenging to solve due to several reasons:
Lack of Problem Definition: The automatic program synthesis problem is still an open problem to this context so far. A formal definition of automatic program synthesis will be required before proposing potential solutions to address it.
Program Hierarchical Structure Extraction: There usually exists a concrete hierarchical-sequential structure of program code according to its logic flows hierarchically and sequentially. Generally, code tokens at the lower level of programs will precisely implement the desired physical functions of the program components at higher levels; meanwhile, at each level, the logic will flow in a sequential manner from the beginning to the end. Extraction of such a hierarchical-sequential program structure will be useful for effective program information modeling and representation learning.
Unit Model: For each component in the hierarchical-sequential structure aforementioned, depending on the specific running mode, it will accept the input from the components above/below and before/after the component. A new unit model for implementing such an intertwined relationships in the learning process will be desired.
Program Intention Incorporation: Besides the program code itself, there usually exist some textual descriptions of the program code in a natural language, which indicates the physical function of the program, e.g., ranking, shuffling, searching, factorization and dynamic programing, etc. Effectively incorporating the program intention into the learning process will allow both program generation and interpretation across natural languages and programing languages.
To effectively resolve the above challenges, in this paper, we will introduce a novel neural network model, namely EgoCoder, with a deep architecture. EgoCoder provides a formal definition of the automatic program synthesis problem, which covers three different sub-problems respectively: program generation, program interpretation and program completion. Instead of learning the models based on the pure text information in the program code, EgoCoder extracts the hierarchical-sequential structure with a programming language parser, which translates the input program code into abstract syntax tree (AST) structured diagrams. For each node in the extracted ASTs, it contains both syntax types and tokens as its content. Meanwhile, the structure of the extracted ASTs will also effectively indicate the semantic logic flows of the program. To capture both the syntax contents of the program components and the semantical logic flow of the program, a new unit model, namely Hsu (hierarchical sequential unit), will be used as the basic component in EgoCoder. Unit model Hsu can accept inputs from sibling nodes at the same levels, as well as evolving information from the child nodes and inheriting information from the father node simultaneously. Based on a set of sampled sub-tree batches from the extracted program ASTs, EgoCoder can be trained effectively to capture the substructures covered in the ASTs. These new technical terms mentioned above will be clearly illustrated in great details in this paper.
2. Problem Formulation
In this section, we will first define several important concepts used in this paper, based on which we will provide the formulation of the studied problem and its three different running modes.
2.1. Terminology Definition
Computer program usually has a highly structured hierarchy, involving the code components belonging to different syntax types.
Definition 2.1 ().
(Program Syntax Type): Formally, we can represent the set of syntax types involved in the program as set module, class, function, statement, expressionunit token syntax type, where the unit token syntax type set involves various variable and operator types used in the program.
Based on the program syntax type set, we can translate a program into a program abstract syntax tree, where the nodes denote program code components (i.e., code blocks) belonging to different syntax types, and the links represent the semantic logic flows among the code components.
Definition 2.2 ().
(Program AST): Formally, a program AST can be represented as a graph structured diagram: , where denotes the set of program component nodes, and denotes the set of logic-flow relationships among the nodes at either different hierarchical levels or at the same hierarchical levels. In , the represents the top program component node, which usually denotes the program module component by default.
Definition 2.3 ().
(Program Component Node): Each program component node in the program AST can be denoted as a triple , where denotes its syntax type, represents its textual content and denotes the functional intention of the program component. The overall program intention can be represented as the AST root node intention by default.
For instance, as shown in Figure 1, given the input program on the left, we can represent its corresponding program AST on the right, where the top program component is module. The program module covers the one import statement and one class component, which further involves two function components. The first function componennt contains multiple statements with sequential relationships, and each statement further contains multiple sequential expressions, i.e., sequences of tokens. Different from natural language, the program code is well-structured, and each token also has a corresponding concept denoting its type, e.g., key words vs variables vs operators, which can be precisely extracted with the corresponding programming language interpreter/parser.
2.2. Problem Formulation
The automatic program synthesis problem studied in this paper actually covers three sub-problems simultaneously, each of which describes a special case of the “problem synthesis” problem. Formally, these three sub-problems covered in the automatic program synthesis problem are illustrated as follows:
Program Generation: Given the program intention of the top program module component in the program AST, the program generation problem aims at generating the program source code that can implement the specified intentions.
Program Interpretation: With the complete program source code or merely a fragment, the program interpretation problem aims at inferring the potential intention of the program, i.e., interpreting the physical functions of the program code.
Program Completion: Given a fragment of the program code, which can be either a function or merely several statements of the code, the program completion problem aims at completing the missing components of the program.
3. Proposed Methods
In this section, we will introduce the EgoCoder framework to solve the automatic program synthesis problem (including all these three aforementioned sub-problems). Framework EgoCoder involves several crucial steps: (1) program parsing, (2) hierarchical sequential statement encoding with Hsu, and (3) framework learning. In the following part of this section, we will introduce these three steps in great detail.
3.1. Program Parsing
Different from natural languages, the program written in programing languages is highly structured. Instead of handling the code characters by characters, we propose to translate the program code into program ASTs in this paper, which will be taken as the input for modeling to be introduced in the next subsection. For instance, given a program statement “pivot_value = seq[pivot_index]”, it assigns an entry (with index “pivot_index”) from list “seq” to a variable “pivot_value”, where “=” and “” are the operators, and “pivot_value”, “seq”, “pivot_index” denote the assignment target, source list, and index variables respectively. For many programming languages, like Python, the space among the tokens has no impact on the program functions. For instance, the program statement “pivot_value=seq[pivot_index]” (with no space between the tokens) will work exactly as “pivot_value = seq [ pivot_index ]” (with tokens well separated by the space). However, such a characteristic will create lots of challenges for partitioning the program line into unit tokens. Traditional text mining and natural language processing techniques will either partition the code line into a sequence of characters, i.e., ‘p’, ‘i’, ‘v’, ‘o’, , ‘x’, ‘]’, or separate the string by certain characters among them. Neither of these two partition methods will work well for programs, and they will also create lots of problems for modeling the program code and understanding the program intention.
In addition, in most of the cases, program operators will be deeply buried in the variables. For instance, the expression “seq[pivot_index]” actually represents an entry in a list, where “” is an operator. Without differentiating ‘[’ and ‘]’ from the remaining characters, it is highly likely that we will treat “seq[pivot_index]” merely as a new variable name and fail to process the code correctly. In this paper, to resolve such a problem, we propose to parse the program code lines into a program AST instead.
For instance, in Figure 2, we show two examples of program ASTs corresponding to two input program statements. The first statement involves the assignment of value “seq[pivot_index]” to variable “pivot_value”. In its AST, we have “pivot_value”, “seq” and “pivot_index” as the variable tokens, and “=” and “” as the operator tokens. Furthermore, “seq”, “” and “pivot_index” together will compose an expression in the syntax tree. For the nodes in the same level, i.e., the siblings, we will add sequential links connecting them, which are denoted by the dashed links as shown in Figure 2.
The second example shown in Figure 2 is more complicated, it is a “FOR”-statement. According to the provided syntax tree shown in the figure, this statement contains the “FOR-Condition”-statement and “FOR-Body”-statement as the child nodes of the root. For the “FOR-Condition”-statement, it starts with a reserved keyword token “for”, followed by variable token and another reserved keyword token “in” respectively, and ends with an expression “range(left, right)” (involving function call token “range()” as well as variable tokens “left” and “right”). Furthermore, in the “FOR-Body”-statement, it contains an “IF”-statement, involving both the “IF-Condition”-statement and “IF-Body”-statement respectively.
For long programs, their ASTs will be in an extremely deep structure, which may cause many computational problems in model learning. In this paper, we will allow EgoCoder to truncate ASTs to shrink the tree depth. For instance, if we use statement as the smallest basic syntax type in the AST leaf nodes, then the ASTs of program statements 1 and 2 in Figure 2 will be of a much simpler structure, whose involved nodes are marked in green circles in Figure 2. There exist some open-source tools which can generate the syntax tree of Python code automatically, e.g., the Python AST package111https://docs.python.org/2/library/ast.html. With these tools, instead of modeling the program raw textual code, we can translate the program into its AST, and the following learning steps will be all based on the obtained ASTs by default.
3.2. Hierarchical Sequential Unit (HSU)
As shown in the constructed ASTs, among the nodes in the tree structured diagram, there exist two different relationship types: hierarchical relationship between the father nodes and children nodes at different levels, and sequential relationship between sibling nodes at the same levels. To effectively model the contents of the nodes as well as the hierarchical-sequential relationships among the nodes, in this section, we will introduce a novel unit model, namely HSU (Hierarchical Sequential Unit). Hsu will be used as the basic structure for constructing the EgoCoder model (to be illustrated in the next subsection), which involves two sub-units, ESU (Evolutional Sequential Unit) and ISU (Inherited Sequential Unit), for handling the program generation and interpretation tasks respectively. The general structure of the HSU is provided in Figure 3, where the arrows denote the information flow directions, black/red dots represent the concatenation operations of vectors, and denote the sigmoid and hyperbolic tangent functions respectively, and icons , represent the entry-wise vector product and sum operators.
3.2.1. Evolutional Sequential Unit
In Figure 3, the component on the left is an ESU, which accepts the input from the children nodes, i.e., and the left sibling node, i.e., . For the input from sibling node, ESU adopts a “forget gate”, which may choose one part of to update. In programs, the scope of variables can be different between statements, which may be updated as the code runs into a new statement. Formally, we can represent the “forget gate” together with the updated left-sibling node state as
Here, denotes the concatenated input state vector from the children nodes and matrix represents the variables of the “forget gate” in ESU.
Meanwhile, for the inputs from the children nodes, ESU introduces a gate, namely the “evolve gate”, which can evolve the children input states to the upper level. Here, the term “evolve” models the changes from the lower-level program expression to higher-level program statement, which is effective to represent the changes in the scope of variables and other program context information across levels in program ASTs. Formally, we can represent the “evolve gate” as well as the updated children node state vector as
where denotes the variable matrix in the “evolve gate” in ESU.
ESU computes the output with the original inputs from sibling and children nodes, i.e., , , as well as the updated sibling-node state vector and the evolved child-node state vector . ESU allows different combinations of the state vectors, which are controlled by two new selection gates and respectively. Formally, we can represent the final output of ESU as
where , and denotes a vector filled with value . Matrices , , represent the variables involved in the components. Vector will be the output to both the right sibling node and the father node in ESU.
3.2.2. Inherited Sequential Unit
The component on the right of Figure 3 is called the ISU, which accepts input from the left sibling node, i.e., , higher-level father node, i.e., , and generates the output for the right sibling node and children nodes at the lower level. Similar to ESU, there also exists a “forget gate” in ISU for updating some information from the sibling state input. Slightly different from ESU, the “forget gate” in ISU is controlled by the states of sibling and father nodes, which together with the updated input from the left-sibling node can be represented as follows:
Here, is the variable of the “forget gate” in ISU.
Another significant difference between ISU and ESU is, for inheriting and updating the program context from the father node, e.g., the scopes of variables and other program information, ISU has an “inherit gate” for changing the input states of the father node. Formally, we can represent the “inherit gate” together with the updated input from the father node as
where is the variable of the “inherit gate” in ISU.
ISU will compute the final output based on the combination of the original input vectors and the updated vectors, which is controlled by the gates and respectively. Formally, we can represent the final output of ISU as
where gates and matrices , , denote the variables of ISU. Vector will be the output to both the right sibling node as well as all the children nodes.
In sum, the ESU and ISU components covered in the HSU unit model have a lot in common, as they (1) both have the forget gate, (2) both have the evolve/inherit gate, and (3) both combine the original states and updated states to generate the output. There also exist many difference between ESU and ISU. Besides the input/output among the sibling nodes, ISU also accepts input from higher-level father nodes to generate output to the children nodes; while ESU accepts input from the children nodes instead and generate output to the father node. The evolve/inherit gates in ESU and ISU effectively adapt the program context changes between different levels but in different directions. In the training and testing stages of EgoCoder, ESU and ISU will be mainly used as the unit structure for program interpretation and program generation to be introduced as follows.
3.3. Framework Learning
With the HSU introduced before, we can represent the architecture of EgoCoder in Figure 4, which is also in a tree structured diagram. Based on the ASTs parsed from the input program source code, a set of sub-trees will be sampled for training EgoCoder. For the children HSU nodes at the lower level, they are fed with their raw encoding features and sibling node states as the inputs. Here, denotes the maximum node degree in the program AST, and dummy padding will be used for the sub-trees with less than children nodes. Among these children nodes, the data flow is bi-directed, which can effectively model the sequential patterns in ASTs in both directions. Furthermore, the outputs of the children HSU nodes will be all fed to a father node at the higher level, which accepts no sibling node input. The output of the father HSU node will effectively recover its content. Besides the bottom-up mode, EgoCoder can also work well in a top-down mode, where the input of father HSU node will generate the contents of children HSU nodes. In this part, we will introduce the EgoCoder model in great detail to illustrate how to train the model with program ASTs.
3.3.1. Token Raw Encoding
As introduced before, in the program ASTs, the nodes denote the program components, which contain program syntax types, token contents and program intentions (optional). Based on the parsing results obtained from the program, we can obtain the syntax type set and the set of concrete keyword, variable, operator and other tokens used in the program, which will be represented as sets and respectively. Formally, for each node in the program ASTs, its representation can be represented as a vector , where and represent the one-hot feature vector of syntax types and tokens respectively and represents the maximal number of tokens contained in the tree nodes. For the tree nodes with less than tokens, dummy padding will be adopted.
3.3.2. Program Generation: Top-Down Training of EgoCoder
Based on the input raw feature vector from the father node in EgoCoder as illustrated in Figure 4, we can denote its output result of the father node via the ISU model as
where denotes a dummy padding vector and covers all the variables involved in the ISU model introduced before.
By feeding as the input to the children nodes at the lower level, model EgoCoder will generate the output representations of the children nodes. We can denote the state and output vectors of the child node as
where denotes the input from the left sibling node, represents the softmax function and for the first child node without left sibling. and are the variables involved to project node state to the output.
Compared with the ground-truth representation of the children nodes in the sampled sub-tree, i.e., , the loss introduced by the ISU model on the sub-tree can be represented as
which is defined based on the cross-entropy loss function, and index enumerates all the syntax types and tokens involved in the node representation vector.
3.3.3. Program Interpretation: Bottom-Up Training of EgoCoder
On the other hand, besides the top-down direction, we will also train the EgoCoder model in a bottom-up manner. Based on the input for the children nodes, we can generate the contents of the father node as well. Formally, we can represent the input vectors for the children nodes as . By feeding these vectors to the children nodes, we can represent the output vector from the child node as vector :
where for the first children node, and represents the variables involved in the ESU model.
Furthermore, based on the children node representations, we will be able to represent the state vector and output vector of the father node as
where vector contains all the children node states. and are the variables used to project the father node state to the its output.
The introduced loss based on the input sub-tree by comparing with the ground-truth vector can be represented as
3.3.4. Program Completion: Sequential Training of EgoCoder
In the case when only a fragment of the program is provided for feeding the child nodes, the training process for the ESU will encounter great challenges, since the incomplete input will mislead the model to generate a wrong output. This happens very often, since missing any line of the program code will introduce an incomplete sub-tree structured diagram in the program AST. To resolve such a problem, we propose to generate the complete child node input information based on the program fragments by training the bi-directed HSU structure in EgoCoder.
As introduced before, based on the input of children nodes , we can represent their state vectors as . In the bi-directed HSU, based on the state vectors of the child node, we can represent the inferred output vectors for the tokens on the left and on the right as vectors and respectively:
where , , and , are the variables used to project the states to the output in the left and right HSUs respectively. Compared with the ground truth, we can represent the loss introduced in generating children node tokens as:
3.3.5. Joint Optimization Objective Function
Based on the above descriptions, we can represent the joint optimization function of model EgoCoder as
where covers all the variables adopted to project the state vector to the output space introduced above, and , denote the weights of the last two loss terms (in the experiments and are both assigned with value ).
Formally, to solve the above objective function, the learning process of EgoCoder can be done based on the sub-tree structures (involving one parent node and all its child nodes) sampled from the program AST. To optimize the above loss function, we utilize Stochastic Gradient Descent (SGD) as the optimization algorithm. To be more specific, the training process involves multiple epochs. In each epoch, the training data is shuffled and a minibatch of the instances are sampled to update the parameters with SGD. In addition, for each sampled sub-tree, we will feed the EgoCoder model to minimize the loss terms , and iteratively for parameter learning. Such a process continues until convergence.
To test the effectiveness of the proposed unit model Hsu and the learning framework EgoCoder, we have conducted extensive experiments on a real-world program-comment dataset, and compared EgoCoder with several existing text generation methods. In the following part of this section, we will first introduce the experimental settings, including dataset descriptions, detailed experiment setup, comparison methods and evaluation metrics. After that, the experimental results and case studies will be provided and analyzed.
4.1. Experimental Setting
4.1.1. Dataset Description
In the experiments, we will take the program code written in Python programing language as an example. The program dataset used in the experiments covers the Python implementation code of basic algorithms, like different sort algorithms, search algorithms, hash algorithms and dynamic program algorithms. In the program source code file, besides the source code, there also exist a sequence of comments indicating the functions of the program, which will be used as the program intention in the experiments. The dataset will be released as a benchmark for code generation soon.
4.1.2. Experimental Setup
In the experiments, instead of modeling the program code characters by characters, we propose to parse the code into ASTs, in which the smallest syntax type is the basic statement in the experiments. From the ASTs, we can sample a set of sub-tree structured diagrams. The contents attached to the sub-tree nodes together with its structure will be fed to learn the EgoCoder model. Based on the program ASTs, we can denote the maximum children node number as , and the maximum number of tokens attached to each node as . For the nodes with less than nodes or tokens, a dummy one-hot key feature vector representation will be used for padding. At the same time, for the AST root node, we extract the textual comments of the whole program as its content, which will be represented as a sequence of natural language tokens actually, and can be modeled with the Hsu model effectively as well. Based on the sampled sub-trees, we propose to train EgoCoder iteratively as introduced at the end of Section 3 to learn the variables.
4.1.3. Comparison Methods
In the experiments, we will compare EgoCoder with various existing prediction and generative models, which are listed as follows:
EgoCoder Model: The EgoCoder model proposed in this paper is based on the new Hsu unit model, which can learn the information in program code based on its ASTs.
Ast-BiRnn-LSTM: The Ast-BiRnn-LSTM model is an AST based bi-directional RNN model (SP97, ) using LSTM (HS97, ) as the unit cell. Ast-BiRnn-LSTM can capture the sequential patterns in program code textual data in bi-directions simultaneously, which is able to infer the tokens ahead of and after the input.
Ast-BiRnn-Basic: In the experiments, we also compare with the bi-directional RNN model Ast-BiRnn-Basic (SP97, ), which uses the basic neuron cell as the unit cell.
Ast-AutoEncoder: Via two hidden layers, we propose to use the deep Autoencoder model (VLLBM10, ) as another baseline method in the experiments. Ast-AutoEncoder can effectively capture the patterns for sequential program components extracted from the ASTs.
BiRnn-LSTM: To show the advantages of modeling the program code textual information based on the AST, we also compare the methods with the traditional bi-directional RNN (SP97, ) models based on the raw program textual information. Model BiRnn-LSTM splits the program code and comment into tokens based on the space among them.
BiRnn-GRU: Model BiRnn-GRU using GRU (CGCB14, ) as the unit model also splits the program code and comment into tokens based on the space among them and infers the following tokens iteratively.
BiRnn-Basic: Model BiRnn-Basic is of the same architecture as BiRnn-LSTM and BiRnn-GRU, but it uses the basic neuron as the unit model in the learning process.
4.1.4. Evaluation Metrics
We formulate the program code generation (from comments to program code), program code interpretation (from program code to program comments), and program completion problems as a multi-class classification problem, where the inferred tokens can be used as labels. In the experiments, we will use traditional classification evaluation metric Accuracy, Precision, Recall and F1 for measuring the performance of models. Here, the Precision, Recall and F1 metrics cover the micro, macro and weighted versions respectively. In addition, we will also show the number of iterations required in training the models as another evaluation metric. Here, we need to add a remark that, as indicated in page222http://scikit-learn.org/stable/modules/generated/sklearn.metrics.precision_recall_fscore_support.html, for the weighted-F1 metric which considers the label imbalance, its value may not be between the corresponding weighted precision and recall in the experimental results.
4.2. Experimental Result
4.2.1. Program Generation from Comments
In Table 1, we show the performance of different methods in generating the program code (line by line). Based on the input program code line, the models will predict the next line of the program code, and the inferred tokens in the new line are treated as the labels in evaluation.
According to the results in Table 1, model EgoCoder can achieve much better performance generating the program code line compared with the other baseline methods. For instance, the Accuracy achieved by EgoCoder is , which is almost the triple of the Accuracy achieved by Ast-AutoEncoder and also surpasses Ast-BiRnn-LSTM, Ast-BiRnn-GRU and Ast-BiRnn-Basic by more than and outperforms BiRnn-LSTM, BiRnn-GRU and BiRnn-Basic by more than . Similar results can also be observed for the other evaluation metrics. In addition, model EgoCoder takes far less iterations before convergence based on the training set. As shown in Table 1, the iteration required for EgoCoder to converge is merely about , which is about of the required iterations by Ast-AutoEncoder, of the required iterations by Ast-BiRnn-LSTM, Ast-BiRnn-GRU, Ast-BiRnn-Basic, and about of the required iterations by BiRnn-LSTM, BiRnn-GRU and BiRnn-Basic.
In Table 2, we show the results obtained by EgoCoder in generating the complete program code based on the input program comments. Here, the generation process involves the iterative inferences of the program tokens at the next lines based on the input program comments without any interactions with the outside world. Among the input program comments, EgoCoder is able to generate of them without making any mistakes, which outperform the baseline methods with great advantages. For the AST-BiRNN methods, they can generate - of the program without any mistakes. For the traditional BiRNN methods, they can only generate 1-2 programs, while Ast-AutoEncoder cannot generate any program at all.
4.2.2. Program Interpretation based on Code
In Table 4, we provide the experimental results of the comparison methods in generating the program comments based on the program code input. Compared with the program code, the program comments are of a shorter length and have less tokens to be predicted, and the evaluation scores achieved by the baseline methods in Table 4 are also slightly larger than the scores in Table 1.
Among the baseline methods, EgoCoder can still achieve much better results than the baseline methods with great advantages. Among all the program code input, EgoCoder can correctly generate about the program comment tokens. The AST-BiRNN methods can also achieve a very good performance, and they can obtain an average Accuracy around , which is better than the traditional BiRNN methods. Method Ast-AutoEncoder performs the worst in the program interpretation task, which can merely achieve an average Accuracy score around .
4.2.3. Program Completion with Code Fragments
Table 3 covers the program code completion experimental results of the comparison methods. Here, for each program in the dataset, we randomly pick one line in the program as the input for the models to complete the program code (i.e., generate the code ahead of or after the input line). Slightly different from the program generation as shown in Table 2, where the input is the tree root node content, the input in the program completion can be any lines in the program code, results obtained in which are slightly lower than those in Table 2.
Among these programs in the dataset, EgoCoder completes of the correctly, which is much better than the other baseline methods. The AST-BiRNN methods can still complete about of the programs correctly, while the remaining methods cannot complete the program code at all. The program completion task may require the model to be able to generate contents in both the sequential directions and the hierarchical directions, i.e., ahead of the input, after the input, above the input and below the input, which can demonstrate the advantages of the Hsu model compared against the traditional RNN models.
4.2.4. Experimental Discoveries
Generally, according to the program generation, program interpretation and program completion experimental results, EgoCoder performs very well in inferring both the contents at both the children nodes and father node. The main reason can be due to that the Hsu model effectively captures both the sequential and hierarchical information patterns in the ASTs, which performs much more effectively than the models merely capturing the sequential patterns. In addition, the AST will also greatly improve the model performance, since the tree diagram will effectively help the models outline the program hierarchical structure. The Ast-AutoEncoder model cannot achieve a good performance in these content generation tasks.
4.3. Case Study
In this part, we will provide a study about the succeeded and failed cases of EgoCoder in the experiments.
4.3.1. Succeeded Cases
In Figures 5, we show the program code that EgoCoder can handle very well in both generation, interpretation and completion. The left program code is about the Binary Search algorithm and the right code is about the Quick Sort algorithm. We show both the original and the generated program code of both algorithms in the plots. By checking these two program code blocks, we can observe that the code generated by EgoCoder can implement exactly the same function as the original program code in the dataset. Furthermore, we can also observe some differences between the program code blocks: (1) many of the operator and variable tokens in the original code blocks are connected, while the tokens in the generated code block are well separated; (2) in the generated code block, some extra parentheses are inserted, especially for some expressions in statements; (3) the code indent in the original code uses two space keys, but in the generated code involves 1 tab key instead. These differences are mainly due to our model EgoCoder is trained based on the AST, whose contents are well organized and structured by the program parser.
4.3.2. Failed Cases
Besides the succeeded cases aforementioned, in Figure 6, we also provide two cases that EgoCoder cannot handle well, especially in program code generation and completion. The left program code is about the Sieve of Atkin algorithm, and the right code is about the Union Find class with compressed path. The main problem with the code is that it contains so many duplicated contents. In the blocks, we can identify several common statements (in the same colors), which will make the EgoCoder fail to work. For instance, in the Union Find class code, given a statement “self.__validate_ele(y)” (in bolded blue font), it will be very hard for the model to generate the statement after it, since there are two different options “x_root = self.__find(x)” and “return self.find(x) == self.find(y)”. Such a problem can be hopefully addressed by incorporate a even deeper architecture in EgoCoder. Just like this failed case, if we can effectively incorporate the father node of “self.__validate_ele(y)” (i.e., “def union(self, x, y):” and “def is_connected(self, x, y):”), the conflict can be resolved promisingly. We will leave it as a potential future work.
5. Related Work
The problem studied in this paper is strongly correlated with research problems about deep neural network, text generation and program synthesis.
Deep Neural Networks: The essence of deep learning is to compute hierarchical features or representations of the observational data (GBC16, ; LBH15, ). With the surge of deep learning research and applications in recent years, lots of research works have appeared to apply the deep learning methods, like deep belief network (HOT06, ), deep Boltzmann machine (SH09, ), Deep neural network (J02, ; KSH12, ) and Deep autoencoder model (VLLBM10, ), in various applications, like speech and audio processing (DHK13, ; HDYDMJSVNSK12, ), language modeling and processing (ASKR12, ; MH09, ), information retrieval (H12, ; SH09, ), objective recognition and computer vision (LBH15, ), as well as multimodal and multi-task learning (WBU10, ; WBU11, ).
Text Generation: Text generation has been an important problem in both text mining and natural language processing. Depending on the input information, the text generation problem can be categorized into text generation from keywords (UIS02, ), concepts (KL13, ), topics (CH15, ), ontologies (B05, ) and images (VTBE14, ). In (UIS02, ), the authors propose a method consisting of candidate-text construction and evaluation for sentence generation from keywords/headwords. Konstas et al. (KL13, ) introduced a global model for concept-to-text generation, which refers to the task of automatically producing textual output from non-linguistic input. In terms of the objective output, the text generation problem includes question generation (CH15, ), image captions (VTBE14, ) and image descriptions (KPDLCBB11, ). Various models have been used in the text generation problems, including RNN (SMH11, ), Autoencoder (LLJ15, ) and GAN (ZGFCHSC17, ).
Program Synthesis: The problem studied in this paper is also closely related with the program synthesis problem studied in software engineering. Formally, the goal of software program synthesis is to generate programs automatically from high-level specifications, lots of research works have been done on this topic already. Program synthesis is a challenging problem, which may require external supervisions from either template (SGF13, ), examples and type information (OZ15, ), and oracles (JGST10, ). In (JGST10, ), the authors present a novel approach to automatic synthesis of loop-free programs based on a combination of oracle-guided learning from examples. Based on the program templates, (SGF13, ) introduces an approach to generate the programs from the templates. Osera et al. (OZ15, ) introduce an algorithm for synthesizing recursive functions that process algebraic datatypes, which exploits both type information and input-output examples to prune the search space. Some other program synthesis works address the problem with recursive algorithms (AGK13, ), deductive approach (MW80, ), crowd-sourcing (CDLMV15, ), and program verification (SGF10, ).
In this paper, we have studied a novel research problem about program generation, which covers the tasks about program code generation, program interpretation and program completion. To address such a challenging problem, a new learning model, namely EgoCoder, has been introduced. EgoCoder learns the program code contents by parsing the program code into ASTs, whose nodes contain the program code/comment contents while the AST structure can indicate the program logic flows. To effectively capture both the hierarchical and sequential patterns in the ASTs, a new unit model, i.e., Hsu, is introduced as the basic structure covered in EgoCoder. We have tested the effectiveness of EgoCoder on real-world program datasets, and EgoCoder can achieve very outstanding performance than the other state-of-the-art baseline methods in addressing the program generation tasks.
-  Codebases: Millions of lines of code. http://www.informationisbeautiful.net/visualizations/million-lines-of-code/. [Online; accessed 2-December-2017].
-  Engineering software market to reach $50.34 bn in 2022. https://www.automation.com/automation-news/industry/engineering-software-market-to-reach-5034-bn-in-2022. [Online; accessed 2-December-2017].
-  The labor market supply & demand of software developers. http://www.economicmodeling.com/2017/06/01/labor-market-supply-demand-software-developers/. [Online; accessed 2-December-2017].
-  Why google stores billions of lines of code in a single repository. https://cacm.acm.org/magazines/2016/7/204032-why-google-stores-billions-of-lines-of-code-in-a-single-repository/fulltext. [Online; accessed 2-December-2017].
-  A. Albarghouthi, S. Gulwani, and Z. Kincaid. Recursive program synthesis. In CAV, 2013.
-  E. Arisoy, T. Sainath, B. Kingsbury, and B. Ramabhadran. Deep neural network language models. In WLM, 2012.
-  K. Bontcheva. Generating tailored textual summaries from ontologies, 2005.
-  Y. Chali and S. Hasan. Towards topic-to-question generation. Comput. Linguist., 2015.
-  J. Chung, C. Gulcehre, K. Cho, and Y. Bengio. Empirical evaluation of gated recurrent neural networks on sequence modeling. 2014.
-  R. Cochran, L. DAntoni, B. Livshits, D. Molnar, and M. Veanes. Program boosting: Program synthesis via crowd-sourcing. In POPL, 2015.
-  L. Deng, G. Hinton, and B. Kingsbury. New types of deep neural network learning for speech recognition and related applications: An overview. In ICASSP, 2013.
-  I. Goodfellow, Y. Bengio, and A. Courville. Deep Learning. MIT Press, 2016. http://www.deeplearningbook.org.
-  S. Hill. Elite and upper-class families. In Families: A Social Class Perspective. 2012.
-  G. Hinton, L. Deng, D. Yu, G. Dahl, A. Mohamed, N. Jaitly, A. Senior, V. Vanhoucke, P. Nguyen, T. Sainath, and B. Kingsbury. Deep neural networks for acoustic modeling in speech recognition. IEEE Signal Processing Magazine, 2012.
-  G. Hinton, S. Osindero, and Y. Teh. A fast learning algorithm for deep belief nets. Neural Comput., 2006.
-  S. Hochreiter and J Schmidhuber. Long short-term memory. Neural Comput., 1997.
-  H. Jaeger. Tutorial on training recurrent neural networks, covering BPPT, RTRL, EKF and the “echo state network” approach. Technical report, Fraunhofer Institute for Autonomous Intelligent Systems (AIS), 2002.
-  S. Jha, S. Gulwani, S. Seshia, and A. Tiwari. Oracle-guided component-based program synthesis. In ICSE, 2010.
-  I. Konstas and M. Lapata. A global model for concept-to-text generation. J. Artif. Int. Res., 2013.
-  A. Krizhevsky, I. Sutskever, and G. Hinton. Imagenet classification with deep convolutional neural networks. In NIPS, 2012.
-  G. Kulkarni, V. Premraj, S. Dhar, S. Li, Y. Choi, A. Berg, and T. Berg. Baby talk: Understanding and generating simple image descriptions. In CVPR, 2011.
-  Y. LeCun, Y. Bengio, and G. Hinton. Deep learning. Nature, 521, 2015. http://dx.doi.org/10.1038/nature14539.
-  J. Li, M. Luong, and D. Jurafsky. A hierarchical neural autoencoder for paragraphs and documents. In ACL, 2015.
-  Z. Manna and R. Waldinger. A deductive approach to program synthesis. ACM Trans. Program. Lang. Syst., 1980.
-  A. Mnih and G. Hinton. A scalable hierarchical distributed language model. In NIPS. 2009.
-  P. Osera and S. Zdancewic. Type-and-example-directed program synthesis. In PLDI, 2015.
-  R. Salakhutdinov and G. Hinton. Semantic hashing. International Journal of Approximate Reasoning, 2009.
-  M. Schuster and K.K. Paliwal. Bidirectional recurrent neural networks. Trans. Sig. Proc., 1997.
-  S. Srivastava, S. Gulwani, and J. Foster. From program verification to program synthesis. In POPL, 2010.
-  S. Srivastava, S. Gulwani, and J. Foster. Template-based program verification and program synthesis. International Journal on Software Tools for Technology Transfer, 2013.
-  I. Sutskever, J. Martens, and G. Hinton. Generating text with recurrent neural networks. In ICML, 2011.
-  K. Uchimoto, H. Isahara, and S. Sekine. Text generation from keywords. In COLING, 2002.
-  P. Vincent, H. Larochelle, I. Lajoie, Y. Bengio, and P. Manzagol. Stacked denoising autoencoders: Learning useful representations in a deep network with a local denoising criterion. Journal of Machine Learning Research, 2010.
-  O. Vinyals, A. Toshev, S. Bengio, and D. Erhan. Show and tell: A neural image caption generator, 2014.
-  J. Weston, S. Bengio, and N. Usunier. Large scale image annotation: Learning to rank with joint word-image embeddings. Journal of Machine Learning, 2010.
-  J. Weston, S. Bengio, and N. Usunier. Wsabie: Scaling up to large vocabulary image annotation. In IJCAI, 2011.
-  Y. Zhang, Z. Gan, K. Fan, Z. Chen, R. Henao, D. Shen, and L. Carin. Adversarial feature matching for text generation. arXiv preprint arXiv:1706.03850, 2017.