Abstract
Benefited on the open source software movement, many code search tools are proposed to retrieve source code over the internet. However, the retrieved source code rarely meets user needs perfectly so that it has to be changed manually. This is because the retrieved source code is concretely over-specific to some particular context. To solve this problem, we propose an Abstract Change Pattern Model (ACPM) to ensure the context-specific source code general for various contexts. This model consists of the ACP abstracting and the ACP concretizing algorithms. The former exploits the abstractly context-aware change pattern from the code changes. Based on the change pattern, the latter transforms the context-specific source code into the correct one meeting different user needs. To evaluate ACPM, we extract 7 topics and collect 5-6 code snippets per topic from the Github, while performing 5 different experiments where we explore 2 sensitivity-related rules and use them to raise the accuracy gradually. Our experimental results show that ACPM is feasible and practical with 73.84% accuracy.
Introduction
With the popularity of the open source software movement, there has been an increasing availability of source code over the internet [1–3]. The study of finding source code experiences the keyword-based search [4], the signature-based search [5], the formal semantics-based search [6] using λprolog specifications and the dynamic semantic-based search [7] using test cases. Many popular code search tools are proposed, such as Code Conjurer [8], Strathcona [9] and Prospector [10]. However, the retrieved source code still has to be changed manually, as it cannot meet user needs. It either takes slightly different parameters or returns slightly different values. Even if it meets one’s needs, but dissatisfy with the others.
One major reason is that the retrieved source code is context-specific, which suffers from the over-specification to some particular context. Recent approaches use program formal specifications to solve this problem. For example, Gopinath, Malik and Khurshid [11] build a SAT formula encoding the constraints imposed by the specification on the program behavior. If the formula is satisfiable, they will derive a repair from the SAT solution. However, these approaches are impractical since they require too much specification.
In this paper, we propose an Abstract Change Pattern Model (ACPM) to ensure the context-specific source code general for various contexts. This model contains the ACP abstracting and the ACP concretizing algorithms. The former exploits the abstractly context-aware change pattern from code changes by extracting the abstract changes and changes-relevant context. The latter applies the change pattern to automatically transform the retrieved source code into the correct one meeting different userneeds.
To evaluate ACPM, we extract 7 topics and collect 5-6 code snippets per topic from the GitHub. Then we perform 5 different experiments, in which we explore 2 sensitivity-related rules and use them to raise accuracy gradually. All experimental results indicate that ACPM is effective and promising for users.
Main contributions are following: The Abstract Change Pattern Model (ACPM) is proposed to ensure the context-specific code general for various contexts. An ACP abstracting algorithm is proposed to exploit the abstractly context-aware change pattern from code changes; an ACP concretizing algorithm is proposed to apply the change pattern to transform the context-specific source code into the correct one meeting the different user needs. The experiments present evidence of the applicability of ACPM in the reuse of the retrieved source code with 73.84% accuracy.
Motivating example
Figure 1 shows a motivating example that is ap-plied throughout the paper. In the example, three pieces of source code are downloaded from Github: m A (textChanged), m B (updateAction) and m C (selection Changed). The old position of the original source code (m A , m B and m C ) is in black and the new position of the changed one (m A ’, m B ’ and m C ’) is in red.

