社団法人 電子情報通信学会
THE INSTITUTE OF ELECTRONICS,
INFORMATION AND COMMUNICATION ENGINEERS

信学技報
TECHNICAL REPORT OF IEICE.

自動生成コードの可読性向上を目的とした探索的ソースコード整形手法の提案
岩瀬匠†柗本 真佑†

楠本真二†† 大阪大学大学院情報科学研究科
E-mail: †{tk-iwase,shinsuke,kusumoto}@ist.osaka-u.ac.jp
あらまし

デバッグの全自動化を目的として，探索に基づく自動プログラム修正手法（Automated Program Repair;APR）が多数提案されている．探索ベースの APR ではソースコードの意味を考慮せずに探索するという性質上，修正されたソースコードは人の記述するソースコードとはかけ離れた内容となりやすい．ソースコードの最適化を目的とした，デッドコードの排除と呼ばれる研究も存在するが，APR の生成したソースコードの可読性を向上させるという目的に対しては機能的に不十分である．本研究では APR が生成したソースコードの可読性向上を目的として，探索的なソー
スコード整形手法を提案する．提案手法では，遺伝的アルゴリズムに基づき，部分的な整形を繰り返し適用することでソースコードを自然な形へと少しずつ整形する．本稿では，分岐，及び整数値の加減算というプログラムにおける基本処理に限定し，提案する探索的整形手法の実現可否を確かめる．数行程度の小規模題材に対し予備実験を行った結果，全てのソースコードについて無駄な部分が削除され，人の記述する自然なソースコードへと整形できることを確認した．
キーワード

自動プラグラム修正，APR，ソースコード整形，デッドコード，リファクタリング，可読性

1. は じ め にという互いに打ち消し合う無駄な処理や，「n++; n=10;」のような片方が上書きされる無駄な処理が発生することがある．また自動プログラム修正（Automated Program Repair; APR）と削除処理を繰り返した結果，空のブロック宣言「{}」だけが残さ呼ばれる，ソースコード中に含まれるバグを全自動で取り除く技

れる，といったケースも存在する．探索が深くなるほど適用され術の研究が進められている [1]．APR は探索ベースの手法 [2] とる改変回数が増える．よって，修正が困難なバグの場合，APR

意味論ベースの手法 [3] の 2 種類に大別できるが，本研究では探により得られたソースコードの大半が無駄な処理で構成されて索ベースの手法のみに着目し，以降単に APR と呼称する．このいる，というケースも考えられる．

APR ではバグを含むソースコードと対応するテストスイートを

この可読性の低さは，APR が抱える重要課題の 1 つであるテ

入力とし，ソースコードへの小さな改変を繰り返すことで，バグストへの過剰適合 [8] の解決を困難にする．多くの APR では，を含まない状態へと探索的に近づける．探索のメタアルゴリズ

その成否の基準としてテストスイートの通過の可否が用いられ

ムとしては遺伝的アルゴリズムが用いられることが多い．意味る．そのため，改変されたソースコードが与えられた全テストに論ベースの手法が条件分岐のバグ [4] や同時並行性のバグ [5] なは通過するが，意味的には正しくないという過剰適合の問題がどの特定のバグ種別に限定している場合が多い一方で，探索ベー

避けられない．この過剰適合は特にテストスイートが不十分な

スの手法は理論上どのような種類のバグでも修正可能，という汎場合に発生しやすい [9] ことが知られており，APR 実用に対す用性の面での利点が存在する．

る大きな障壁となっている．過剰適合の自動判別手法 [10] も提本研究では APR が抱える課題の 1 つである，修正済みソース

案されているが，得られたソースコードの最終的な意味的な確コードの可読性の低さに着目する．探索ベースの APR では，修認，及び受理するか否かの意思決定は開発者に委ねる必要があ

正対象となるソースコードの意味的な振る舞いを考慮せず，ある．しかし先述の通り，APR が修正したソースコードは可読性

