プログラミング言語のコンパイルエラーを自動で検知して修復することができたら、プログラマの作業時間を減らせる可能性があります。もしくは、テキストエディタがプログラムを書いている最中に、エラーだろうと思われる構文を見つけたときにさり気なく教えてくれたら生産性が著しく向上することも考えられます。

Software is eating the world.“という言葉は、マーク・アンドリーセンの提唱した言葉です。まだまだ「食い尽くす」ほどではないものの、徐々にその影響力は高まっていると感じます。ソフトウェアを開発する必要性が増すにつれて、ソフトウェアエンジニアも次第に求められていくことでしょう。そして、そのプログラマの仕事の大部分はデバッグに費やされます。

バグや構文エラーを自動検知するシステムがテキストエディタのプラグインとなれば、その社会的なインパクトは大きそうです。

本記事では、RNNでC言語の構文エラーを見つける仕組みや、自動修復する可能性について探っていきます。

コンパイルエラーの問題点

多くのプログラムのエラーは、プログラマのちょっとしたミスから生まれるにも関わらず、コンパイラのエラーメッセージは誤解を招く表現が出力されることがあります。

例えば、以下のC言語のコードを見てください。

 1  #include <stdio.h>
 2  #include <stdlib.h>
 3  int pow(int a, int b);
 4  int main(){
 5    int n;
 6    scanf("%d",&n);
 7    int i, j;
 8    for(i=1;i<=n;i++){
 9      for(j=0;j<=n;j++){
10       if(j<i){
11         printf("%d ",pow(i,j));}}
12       printf("\n");}
13    return 0;
14  int pow(int a, int b){
15    int i, res=1;
16    for(i=0;i<b;i++)
17      res = a * res;
18    return res;}

このC言語のコードは、13行目の最後に}が抜けています。コンパイラが論理エラーでそのような警告を出力してくれれば役に立つのですが、実際のエラーメッセージは次のようになります。

 p.c: In function ‘main’:
 p.c:18:2: error: expected declaration or statement at end of input
                  return res;}
                  ^

gccでコンパイルした場合にも、このようなエラーが出力されます。

test.c:3:7: warning: incompatible redeclaration of library function 'pow' [-Wincompatible-library-redeclaration]
  int pow(int a, int b);
      ^
test.c:3:7: note: 'pow' is a builtin with type 'double (double, double)'
test.c:14:24: error: function definition is not allowed here
  int pow(int a, int b){
                       ^
test.c:18:17: error: expected '}'
    return res;}
                ^
test.c:4:13: note: to match this '{'
  int main(){

13行目の最後に}が抜けているんじゃないかとエラーメッセージを出力してくれれば役に立ちますが、「18行目に宣言か文が期待されます」といったエラーや、「18行目に}が期待されます」とエラーメッセージが出力されるせいで、プログラマは困惑することになるでしょう。

DeepFix

インド理科大学院の研究成果のDeepFix [1] は、このような問題に対してディープラーニングで誤りのあるプログラムを自動修正するアプローチで解決しようという試みです。

DeepFixのベースとしたアイデアは、「AttentionベースのSeq2Seqモデルをプログラミング言語に適用しよう。」というものです。上図のように、行番号を含めたプログラムを行毎にトークン化して、誤りを訂正した正確なプログラムを出力します。AttentionやRNNに関しての詳細は、以下の記事を参考にしてください。

Attentionで拡張されたRecurrent Neural Networks /deep_learning/2017/03/03/attention-augmented-recurrent-neural-networks.html

RNN:時系列データを扱うRecurrent Neural Networksとは /deep_learning/2017/05/23/recurrent-neural-networks.html

Iterative Repair

さらに予測時には、下図のようにコンパイラと協力して何度も再帰的に予測させる「Iterative Repair」という戦略をとることによって、修正できるエラーの数を増やしています。

このようにすることで、DeepFixはテストデータで27%のエラーを含むプログラムを完全に修正し、19%のプログラムを部分的に修正することに成功しています。

まとめ

本記事では、ディープラーニングでプログラムを修正する試みであるDeepFixの紹介をしました。機械学習でプログラムを修正することは、少しトリッキーに思えるかもしれません。しかし、どんなプログラミング言語でもデータセットさえあれば学習させることができ、すべてのプログラムを構文解析することなく、短い時間で警告することができれば、有用かと思います。

今後もさらに研究開発が進み、プログラマの作業負担が減ると良いですね。

参考文献