Similar changes to three pieces of source code.
Suppose that Smith retrieves m A ’ but he is so dissatisfied with it that he changes it manually. His changes contain deletion (m A : line 3–4), update (m A : line 6), insertion (m A ’: line 5’– 6’)) and move (m A : line 7–8). Steve does so for m B as well. His changes contain deletion (m B : line 4), update (m B : line 5), insertion (m B ’: line 5’– 6’ and 9′– 12′) and move (m B : line 6–7). Jim does so for m C as well, His changes contain update (m C : line 4), insertion (m C ’: line 5’– 6’) and move (m C : line 5–6).
Although m A , m B and m C are different, three users changes similarly. If we find the common changes between m A and m B , such as {update (m A : line 6), insertion (m A ’: line 5′– 6′), move (m A : line 7–8)} in m A and {update (m B : line 5), insertion (m B ’: line 5′– 6′), move (m B : line 7–8)} in m B . Mean while we omit their different changes, such as {deletion (m A : line 3–4)} in m A and {deletion (m B : line 4), insertion (m B : line 9’– 12’)} in m B . Then we applies the similar changes to m C ’ such as update (m C : line 4), insertion (m C ’: line 5′– 6′) and move (m C : line 5–6). If the hypothesis are achieved, m C will be changed without Jim’s effort.
To achieve the above motivating hypothesis, we define an Abstract Change Pattern Model (ACPM), concretizing the ACP abstracting and the ACP con-cretizing algorithms.
The abstractly context-aware change pattern P is exploited from many concrete code changes with the ACP abstracting algorithm. Algorithm 1 describes this process procedurally in the six steps.
ACP Abstracting
Step 1: Obtaining changes
Let M = {m1, ⋯, m i }. m i is the ith original source code. Let M′= {m1’, ⋯, m i ’}. m i ’ is the changed version of m i . For the source code m i , we represent it with Abstract Syntax Tree (AST i ), characterize code changes as AST changes Δ i given by Δ i = {e i | e i ∈ delete(u,v,k), insert(u,v,k), move(u,v,k), update(u,v)}.
Insert (node u, node v, int k): insert u and position it as the (k+1)-th child of v;
Delete (node u, node v, int k): delete u at the (k+1)-th child of v;
Update (node u, node v): replace the label and AST type of u with v while maintaining u’s position;
Move (node u, node v, int k): delete u from its current position and insert it as the (k+1)-th child of v.
Let m i + Δ i = m i ’. It implies that source code m i undergoes the changes Δ i and becomes a new source code m i ’. These code changes are obtained with Distiller [12], such that Δ i = m i ’-m i . Distiller computes the one-to-one node mapper between the versions of m i ’s AST before and after changes.
In our example, the original methods m A , m B and the changed source code m A ’, m B ’ are transformed into AST A , AST A ’ and AST B , AST B ’ as shown in Fig. 2, where ′O′ represents the nodes in m A and m B while ′N′ represents the nodes in m A ’ and m B ’. Each node corresponds to each line of code statement in Fig. 1. For example, O6 in AST A corresponds to ″MVAction action = (MV Action)e.next();″ in m A . N4 in AST A ’ corresponds to ″object next = e.next();″ in m A ’.