らかじめ定められた改変処理を繰り返し適用する．具体的な改が極めて低く，開発者による過剰適合の目視確認作業を妨げる要変処理としては，AST 単位での挿入/削除/再利用 [2] や，メソッ因となる．

ド呼び出しの挿入/削除 [6]，変数名や演算子の変更 [7] などが用本研究では APR が生成したソースコードの可読性向上を目的いられる．いずれの改変処理を用いても，ソースコードの意味

として，探索的なソースコード整形手法を提案する．本手法でを考慮せずに探索するという性質上，修正されたソースコード

は，ソースコード中に含まれる実行可能な文のうち，外的な振るは人の記述するソースコードとはかけ離れた内容となりやすい．

舞いに影響を与えない処理を無駄な処理と定義し，整形の対象と

例えば，AST 単位での再利用の繰り返しにより，「n++; n––;」する．本手法の実現により，ソースコード中のバグを機械が修正—1—

し，さらに機械が自然な形に整形するという利用が可能となる．

ング手法の多くが人の記述したソースコードを前提としている提案手法では入力となるソースコードに対し，事前に用意した整点にある．リファクタリングの前提となる不吉な臭いは，開発者

形ルールを適用し，その効果を行数等のメトリクスにより評価すが陥りがちな悩みや間違いを基準としている．他方，APR の生る．この流れを遺伝的アルゴリズムに基づいて繰り返すことで，成するソースコードは，人がまず記述しないような極めて不自然

APR の生成した極めて不自然なソースコードを少しずつ自然なな部分を含む．例えば，「n++; n––;」のような無駄であること

形に近づけていく．適用する整形ルールを外的な振る舞いに影が誰の目から見ても明白，かつ開発者が記述しないような処理は

響しない処理に限定することで，整形前後での振る舞いの等価性

リファクタリング手法の対象外となる．不吉な臭いは開発者がを保つ．

ある程度の意思を持って記述した「高水準」な改善可能箇所であ

本稿では，分岐，及び整数値の加減算というプログラムにおける基本処理に限定し，提案する探索的整形手法の実現可否を確るのに対して，APR の生成したコードに含まれる無駄な処理は意思のない「低水準」であると見なすこともできる．

かめる．実験では，まず数行程度の小規模題材に対し，ミュー

このような「低水準」な無駄を表す概念として，デッドコー

テーション解析を用いて人為的にバグを注入する．次に，このド [14] が広く知られている．しかしこのデッドコードの排除も，バグを含むソースコードを APR により修正する．最後に，得らAPR の生成したソースコードの可読性を向上させるという目的

れた無駄を含む修正済みソースコードを提案手法により整形し，に対しては機能的に不十分である．様々なデッドコードの定義

その効果を確かめる．

が存在するが，未使用や到達不能といった，実行経路に存在しな

2. 準

備

2. 1 APR

い文やメソッドなどが共通してデッドと定義される [14]．よって
先述の「n++; n––;」のような互いに打ち消し合う無駄な処理は排除の対象外となる．

探索ベースの APR には，遺伝的アルゴリズムを利用する手ソースコードの自動整形という観点では，IDE 等に組み込ま

法 [11] と変更パターンを利用した手法 [12] の 2 つが存在する．

れたフォーマッタが最も広く利用されている技術であるといえ本節では，APR 分野のブレイクスルーとなった GenProg [2] がる．このフォーマッタは，改行や空白文字などのトークン区切り

使用する，遺伝的アルゴリズムを用いた手法について説明する．

文字を対象として，自動的にソースコードを見やすい形に整え

GenProg の入力は修正対象のソースコードとテストスイート

る．これらトークン区切り文字をどこに挿入すべきか，という問であり，出力はテストを全て通過するソースコードである．APR

題は一般的にはコーディングスタイルと呼ばれる．他方，本稿でによる修正は個体の生成，評価，選択の 3 つの処理を繰り返し行

