ソフトウェア工学研究の日々

ソフトウェア工学の学術研究を紹介しています。ソフトウェア開発に関する調査と実験が大好きです。

バグのあるプログラムからバグのないプログラムへの機械翻訳

機械翻訳技術は、たとえば英語の文を日本語の文へと自動的に翻訳するというのが一般的な使い方だと思います。ソフトウェア工学分野では、これを「バグのあるプログラム文からバグのないプログラム文への翻訳」とすることで、バグ修正に適用する方法を実験しています。

arxiv.org

Neural Machine Translation 技術は、対応関係のある文の組をたくさん用意してニューラルネットワークを構築し、そこに新しい文を入れると翻訳文が出てくるという手法です。そこに1文だけ命令が修正されたようなバグ修正を学習データとして投入します。1文だけの修正というのはバグ修正の中ではかなりの割合を占めていることが知られていて、たとえば以下は Apache Camel プロジェクトでの修正の事例です。

  uptime /= 24;
  long days = (long) uptime;
- long hours = (long) ((uptime - days)*60);
+ long hours = (long) ((uptime - days)*24);
  String s = fmtI.format(days) + (days > 1 ? " days" : " day");

このような事例を大量に集めて、修正パッチで削除された文(マイナス記号の付いている行)から修正パッチで追加された文(プラス記号の付いている行)への「翻訳」を学習するわけです。実験では5プロジェクトの最大10年ほどのバグ修正履歴から、 35,137件の学習データを収集して使用しています。

ソフトウェア工学における自動デバッグの研究は、「修正結果のコードのほとんどは実は対象プログラムのソースコードのどこかに既に存在していることが多い」という観測結果に基づいていて、コードを対象プログラム内部のどこかからコピーしてきて移植する形成外科(Plastic Surgery)アプローチから始まっていました。このアプローチと比較すると、「行の中をちょっとだけ直す」バグ修正に強い傾向がありそうだ、ということが分かりました。たとえば以下のような修正です。

- Set<String> knownRoles = new HashSet();
+ Set<String> knownRoles = new HashSet<>();

これは、まったく同一の文はプログラム内部に存在しないが、同じような書き換えが何度もあった事例です。このほかにも "this." の追加や式中に登場する配列の添え字の修正などをうまく実現していました。

2018年には同系統の関連論文も登場しており、アプローチ自体が発展途上の段階にあります。学習データとして大量の修正の履歴を蓄積していく必要があるため、今後どこまで発展するかは分かりませんが、よくある書き間違いに対しては、エディタがバグ修正を提案してくるようになるだろうと思います。