AST comparing analysis for m A and m B .
The code changes (Δ A , Δ B ) of the source code (m A , m B ) are obtained as follows:
Δ A = {e A 1 (Delete 03 01 1), e A 2 (Delete 04 01 2), e A 3 (Move 05N1 1), e A 4 (Update 06N4), e A 5 (Move 07N5 1), e A 6 (Move 08N7 0), e A 7 (InsertN5N3 1), e A 8 (InsertN6N5 0)};
e A 1 refers to deleting 03 at the second child of 01, corresponding to the deletion (m A : line 3) inFig. 1;
e A 4 refers to replacing the label and AST type of 06 with N4 while maintaining 06’s position in the tree, corresponding to the update (m A : line 6) inFig. 1;
e A 5 refers to deleting 07 from its current position and insert it as the second child of N5, corresponding to the move (m A : line 7) in Fig. 1;
e A 7 refers to inserting N5 and position it as the second child of N3, corresponding to the insertion (m A ’: line 5′) in Fig. 1.
In the same way, Δ B = {e B 1 (Delete 04 03 1), e B 2 (Update 05N4), e B 3 (Move 05N3 0), e B 4 (Move 06N5 1), e B 5 (Move 07N7 0), e B 6 (InsertN5N3 1), e B 7 (InsertN6N5 0), e B 8 (InsertN9N3 2), e B 9 (InsertN10N9 0), e B 10 (InsertN11N9 1), e B 11 (InsertN12N11 0)}.
Step 2: Identifying common changes
The common changes Δ
c
are identified with the modified Longest Common Edit Operation Subsequence (LCEOS) algorithm [13]. The algorithm iteratively compares the node operations in Δ
i
pairwise, such that
In our example, the longest common changes are identified as follows: Δ c = {pair1 (e A 4 , e B 2 ), pair2 (e A 5 , e B 4 ), pair3 (e A 6 , e B 5 ), pair4 (e A 7 , e B 6 ), pair5 (e A 8 , e B 7 )}, which refers to {updates (m A : line 6), insertions (m A ’: line 5′– 6′), moves (m A : line 7–8)} and {updates (m B : line 5), insertions (m B ’: line 5′– 6′), moves (m B : line 6–7)}, as shown in Fig. 1.
Step 3: Generalizing abstract changes
Comparing the node operations in Δ c pairwise, the abstract changes are generalized, which are applicable to any target source code with the different identifiers. In these node operation pairs, if one or more concrete instances of types, methods and variables have the same edit type or inheriting type, but the different name, these instances are abstractly equivalent. Then the abstract identifiers $t, $m and $v are substituted for these concrete instances in both node operation pairs and the method itself. Meanwhile, the mapper between the identifiers and the concrete instances are recorded. To enforce a consistent naming, if some subsequent node operation pairs are inconsistent with the current mapper, they are omitted. Algorithm 2 describes the whole process.
In our example, e A 4 (Update 06N4) matches with e B 2 (Update 05N4) in pair1 (e A 4 , e B 2 ). The discrepant variable names e vs. iter are detected. The identifiers mapper (e, $v1) and (iter, $v1) are recorded, which substitutes a fresh abstract identifier $v1 for e in e A 4 (Update 06N4), m A (O2, O5, O6), m A ’ (N2, N3, N4), as well as iter in e B 2 (Update 05N4), m B (O2, O3, O5), m B ’ (N2, N3, N4). pair2 (e A 5 , e B 4 ) does so as well. The identifiers mapper {(isContentDependent, $m1) (isDependent, $m1)} are recorded, which substitutes $m1 for isContentDependent in e A 5 (Move 07N5 1), m A (O7) as well as all isDependent in e B 4 (Move 06N5 1), m B (O6).
Step 4: Extracting changes-relevant context
Let C = {c i |c i ∈ DataDepend (x,y), ControlDepend (x,y), ContainDepend (x,y)}. c i is the changes-relevant context of m i while contains the unchanged nodes of AST i ’ on which changed nodes in e i . The context increases the chance of generating the valid changes syntactically and also serves as the anchors to position changes correctly in a new target location.
Formally, the node y depends on the node x if one of the following relationships holds:
DataDepend (node x, node y): the node x uses or defines a variable whose value is defined in thenode y.
ControlDepend (node x, node y): the node y is control dependent on the node x if y may or may not execute depending on a decision made by x. Formally, given a control-flow graph, y is control dependent on x, if: (i) y post-dominates every vertex p in x ⇝ y, p ≠ x and (ii) y does not strictly post-dominate x.
ContainDepend (node x, node y): the node y is containment dependent on the node x if y is a child of x in the AST.
The changes-relevant context c i of the method m i is extracted with the control, data and containment dependence analysis. All irrelevant nodes are omitted because blindly including the irrelevant nodes as context puts the unnecessary constraints on the potential change locations and results in the false negatives during change location search. Then the node positions are recalculated in AST i and Δ i .
In our example, as shown in Fig. 2-AST A , we consider (i) e A 7 (Insert N5N3 1): The inserted node N5 is control dependent on N3 and data dependent on N4 and N2. Mapping these nodes to the old version yields the context nodes {O2, O5, O6}; (ii) e A 5 (Move O7N5 1): The moved node O6 depends on the nodes c1 = {O2, O5, O6} in the m A , while N7, N5’s child at position 1, depend on the nodes c2 = {N2, N3, N4, N5} in the new m A ’; (iii) the other changes do so as well. After extracting context, irrelevant nodes with dotted lines are omitted, such as {O3, O4, O9} in AST A and N9 in AST A ’. Then the node position are reset in AST A and AST A ’.
Step 5: Generalizing abstract contexts
Using the LCEOS algorithm [13], the common contexts C
c
are identified by iteratively comparing the node operation in c
i
pairwise, such that
In our example, the common contexts are identified, such as pair3(m A (O2), m B (O2)), pair4 (m A (O5), m B (O3)). Then the same for the pair3 (m A (O2), m B (O2)) is done as step1-B to generalize the abstract contexts. The identifiers mapper {(fAction,$m2), (getAction, $m2)}, are recorded, and $m2 is substituted for fActions in m A (O2) and getActions() m B (O2).
Step 6: Generating the context-aware change pattern
All common contexts C
c
are merged into an abstract changes-relevant context C. In our example, C is described as follow: public void method declaration (⋯){ Iterator $v1 = $ m2(⋯).values().iterator(); Whiler($v1.has Next){ MVAction action = (MVAction) $v1.next() If (action. $m1 ()) Action.update()}}
All the common changes Δ c are merged into an abstract changes Δ. In our example, Δ is described as follow:
Update O4N4
O4 = ′MVAction action = (MVAction) $v1.next();′
N4 = ′object next = $V1.next;′
Move O5N5 1O5 = ′if(cation.$m1())′
Move O6N7 0 O6 = ′action.update()′
Insert N5N3 1 N5 = ′if (next instance of MVAction)′
Insert N6N5 0 N6 = ′MVAction action =(MVAction) next′
C and Δ are combined into the abstractly context-aware change pattern P, such that P (C, Δ). The P implies that the source code C undergoes the changes Δ and becomes a new source code C’, such that C +Δ= C’, as shown in Fig. 3.