整形対象となる無駄な処理とは，実行可能な文のうち機能的にはう．個体の生成には変異と交叉の 2 つの方法があり，いずれか不要という部分であり，コーディングスタイルに基づいた整形とを用いてソースコードに改変を加える．次に，生成した個体がどはその整形の観点が異なる．

の程度バグ修正に近づいたのか評価を行う．GenProg ではテス

2. 3 Motivating Example

ト通過数を用いている．最後に，この評価値に基づいて次の世代

本研究で対象とするソースコードの整形について，具体例をに残す個体を選択する．この一連の処理を繰り返し，入力された用いて説明する．図 1 に実際の APR により得られた実プロジェ

テストを全て通過する個体を規定数以上生成すると，遺伝的アルクトのバグの修正パッチを示す．このパッチは複数 APR の実験

ゴリズムを終了する．

デートセット，RepairThemAll [16] から取得したパッチである．

APR ではソースコードへの改変を繰り返し，全てのテストを

より具体的には，ARJA [17] と呼ばれる探索ベース APR が生成

通過する，機能的に正しいソースコードを生成する．この時，変した，Apache Math プロジェクトで発生したガンマ式に対する

異，交叉，いずれの方法を用いても，ソースコードの意味を考慮

バグ [18] の修正パッチである．本パッチは 2 つの diﬀ ブロック

せずにソースコードを改変する．ゆえに，加えられた改変の意味（3 行目から 28 行目と，29 行目から 34 行目）で構成される．

の理解は難しい [10]．そのため，人の理解しやすいソースコード

前半の diﬀ ブロックは 1 行の削除と 19 行の追加行で構成されに整形する必要がある．

るが，パッチの適用前後で機能的な振る舞いの変化は全くなく，

2. 2 可読性向上を目的としたソースコード変換

全て無駄な改変である．この改変箇所は，メソッドの返り値とソースコードの外的な振る舞いを保ちつつ，可読性を改善させなる一時変数 ret を算出する処理に該当する．まず，6 行目のるソースコード変換のアイデア [13] [14] がこれまでに多数提案

if 式と追加する 8 行目の if 式が全く同じであるため，8 行目と 9

されてきた．最も広く知られた手法として，Fowler による不吉行目，及び if ブロック外の 27 行目のみが実行経路上にあり，そな臭いとそのリファクタリング手法 [13] が挙げられる．Fowler

れ以外の 10 行目から 26 行目は完全なデッドコードとなる．まのリファクタリング手法では，一時変数や分岐などのメソッドをた if ブロック外の 27 行目の存在により 8 行目と 9 行目は完全に構成する文単位での改善方法から，メソッド単位，クラス設計単不要となり，さらに追加する 27 行目と削除した 7 行目は完全に位などの手法が幅広く定義されている．リファクタリング可能一致する．結果的に，バグを修正，つまり全テストを通過するに箇所の自動検出を目的とした支援ツール [15] も数多く提案され至った有効な改変は，2 つ目の diﬀ ブロックのみとなる．

ており，開発者は手軽にリファクタリングを実施できる．

APR により図 1 のソースコードを得られた場合，上記のよう

しかし，APR の生成したソースコードへのリファクタリング

なソースコード読解を行った上で，どの改変がテスト通過に寄与

手法の適用には限界がある．その理由の 1 つは，リファクタリ

しているのか，その改変は意味的に正しいか，過剰適合ではな

—2—

1

--- / tmp / A r j a _ D e f e c t s 4 J _ M a t h _ 1 0 3 / src /../ Gamma . java2+++ / tmp / A r j a _ D e f e c t s 4 J _ M a t h _ 1 0 3 / src /../ Gamma . java3@@ -158 ,7 +158 ,26 @@整形ルール