The mechanism of change pattern.
Based on the abstractly context-aware change pattern P, the target source code m are changed automatically by producing mapping, customizing the concrete changes and replicating the changes on m. Algorithm 3 describes this process procedurally in three steps.
ACPConcretizing
Step1: Producing nodes/identifiers mapper
For target method m and the abstract context C of the abstractly context-aware change pattern P, with Matching Abstract Context to Target Tree [14, 15], the nodes mapping is established by finding the nodes in m that match the nodes in C, and induces the one-to-one identifiers mapper between the abstract identifiers in C and the concrete identifiers in m. In this process, if every node in C has a match in m, the concrete changes are derived to customize m. If no match for each node is found, it reports the change pattern cannot replicate the changes on m.
In our example, the nodes mapping (C, m C ) = {(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)} and the instances/identifiers mapper {($v1, e). ($m1,isSelectionDependent), ($m2, fActions)} are established by matching the nodes between C and AST c .
Step 2: Customizing the concrete changes script
All abstract identifiers in the abstract changes Δ are replaced with the corresponding concrete names of the target source code m based on the instances/identifiers mapper. Then the node positions of Δ are recalculated with respect to the concrete nodes in m.
In our example, the concrete changes Δ c for m c are customized based on the instances/identifiers mapper. $v1, $m1(), $m2() are substituted for all instances of e, isSelectionDependent (), fActions in Δ, as follows:
Update O4N4
O4=′MVAction action = (MVAction) $v1.next();′
N4=′object next = e. next ();′
Move O5N5 1O5 = ′if (cation.isSelectionDependent())′
Move O6N7 0 O6 = ′action.update();′
Insert N5N3 1 N5 = ′if (next instance of MVAction);′
Insert N6N5 0 N6 = ′MVAction action =(MVAction) next;′
Setp 3: Changing the target method
With Δ m ’ the target method m is transformed to the source code m′ meeting user needs, such that m +Δ m = m′. In our example, instead of Jim’s manual changes, the update (m c : line 4), the insertions (m c ’: line 5′– 6′) and the moves (m c : line 5–6) are applied to m c to instead achieve the motivating hypothesis described as shown in Fig. 1 (m c ).
To evaluate ACPM, we (i) use a command “git clone” to grab and organize code snippets from GitHub by topic, (ii) extract 7 topics and collect 5-6 code snippets per topic, (iii) and save them as the testing set: T1 (Conversion of Arabic numbers to Roman numerals, 5), a topic post, where 5 represents 5 code snippets replies, T2 (Computing the Easter holiday for a given year, 5), T3(Generating the complementary DNA seq, 6), T4 (Sharpening an image, 5), T5 (Sorting objects using QuickSort, 6), T6 (Computing the MD5 hash of a string, 5) and T7 (Capturing the screen into an image, 5).
We use the accuracy as the evaluation metric. The accuracy is the syntactic similarity between the ACPM-suggested output and the expected output which is semantically identical to what a user actually did. For each code snippet pair (m1, m2) experienced similar changes, we use the following accuracy formula (2) where matchingNodes (m1, m2) is the number of matched AST node pairs computed by ChangeDistiller and size (m1), size (m2) are the numbers of AST nodes in m1 and m2.
We conduct 5 different experiments with this testing set. We (i) analyze the reasons for decreasing accuracy, (ii) explore 2 sensitivity-related rules and (iii) use the rules to improve the accuracy gradually. Table 1 list the accuracy of these 5 experimental results, where ″topic″ represents 7 different topics, ″num″ represents the number of code snippets used for generating the change pattern per topic, ″A∼E″ represent the respective results of 5 different experiments. For example, Table1-A represents the accuracy result of experiment-A.
The accuracy of 5 different experiments results
Experiment-A: We collect 7 topics, each topic has many different code snippets replied by users. From the code changes of these code snippets, ACPM exploits the change pattern about this topic. Based on the change pattern ACPM could transform other different code snippet of the same topic. The accuracy helps us evaluate whether ACPM ensures the context-specific code is general for the various contexts or not.
However, Table 1-A shows the opposite results with T1 (35%), T2 (34.37%), T4 (35%), T6 (33.75%) and T7 (33.56%), but a few promising results with T3 (80.6%), T5 (78.6%). To analyze the reason for these results, we explore how sensitive ACPM is to the similarity and the number of code snippets.
We depict the poor results (T1, T2, T4, T6 and T7 in Table 1-A). The accuracy goes down as shown in Fig. 4(a). It illustrates that the more code snippets provided, the less similar code snippets are, the less context is likely to be shared among them. Exploiting from multiple code snippets has the lower accuracy when suggesting changes for correctly identified locations. Because using multiple code snippets reduces the common changes, the derived change is likely to be less accurate for any one target location.

The analysis of the poor or good results.
We depict the promising results (T3 and T5 in Table 1-A) as shown in Fig. 4(b). The accuracy can go up when more code snippets are given, which is different from Fig. 4(a). It illustrates the accuracy can vary inconsistently with the number of code snippets, because it strictly depends on the similarity of code snippets. For instance, when code snippets are diverse, ACPM extracts the fewer common changes which decrease the accuracy. When code snippets are similar, adding code snippets may not decrease the number of common changes, but induce more identifier abstraction and generate the more flexible changes to increase the accuracy.
In sum, if code snippets are different, T1, T2, T4, T6 and T7 in Table 1-A occurs, otherwise T3 and T5 in Table 1-A occurs. From these results, a sensitivity-related rule (1) is found: the accuracy varies with the similarity and the number of code snippets, while the similarity taking precedence over the number. The more similar code snippets are, the more code snippets given, the higher accuracy is.
To improve the above poor results (T1, T2, T4, T6 and T7 in Table 1-A), we change the experiment-A to the experiment-B according to the rule (1). We pick the representative code snippet outs of all snippets. Then ACPM exploits the change pattern from the code changes of the representative code snippets instead of all code snippets. Because the similarity between the different versions of the same code snippet is higher than the similarity between the different code snippets.
In the experiment-A, let m i + Δ i = m i ’, the source code m i undergoes the changes Δ i and becomes a new source code m i ’. Δ i is the changes of the different source code m i . For example, Δ1 is the changes of the first source code m1. Δ i is the changes of the second source code m2. In the experiment-B, let mi-1 + Δ i = m i ’ instead of m i + Δ i = m i ’. Each source code has many changed version. Δ i represents the changes between the current changed version and the last changed version, such that Δ i = m i ’– mi-1. For example, Δ1 is the first changes of the source code m. Δ2 is the second changes of the changed source code m1. Note that the ″num″ column in Table 1 represents the number of different versions of the representative code snippet. To evaluate whether the accuracy of T1, T2, T4, T6 and T7 raise or not, we conduct experiment B. Table 1-B shows the better results with T1 (63.75%) and T7 (63.5%) than the ones in Table 1-A.
The effect of the stable change pattern
In Table 1-B, the accuracy of T2 is still 0 because every new changes is the addition of the last changes. Suppose that first only m exists, then m1 = m + Δ1, next m2 = m + Δ1 + Δ2, finally m3 = m + Δ1 + Δ2 + Δ3 and Δ1 ≠ Δ2 ≠ Δ3, such that (m1 - m) ⋂ (m2 - m1) ⋂ (m3 - m2) = Δ1 ⋂ Δ2 ⋂ Δ3 = Φ, ACPM decides there is no common changes.
To improve it, we change the experiment-B to the experiment-C. In the experiment-C, let Δ i = m i ’-m instead of Δ i = m i ’– mi-1. Δ i represents the different changes of the same source code m. For example, Δ1 is the first changes of the source code m. Δ2 is the second changes of the same source code m. In this case, T2 supposes that (m1– m) ⋂ (m2 - m)⋂ (m3 - m) = Δ1 ⋂ (Δ1 + Δ2) ⋂ (Δ1 + Δ2 + Δ3) = Δ1, ACPM decides that there are common changes Δ1.
To evaluate whether T2 restore or not, we conduct the experiment-C. Table 1-C shows T2 recovers from 0% to 69.18% and T1, T7 are also a little better than the ones in Table 1-B.
The effect of the first modification
In Table 1-C, the accuracy of T4 is still 0. We discover each changes Δ i is similar except the first changes Δ1. Because Δ1 involves amounts of changes to fix bugs while other subsequent Δ i involves small changes unrelated to bugs. In this case, Δ1 is a outlier such that Δ outlier ⋂ ∀ Δ i = Φ.
To evaluate whether T4 restore or not, we change the experiment-C to the experiment-D. We identify the common changes Δ
c
starting from Δ2 instead of Δ1, such that
The effect of the similar changes
To explore how sensitive ACPM is to the similarity of Δ i , we re-focus in Table 1-B. we (i) depict the result of T1 as Fig. 5(a-T1) where the accuracy still decreases because no Δ outlier exists; (ii) depict the result of T4 as Fig. 5(a-T4) where the accuracy decreases to 0 suddenly at the second changes and never goes up again because Δ1 is a outlier; (iii) depict the result of T6 as Fig. 5(a-T6) where the accuracy decreases to 0 suddenly at the forth changes because Δ4 is a outlier. In sum, the accuracy decreases as the number of Δ i . Sometimes, it decreases suddenly to 0 and never restores if Δ outlier exists. Thus the second sensitivity-related rule (2) is the more similar changes Δ i are, the higher accuracy is.