if ( Double . isNaN ( a ) || Double . isNaN ( x ) || ( a <= ..

4

ret = Double . NaN ;5} else if ( x == 0.0) {6
7-

ret = 0.0;8+

if ( x == 0.0) {乱択したルールに基づいて整形

9

+

10

+

11

+

12

+

13

+

double n = 0.0;

14+

double an = 1.0 / a ;15+

double sum = an ;16+

while ( Math . abs ( an ) > epsilon && n < maxIte ..

17+n = n + 1.0;

18+

an = an * ( x / ( a + n ) ) ;

19

+

20

+

}

21

+

if ( n >= maxIterations ) {

22

+

23

+

24

+

25

+

26

+

}

まず整形処理では，事前に用意された複数の整形ルールからラン

27+

ret = 0.0;

ダムに 1 つ選び，ソースコードを部分的に整形する．この時，整} else if ( a >= 1.0 && x > a ) {throw new M a x I t e r a t i o n s E x c e e d e d E x c e p t i o n ( ..
} else {ret = Math . exp ( - x + ( a * Math . log ( x ) ) - l ..
}if ( n >= maxIterations ) {+では遺伝的アルゴリズムを用いて，整形，評価，選択の 3 つの処理を繰り返す．この 3 つの処理を合わせて 1 世代と呼称する．

形対象のソースコード 1 つに対して，使用するルールの決定を複数回行い，部分的な整形が行われたソースコードを複数用意す

}

34

選択

図 2: 提案する探索的整形手法の概要

31

33

整形された
ソースコードsum = sum + an ;

30

-

評価

} else {@@ -177 ,7 +196 ,7 @@32

整形

ret = 1.0 - r e g u la r iz e dG a mm a Q (a , x , epsilon ..

} else if ( a >= 1.0 && x > a ) {28
29

ret = 0.0;

APRが修正した
ソースコードthrow new M a x I t e r a t i o n s E x c e e d e d E x c e p t i o n ( maxI ..
ret = 1.0;
} else {る．次に，部分的な整形が行われたソースコードをそれぞれ評価
する．評価値として，ソースコードの巡回的複雑度や行数など，
可読性の指標であるメトリクスを用いる方法が考えられる．最図 1: 探索ベース APR で得られた実プロジェクトバグの修正パッチ．

後に，選択処理ではそれぞれの評価値をもとに次世代の整形処理

diﬀ の前半部分は 1 行の削除と 19 行の追加で構成されるが，パッの対象となるソースコードを選択する．以上を繰り返し，評価値

チの適用前後で機能的な振る舞いの変化は全くなく，全て無駄なが改善しないまま世代数だけが増える等，これ以上の整形処理が改変である．

不可能となった時，最も評価値の良いソースコードを出力する．
提案手法の特徴としては整形ルールが追加可能である点と，遺いかを確認する必要がある．しかし，本図のように APR の生成

伝的アルゴリズムによる探索的なソースコード整形があげられ

コードのほとんどが無駄な改変で構成されると，その可読性は低る．整形ルールの事前定義不足により，整形ができなかったソー

く意味的な確認も困難になる．加えて，多くの言語では return

スコードが存在した場合，適切なルールの追加により，より可読

節や throw 節などのある種のジャンプ命令を含んでおり，目視性の高いソースコードへと整形が可能になる．また，探索的な実確認のコストを増加させる要因となる．例えば本図の場合，22

行により，自然な整形が可能となる．詳細は 3. 3 節で述べるが，行目に例外を送出する処理が追加されており，この処理が実行経

ルールの適用順序を事前に定義するような，非探索的な整形で路に存在するかを確認する必要がある．また，メソッド呼び出

は，ソースコード内に無駄な処理が残る場合が存在する．

しによる作用の有無も考慮に入れる必要がある．上記のような3. 2 整形ルール

APR の生成パッチの理解を支援するためには，APR の生成し提案手法は，外的な振る舞いを保ちつつ，ソースコードに変更

たソースコードを前提とした，ソースコードの可読性改善手法がを加える．整形前後での振る舞いの保持として，整形後のソース必要であるといえる．

コードに対してテスト実行をする方法と，整形ルール自体が振る

3. 提 案 手 法

舞いを変化させないことを保証する方法がある．テスト実行をする場合，提案手法における整形対象は APR が修正したソース

3. 1 手法の概要

コードであるため，APR の入力となったテストスイートを用い提案手法において，ソースコード内に存在する機能的に不要なる．この方法の長所は極めて柔軟にコードの書き換えが可能な

文を無駄な文と定義する．また，整形とは，この無駄な文を排除点である．短所としては毎回テストを実行する必要があり所要する処理である．図 2 に提案する探索的整形手法の概要を示す．

時間が長くなる点である．整形ルール自体が機能の保持を満た

入力は整形対象となる APR が生成したソースコード，出力は入す場合，機能を変化させない単純なルールに限定して整形する．

力と機能的に等価な整形されたソースコードである．提案手法

長所は機能保持の確認が不要なので，前者と比べて，所要時間が—3—短くなる点である．短所としては整形可能なソースコードの対象が限定されてしまう点である．提案手法では後者のみを用い

1

void plus ( int n ) {1

void plus ( int n ) {る．この理由としては，一回の探索に時間を要して柔軟にコード

2

n ++;

2

n ++;

を書き換えるよりも，単純なルールを用いて，一回辺りの整形に

3

n ++;

3

{

4

{

4

5

}

5

からである．整形可能な対象が限定されるという短所について

6

n - -;

6は，プラグイン形式でのルール追加により整形対象を拡充する．

7

return n ;7

かかる時間を短くし，探索の回数を増やす方が効果的だと考えた

実用的な整形のためには整形ルールの充足が必要不可欠であ

8

}

8

(a) APR の修正ソースコード 1

る．しかし，本稿では提案手法の実現可否を目的としている．そn - -;n ++;}return n ;}(a) APR の修正ソースコード 2のため，分岐と整数の加減算を扱うプログラムに頻出する，機能1

void plus ( int n ) {1

void plus ( int n ) {的に意味を持たない無駄な箇所に限定した．表 1 に本稿で使用

2

n ++;

2

n ++;

する整形ルール一覧を示す．これらの整形ルールは単純なもの

3

n ++;

3

{

であり，整形前後で機能の保持が行われている．

4n - -;

4

5

return n ;5

3. 3 探索的ソースコード整形

6}

整形ルールの適用方法には，事前にルールの適用順序を決め

順序を決めて整形を行うと，自然な整形ができない場合が生じる

2からである．例えば，あらかじめ整形ルールの適用順序を空ブ

3

ロックの削除，打消しあう単項演算子の削除という順番に決めていた場合を考える．与えられた int 型の引数に 1 を加算するプ

48}(b) 空ブロックの削除後

void plus ( int n ) {n ++;return n ;1}(c) 打消しあう単項演算子の削除後

void plus ( int n ) {

2

n ++;

3

{

4

}
return n ;5

ログラムにおいて，バグが含まれているソースコードを修正し，

6

図 3(a) が得られたとする．この時，ソースコードは図 3(b) を経}(c) 打消しあう単項演算子の削除後て，図 3(c) のように整形される．一方，修正後のソースコード
として図 4(a) が得られた場合，このソースコードには空ブロッ

return n ;7

る方法と，探索的に適用する方法がある．提案手法では，整形
1

n ++;
}

6

(b) 空ブロックの削除後ルールを探索的に適用する方法を選択する．これは，事前に適用

n - -;

図 3: 無駄な処理が残らない整形

図 4: 無駄な処理が残る整形

クが存在しないので，図 4(b) を経て，図 4(c) のように整形されバグを含まない
ソースコードる．図 3(c) では整形後のソースコードに無駄な処理は存在しな
いが，図 4(c) では無駄な処理である空のブロック宣言「{}」がステップ1 変異によるバグ注入

残っている．これはルールの適用順序を事前に決めたためである．このような場合を回避するために，提案手法では事前にルー

ステップ2 APRによる修正

表 1: 整形ルール
整形ルール

整形前

同一変数に対する打ち消しあうn++;

単項演算子文の削除

n–-;

同一変数に対する上書きが

n++;

整形後

ステップ3 提案手法による整形

n = n + 1;

行われる部分の削除

n = n + 1;

式を持たないブロック宣言の削除{n++;}

n++;

制御分の条件式が常に true や

if (true) {n++;false である制御文の省略

VS比較

図 5: 実験概要n++;}

空のブロックの削除

n++;

n++;

{

n–-;

}

4. 予 備 実 験n–-;if-else 文の後にある処理を

if (n > 0) {if-else 内に挿入ルを決めるのではなく，探索的な整形を行う．

if (n > 0) {

n++;

n++;

} else {n++;

4. 1 概要

提案手法により，APR が修正したソースコードを人が記述す} else {る自然なソースコードへと整形可能か確かめるために，数行程

}

n–-;

度の小さな題材を用いた予備実験を行う．実験の流れを図 5 に

n++;

n++;

示す．本実験はバグを含まないソースコードをベースラインと

n–-;

}

して実施する．このソースコードに対し，バグの注入，APR で

—4—

1

if ( n == 0) {3

} else if ( n > 0) {4

n - -;

5} else {

6

n ++;

16

}

7

return n ;

8
9

18

int closeToZero ( int n ) {

2

14

}

行数

図 6: 実験で用いるバグを含まないソースコード（ベースライン）
12の修正，提案手法での整形の 3 つのステップを実行する．まず，APR が修正したソースコードを用意するためにソースコードにバグを注入する．バグ注入の方法として，ミューテーション解析 [19] を利用する．ミューテーション解析ではソースコード内の単一行を人為的に変更する．以降この処理を単に変異と呼称する．その際，1 つのソースコードに対し変異する箇所や内容が10
ベースラインの⾏数8

複数存在する．したがって，バグが注入されたソースコードは複整形前数用意される．次に，それぞれのソースコードを APR で修正す

整形後る．バグの注入されたソースコード 1 つに対しバグ修正された
ソースコードを複数得る．これは，APR が複数のソースコード

図 7: 整形前後での行数の比較を出力する場合，探索が深くなり，機能的に無駄な処理を多数含む可能性が上がるためである．最後に，バグ修正されたそれぞれは与える引数が正，負，0 の場合の全てを網羅している．バグ注のソースコードに対し，提案手法による整形を行う．提案手法

入されたソースコード 1 つあたり，10 個の修正済みソースコー

による整形の効果を確認する方法として，整形後のソースコー

ドを生成する．APR により修正された 40 個のソースコードにド及び，ベースラインのソースコードと行数を比較する．また，対し，提案手法による整形を行う．提案手法における探索時の評

実用的な時間で整形可能か確認するため，APR の修正時間と整価値には行数を用いる．行数を選んだ理由としては，題材が小規

形時間についても比較する．

模であり，行数以外のメトリクスでは整形前後の差が生まれにく4. 2 実 験 設 定

いからである．行数の変化が見られなくなるまで，つまりこれ以

ベースラインとして用いる題材は図 6 に示すソースコードで上の整形が不可能になった時を終了判定とした．

ある．このソースコードは int 型の引数を受け取りその値が正で4. 3 実 験 結 果

あれば 1 を引き，負であれば 1 を足し，値を 0 に近づける．実4. 3. 1 整形前後でのソースコードの比較

験の各ステップにおける実験設定の一覧を表 2 に示す．図 6 の提案手法による各ソースコードの整形前後の行数を図 7 に示

ソースコードにミューテーション解析を用いて，表 3 に示す 4

す．縦軸がソースコードの行数であり，この値が少ないほどソーつの変異を与えた．ソースコードを修正するための APR ツール

スコード内に無駄な処理が少ないといえる．また，図中の赤い点

として，kGenProg [20] を用いた．また，テストケースに関して

線はベースライン (図 6) の行数を表している．図より，整形による行数の減少が見られる．また，40 個中 26 個のソースコード
がベースラインの行数である 9 行となった．可読性が向上して

表 2: 実験設定
ステップ

いるかの確認のため，各ソースコードに対し目視を行った．整形

項目

値

1

変異数

4 個（表 3）後の行数が 9 行のソースコードは全てベースラインと同じ，もし2

APR ツール

kGenProg [20]

くは if 文の条件式が異なるだけで，無駄な処理は存在しなかっ

生成ソースコード数

1 試行あたり 10 個た．その他の行数に変化しているソースコードに関して，10 行

対象ソースコード数

40 個

や 11 行になったソースコードは APR による修正で if ブロック

評価値

行数

内に return 文が挿入されたためであった．しかし，挿入された

3

return 文を無視した箇所はこちらもベースラインと同じ，もし
表 3: 与えた変異
変異 ID

変異した行 変異前コード

くは if 文の条件式が異なるだけであった．また，8 行になった
変異後コードソースコードは APR による修正で if-else 文の条件式が変更さ

a2n == 0n != 0

れたことによるものであった．目視の結果，40 個中 27 個のソー

b

3

n > 0

n <= 0スコードは整形により無駄な処理が完全に排除でき，可読性が向

c

4

n––;

n++;

d

6

n++;

n––;

上していた．一方，残りのソースコードには if ブロック内外に同一の return 文が存在していた．そのため，不要な return 文の

—5—

修正時間
整形時間

[4]

所要時間（秒）

12
10
8

[5]

6
4

[6]

2
0

変異a

変異b

変異c

変異d

[7]

図 8: 修正と整形の所要時間の比較[8]

削除というルールを追加することで，さらなる可読性向上が可能であると考えられる．

4. 3. 2 整形の所要時間[9]提案手法による整形時間が実用的かを確認するために，APRの修正時間と比較する．ここで，比較対象はバグ注入されたソー
スコードから APR が 10 個の修正済みソースコードを出力する[10]

時間と，その修正された 10 個のソースコード全ての整形に要した時間である．その結果を図 8 に示す．横軸は表 3 の各変異 ID[11]である．縦軸が所要時間である．修正時間と比べると整形にかかる時間の方が最小でも約 6.4 倍と極めて短いことがわかり，実用的な時間で整形が完了した．また，各変異ごとの整形時間に大[12]きな差は見られず，どのようなバグを修正したかに関わらず一定，なおかつ短時間で整形できた．修正と整形の時間にこれほどの差が出たことの要因は，3. 2 節で述べた，整形前後で機能を保持する方法として，整形ルール自体が機能保持を満たす方法の採

[13]
[14]

用によるテスト実行の省略が理由と考えられる．
[15]

5. お わ り に本研究では機械によって生成された不自然なソースコードを自然なソースコードへと整形する手法を提案した．また，実際に[16]

小規模なプログラムを題材とした予備実験を行い，その効果を確認した．
今後の課題として，整形対象の拡充が必要である．例えば，制御フローやデータフローも考慮した，より一般的な整形ルールを追加することが挙げられる．また，図 1 に示したような実題材[17]を用いた実験を実施する必要がある．
謝辞 本研究の一部は，JSPS 科研費（JP21H04877）による[18]

助成を受けた．
文

献[1] L. Gazzola, D. Micucci, and L. Mariani, “Automatic Software
Repair: A Survey,” IEEE Transactions on Software Engineering, vol.45, no.1, pp.34–67, 2019.
[2] C.L. Goues, T. Nguyen, S. Forrest, and W. Weimer, “GenProg: A Generic Method for Automatic Software Repair,”IEEE Transactions on Software Engineering, vol.38, no.1,
pp.54–72, 2012.
[3] H.D.T. Nguyen, D. Qi, A. Roychoudhury, and S. Chandra,“SemFix: Program Repair via Semantic Analysis,” Proc. In-

[19]

[20]

ternational Conference on Software Engineering, pp.772–781,
2013.
J. Xuan, M. Martinez, F. DeMarco, M. Clément, S.L. Marcote, T. Durieux, D. Le Berre, and M. Monperrus, “Nopol:
Automatic Repair of Conditional Statement Bugs in Java
Programs,” IEEE Transactions on Software Engineering,
vol.43, no.1, pp.34–55, 2017.
G. Jin, L. Song, W. Zhang, S. Lu, and B. Liblit, “AutomatedAtomicity-Violation Fixing,” Proc. Conference on Programming Language Design and Implementation, p.389–400, 2011.
V. Dallmeier, A. Zeller, and B. Meyer, “Generating Fixes
from Object Behavior Anomalies,” Proc. International Conference on Automated Software Engineering, pp.550–554,
2009.
F.Y. Assiri and J.M. Bieman, “An Assessment of the Quality of Automated Program Operator Repair,” Proc. International Conference on Software Testing, Veriﬁcation and Validation, pp.273–282, 2014.
E.K. Smith, E.T. Barr, C. Le Goues, and Y. Brun, “Is theCure Worse Than the Disease? Overﬁtting in AutomatedProgram Repair,” Proc. Joint Meeting on Foundations ofSoftware Engineering, pp.532–543, 2015.
F. Long and M. Rinard, “An Analysis of the Search Spaces
for Generate and Validate Patch Generation Systems,” Proc.
International Conference on Software Engineering, pp.702–
713, 2016.
H. Ye, M. Martinez, and M. Monperrus, “Automated patch
assessment for program repair at scale,” Empirical Software
Engineering, vol.26, pp.1–38, 2021.
M. Martinez and M. Monperrus, “Astor: A Program Repair
Library for Java,” Proc. International Symposium on Software Testing and Analysis, pp.441–444, 2016.
D. Kim, J. Nam, J. Song, and S. Kim, “Automatic Patch
Generation Learned from Human-Written Patches,” Proc. International Conference on Software Engineering, pp.802–811,
2013.
M. Fowler, Refactoring: Improving the Design of Existing
Code, Addison-Wesley Professional, 1999.
S. Romano, C. Vendome, G. Scanniello, and D. Poshyvanyk,“A Multi-Study Investigation into Dead Code,” IEEE Transactions on Software Engineering, vol.46, no.1, pp.71–99, 2020.
L. Tan and C. Bockisch, “A Survey of Refactoring Detection Tools.,” Proc. Collaborative Workshop on Evolution and
Maintenance of Long-Living Software Systems, pp.100–105,
2019.
T. Durieux, F. Madeiral, M. Martinez, and R. Abreu, “Empirical Review of Java Program Repair Tools: A Large-Scale
Experiment on 2,141 Bugs and 23,551 Repair Attempts,”
Proc. Joint Meeting on European Software Engineering Conference and Symposium on the Foundations of Software Engineering, pp.302–313, 2019.
Y. Yuan and W. Banzhaf, “ARJA: Automated Repair ofJava Programs via Multi-Objective Genetic Programming,”
IEEE Transactions on Software Engineering, vol.46, no.10,
pp.1040–1067, 2018.
R. Just, D. Jalali, and M.D. Ernst, “Defects4J: A Databaseof Existing Faults to Enable Controlled Testing Studies forJava Srograms,” Proc. International Symposium on Software
Testing and Analysis, pp.437–440, 2014.
Y. Jia and M. Harman, “An Analysis and Survey of the Development of Mutation Testing,” IEEE Transactions on Software Engineering, vol.37, no.5, pp.649–678, 2010.
柗本真佑，肥後芳樹，有馬諒，谷門照斗，内藤圭吾，松尾裕幸，松本淳之介，富田裕也，華山魁生，楠本真二，“高処理効率性と高可搬性を備えた自動プログラム修正システムの開発と評価，” 情報処
理学会論文誌，vol.61，no.4，pp.830–841，2020．

—6—