The before and after heuristic strategy.
To avoid ill-effects of Δ outlier , such as a sudden decrease, we change the experiment-D to the experiment-E. We design a heuristic changes-choosing strategy to choose the top-N similar Δ i with the largest intersection and exclude Δ outlier actively. N represents as the maximum number of the common changes Δ c . Suppose that N = 2, Δ1 occurs, Δ c = Δ1; next Δ2 occurs, Δ c = Δ1 ⋂ Δ2; then Δ3 occurs, if Δ1 ⋂ Δ2 ≠Φ, Δ1 ⋂ Δ3 = Φ and Δ2 ⋂ Δ3 = Φ, we choose Δ c = Δ1 ⋂ Δ2 as the largest intersection and omit Δ3; go on Δ4 occurs, if (Δ1 ⋂ Δ4) > ((Δ1 ⋂ Δ2) or (Δ2 ⋂ Δ4)), we choose Δ c = Δ1 ⋂ Δ4 and omit Δ2, and so on.
We conduct the experiment-E with the default setting of 2 for N. Surprisingly, Table 1-E shows T6 decreased to 0 at the fourth changes previously but now it still increases, while T4 decreased to 0 at the second changes previously but now it also still increases, even recovers from 34.81% to 74.56% averagely. T1, T2, T4, T7, T8 are also a little better than the ones in Table 1-D.
Besides in Table 1-E, we (i) depict the result of T1 as Fig. 5(b-T1) where the accuracy still increases as the number of code snippets; (ii) depict the result of T4 as Fig. 5(b-T4) where the accuracy decreases to 0 suddenly at the second changes and goes up again despite a outlier Δ1; (iii) depict the result of T6 as Fig. 5(b-T6) where the accuracy still increases despite a outlier Δ4. In sum, the heuristic changes-choosing strategy makes sense that no matter how many times the code snippet is changed, the accuracy still remains or increases as the number of Δ i or recovers soon despite sudden decreasing immediately to 0 at the second changes.
Program transformation [16] is a mapping from a set of candidate solutions to a more appropriate set meeting the user specification. The set of transformations can be divided into two categories. The first category is the compilation transformation. It fixes the bugs automatically and makes the source code compile correctly in the testing environment. For example, GenProg [16] and Par [17] generates candidate patches by replicating, mutating or deleting code randomly from the existing program [16]. BugModify [18] generates suggestions with a machine-learning approach based on knowledge acquired from previous bug repairs. RSRepair tries to repair faulty programs with the same mutation operations as does GenProg but uses random search to guide the patch generation process.
The second category is the generative transformation. It builds the new solutions from the existing source code and makes the solution conform to the given user needs. Recently, most approaches use program formal specifications to do such thing. Gopinath, Malik and Khurshid [11] build a SAT formula encoding the con-straints imposed by the specification on the program behavior. If the formula is satisfiable, they derive a repair from the SAT solution. Actually, ACPM can be viewed as the generative transformation [19]. But we differ from the previous work, because we use the abstractly con-text-aware change pattern to adapt the original source code snippet to meet the new environment rather than replacing programmer-defined types throughout a class with the types used in the user specification simply.
Besides, ACPM is similar to LASE [20], because they both exploit the abstractly context-aware change pattern from the code changes. But ACPM differs from LASE in two major aspects. First, ACPM is used to transform the retrieved code to meet the user needs automatically. But LASE is used for the systematic edits in many similar, but not identical code locations; Second, in ACPM the code changes are different as they are randomly chosen automatically. But in LASE the code changes are similar as they are carefully chosen by users. Thus we implement ACPM by improving LASE rather than copying it. For example, we add the heuristic changes-choosing algorithm to select the best changes automatically instead of all changes.
Conclusions
In this paper, an Abstract Change Pattern Model (ACPM) is proposed to ensure the context-specific source code general for various contexts. Using a motivating example throughout the paper, we illustrate ACPM in details from exploiting the abstractly context-aware change pattern to applying the change pattern to transform the context-specific source code to meet different user needs without manualeffort.
In addition, we conduct five experiments where we constantly discover the problems, analyze the reasons, explore three sensitivity-related rules and use them to overcome the problems and raise the accuracy gradually. However, our experimental results also reveal a limitation. ACPM only exploits the change pattern from the code changes of the representative source code with the high similarity, but not exploit the pattern from different source code. In the future, we would exploit change patterns at a fine-granularity level to exploit the change pattern from different source code and apply the pattern into other different source code. Another limitation is ACPM only exploits the change pattern from syntactically similar code changes. It cannot derive the change pattern from the semantically similar but syntactically different code changes. To overcome the limitation, we will infer semantic information from the code changes to make locations with different statements based on semantic similarity.
Footnotes
Acknowledgments
This work is supported by National Natural Science Foundation of China (61562026, 61640221, 61563016, 61603242 and 61461021) as well as the Opening Project of Collaborative Innovation Center for Economics crime investigation and prevention technology (JXJZXTCX-030).
