(57)【特許請求の範囲】
【請求項１】
当初のソースコードと、リファクタリング実施後のソースコードとの等価性を検証するソースコード等価性検証装置であって、
リファクタリング前のソースコードと、リファクタリング後のソースコードを入力するソースコード入力手段と、
前記ソースコードのリファクタリングパターン情報を入力するリファクタリングパターン入力手段と、
前記リファクタリング前のソースコードと、前記リファクタリング後のソースコードの各々の字句解析・構文解析を行い、構造グラフに変換して、リファクタリング前ソースコード情報と、リファクタリング後ソースコード情報を生成するソースコード情報生成手段と、
リファクタリングパターン情報に対して定義された正規化情報を参照し、前記リファクタリング前ソースコード情報と、前記リファクタリング後ソースコード情報を正規化し、各々リファクタリング前正規化ソースコード情報と、リファクタリング後正規化ソースコード情報を生成する正規化手段と、
前記リファクタリング前正規化ソースコード情報と、前記リファクタリング後正規化ソースコード情報の構造を比較する構造比較手段と、
前記リファクタリング前正規化ソースコード情報と、前記リファクタリング後正規化ソースコード情報を記号実行する記号実行手段と、
前記記号実行手段による記号実行の結果を比較して、前記リファクタリング前ソースコードと前記リファクタリング後ソースコードの等価性を判定する等価性判定手段とを有することを特徴とするソースコード等価性検証装置。
【請求項２】
前記構造比較手段は、前記リファクタリング前正規化ソースコード情報と、前記リファクタリング後正規化ソースコード情報の構造グラフを比較して、構造が一致すると判定された場合には、前記リファクタリング前ソースコードと前記リファクタリング後ソースコードを等価と判定して、等価性の検証処理を終了し、
前記構造が不一致と判定された場合には、前記記号実行手段の処理へ移行することを特徴とする請求項１記載のソースコード等価性検証装置。
【請求項３】
前記正規化手段は、前記リファクタリングパターン情報に対して定義された変更箇所特定情報を参照して、前記リファクタリング前ソースコード情報と、前記リファクタリング後ソースコード情報とを比較して、ソースコードの構造上の変更箇所を特定する変更箇所情報を生成する変更箇所特定手段を更に備え、
前記記号実行手段は、前記変更箇所特定手段が抽出した前記リファクタリング前ソースコード情報と、前記リファクタリング後ソースコード情報との変更箇所情報と、前記リファクタリングパターン情報に対して定義された抽象化情報を参照して、前記リファクタリング前正規化ソースコード情報と、前記リファクタリング後正規化ソースコード情報を抽象化する抽象化手段を更に備え、
前記抽象化手段が生成したリファクタリング前抽象化ソースコード情報と、リファクタリング後抽象化ソースコード情報に対して、記号実行をすることを特徴とする請求項１記載のソースコード等価性検証装置。
【請求項４】
前記記号実行手段が、前記リファクタリング前正規化ソースコード情報と、前記リファクタリング後正規化ソースコード情報に対して、前記リファクタリングパターン情報毎に定義された抽象化処理を実施した後、実行木を生成し、全ての葉ノードに対して、各葉ノードのパス制約と変数状態との論理積を取り、全ての葉ノードの論理積に亘って論理和を取って記号実行サマリを表わす論理式を算出し、
前記等価性判定手段は、前記記号実行手段が算出した前記リファクタリング前正規化ソースコード情報の記号実行サマリを表わす論理式と、前記リファクタリング後正規化ソースコード情報の記号実行サマリを表わす論理式が、論理的に等価であるか否かを判定する
ことを特徴とする請求項１記載のソースコード等価性検証装置。
【請求項５】
表示画面上に、ソースコード等価性検証結果と共に、前記リファクタリング前正規化ソースコード情報の構造グラフと、前記リファクタリング後正規化ソースコード情報の構造グラフとを対比して表示し、更に、リファクタリング前のソースコードに対する記号実行サマリ情報と、リファクタリング後のソースコードに対する記号実行サマリ情報とを対比して表示する、または前記表示情報を全て出力装置へ出力する検証結果出力手段を更に有することを特徴とする請求項１記載のソースコード等価性検証装置。
【請求項６】
前記検証結果出力手段は、前記等価性判定手段が前記リファクタリング前正規化ソースコード情報の論理式と、前記リファクタリング後正規化ソースコード情報の論理式が論理的に等価ではないと判定した場合に、反例情報を更に表示、若しくは出力することを特徴とする請求項４、または請求項５に記載のソースコード等価性検証装置。
【請求項７】
当初のソースコードと、リファクタリング実施後のソースコードとの等価性を検証するソースコード等価性検証方法であって、
リファクタリング前のソースコードと、リファクタリング後のソースコードを入力するソースコード入力ステップと、
前記ソースコードのリファクタリングパターン情報を入力するリファクタリングパターン入力ステップと、
前記リファクタリング前のソースコードと、前記リファクタリング後のソースコードの各々の字句解析・構文解析を行い、構造グラフに変換して、リファクタリング前ソースコード情報と、リファクタリング後ソースコード情報を生成するソースコード情報生成ステップと、
リファクタリングパターン情報に対して定義された正規化情報を参照し、前記リファクタリング前ソースコード情報と、前記リファクタリング後ソースコード情報を正規化し、各々リファクタリング前正規化ソースコード情報と、リファクタリング後正規化ソースコード情報を生成する正規化ステップと、
前記リファクタリング前正規化ソースコード情報と、前記リファクタリング後正規化ソースコード情報の構造を比較する構造比較ステップと、
前記リファクタリング前正規化ソースコード情報と、前記リファクタリング後正規化ソースコード情報を記号実行する記号実行ステップと、
前記記号実行ステップによる記号実行の結果を比較して、前記リファクタリング前ソースコードと前記リファクタリング後ソースコードの等価性を判定する等価性判定ステップとを有することを特徴とするソースコード等価性検証方法。
【請求項８】
前記構造比較ステップは、前記リファクタリング前正規化ソースコード情報と、前記リファクタリング後正規化ソースコード情報の構造グラフを比較して、構造が一致すると判定された場合には、前記リファクタリング前ソースコードと前記リファクタリング後ソースコードを等価と判定して、等価性の検証処理を終了し、
前記構造が不一致と判定された場合には、前記記号実行ステップの処理へ移行することを特徴とする請求項７記載のソースコード等価性検証方法。
【請求項９】
前記正規化ステップは、前記リファクタリングパターン情報に対して定義された変更箇所特定情報を参照して、前記リファクタリング前ソースコード情報と、前記リファクタリング後ソースコード情報とを比較して、ソースコードの構造上の変更箇所を特定する変更箇所情報を生成する変更箇所特定ステップを更に含み、
前記記号実行ステップは、前記変更箇所特定ステップで抽出した前記リファクタリング前ソースコード情報と、前記リファクタリング後ソースコード情報との変更箇所情報と、前記リファクタリングパターン情報に対して定義された抽象化情報を参照して、前記リファクタリング前正規化ソースコード情報と、前記リファクタリング後正規化ソースコード情報を抽象化する抽象化ステップを更に含み、
前記抽象化ステップで生成したリファクタリング前抽象化ソースコード情報と、リファクタリング後抽象化ソースコード情報に対して、記号実行をすることを特徴とする請求項７記載のソースコード等価性検証方法。
【請求項１０】
前記記号実行ステップにおいて、前記リファクタリング前正規化ソースコード情報と、前記リファクタリング後正規化ソースコード情報に対して、前記リファクタリングパターン情報毎に定義された抽象化処理を実施した後、実行木を生成し、全ての葉ノードに対して、各葉ノードのパス制約と変数状態との論理積を取り、全ての葉ノードの論理積に亘って論理和を取って記号実行サマリを表わす論理式を算出し、
前記等価性判定ステップにおいて、前記記号実行ステップで算出した前記リファクタリング前正規化ソースコード情報の記号実行サマリを表わす論理式と、前記リファクタリング後正規化ソースコード情報の記号実行サマリを表わす論理式が、論理的に等価であるか否かを判定することを特徴とする請求項７記載のソースコード等価性検証方法。
【請求項１１】
表示画面上に、ソースコード等価性検証結果と共に、前記リファクタリング前正規化ソースコード情報の構造グラフと、前記リファクタリング後正規化ソースコード情報の構造グラフとを対比して表示し、更に、リファクタリング前のソースコードに対する記号実行サマリ情報と、リファクタリング後のソースコードに対する記号実行サマリ情報とを対比して表示する、または前記表示情報を全て出力装置へ出力する検証結果出力ステップを更に有することを特徴とする請求項７記載のソースコード等価性検証方法。
【請求項１２】
前記検証結果出力ステップにおいて、前記等価性判定ステップで前記リファクタリング前正規化ソースコード情報の論理式と、前記リファクタリング後正規化ソースコード情報の論理式が論理的に等価ではないと判定した場合に、反例情報を更に表示、若しくは出力することを特徴とする請求項１０、または請求項１１に記載のソースコード等価性検証方法。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、ソースコード等価性検証装置、および、ソースコード等価性検証方法に係り、特に、ソフトウェアのリファクタリングにおいて、リファクタリング実施による不具合混入を防ぐために、記号実行の手法により、プログラムとしての振る舞いが等価であることを検証する場合に、計算量の爆発的増加を防止し、迅速にリファクタリングの正当性を検証するのに好適なソースコード等価性検証装置、および、ソースコード等価性検証方法に関する。
【背景技術】
【０００２】
近年、情報処理社会が進展することにより、ソフトウェアシステムが一般社会に浸透し、ソフトウェアに求められる信頼性が非常に高度なものになってきている。一方で、ソフトウェアは、長年にわたる差分・派生開発によって複雑化および大規模化の一途をたどり、ソフトウェアの拡張し易さや理解し易さといった保守性の低下が問題となっている。【０００３】
リファクタリングは、非特許文献１乃至３に開示されている方法であって、ソフトウェアの振る舞いを変えずに、内部構造を変更することにより、ソフトウェアの設計品質を改善する手法の総称であり、複雑さを軽減し保守性を向上させるものである。このリファクタリングの手法は、複雑化および大規模化の一途をたどるソフトウェアの保守性を確保するために有望な技術であるが、ソースコードを変更するため新たに不具合を混入してしまう可能性がある。具体的には、リファクタリングには、複数のパターンとして類別される方法が存在し、それぞれソースコードの変更の手順と、その変更によりソフトウェアの振る舞いを変えないことを保証するためのソースコードに対する条件とが、明示的もしくは暗黙的に定められている。この変更の手順に従わずに、ソースコードを変更した場合、または、そのような条件に従っていないソースコードを変更した場合には、対象となっているソフトウェアの振る舞いを変えないことが保証されないため、ソフトウェアに不具合が混入する可能性がある。したがって、ソフトウェア開発者が、ソフトウェアの保守段階において、リファクタリングが原因で正しく動作していたソフトウェアに不具合が混入することをおそれ、リファクタリングを行わない判断が有り得る。そのため、ソフトウェアの保守段階において、リファクタリングを積極的に行うために、リファクタリングによる不具合の混入が無いことを検証する手法が求められる。【０００４】
非特許文献３では、７２種の典型的に用いられるリファクタリングのパターン（以下、単に「リファクタリングパターン」という）が定義されている。【０００５】
本明細書中において、二つのソースコードが外的な振る舞いが同じであることを、すなわち、同じ入力に対して、実行時に、同じ出力が得られることを、両ソースコードが「等価」であると定義し、リファクタリング実施前のソースコードとリファクタリング実施後のソースコードが、等価であることを検証することを「等価性検証」ということにする。【０００６】
リファクタリング実施前のソースコードとリファクタリング実施後のソースコードが等価であることを検証する手法に求められる条件としては以下のような条件がある。
(1) ひとつは、その作業の大部分が自動化されており、人手による作業が少ないことである。従来、ソースコードの等価性は、人手によるレビューやテストによって検証されていた。これをツールによる自動的な検証を実現にすることにより、検証工数が削減され、リファクタリングが促進される。
(2) もうひとつの条件は、リファクタリング検証手法により動作が等価、もしくは非等価であると判断された場合に、その根拠となる情報を開発者に提示することである。開発者に分かり易く判定基準となった情報を提示することにより、開発者自身が再検証することが可能となり、ツールに対する信頼性が向上し、リファクタリングが促進される。【０００７】
等価性検証の手法として、特許文献１に開示されるソースコード比較によって差異が生じている部分にテストを実施し、その結果を比較する手法、非特許文献１に開示されるソースコードをグラフで表現しリファクタリングごとに定めた事前条件をグラフが満たすかを検証する手法、非特許文献２に開示される記号実行を用いて振る舞いが保持されていることを検証する手法がある。
【先行技術文献】
【特許文献】
【０００８】
【特許文献１】米国特許出願公開第２００７／００３３５７６号明細書
【非特許文献】
【０００９】
【非特許文献１】T. Mens, S. Demeyer, D. Janssens, "Formalising Behaviour Preserving Program Transformations", Proceedings of the First International Conference on Graph Transformation, USA, 2002
【非特許文献２】S. Person, M. B. Dwyer, S. Elbaum, C. S. Pasareanu, "Differential Symbolic Execution", Proc. of ACM SIGSOFT Symposium on the Foundations of Software Engineering 2008, USA, 2008
【非特許文献３】M. Fowler et al., “Refactoring: Improving the Design of Existing Code”, USA, Addison-Wesley Professional, 1 edition, July 8, 1999
【発明の概要】
【発明が解決しようとする課題】
【００１０】
非特許文献１では、プログラムのメソッド呼び出し関係をグラフで表現し、リファクタリングごとに定めた事前条件を満たすか否かを検証する手法を開示している。このアプローチは、振る舞いの検証を構造上の検証で実現するため、リファクタリングごとに、その操作を厳密に定義した上で、振る舞いに影響を及ぼさないための条件を網羅している。そのため、事実上、リファクタリングがツールにより自動化されることが必須であり、リファクタリング操作そのものを誤り得る人手でのリファクタリングの検証には利用できないという問題点がある。【００１１】
特許文献１では記号実行を用いることにより、対象となるソースコードに対するテストケースを生成する方法が開示されている。さらに、特許文献１では異なる抽象度を用いて、記号実行の計算量爆発を抑えながらテストケースを生成する手法が示されている。これらの方法をリファクタリング前後の等価性検証に適用するには、リファクタリング前とリファクタリング後のソースコードに関するテストを生成し、それぞれのソースコードに対して生成したテストを実施し、それらの結果を検証する。これは、リファクタリング実施時に特別なプロセスを必要としない半面、いくつかの問題が存在する。リファクタリング箇所によっては影響が広範囲に波及し、生成したテストのみでは等価性を検証しきれない可能性が残る。また、影響の波及がなく差異部分のみの検証であっても、テストのカバレッジによって、検証漏れが生じる可能性が残る。テストによる等価性検証は、検証漏れなどの可能性のため不完全である。また、等価性の判断の根拠としては、開発者に対して実施したテストケースを提示することとなる。しかし、テストケースの列挙だけでは開発者はそれが充分なテストケースかどうかを判断できないという問題点がある。【００１２】
非特許文献２では、リファクタリング前後のソースコードに対して等価性検証を行う技術として、記号実行を用いる手法を開示している。
記号実行とは、対象のプログラムの入力として、数値を与える代わりに、記号を与えることにより、プログラムの振る舞いを網羅的に解析する手法である。【００１３】
以下、図１９を用いて記号実行の一例について説明する。
図１９は、記号実行の一例を説明するために、ソースコードとそれより派生するデータ構造について示した図である。【００１４】
記号実行においては、入力変数の値を記号変数と呼ばれる記号を用いて表現し、その記号変数がプログラム中でどのように参照・更新されていくかを解析する。ここでは、Ｃ言語で記述されたソースコードＥ００１に記載する関数ｆｏｏを対象に記号実行を実施するものとする。記号実行の対象となるソースコードＥ００１に対して記号実行を行うにあたり、先ず、通常のソースコードをコンパイルするときと同様に、字句解析や構文解析を実施する。その結果から、ソースコードＥ００１から制御フローや制御依存グラフ、データ依存グラフなどを抽出した構造グラフＥ００２が得られる。記号実行では、構造グラフＥ００２を用いて、実行木Ｅ０２０を生成していく。実行木Ｅ０２０中の各ノードは、そのノードに到達するための記号変数で表現されたパス制約と、そのノードにおける各変数の値を記号変数で表現した変数状態から構成される。図１９の実行木Ｅ０２０では、各ノードの上側にパス制約を、下側に変数状態を表現している。【００１５】
実行木Ｅ０２０の生成過程について以下に詳細を説明する。
記号実行の開始段階において、ソースコードＥ００１中で、プログラムの入力となる変数に対して記号変数を割当てる。ソースコードＥ００１の例では、グローバル変数ａ，ｂ，ｃが入力となる変数であるため、それぞれに対して、α，β，γという記号変数を割当てる。構造グラフＥ００２上では、ノードＥ００３に対応する開始状態においては、実行木Ｅ０２０は、単一のノードＥ０１０のみからなる実行木となる。ノードＥ０１０のパス制約Ｅ０１０ａは、制約無し（任意の変数状態に対して制約を満たす）を意味するｔｒｕｅとなり、変数状態Ｅ０１０ｂは記号変数の割当てに従って、各変数と対応する記号変数が等しいことを示している。【００１６】
構造グラフＥ００２上では、ノードＥ００３の次にはノードＥ００４が実行される。それにともなって、実行木においてもＥ０１０の子ノードＥ０１１が生成される。子ノードＥ０１１におけるパス制約Ｅ０１１ａ、および、変数状態Ｅ０１１ｂは、親ノードＥ０１０のパス制約Ｅ０１０ａ、および、変数状態Ｅ０１０ｂがコピーされた上で、構造グラフＥ００２上のノードＥ００４が実行される。
ノードＥ００４においては、変数ａに対して０が代入されている。そのため、実行木のノードＥ０１１の変数状態Ｅ０１１ｂにおける、変数ａに対する状態はａ＝０に更新される。【００１７】
構造グラフＥ００２上で、ノードＥ００４の次に実行されるのはノードＥ００５である。ノードＥ００５においては、変数状態の更新が行われていないため、実行木における新たなノードを生成しない。ノードＥ００５は、ｉｆ文による条件分岐である。そのため、構造グラフＥ００２の制御フローで次となるノードは、ノードＥ００６とノードＥ００７の二つのノードがある。記号実行においては、取り得る制御フローをすべて網羅するために、条件分岐においては、それぞれの分岐に応じた子ノードを生成する。すなわち、ノードＥ００６に対応して実行木中のノードＥ０１１の子ノードとしてＥ０１２を生成し、ノードＥ００７に対応して実行木中のノードＥ０１１の子ノードとしてＥ０１３を生成する。【００１８】
実行木のノードＥ０１２のパス制約Ｅ０１２ａは、親ノードのパス制約Ｅ０１１ａと条件分岐の分岐条件との論理積（ＡＮＤ、図では、＆）になる。ノードＥ００５における分岐条件は、ｃ＜０であり、また、変数状態Ｅ０１１ｂから、変数ｃを記号変数で表わすとγとなることから、条件分岐が成立するための条件はγ＜０であることが分かる。そこで、ｔｒｕｅとγ＜０との論理積であるγ＜０がノードＥ０１２におけるパス制約Ｅ０１２ａとなる。【００１９】
次に、子ノードＥ０１３のパス制約Ｅ０１３ａは、Ｅ０１３が条件分岐の分岐条件が成立しない場合に対応していることから、親ノードのパス制約Ｅ０１１ａと条件分岐の分岐条件の否定（ＮＯＴ、図では、！）との論理積になる。すなわち、ｔｒｕｅと！（γ＜０）との論理積である！（γ＜０）が、子ノードＥ０１３のパス制約Ｅ０１３ａとなる。【００２０】
ノードＥ０１１の子ノードＥ０１２の変数状態Ｅ０１２ｂ、子ノードＥ０１３の変数状態Ｅ０１３ｂは、親ノードＥ０１１の変数状態Ｅ０１１ｂがコピーされた上で、計算が続行される。ノードＥ０１２の変数状態Ｅ０１２ｂは、ノードＥ００６で変数ｃに０が代入されるため、ｃに対する変数状態がｃ＝０に更新される。ノードＥ０１３の変数状態Ｅ０１３ｂは、ノードＥ００７で変数ａに変数ｃの値が代入されている。この時点において、変数ｃの変数状態が記号変数のγとなっているので、変数状態Ｅ０１３ｂにおいて、変数ａの変数状態がａ＝γに更新される。【００２１】
以降も上記と同様の手順により実行木を生成していく。制御フロー上においてノードＥ００６の次のノードはＥ００８であり、このＥ００８は条件分岐であるため、実行木においては、ノードＥ０１２に対して二つの子ノードＥ０１４およびＥ０１５が生成される。ノードＥ００８における分岐条件は（ｂ＜０）であるが、これを変数状態Ｅ０１２ｂを用いて記号変数で表現すると（β＜０）になる。そのため、子ノードＥ０１４、および、Ｅ０１５のパス制約は、親ノードＥ０１２のパス制約Ｅ０１２ａにそれぞれ（β＜０）、および、！（β＜０）との論理積をとったものとなる。子ノードＥ０１４では、次に制御フロー上のノードＥ００９ａが実行される。Ｅ００９ａは変数ａにａ−ｂの値を代入するものであり、変数状態から、変数ａの状態が０、変数ｂの状態がβであると分かるので、変数ａの状態が−βに更新される。子ノードＥ０１５では、次に制御フロー上のノードＥ００９ｂが実行される。Ｅ００９ｂは変数ａにａ＋ｂの値を代入するものであり、変数状態から、変数ａの状態が０、変数ｂの状態がβと分かるので、変数ａの状態がβに更新される。【００２２】
制御フロー上においてノードＥ００７の次のノードはＥ００８であり、このＥ００８は条件分岐であるため、実行木においては、ノードＥ０１３に対して二つの子ノードＥ０１６およびＥ０１７が生成される。ノードＥ００８における分岐条件は（ｂ＜０）であるが、これを変数状態Ｅ０１３ｂを用いて記号変数で表現すると（β＜０）になる。そのため、子ノードＥ０１６、および、Ｅ０１７のパス制約は、親ノードＥ０１３のパス制約Ｅ０１３ａにそれぞれ（β＜０）、および、！（β＜０）との論理積をとったものとなる。子ノードＥ０１６では、次に制御フロー上のノードＥ００９ａが実行される。Ｅ００９ａは、変数ａにａ−ｂの値を代入するものであり、変数状態から、変数ａの状態がγ、変数ｂの状態がβであると分かるので、変数ａの状態がγ−βに更新される。子ノードＥ０１７では、次に制御フロー上のノードＥ００９ｂが実行される。Ｅ００９ｂは変数ａにａ＋ｂの値を代入するものであり、変数状態から、変数ａの状態がγ、変数ｂの状態がβと分かるので、変数ａの状態がγ＋βに更新される。【００２３】
実行木Ｅ０２０のすべての葉ノードに対して、その制御フローが関数の終了まで到達すると、実行木の生成が終了する。図１９の実行木Ｅ０２０は、関数ｆｏｏに対する記号実行が終了した時点での実行木を示している。記号実行が終了した時点での実行木の各葉ノードを集めたものが記号実行の結果となる（これを「記号実行サマリ」ということにする）。記号変数α，β，γの任意の組合せは、記号実行サマリ中の各葉ノードのうちいずれかのパス制約を満たす。そのノードに含まれる変数状態を用いることによって、入力となる記号変数の値から、プログラム実行後の各変数の値を知ることができる。例えば、関数ｆｏｏの実行前の変数ａ，ｂ，ｃのいずれの値も１である場合、記号変数はα＝β＝γ＝１となり、ノードＥ０１７のパス制約を満たす。ノードＥ０１７の変数状態から関数ｆｏｏ実行後の変数ａの値はａ＝γ＋β＝２、ｂ＝β＝１、ｃ＝γ＝１となることが分かる。上記のように、記号実行は、プログラムが取り得る制御パスを網羅した上で、プログラム実行前後の変数値の関係を入力値の条件（パス制約）と、出力変数の状態（変数状態）の組の集合である記号実行サマリを求める計算であるということができる。【００２４】
リファクタリング前後のソースコードの構造グラフに対して、それぞれ記号実行し、論理的に等価な記号実行サマリが得られたとき、すなわち、同じ入力に対し同じ出力が得られる場合に、上で定義したように、ソースコードが等価であると判断できる。このように、記号実行は、対象のプログラムの取り得る動作系列を網羅的に解析するため、テストを用いた検証におけるカバレッジの問題や、事前条件の検証におけるツール依存の問題が生じない。その一方で、繰り返し文や再帰構造を持つプログラムでは、実行木が複雑なものになり、計算量が発散し爆発し易い。計算量を抑えるためには、記号実行の範囲の限定や、事前条件による実行の制限が必要であり、記号実行の利点である検証の完全性が失われる。【００２５】
非特許文献２では、比較するソースコード間に共通部分が存在する点に着目し、完全性を維持したまま計算量を減らす工夫をしている。変更されていない共通のブロックの実行結果を関数（uninterrupted function）で表現することにより、実行木の上の計算量の発散を防ぐ。しかしながら、差異部分の実行木上の計算量が発散するケースが依然として残り、計算量が爆発する可能性が残る。また、ハードウェア等外界との相互作用を持つプログラムの扱いに対しては言及されていない。【００２６】
本発明は、上記問題点を解決するためになされたもので、その目的は、人手で実施されたリファクタリングに対する等価性検証を、記号実行により行うときに、計算量を爆発させずに、迅速に行えるようなソースコード等価性検証方法を提供することにある。
【課題を解決するための手段】
【００２７】
上記課題を解決するために本発明では、当初のソースコードと、リファクタリング実施後のソースコードとの等価性を検証するソースコード等価性検証装置を、リファクタリング前のソースコードと、リファクタリング後のソースコードを入力するソースコード入力手段と、前記ソースコードのリファクタリングパターン情報を入力するリファクタリングパターン入力手段と、前記リファクタリング前のソースコードと、前記リファクタリング後のソースコードの各々の字句解析・構文解析を行い、構造グラフに変換して、リファクタリング前ソースコード情報と、リファクタリング後ソースコード情報を生成するソースコード情報生成手段と、リファクタリングパターン情報に対して定義された正規化情報を参照し、前記リファクタリング前ソースコード情報と、前記リファクタリング後ソースコード情報を正規化し、各々リファクタリング前正規化ソースコード情報と、リファクタリング後正規化ソースコード情報を生成する正規化手段と、前記リファクタリング前正規化ソースコード情報と、前記リファクタリング後正規化ソースコード情報の構造を比較する構造比較手段と、前記リファクタリング前正規化ソースコード情報と、前記リファクタリング後正規化ソースコード情報を記号実行する記号実行手段と、前記記号実行手段による記号実行の結果を比較して、前記リファクタリング前ソースコードと前記リファクタリング後ソースコードの等価性を判定する等価性判定手段とを備えて構成した。【００２８】
また、上記課題を解決するために本発明では、前記ソースコード等価性検証装置において、前記構造比較手段は、前記リファクタリング前正規化ソースコード情報と、前記リファクタリング後正規化ソースコード情報の構造グラフを比較して、構造が一致すると判定された場合には、前記リファクタリング前ソースコードと前記リファクタリング後ソースコードを等価と判定して、等価性の検証処理を終了し、前記構造が不一致と判定された場合には、前記記号実行手段の処理へ移行するように構成した。【００２９】
また、上記課題を解決するために本発明では、前記ソースコード等価性検証装置において、前記正規化手段は、前記リファクタリングパターン情報に対して定義された変更箇所特定情報を参照して、前記リファクタリング前ソースコード情報と、前記リファクタリング後ソースコード情報とを比較して、ソースコードの構造上の変更箇所を特定する変更箇所情報を生成する変更箇所特定手段を更に備え、前記記号実行手段は、前記変更箇所特定手段が抽出した前記リファクタリング前ソースコード情報と、前記リファクタリング後ソースコード情報との変更箇所情報と、前記リファクタリングパターン情報に対して定義された抽象化情報を参照して、前記リファクタリング前正規化ソースコード情報と、前記リファクタリング後正規化ソースコード情報を抽象化する抽象化手段を更に備え、前記抽象化手段が生成したリファクタリング前抽象化ソースコード情報と、リファクタリング後抽象化ソースコード情報に対して、記号実行をするように構成した。【００３０】
また、上記課題を解決するために本発明では、当初のソースコードと、リファクタリング実施後のソースコードとの等価性を検証するソースコード等価性検証方法において、リファクタリング前のソースコードと、リファクタリング後のソースコードを入力するソースコード入力ステップと、前記ソースコードのリファクタリングパターン情報を入力するリファクタリングパターン入力ステップと、前記リファクタリング前のソースコードと、前記リファクタリング後のソースコードの各々の字句解析・構文解析を行い、構造グラフに変換して、リファクタリング前ソースコード情報と、リファクタリング後ソースコード情報を生成するソースコード情報生成ステップと、リファクタリングパターン情報に対して定義された正規化情報を参照し、前記リファクタリング前ソースコード情報と、前記リファクタリング後ソースコード情報を正規化し、各々リファクタリング前正規化ソースコード情報と、リファクタリング後正規化ソースコード情報を生成する正規化ステップと、前記リファクタリング前正規化ソースコード情報と、前記リファクタリング後正規化ソースコード情報の構造を比較する構造比較ステップと、前記リファクタリング前正規化ソースコード情報と、前記リファクタリング後正規化ソースコード情報を記号実行する記号実行ステップと、前記記号実行ステップによる記号実行の結果を比較して、前記リファクタリング前ソースコードと前記リファクタリング後ソースコードの等価性を判定する等価性判定ステップとを有するようにした。
【発明の効果】
【００３１】
本発明によれば、人手で実施されたリファクタリングに対する等価性検証を、記号実行により行うときに、計算量を爆発させずに、迅速に行えるようなソースコード等価性検証方法を提供することができる。
【図面の簡単な説明】
【００３２】
【図１】本発明の一実施形態に係るソースコード等価性検証装置のハードウェア構成図である。
【図２】本発明の一実施形態に係るソースコード等価性検証装置のソフトウェア構成図である。
【図３】本発明の一実施形態に係るソースコード等価性検証装置の機能構成図である。
【図４】本発明の一実施形態に係るソースコード等価性検証装置全体の機能と、データフローを示した図である。
【図５】本発明の一実施形態に係るソースコード等価性検証装置の処理を示すフローチャートである。
【図６】入力部１１００の機能の詳細とデータフローを示した図である。
【図７】正規化部１２００の機能の詳細とデータフローを示した図である。
【図８】構造比較検証処理部１３００の機能の詳細とデータフローを示した図である。
【図９】記号実行実施判定部１７００の機能の詳細とデータフローを示した図である。
【図１０】記号実行検証処理部１４００の機能の詳細とデータフローを示した図である。
【図１１】リファクタリング前後のソースコードの例を示す図である（その一）。
【図１２】リファクタリング前後のソースコードに対応するソースコード情報の例を示す図である（その一）。
【図１３】ソースコード情報に対して行われる正規化の例を示す図である。
【図１４】正規化した構造グラフを構造比較により等価性検証した結果を表示する出力部の表示例を示す図である。
【図１５】リファクタリング前後のソースコードの例を示す図である（その二）。
【図１６】リファクタリング前後のソースコードに対応するソースコード情報の例を示す図である（その二）。
【図１７】抽象化されたソースコード情報の例を示す図である。
【図１８】リファクタリング前ソースコードとリファクタリング後ソースコードに対して記号実行したときの実行木を示した例である。
【図１９】記号実行の一例を説明するために、ソースコードとそれより派生するデータ構造について示した図である。
【図２０】記号実行検証処理部により等価性検証した結果を表示する表示部の表示例を示す図である。
【図２１】リファクタリング前後のソースコードの例を示す図である（その三）。
【図２２】リファクタリング前のソースコードに対応するソースコード情報の例を示す図である（その三）。
【図２３】リファクタリング後のソースコードに対応するソースコード情報の例を示す図である（その三）。
【図２４】正規化されたリファクタリング後のソースコード情報の例を示す図である。
【図２５】抽象化されたソースコード情報の例を示す図である。
【図２６】抽象化された場合における、リファクタリング前ソースコードとリファクタリング後ソースコードに対して記号実行したときの実行木を示した例である。
【図２７】抽象化された場合における、表示部による等価性検証結果の表示例を示した図である。
【発明を実施するための形態】
【００３３】
以下、本発明における実施形態を、図面を用いて説明する。
【実施例１】
【００３４】
以下、図１乃至図１０を用いて本発明の一実施形態に係るソースコード等価性検証装置１０００の構成と処理について説明する。【００３５】
先ず、図１を用いて本発明の一実施形態に係るソースコード等価性検証装置のハードウェア構成について説明する。
本発明の一実施形態に係るソースコード等価性検証装置のハードウェア構成としては、例えば、図１に示されるような一般的なパーソナルコンピュータで実現される。
ソースコード等価性検証装置１０００は、ＣＰＵ（Central Processing Unit）１０１、主記憶装置１０２、ネットワークＩ／Ｆ１０３、グラフィックＩ／Ｆ１０４、入出力Ｉ／Ｆ１０５、補助記憶装置Ｉ／Ｆ１０６が、バスにより結合された形態になっている。【００３６】
ＣＰＵ１０１は、ソースコード等価性検証装置１００の各部を制御し、主記憶装置１０２にソースコード等価性検証プログラム２００をロードして実行する。
主記憶装置１０２は、通常、ＲＡＭなどの揮発メモリで構成され、ＣＰＵ１０１が実行するプログラム、参照するデータが補助記憶装置などからロードされて、記憶される。【００３７】
ネットワークＩ／Ｆ１０３は、外部ネットワーク１５０と接続するためのインタフェースである。
グラフィックＩ／Ｆ１０４は、ＬＣＤ（Liquid Crystal Display）などの表示装置１２０を接続するためのインタフェースである。
入出力Ｉ／Ｆ１０５は、入出力装置を接続するためのインタフェースである。図１の例では、キーボード１３１とポインティングデバイスのマウス１３２が接続されている。
補助記憶装置Ｉ／Ｆ１０６は、ＨＤＤ（Hard Disk Drive）１４１やＤＶＤ（Digital Versatile Disk）ドライブ装置１４２などの補助記憶装置を接続するためのインタフェースである。【００３８】
ＨＤＤ１４１は、大容量の記憶容量を有しており、本実施形態を実行するためのソースコード等価性検証プログラム２００が格納されている。
ＤＶＤドライブ装置１４２は、ＤＶＤやＣＤなどの光学ディスクにデータを書き込んだり、光学ディスクからデータを読み込んだりする装置であり、ソースコード等価性検証プログラム２００は、例えば、ＣＤ−ＲＯＭにより提供されたものをインストールすることができる。【００３９】
本実施形態のソースコード等価性検証装置１０００は、上記のようなパーソナルコンピュータに、ソースコード等価性検証プログラム２００をインストールして、各機能を実行するものである。【００４０】
次に、図２を用いて本発明の一実施形態に係るソースコード等価性検証装置のソフトウェア構成について説明する。
ソースコード等価性検証装置１０００で実行するプログラム等価性検証プログラム２００のモジュール構成は、サブルーチンであるソースコード解析モジュール２０１、構造グラフ生成・更新モジュール２０２、構造グラフ解析モジュール２０３、実行木生成モジュール２０４、記号実行実行モジュール２０５、入出力モジュール２０６、データベースモジュール２０７からなる。
なお、プログラム等価性検証プログラム２００は、ＯＳ（Operating System）上で動作するアプリケーションソフトウェアであり、ソースコード等価性検証装置のソフトウェア構成として、ＯＳやライブラリプログラムも含むが図では、省略している。【００４１】
ソースコード解析モジュール２０１は、ソースコードの字句解析・構文解析を行い、構造グラフ生成のために必要な情報を取り出すモジュールである。
構造グラフ生成・更新モジュール２０２は、ソースコード解析モジュール２０１の解析結果に基づいて、構造グラフを生成したり、更新したりするモジュールである。
構造グラフ解析モジュール２０３は、構造グラフのグラフ構造を解析するモジュールである。
実行木生成モジュール２０４は、構造グラフ解析モジュール２０３の解析結果に基づき、実行木を生成するモジュールである。
記号実行実行モジュール２０５は、実行木生成モジュール２０４が生成した実行木に対する記号実行を行うモジュールである。
入出力モジュール２０６は、外部から必要なデータの入出力を行うモジュールである。
データベースモジュール２０７は、各種データベースにアクセスするためのモジュールである。【００４２】
図３は、ソースコード等価性検証装置１０００の機能構成図を示す。制御部１１０は、図１のＣＰＵ１０１、主記憶装置１０２から成り、記憶部１６００は主に図１のＨＤＤ１４１から成るが、主記憶装置１０２を含めることもある。入力装置１３０は、図１の入出力Ｉ／Ｆ１０５、キーボード１３１、マウス１３２などを含み、更に補助記憶装置Ｉ／Ｆ１０６を介してＤＶＤドライブ装置１４２から読込む構成を含めてもよい。出力装置１２０は、グラフィックＩ／Ｆ１０４、表示装置１２０などを含み、更に補助記憶装置Ｉ／Ｆ１０６を介してＤＶＤドライブ装置１４２へ書き込む構成を含めてもよい。通信部１０３は、図１のネットワークＩ／Ｆ１０３を表わすが、ネットワーク１５０を介して例えば外部計算機１６０と接続されている。【００４３】
記憶部１６００は、ソースコード等価性検証プログラム２００、本装置で対応するリファクタリングの種類を予め登録しているリファクタリングパターン登録情報１１２０、リファクタリング前／後ソースコード情報に施す正規化処理を前記リファクタリングパターン毎に予め登録している正規化データベース１６０１、およびリファクタリング前／後ソースコード情報に施す抽象化処理を前記リファクタリングパターン毎に予め登録している抽象化データベース１６０２を予め備えておく。【００４４】
記憶部１６００は更に、ソースコード等価性検証処理が実施される際に確保されるリファクタリング前／後ソースコード記憶領域１６０３、リファクタリング前／後ソースコード情報記憶領域１６０４、リファクタリング前／後記号実行結果記憶領域１６０５、及び検証結果記憶領域１６０６を有する。【００４５】
制御部１１０は、記憶部１６００からソースコード等価性検証プログラム２００をロードして、ＣＰＵ１０１で実行することにより、入力部１１００、正規化部１２００、構造比較検証処理部１３００、記号実行実施判定部１７００、記号実行検証処理部１４００、出力部１５００の各機能を実現する。【００４６】
次に、図４乃至図１０を用いて本発明の一実施形態に係るソースコード等価性検証装置の各機能と、それらの処理について説明する。
図４は、本発明の一実施形態に係るソースコード等価性検証装置全体の機能と、データフローを示した図である。
図５は、本発明の一実施形態に係るソースコード等価性検証装置の処理を示すフローチャートである。
図６は、入力部１１００の機能の詳細とデータフローを示した図である。
図７は、正規化部１２００の機能の詳細とデータフローを示した図である。
図８は、構造比較検証処理部１３００の機能の詳細とデータフローを示した図である。
図９は、記号実行実施判定部１７００の機能の詳細とデータフローを示した図である。
図１０は、記号実行検証処理部１４００の機能の詳細とデータフローを示した図である。【００４７】
ソフトウェア開発者は、外部計算機１６０に実装されたソフトウェア開発装置で作成したソフトウェアにリファクタリングを実施して、リファクタリング実施後のソースコードがリファクタリング実施前のソースコードと等価であるかどうかを検証するために、リファクタリング前／後ソースコードを、ネットワーク１５０を介してソースコード等価性検証装置１０００へ送って、検証を依頼する。依頼されたリファクタリング前／後ソースコードは、記憶部１６００のリファクタリング前／後ソースコード記憶領域１６０３に記憶され、等価性検証処理がなされる。【００４８】
または、ソフトウェア開発装置が本実施形態のソースコード等価性検証装置１０００と同じパーソナルコンピュータに実装されている場合には、ソフトウェア開発者は、図３の入力装置１３０などにより、リファクタリング前／後ソースコードを入力して、それらのデータをリファクタリング前／後ソースコード記憶領域１６０３に記憶させて等価性検証処理を実行する。【００４９】
ソフトウェア開発者が、リファクタリング前／後ソースコードを入力して、等価性検証処理を依頼する際に、如何なる種類のリファクタリングを実施したのかを表わすリファクタリングパターン入力情報０００３を添付して入力する。【００５０】
本実施形態のソースコード等価性検証装置１０００は、図４に示されるように、リファクタリング前ソースコード０００１とリファクタリング後ソースコード０００２の二つのソースコードと、リファクタリング前ソースコード０００１に対して適用されたリファクタリングパターンに関する入力情報であるリファクタリングパターン入力情報０００３の入力によって、リファクタリング前ソースコード０００１とリファクタリング後ソースコード０００２のソースコードの等価性を検証するものである。【００５１】
先ず、入力部１１００において、入力された、または既に記憶部１６０３に記憶されたリファクタリング前ソースコード０００１を受け付ける（図５のＳ１０１）。リファクタリング後ソースコード入力ステップＳ１０２では、入力部１１００において、リファクタリング後ソースコード０００２を受け付ける（Ｓ１０２）。また、入力部１１００において、リファクタリングパターン入力情報０００３の入力を受け付ける（Ｓ１０３）。【００５２】
以下、図６を用いて上記の入力部１１００の機能の詳細とその処理について説明する。
リファクタリング前ソースコード０００１は、図６に示されるように、入力部１１００におけるソースコード入力部１１０１によって受付けられ、ソースコードの字句解析と構文解析を行い、リファクタリング前ソースコード情報１００１に変換される。リファクタリング後ソースコード０００２も、入力部１１００におけるソースコード入力部１１０１によって受付けられ、ソースコードの字句解析と構文解析を行い、リファクタリング後ソースコード情報１００２に変換され、記憶部１６００に格納される。また、リファクタリングパターン入力情報０００３は、入力部１１００におけるリファクタリングパターン入力部１１０２によって受け付けられ、リファクタリングパターン種別を表すリファクタリングパターン情報１００３に変換され、記憶部１６００に格納される。【００５３】
次に、リファクタリング前ソースコード情報１００１と、リファクタリング後ソースコード情報１００２を比較し、ソースコードの構造上の変更箇所を特定する（Ｓ１０４１）。
そして、正規化部１２００は、記憶部１６００に格納された情報を用いて、リファクタリング前ソースコード情報１００１とリファクタリング後ソースコード情報１００２の正規化を行う（Ｓ１０４２）。【００５４】
ここで、正規化とは、リファクタリングが行われたソースコードのソースコード情報を、そのソースコードと等価なソースコードに対応するソースコード情報に変換することを意味する。この正規化は、この後に続く構造比較ステップＳ１０４３と記号実行ステップＳ１０４５に適した形にするために行われる。【００５５】
以下、図７を用いて上記の正規化部１２００の機能の詳細とその処理について説明する。
リファクタリング前ソースコード情報１００１とリファクタリング後ソースコード情報１００２は、正規化部１２００の変更箇所特定部１２０１に入力される。一方、正規化ＤＢ１６０１に格納されているリファクタリングパターン情報１００３に対応した変更箇所特定情報１００７ｂが読み出される。そして、変更箇所特定部１２０１はソースコード情報を比較し、リファクタリングパターン情報１００３に対応した変更箇所特定情報１００７ｂを参照し、ソースコードの構造上の変更箇所を特定し、変更箇所情報１００４を生成する（Ｓ１０４１）。【００５６】
次に、リファクタリングパターン入力情報１００３に対応する正規化の方法を表した正規化情報１００７ａを記憶部１６００の正規化ＤＢ１６０１から取得する（Ｓ１０４２）。正規化ＤＢ１６０１には、リファクタリングパターンごとに対応した正規化情報１００７ａを格納してある。正規化部１２００のソースコード正規化部１２０２において、リファクタリング前ソースコード情報１００１に対して、取得した正規化情報１００７ａに基づき正規化を行い、リファクタリング前正規化ソースコード情報１００５を生成する。また、正規化部１２００のソースコード正規化部１２０２において、リファクタリング後ソースコード情報１００２に対して、正規化情報１００７ａに基づき、正規化を行い、リファクタリング後正規化ソースコード情報１００６を生成する。【００５７】
次に、構造比較検証処理部１３００は、リファクタリング前正規化ソースコード情報１００５とリファクタリング後正規化ソースコード情報１００６の構造を比較し、同じ構造であるか否かを検証する（ステップＳ１０４３）。【００５８】
以下、図８を用いて構造比較検証処理部１３００の機能の詳細とその処理について説明する。
構造比較検証処理部１３００は、リファクタリング前正規化ソースコード情報１００５とリファクタリング後正規化ソースコード情報１００６を受け取り、二つの正規化後のソースコード情報の構造が一致しているか否かの比較を行い、一致した場合は、構造比較結果１００８として、一致しているという情報を生成し、不一致の場合は、構造比較結果１００８として、不一致であるという情報を生成する（Ｓ１０４３）。【００５９】
次に、記号実行実施判定部１７００では、記号実行を行うべきか否かを判定する（Ｓ１０４７）。ここで、上記の構造比較ステップＳ１０４３の結果で、構造が一致していると判定されたときには、等価非等価出力ステップＳ１０５に行き、構造が不一致であると判定されたときには、ソースコード情報抽象化ステップＳ１０４４に行く。【００６０】
以下、図９を用いて記号実行実施判定部１７００の機能の詳細とその処理について説明する。
記号実行実施判定部１７００は、構造比較結果１００８を受け取り、構造比較結果１００８で、構造が「一致」であれば、等価非等価出力ステップＳ１０５へ移行し、出力部１５００より、ソースコードが等価であるとして検証結果０００４を出力する。
ソースコードが等価であるという結果が出力されたときには、ユーザは、行われたリファクタリングが正当であると判断することができる。【００６１】
記号実行実施判定部１７００は、構造比較結果１００８を受け取り、構造比較結果１００８で、構造が「不一致」であれば、記号実行開始指示１００９を生成する。【００６２】
次に、ソースコード情報の抽象化を行う（Ｓ１０４４）。
ここで、ソースコード情報の抽象化とは、各々のソースコード情報に対して、記号実行したときに、同じ入力を与えて、同じ結果がでるようにした状態を保ったまま、ソースコード情報を縮約することを意味する。【００６３】
次に、抽象化したリファクタリング前のソースコード情報と、抽象化したリファクタリング後のソースコード情報に対して、記号実行を行う（Ｓ１０４５）。
そして、記号実行の結果（記号実行サマリ）を論理的に比較し、同じ入力に対して、同じ出力が得られるときには、元のソースコードが等価であると、判断し、出力（記号実行サマリ）が異なるときには、元のソースコードが非等価であると、判断して（Ｓ１０４６）、等価非等価の結果出力を行う。【００６４】
リファクタリング前とリファクタリング後の記号実行の結果である記号実行サマリを比較し、論理的に等価であるかどうかの判定は、ＳＡＴソルバやＳＭＴソルバや決定手続きなどと呼ばれる手法を用いることで行う。記号実行サマリを構成する各葉ノードに対して、そのパス制約と変数状態との論理積を求め、それらの論理和を計算することにより記号実行サマリを表現する論理式を生成することができる。リファクタリング前の記号実行サマリから生成した論理式とリファクタリング後の記号実行サマリから生成した論理式とが等価であることをＳＡＴソルバで判定することにより、記号実行サマリの等価性が判定できる。【００６５】
ここで、ソースコードが等価であるという結果が出力されたときには、ユーザは、行われたリファクタリングが正当であると判断することができ、ソースコードが非等価であるいう結果が出力されたときには、ユーザは、行われたリファクタリングが不当であると判断することができる。そして、ユーザは、行われたリファクタリングが不当であると判断したときには、行ったリファクタリングを見直して、正当なものに修正する作業を開始することができる。【００６６】
記号実行検証処理部１４００は、記号実行開始指示１００９を受けて、ソースコード抽象化ステップＳ１０４４を開始する。ソースコード抽象化ステップＳ１０４４では、記憶部１６００の抽象化ＤＢ１６０２に格納されている抽象化情報１０１０を用いて、リファクタリング前正規化ソースコード情報と変更箇所情報１００４を受け取り、抽象化を行い、リファクタリング前抽象化ソースコード情報１４０３を生成する。また、ソースコード抽象化ステップＳ１０４４では、記憶部１６００の抽象化ＤＢ１６０２に格納されている抽象化情報１０１０を用いて、リファクタリング後正規化ソースコード情報と変更箇所情報１００４を受け取り、抽象化を行い、リファクタリング後抽象化ソースコード情報１４０４を生成する。ここで、抽象化ＤＢに格納されている抽象化情報１０１０は、正規化後のソースコード情報に対して、変更箇所情報１００４に関わらない箇所とループや再帰呼び出しの箇所を置き換えて、この後の記号実行ステップＳ１０４５の時に、変更箇所情報１００４に関わらない箇所とループや再帰呼び出しの箇所を記号実行しないように変換する処理の方法に関する情報である。【００６７】
記号実行ステップＳ１０４５では、記号実行部１４０２において、リファクタリング前抽象化ソースコード情報１４０３とリファクタリング後抽象化ソースコード情報１４０４に対して、記号実行を行い、それぞれリファクタリング前記号実行結果１４０５とリファクタリング後記号実行結果１４０６を得る。記号実行結果比較ステップＳ１０４６では、記号実行結果比較部１４０７において、リファクタリング前記号実行結果１４０５とリファクタリング後記号実行結果１４０６が同じものであるか否かを比較し判定する。記号実行結果比較部１４０７において、リファクタリング前記号実行結果１４０５とリファクタリング後記号実行結果１４０６が同じものであった場合、等価非等価出力ステップＳ１０５へ移行し、等価として出力部１５００に検証結果０００４を出力させる。記号実行結果比較部１４０７において、リファクタリング前記号実行結果１４０５とリファクタリング後記号実行結果１４０６が異なるものであった場合、等価非等価出力ステップＳ１０５へ移行し、非等価として出力部１５００に検証結果０００４を出力させる。【００６８】
本実施形態のソースコード等価性検証装置によれば、計算量が爆発しやすい記号実行を行う前に、それぞれのリファクタリング前後のそれぞれのソースコード情報に対して、正規化後に、構造比較を行い、その元になるソースコードが等価であると判定された場合には、記号実行を行わない。【００６９】
また、構造比較で元になるソースコードが非等価と判定された場合には、ソースコード情報の抽象化を行って、ソースコード情報を縮減してから、記号実行を行うので、記号実行の計算量を削減することができる。
【実施例２】
【００７０】
以下、上記の図５を参照しながら、図１１乃至図１４を用いて本発明の一実施形態に係るソースコード等価性検証装置の処理の具体例について説明する。この例は、図５の記号実行実施判定Ｓ１０４７の処理で、ソースコード情報である構造グラフの構造が一致すると判定される例である。
図１１は、リファクタリング前後のソースコードの例を示す図である（その一）。
図１２は、リファクタリング前後のソースコードに対応するソースコード情報の例を示す図である（その一）。
図１３は、ソースコード情報に対して行われる正規化の例を示す図である。
図１４は、正規化した構造グラフを構造比較により等価性検証した結果を表示する出力部の表示例を示す図である。【００７１】
この例では、ソースコードに対するリファクタリングとして、リファクタリングパターンＥｘｔｒａｃｔＭｅｔｈｏｄに基づいたリファクタリングが行われる場合について説明する。リファクタリングパターンＥｘｔｒａｃｔＭｅｔｈｏｄは、複数個所で同じ処理をしているソースコードにおいて、その同じ処理を関数として抜き出し、複数個所で同じ処理をしていた箇所を抜き出した関数への呼び出しに置き換えて、複数箇所に存在したソースコードを共通化するリファクタリングのパターンである。このリファクタリングパターンＥｘｔｒａｃｔＭｅｔｈｏｄは、一つの関数においてソースコードの記述量が多い場合に、関数の可読性を向上させるために、その関数内のソースコードの一部を別の関数として抜き出すリファクタリングとしても用いられる。【００７２】
以下、図１１によりリファクタリングパターンＥｘｔｒａｃｔＭｅｔｈｏｄによって、ソースコードのリファクタリングを行う例を説明する。
ソースコードＣ００１は、リファクタリングパターンＥｘｔｒａｃｔＭｅｔｈｏｄの適用前のソースコードであり、グローバル変数ｇｌｏｂａｌ＿ｖａｒに対してｍａｉｎ関数において１０を代入するプログラムである。このソースコードＣ００１に対して、リファクタリングパターンＥｘｔｒａｃｔＭｅｔｈｏｄを適用したソースコードがＣ００２となる。ソースコードＣ００２は、ソースコードＣ００１におけるｇｌｏｂａｌ＿ｖａｒ＝１０；というグローバル変数への代入文を関数ｆｏｏとして抜き出し、ｇｌｏｂａｌ＿ｖａｒ＝１０；の記述部分であった箇所を関数ｆｏｏの呼び出しに変換している。【００７３】
先ず、図１１に示したリファクタリングの例における、図５のリファクタリング前ソースコード入力Ｓ１０１とリファクタリング後ソースコード入力Ｓ１０２とリファクタリングパターンＳ１０３のステップについて説明する。
入力部１１００では、ソースコード入力部１１０１によって、リファクタリング前ソースコード０００１とリファクタリング後ソースコード０００２を受け付けて、対応するリファクタリング前ソースコード情報１００１とリファクタリング後ソースコード情報を生成する。ここで、リファクタリング前ソースコード０００１はソースコードＣ００１、リファクタリング後ソースコード０００２はソースコードＣ００２に対応する。【００７４】
ソースコード等価性検証装置１０００は、入力されたリファクタリング前ソースコード０００１とリファクタリング後ソースコード０００２をソースコード入力部１１０１によって字句解析と構文解析し、図１２の例で示されるような内部で扱う構造グラフに変換する。リファクタリングパターンＥｘｔｒａｃｔＭｅｔｈｏｄの例では、ソースコードＣ００１は、構造グラフＭ００１、ソースコードＣ００２は、構造グラフＭ００２に変換される。ここで、リファクタリング前ソースコード情報１００１は構造グラフＭ００１、リファクタリング後ソースコード情報１００２は構造グラフＭ００２に対応する。【００７５】
入力部１１００では、リファクタリングパターン入力部１１０２において、リファクタリングパターン入力情報０００３を受け付けて、リファクタリングパターン情報１００３を生成する。この例では、例えば、リファクタリングパターン入力情報０００３が、リファクタリングパターンＥｘｔｒａｃｔＭｅｔｈｏｄを表す文字列“ＥｘｔｒａｃｔＭｅｔｈｏｄ”や、画面のメニューでの選択番号のときに、リファクタリングパターン情報１００３として、内部で、リファクタリングパターンＥｘｔｒａｃｔＭｅｔｈｏｄを指し示すコードを生成する。【００７６】
次に、図５の変更箇所特定Ｓ１０４１のステップについて説明する。
正規化部１２００の変更箇所特定部１２０１において、リファクタリング前ソースコード情報１００１とリファクタリング後ソースコード情報１００２とリファクタリングパターン情報１００３から、正規化ＤＢ１６０１に記憶されている対応する変更箇所特定情報１００７ｂを参照し、ソースコード上のどこを変更したのかを構造グラフ上から特定し、変更箇所情報１００４を出力する。このリファクタリングパターンＥｘｔｒａｃｔＭｅｔｈｏｄの例では、リファクタリングパターンＥｘｔｒａｃｔＭｅｔｈｏｄは、リファクタリング後ソースコード情報１００２において関数(entry foo)が増加するという特徴から、リファクタリング前ソースコード情報１００１とリファクタリング後ソースコード情報１００２の関数の宣言を比較し、リファクタリング後ソースコード情報１００２のみに現れる関数を変更箇所として特定する。図１２上では、リファクタリング前ソースコード情報１００１の構造グラフＭ００１とリファクタリング後ソースコード情報１００２の構造グラフＭ００２の中で、関数を示すｅｎｔｒｙを比較し、ノードＭ００３が指し示すｅｎｔｒｙのｆｏｏ関数が増えていることから、ノードＭ００３およびｆｏｏ関数を呼び出すノードＭ００４が、変更箇所情報１００４に該当する。【００７７】
次に、図５のソースコード情報正規化Ｓ１０４２のステップについて説明する。正規化部１２００のソースコード正規化部１２０２において、変更箇所情報１００４とリファクタリング前ソースコード情報１００１から、正規化ＤＢ１６０１に記憶している対応する正規化情報１００７ａを用いて正規化を行い、リファクタリング前正規化ソースコード情報１００５を生成する。リファクタリング後ソースコード情報１００２も同様に正規化を行い、リファクタリング後正規化ソースコード情報１００６を生成する。このリファクタリングパターンＥｘｔｒａｃｔＭｅｔｈｏｄにおけるソースコード正規化部１２０２の例を示すと、図１３のようになる。先ず、正規化ＤＢ１６０１からリファクタリングパターン情報１００３であるリファクタリングパターンＥｘｔｒａｃｔＭｅｔｈｏｄに対応する正規化情報１００７ａを取得する。リファクタリングパターン情報１００３のＥｘｔｒａｃｔＭｅｔｈｏｄに対応する正規化情報１００７ａによれば、正規化方法は、Ｅｘｔｒａｃｔしたリファクタリング後ソースコード情報０００２における変更箇所１００４の関数を、インライン展開して元に戻したときのソースコードを表す構造にすることである。【００７８】
図１３における変更箇所情報１００４は、リファクタリング後ソースコード情報１００２の構造グラフＭ００２におけるノードＭ００３とノードＭ００４であり、これらのノードは、リファクタリングにより作られたＥｘｔｒａｃｔされた関数ｆｏｏであるので、その関数ｆｏｏを正規化して元に戻すと、構造グラフＭ００６のようになる。これがリファクタリング後正規化ソースコード情報１００６となる。リファクタリング前正規化ソースコード情報１００５は、リファクタリングパターンＥｘｔｒａｃｔＭｅｔｈｏｄに関して正規化処理が無いため、図１３上のリファクタリング前ソースコード情報０００１の構造グラフＭ００１は正規化では何も変更されずに、そのまま、構造グラフＭ００５となる。【００７９】
次に、図５の構造比較Ｓ１０４３のステップについて説明する。
構造比較検証処理部１３００では、リファクタリング前正規化ソースコード情報１００５とリファクタリング後正規化ソースコード情報１００６を受け取り、ソースコード情報の構造の比較を行い、その結果を構造比較結果１００８として生成する。リファクタリングパターンＥｘｔｒａｃｔＭｅｔｈｏｄによるリファクタリングを行った図１３による例において、構造比較検証処理部１３００は、リファクタリング前正規化ソースコード情報１００５のグラフＭ００５とリファクタリング後正規化ソースコード情報１００６のグラフＭ００６の二つのグラフが同じ構造でありそれぞれのノードが同じであるため、構造比較結果１００８として、ソースコードＣ００１とソースコードＣ００２を等価であると判定する。【００８０】
次に、図５の記号実行実施判定Ｓ１０４７のステップについて説明する。
記号実行実施判定部１７００は、リファクタリングパターンＥｘｔｒａｃｔＭｅｔｈｏｄによるリファクタリングを行った図１１による例において、構造比較結果１００８として、リファクタリング前後のソースが等価として判定されるため、等価非等価出力ステップＳ１０５に移行し、出力部１５００は、構造比較検証処理部１３００が等価と判定した結果を受けて、検証結果０００４として等価であることを出力する。【００８１】
記号実行実施判定部１７００は、リファクタリングパターンＥｘｔｒａｃｔＭｅｔｈｏｄによるリファクタリングを行ったこの図１１による例では、正規化部１２００による変換と構造比較検証処理部１３００の判定処理によって、リファクタリング前後のソースコードが、各々等価と判定できるため、記号実行検証処理部１４００により、記号実行の計算を必要とせず、計算量を不必要に増加させずに、迅速な等価判定が可能となる。【００８２】
図１４には、構造比較検証処理部１３００の判定処理によって、等価と判定された場合の出力部１５００による検証結果０００４の表示例を示す。図１４に示す表示例には、判定結果Ｐ１００として構造比較により判定したこと、および、その結果等価と判定されたことを示している。また、構造比較に用いた構造グラフデータとして、正規化を実施した後のリファクタリング前正規化ソースコード情報の構造グラフＰ１１１とリファクタリング後正規化ソースコード情報の構造グラフＰ１１２を表示している。さらに、リファクタリング適用情報Ｐ１２０として、適用されているリファクタリングパターン名であるＥｘｔｒａｃｔＭｅｔｈｏｄ、ＥｘｔｒａｃｔＭｅｔｈｏｄで抽出された関数名であるｆｏｏと、当該リファクタリングパターンが適用されている位置の情報としてリファクタリング適用前ソースコードに対してはファイル名ｓａｍｐｌｅ．ｃと行番号３が、リファクタリング適用後ソースコードに対してはファイル名ｓａｍｐｌｅ．ｃと行番号６が表示されている。【００８３】
図１４に示す、リファクタリング適用情報Ｐ１２０を見ることにより、等価性検証装置が認識したリファクタリングのパターンと箇所が、開発者が意図したリファクタリングと一致していることを確認することができる。
【実施例３】
【００８４】
以下、上記の図５を参照しながら、図１５乃至図２０を用いて本発明の一実施形態に係るソースコード等価性検証装置の処理の具体例について説明する。この例は、図５の記号実行実施判定の処理で、リファクタリングパターンによらないリファクタリングが実施されたソースコードにおいて、ソースコード情報である構造グラフの構造が不一致であると判定される例である。【００８５】
図１５は、リファクタリング前後のソースコードの例を示す図である（その二）。
図１６は、リファクタリング前後のソースコードに対応するソースコード情報の例を示す図である（その二）。
図１７は、抽象化されたソースコード情報の例を示す図である。
図１８は、リファクタリング前ソースコードとリファクタリング後ソースコードに対して記号実行したときの実行木を示した例である。
図１９は、記号実行の一例を説明するために、ソースコードとそれより派生するデータ構造について示した図である。
図２０は、記号実行検証処理部により等価性検証した結果を表示する表示部の表示例を示す図である。【００８６】
この例では、ソースコードに対するリファクタリングとして、ソースコードにおける条件式を変更せずに変数への代入を整理するリファクタリングが行われる場合について説明する。【００８７】
図１５では、リファクタリング前のソースコードＣ００３とリファクタリング後のソースコードＣ００４が示されており、ソースコードＣ００３とソースコードＣ００４の間で、ソースコードにおける条件式を変更せずに変数への代入を整理するリファクタリングが適用されている。具体的には、リファクタリング前のソースコードＣ００３では、ソースコード部分Ｃ００５が示す所において、変数ａに対して値を代入し、ソースコード部分Ｃ００６が示す所において、変数ａ（右辺）の値を用いて演算し変数ａ（左辺）に代入している。リファクタリング後のソースコードＣ００４では、ソースコード部分Ｃ００７が示す所において、変数ｂに対して値を代入し、ソースコード部分Ｃ００８が示す所において、変数ｂの値を用いて演算し変数ａに代入している。リファクタリング前と後で、ソースコード部分Ｃ００５が示す所とソースコード部分Ｃ００７が示す所に存在する条件式、ソースコード部分Ｃ００６が示す所とソースコード部分Ｃ００８が示す所に存在する条件式は一致しているが、用いている変数を変更し、ソースコードＣ００４の方が、ソースコード行数が少なく可読性が高いものになっている。図１５の例で示すリファクタリングは、非特許文献４に記載されているリファクタリングパターン７２種に該当せず、本実施形態のソースコード等価性検証装置１０００においてもパターンとしてデータベースに登録されていないものとする。【００８８】
先ず、図１５に示したリファクタリングの例における、図５のリファクタリング前ソースコード入力Ｓ１０１とリファクタリング後ソースコード入力Ｓ１０２について説明する。このリファクタリングの例では、リファクタリング前ソースコード０００１がソースコードＣ００３、リファクタリング後ソースコード０００２がソースコードＣ００４に対応する。入力部１１００では、ソースコード入力部１１０１によって、リファクタリング前ソースコード０００１とリファクタリング後ソースコード０００２を受け付けて、対応するリファクタリング前ソースコード情報１００１とリファクタリング後ソースコード情報１００２を生成する。図１５のリファクタリングの例において、ソースコード入力部１１０１がリファクタリング前ソースコード０００１としてソースコードＣ００３を受け付け、字句解析と構文解析を行い、リファクタリング前ソースコード情報１００１として図１６の構造グラフＭ００８に変換する。また、ソースコード入力部１１０１は、リファクタリング後ソースコード０００２としてソースコードＣ００４を受けつけ、字句解析と構文解析を行い、リファクタリング後ソースコード情報１００２として図１６の構造グラフＭ００９に変換する。ここで、リファクタリング前ソースコード情報１００１は構造グラフＭ００８、リファクタリング後ソースコード情報１００２は構造グラフＭ００９に対応する。【００８９】
次に、リファクタリングパターンに関する情報を入力するＳ１０３のステップについて説明する。
入力部１１００では、リファクタリングパターン入力部１１０２において、リファクタリングパターン入力情報０００３を受け付けて、リファクタリングパターン情報１００３を生成する。このリファクタリングの例では、リファクタリングパターンは、登録されていないものと仮定しているため、「該当無し」を示す文字列やメニューの選択番号がリファクタリングパターン入力部１１０２に入力され、リファクタリングパターン入力部は、リファクタリングパターン情報１００３として、「該当無し」を示すコードを生成する。【００９０】
次に、図５の変更箇所特定Ｓ１０４１のステップについて説明する。
正規化部１２００の変更箇所特定部１２０１において、リファクタリング前ソースコード情報１００１とリファクタリング後ソースコード情報１００２から、ソースコード上のどこを変更したのかを特定し、変更箇所情報１００４を出力する。このリファクタリングの例では、リファクタリング前ソースコード情報１００１である構造グラフＭ００８とリファクタリング後ソースコード情報０００２である構造グラフＭ００９を比較し、両方に関数ｆｏｏと関数ｖａｒが存在しているため関数レベルの増減が無く、ｆｏｏ関数の内部に差異がみられるため、変更箇所特定部１２０１は、ｆｏｏ関数の内部を変更箇所情報１００４として出力する。なお、この例では、リファクタリングパターンとして「該当無し」なので、正規化ＤＢ１６０１の変更箇所特定情報１００７ｂは、参照せず、構造グラフの構造を解析することだけで、変更箇所を特定する。【００９１】
次に、図５のソースコード情報正規化Ｓ１０４２のステップについて説明する。
正規化部１２００のソースコード正規化部１２０２において、変更箇所情報１００４とリファクタリング前ソースコード情報１００１から、正規化ＤＢ１６０１の中にある対応する正規化情報１００７ａの正規化手法を用いて正規化を行い、リファクタリング前正規化ソースコード情報１００５を生成する。リファクタリング後ソースコード情報１００２も同様に正規化を行い、リファクタリング後正規化ソースコード情報１００６を生成する。このリファクタリングの例では、正規化ＤＢ１６０１からリファクタリングパターン情報１００３が「該当無し」に対応する正規化情報を取得する。ここで、リファクタリングパターン情報１００３が「該当無し」に対応する正規化情報は、変換無しとなるため、ソースコード正規化部１２０２は、リファクタリング前ソースコード情報１００１とリファクタリング後ソースコード情報１００２に関して、何も変更せずにリファクタリング前正規化ソースコード情報１００５とリファクタリング後正規化ソースコード情報１００６を出力する。正規化部１２００で変換されていないので、リファクタリング前正規化ソースコード情報１００５は、図１６における構造グラフＭ００８であり、リファクタリング後正規化ソースコード情報１００６は、図１６における構造グラフＭ００９である。【００９２】
次に、図５の構造比較Ｓ１０４３のステップについて説明する。
構造比較検証処理部１３００では、リファクタリング前正規化ソースコード情報１００５とリファクタリング後正規化ソースコード情報１００６を受け取り、ソースコード情報の構造の比較を行い、構造比較結果１００８を生成する。【００９３】
複数のグラフ構造の間の一致・不一致を探索する方法は種々考えられるが、例えば階層の最上位のノードから比較を開始して、その子供のノード間の比較、さらにその子供のノード間の比較というように、順次階層を下げて、全ての階層のノード間の比較を行ない、その途中で不一致が判定されたら、両グラフ構造は異なると判定する方法が挙げられる。【００９４】
このリファクタリングの例では、リファクタリング前正規化ソースコード情報１００５のグラフＭ００８とリファクタリング後正規化ソースコード情報１００６の構造グラフＭ００９を比較し、グラフＭ００９には、ノード「entry foo」の子供のノード「a＝0」が無いことから、明らかにグラフ構造が異なると判定して、構造比較結果１００８を、リファクタリング前後のソースコードが非等価と判定する。【００９５】
次に、図５の記号実行実施判定ステップＳ１０４７について説明する。
記号実行実施判定部１７００は、このリファクタリングの例において、構造比較結果１００８として、ソースコードが非等価と判定されたため、記号実行開始指示１００９のコマンドを生成する。【００９６】
次に、図５のソースコード情報抽象化ステップＳ１０４４について説明する。
記号実行検証処理部１４００は、記号実行開始指示１００９を受け取ると、抽象化部１４０１において、変更箇所情報１００４と抽象化ＤＢ１６０２の抽象化方法を記録した抽象化情報１０１０を用いて、リファクタリング前正規化ソースコード情報１００５とリファクタリング後正規化ソースコード情報１００６の抽象化を行う。抽象化ＤＢ１６０２の抽象化情報１０１０には、変更箇所情報１００４に対応して適切な抽象化手法が記録されている。このリファクタリングの例では、変更箇所情報１００４は関数ｆｏｏの内部と判明しているため、抽象化ＤＢ１６０２から、関数ｆｏｏを除いたソースコードの中で、リファクタリング前後で差異が生じていない関数を変数に変換して抽象化する方法を記載した抽象化情報１０１０を取得する。抽象化部１４０１において、リファクタリング前後で差異が生じていない関数を変数に変換して抽象化する方法を、リファクタリング前正規化ソースコード情報１００５のグラフＭ００８とリファクタリング後正規化ソースコード情報１００６のグラフＭ００９に適用した結果を示すと、図１７のようになる。図１６のリファクタリング前正規化ソースコード情報１００５の構造グラフＭ００８において、ノードＭ０１０の関数ｖａｒはリファクタリングによって差異が生じていないため、関数ｖａｒを呼び出す箇所のノードＭ０１１と合わせて変数ｖとして抽象化を行い、図１７の構造グラフＭ０１４のように変換する。ただし、この抽象化は、ノードＭ０１０と他のノードとのＤａｔａＤｅｐｅｎｄｅｎｃｙ（データの依存性）がないことが必要である）。図１６におけるリファクタリング後正規化ソースコード情報１００６のグラフＭ００９に関しても、同様に抽象化を行い構造グラフＭ０１５に変換される。抽象化部１４０１は、前記構造グラフＭ０１４をリファクタリング前抽象化ソースコード情報１４０３、前記構造グラフＭ０１５をリファクタリング後抽象化ソースコード情報１４０４として出力する。ここで、この抽象化は、構造グラフＭ００８、Ｍ００９の各々において、ノードがカットされて、各々が記号実行されたときには、計算量が減ることに留意する。【００９７】
次に、図５の記号実行Ｓ１０４５のステップについて説明する。
記号実行検証処理部１４００では、抽象化部１４０１において抽象化を行った後、リファクタリング前抽象化ソースコード情報１４０３とリファクタリング後抽象化ソースコード情報１４０４のそれぞれに対して、記号実行部１４０２において、記号実行を実行し、その結果としてリファクタリング前記号実行結果１４０５とリファクタリング後記号実行結果１４０６を生成する。このリファクタリングの例において、記号実行部１４０２にて、前記リファクタリング前抽象化ソースコード情報１４０３とリファクタリング後抽象化ソースコード情報１４０４を記号実行した結果は、図１８に示されるようになる。このリファクタリングの例では、リファクタリング前抽象化ソースコード情報１４０３は、図１７の構造グラフＭ０１４に該当し、構造グラフＭ０１４に対して記号実行を行うと、図１８における実行木Ｅ１００ができる。また、図１８の実行木Ｅ１００における記号実行サマリであるＥ１０１，Ｅ１０２，Ｅ１０３，Ｅ１０４が、リファクタリング前抽象化ソースコード情報１４０３に対するリファクタリング前記号実行結果１４０５となる。リファクタリング後抽象化ソースコード情報１４０４は、図１７の構造グラフＭ０１５に該当し、構造グラフＭ０１５に対して記号実行を行うと、図１８における実行木Ｅ２００ができる。また、図１８の実行木Ｅ２００における記号実行サマリであるＥ２０１，Ｅ２０２，Ｅ２０３，Ｅ２０４が、リファクタリング後抽象化ソースコード情報１４０４に対するリファクタリング後記号実行結果１４０６となる。【００９８】
次に、図５の記号実行結果比較Ｓ１０４６のステップについて説明する。
記号実行検証処理部１４００の記号実行結果比較部１４０７では、リファクタリング前記号実行結果１４０５とリファクタリング後記号実行結果１４０６とが論理的に等価かどうかを比較し、リファクタリング前後のソースコードが等価か非等価かの判定を行う。図１５のリファクタリングの例では、リファクタリング前記号実行結果１４０５は、Ｅ１０１，Ｅ１０２，Ｅ１０３，Ｅ１０４であり、リファクタリング後記号実行結果１４０６は、Ｅ２０１，Ｅ２０２，Ｅ２０３，Ｅ２０４である。これら二つの記号実行結果が論理的に等価であることを以下のようにして判定する。【００９９】
リファクタリング前の記号実行サマリを表現する論理式として、Ｅ１０１のパス制約と変数状態との論理積、Ｅ１０２のパス制約と変数状態との論理積、Ｅ１０３のパス制約と変数状態との論理積、Ｅ１０４のパス制約と変数状態との論理積、との４個の論理式の論理和を取る。すなわち、（（β＜０）ＡＮＤ（γ＜０）ＡＮＤ（ａ＝−γ）ＡＮＤ（ｂ＝０）ＡＮＤ（ｖ＝γ））ＯＲ（（β＜０）ＡＮＤ（ＮＯＴ（γ＜０））ＡＮＤ（ａ＝γ）ＡＮＤ（ｂ＝０）ＡＮＤ（ｖ＝γ））ＯＲ（（ＮＯＴ（β＜０））ＡＮＤ（γ＜０）ＡＮＤ（ａ＝β−γ）ＡＮＤ（ｂ＝β）ＡＮＤ（ｖ＝γ））ＯＲ（（ＮＯＴ（β＜０））ＡＮＤ（ＮＯＴ（γ＜０））ＡＮＤ（ａ＝β＋γ）ＡＮＤ（ｂ＝β）ＡＮＤ（ｖ＝γ））がリファクタリング前の記号実行サマリを表現する論理式である。リファクタリング後の記号実行サマリを表現する論理式として、Ｅ２０１のパス制約と変数状態との論理積、Ｅ２０２のパス制約と変数状態との論理積、Ｅ２０３のパス制約と変数状態との論理積、Ｅ２０４のパス制約と変数状態との論理積、との４個の論理式の論理和を取る。便宜上、リファクタリング後の出力変数ａ，ｂ，ｖの値をそれぞれａ’，ｂ’，ｖ’とすると、リファクタリング後の記号実行サマリを表現する論理式は、（（β＜０）ＡＮＤ（γ＜０）ＡＮＤ（ａ’＝−γ）ＡＮＤ（ｂ’＝０）ＡＮＤ（ｖ’＝γ））ＯＲ（（β＜０）ＡＮＤ（ＮＯＴ（γ＜０））ＡＮＤ（ａ’＝γ）ＡＮＤ（ｂ’＝０）ＡＮＤ（ｖ’＝γ））ＯＲ（（ＮＯＴ（β＜０））ＡＮＤ（γ＜０）ＡＮＤ（ａ’＝β−γ）ＡＮＤ（ｂ’＝β）ＡＮＤ（ｖ’＝γ））ＯＲ（（ＮＯＴ（β＜０））ＡＮＤ（ＮＯＴ（γ＜０））ＡＮＤ（ａ’＝β＋γ）ＡＮＤ（ｂ’＝β）ＡＮＤ（ｖ’＝γ））となる。【０１００】
リファクタリング前の記号実行サマリを表現する論理式と、リファクタリング後の記号実行サマリを表現する論理式が、論理的に等価であるかどうかを判定する。
その判定方法は、前記リファクタリング前の記号実行サマリを表現する論理式と、リファクタリング後の記号実行サマリを表現する論理式のそれぞれに含まれる記号変数の値が同じである場合には出力変数の値が等しくなることを検証すれば良い。これを、リファクタリング前記号実行サマリを表現する論理式と、リファクタリング後記号実行サマリを表現する論理式と、論理式ＮＯＴ（（ａ＝ａ’）ＡＮＤ（ｂ＝ｂ’）ＡＮＤ（ｖ＝ｖ’））との論理積の式に対する充足可能性問題とおいて、ＳＡＴソルバによって解くことで実現する。ＳＡＴソルバによって解いた結果が充足不可能であれば、同じ入力の値を与えた場合に、リファクタリング前とリファクタリング後で異なる出力の値が得られることは無いことが分かるため、論理的に等価であると判定する。充足可能な場合は、同じ入力の値に対してリファクタリング前とリファクタリング後で異なる値が得られる場合が存在することを示している。この時、ＳＡＴソルバが出力する充足可能な値の例を用いて、非等価である入力の値の例（反例）を得ることができる。ここで使用するＳＡＴソルバは一般に提供されているプログラムを使用する。【０１０１】
この例においては両者の論理式が等価であるとの結果を得ることができる。この結果は、Ｅ１０１とＥ２０１のペアと、Ｅ１０２とＥ２０２のペアと、Ｅ１０３とＥ２０３のペアと、Ｅ１０４とＥ２０４のペアがそれぞれパス制約と変数状態が一致していることからも分かる。【０１０２】
記号実行結果比較部１４０７は、ＳＡＴソルバによって得られた等価という判定を、出力部１５００に送る。このとき、リファクタリング前の記号実行木Ｅ１００とリファクタリング後の記号実行木Ｅ２００の間には構造上の差異が生じているが、記号実行の最終的な記号実行サマリが論理的に一致しているため。ソースコードが等価と判定する。【０１０３】
次に、図５の等価非等価出力Ｓ１０５のステップについて説明する。
出力部１５００は、記号実行結果比較部１４０７が、ソースコードが等価と判定した結果を受けて、検証結果０００４として、ソースコードが等価であることを出力する。出力部１５００が出力する検証結果０００４の例を図２０に示す。【０１０４】
図２０に示す表示例には、判定結果Ｐ２００として記号実行により判定したこと、および、その結果等価と判定されたことを示している。また、構造比較に用いた構造グラフデータとして、正規化を実施した後のリファクタリング前正規化ソースコード情報の構造グラフＰ２１１とリファクタリング後正規化ソースコード情報の構造グラフＰ２１２を表示している。さらに、リファクタリング適用情報Ｐ２２０として、適用された正規化リファクタリングパターンが「該当無し」を表示している。構造グラフＰ２１１とＰ２１２においては、構造比較の結果、相違と判断されたノードに対して色を変化させることにより、ソースコード中のどの部分が構造比較の結果、等価でないと判断されたのかが分かるようになっている。また、構造グラフを比較表示することにより、どのように抽象化が実施されたのかが分かるようになっている。【０１０５】
図２０に示す表示例では、記号実行による判定に特有な情報として、リファクタリング前のソースコードに対する記号実行サマリ情報Ｐ２３０、および、リファクタリング後のソースコードに対する記号実行サマリ情報Ｐ２３１を表示している。記号実行サマリ情報Ｐ２３０およびＰ２３１では、それぞれＥ１０１、Ｅ１０２、Ｅ１０３、Ｅ１０４、および、Ｅ２０１、Ｅ２０２、Ｅ２０３、Ｅ２０４におけるパス制約および変数状態を一行ずつ表示している。これにより、開発者は記号実行の結果を知ることができ、かつ、どのような論理式を用いて等価性を判定したかを知ることができる。そして、これにより、ユーザは、リファクタリングが妥当なものであることを判断できる。【０１０６】
図２０に示す表示例は、記号実行により等価と判定された場合の表示例である。記号実行により非等価と判定された場合には、図２０に示す情報に加えて、反例情報も表示する。反例情報とは、ＳＡＴソルバによって得られる、リファクタリング前の記号実行サマリとリファクタリング後の記号実行サマリとが等価でないような入力の例である。この反例情報を示すことにより、開発者はどのような入力に対してリファクタリング前のソースコードとリファクタリング後のソースコードとが異なる出力をするのかを知ることができる。これにより、不適切なリファクタリングとなっている原因を分析することが可能となる。【０１０７】
本例では、記号実行実施判定Ｓ１０４７の判定で、ソースコード情報である構造グラフ上の構造の差異が認められることから、ソースコードが等価であることを検証するために、記号実行を実施している。ソースコード情報の抽象化を行い、ソースコード情報の縮減を行うことにより、記号実行処理では記号実行における計算量を削減することができる。
【実施例４】
【０１０８】
以下、上記の図５を参照しながら、図２１乃至図２７を用いて本発明の一実施形態に係るソースコード等価性検証装置の処理の具体例について説明する。この例は、図５の記号実行実施判定Ｓ１０４７の処理で、登録されたリファクタリングパターンに該当するリファクタリングが実施されたソースコードにおいて、ソースコード情報である構造グラフの構造が不一致であると判定される例である。【０１０９】
図２１は、リファクタリング前後のソースコードの例を示す図である（その三）。
図２２は、リファクタリング前のソースコードに対応するソースコード情報の例を示す図である（その三）。
図２３は、リファクタリング後のソースコードに対応するソースコード情報の例を示す図である（その三）。
図２４は、正規化されたリファクタリング後のソースコード情報の例を示す図である。
図２５は、抽象化されたソースコード情報の例を示す図である。
図２６は、抽象化された場合における、リファクタリング前ソースコードとリファクタリング後ソースコードに対して記号実行したときの実行木を示した例である。
図２７は、抽象化された場合における、表示部による等価性検証結果の表示例を示した図である。【０１１０】
この例では、ソースコードに対するリファクタリングとして、リファクタリングパターンＰａｒａｍｅｔｅｒｉｚｅｄＭｅｔｈｏｄに基づいてリファクタリングが行われる場合について説明する。リファクタリングパターンＰａｒａｍｅｔｅｒｉｚｅｄＭｅｔｈｏｄは、複数箇所で似た処理をしているソースコードにおいて、その似た処理を関数として抜き出し、複数箇所で似た処理をしていた箇所を抜き出した関数への呼び出しに置き換えて、複数箇所に存在した似たソースコードを共通化するリファクタリングのパターンである。【０１１１】
前記したＥｘｔｒａｃｔＭｅｔｈｏｄでは同一の処理を抜き出すことを想定していたが、ＰａｒａｍｅｔｅｒｉｚｅｄＭｅｔｈｏｄは類似するが同一ではない処理を抜き出すことを想定している点で両者は異なる。ＰａｒａｍｅｔｅｒｉｚｅｄＭｅｔｈｏｄでは、類似はするが同一でない処理の抜き出しを実現するにあたり、抜き出した関数において、処理の差異の種別を示す引数を受取り、その引数に対する条件分岐で差異を実現する。抜き出された箇所では、抜き出した関数を、差異を示す引数を付けて呼び出すことにより、処理の差異を吸収する。【０１１２】
図２１では、リファクタリング前のソースコードＣ００９とリファクタリング後のソースコードＣ０１０が示されている。ソースコードＣ００９は、リファクタリングパターンＰａｒａｍｅｔｅｒｉｚｅｄＭｅｔｈｏｄの適用前のソースコードで、関数ｆｏｏ１は、グローバル変数ａとグローバル変数ｂを加算してグローバル変数ｃに代入し、グローバル変数ｃを引数に関数ｂａｒを呼び出すＣ０１１の部分と、グローバル変数ｃを引数に関数ｑｕｘ１を呼び出すＣ０１２の部分で構成され、関数ｆｏｏ２は、グローバル変数ａとグローバル変数ｂを減算してグローバル変数ｃに代入し、グローバル変数ｃを引数に関数ｂａｒを呼び出すＣ０１３の部分と、グローバル変数ｃを引数に関数ｑｕｘ２を呼び出すＣ０１４の部分で構成される。ソースコードＣ０１０は、リファクタリングパターンＰａｒａｍｅｔｒｉｚｅｄＭｅｔｈｏｄ適用後のソースコードであり、ソースコードＣ００９における関数ｆｏｏ１内の処理の一部であるＣ０１１と、類似した関数ｆｏｏ２内の処理の一部であるＣ０１３の箇所を関数ｂａｚとして抜き出し、抜き出した箇所に対応する位置であるＣ０１５とＣ０１７において関数ｂａｚへの呼び出しに置き換えている。抜き出した関数ｂａｚではＣ０１９に示す処理部分において、関数ｆｏｏ１のＣ０１１と関数ｆｏｏ２のＣ０１３の差異である、グローバル変数ａとグローバル変数ｂへの加算処理と減算処理とを、真偽値を取る引数に対する条件分岐で振り分けることによって対応している。【０１１３】
図２１に示したリファクタリングの例における、図５のリファクタリング前ソースコード入力Ｓ１０１とリファクタリング後ソースコード入力Ｓ１０２について説明する。このリファクタリングの例では、リファクタリング前ソースコード０００１がソースコードＣ００９、リファクタリング後ソースコード０００２がソースコードＣ０１０に対応する。入力部１１００では、ソースコード入力部１１０１によって、リファクタリング前ソースコード０００１とリファクタリング後ソースコード０００２を受け付けて、対応するリファクタリング前ソースコード情報１００１とリファクタリング後ソースコード情報１００２を生成する。【０１１４】
図２１のリファクタリングの例において、ソースコード入力部１１０１がリファクタリング前ソースコード０００１としてソースコードＣ００９を受け付け、字句解析と構文解析を行い、リファクタリング前ソースコード情報１００１として図２２の構造グラフＭ０１７に変換する。また、ソースコード入力部１１０１は、リファクタリング後ソースコード０００２としてソースコードＣ０１０を受け付け、字句解析と構文解析を行い、リファクタリング後ソースコード情報１００２として図２３の構造グラフＭ０１８に変換する。ここで、リファクタリング前ソースコード情報１００１は構造グラフＭ０１７、リファクタリング後ソースコード情報１００２は構造グラフＭ０１８に対応する。【０１１５】
次に、リファクタリングパターンに関する情報を入力するＳ１０３のステップについて説明する。
入力部１１００では、リファクタリングパターン入力部１１０２において、リファクタリングパターン入力情報０００３を受け付けて、リファクタリングパターン情報１００３を生成する。この例では、例えば、リファクタリングパターン入力情報０００３が、リファクタリングパターンＰａｒａｍｅｔｅｒｉｚｅｄＭｅｔｈｏｄを表す文字列“ＰａｒａｍｅｔｅｒｉｚｅｄＭｅｔｈｏｄ”や、画面のメニューでの選択番号の場合に、リファクタリングパターン登録情報１１２０を参照して、内部で、リファクタリングパターンＰａｒａｍｅｔｅｒｉｚｅｄＭｅｔｈｏｄを指し示すコードであるリファクタリングパターン情報１００３を生成する。【０１１６】
次に、図５の変更箇所特定Ｓ１０４１のステップについて説明する。
正規化部１２００の変更箇所特定部１２０１において、リファクタリング前ソースコード情報１００１とリファクタリング後ソースコード情報１００２とリファクタリングパターン情報１００３から、正規化ＤＢ１６０１に登録してある対応する変更箇所特定情報１００７ｂを参照し、ソースコード上のどこを変更したのかを特定し、変更箇所情報１００４を出力する。このリファクタリングパターンＰａｒａｍｅｔｅｒｉｚｅｄＭｅｔｈｏｄの例では、リファクタリングパターンＰａｒａｍｅｔｅｒｉｚｅｄＭｅｔｈｏｄは、リファクタリング後ソースコード情報１００２において関数が増加するという特徴から、リファクタリング前ソースコード情報１００１とリファクタリング後ソースコード情報１００２の関数の宣言を比較し、リファクタリング後ソースコード情報１００２にのみ現れる関数宣言ノードを変更箇所情報として特定する。また、リファクタリング後ソースコード情報１００２にのみ現れる関数を呼び出すノードも変更箇所情報１００４とする。図２２と図２３では、リファクタリング前ソースコード情報１００１の構造グラフＭ０１７とリファクタリング後ソースコード情報１００２の構造グラフＭ０１８の中で、関数を示すｅｎｔｒｙノードを比較し、ノードＭ０１９が指し示すｅｎｔｒｙノードの関数ｂａｚが増えていることから、ノードＭ０１９が変更箇所情報１００４に該当する。さらに、関数ｂａｚを呼び出すノードＭ０２０とＭ０２１も、変更箇所情報１００４に該当する。【０１１７】
次に、図５のソースコード情報正規化Ｓ１０４２のステップについて説明する。正規化部１２００のソースコード正規化部１２０２において、変更箇所情報１００４とリファクタリング前ソースコード情報１００１から、正規化ＤＢ１６０１の中にある対応する正規化情報１００７ａを用いて正規化を行い、リファクタリング前正規化ソースコード情報１００５を生成する。リファクタリング後ソースコード情報１００２も同様に正規化を行い、リファクタリング後正規化ソースコード情報１００６を生成する。リファクタリングパターン情報１００３であるリファクタリングパターンＰａｒａｍｅｔｅｒｉｚｅｄＭｅｔｈｏｄに対応する正規化情報１００７ａによれば、正規化方法は、リファクタリング後ソースコード情報０００２に対して、変更箇所１００４で識別している抜き出した関数を、インライン展開したときのソースコードを表す構造にすることである。リファクタリング後ソースコード情報１００２に対してソースコード正規化部１２０２で正規化を行った例を示すと、図２４のようになる。【０１１８】
図２４における変更箇所は、リファクタリング後ソースコード情報１００２の構造グラフＭ０１８におけるノードＭ０１９とノードＭ０２０とノードＭ０２１であり、これらのノードは、リファクタリングによって抜き出された関数ｂａｚの宣言および呼び出し箇所であるので、その関数ｂａｚを正規化してインライン展開すると、構造グラフＭ０２２のようになる。これがリファクタリング後正規化ソースコード情報１００６となる。リファクタリング前正規化ソースコード情報１００５は、リファクタリングパターンＰａｒａｍｅｔｅｒｉｚｅｄＭｅｔｈｏｄに関して正規化処理が無いため、リファクタリング前ソースコード情報１００１の構造グラフＭ０１７は正規化では何も変更されずに、リファクタリング前正規化ソースコード情報１００５となる。【０１１９】
次に、図５の構造比較Ｓ１０４３のステップについて説明する。
構造比較検証処理部１３００では、リファクタリング前正規化ソースコード情報１００５とリファクタリング後正規化ソースコード情報１００６を受け取り、ソースコード情報の構造の比較を行い、その結果を構造比較結果１００８として生成する。リファクタリングパターンＰａｒａｍｅｔｅｒｉｚｅｄＭｅｔｈｏｄによるリファクタリングを行った図２１の例において、構造比較検証処理部１３００は、リファクタリング前正規化ソースコード情報１００５のグラフＭ０１７とリファクタリング後正規化ソースコード情報１００６のグラフＭ０２２の二つのグラフを比較し、明らかにグラフ構造が異なるため、構造比較結果１００８を、リファクタリング前後のソースコードが構造不一致による非等価と判定する。【０１２０】
次に、図５の記号実行実施判定ステップＳ１０４７について説明する。
記号実行実施判定部１７００は、このリファクタリングの例において、構造比較結果１００８として、ソースコードが非等価と判定されため、記号実行開始指示１００９のコマンドを生成する。【０１２１】
次に、図５のソースコード情報抽象化ステップＳ１０４４について説明する。
記号実行検証処理部１４００は、記号実行開始指示１００９を受け取ると、抽象化部１４０１において、変更箇所情報１００４と抽象化ＤＢ１６０２の抽象化方法を記録した抽象化情報１０１０を用いて、リファクタリング前正規化ソースコード情報１００５とリファクタリング後正規化ソースコード情報１００６の抽象化を行う。抽象化ＤＢ１６０２の抽象化情報１０１０には、リファクタリングパターン情報１００３と変更箇所情報１００４に対応して適切な抽象化手法が記録されている。リファクタリングパターン情報１００３がリファクタリングパターンＰａｒａｍｅｔｅｒｉｚｅｄＭｅｔｈｏｄｅである例では、抽象化ＤＢ１６０２から、リファクタリング前正規化ソースコード情報１００５であるグラフＭ０１７とリファクタリング後正規化ソースコード情報１００６であるグラフＭ０２２を比較して、同じグラフ構造を持つ箇所をすべて削除することを記載した抽象化情報１０１０を取得する。抽象化部１４０１において、リファクタリング前正規化ソースコード情報１００５であるグラフＭ０１７とリファクタリング後正規化ソースコード情報１００６であるグラフＭ０２２に対して、抽象化情報１０１０を適用した結果を示すと、図２５のようになる。リファクタリング前正規化ソースコード情報１００５であるグラフＭ０１７の関数ｆｏｏ１を示すグラフとリファクタリング後正規化ソースコード情報１００６であるグラフＭ０２２の関数ｆｏｏ１を示すグラフを比較すると、関数ｂａｒを呼び出すグラフＭ０１７のノードＭ０２３とグラフＭ０２２のノードＭ０２５が一致し、関数ｑｕｘを呼び出すグラフＭ０１７のノードＭ０２４とグラフＭ０２２のノードＭ０２６が一致するため、これらのノードを削除し、関数ｆｏｏ２に関しても同様に同じグラフ構造を持つ箇所をすべて削除すると、リファクタリング前正規化ソースコード情報１００５であるグラフＭ０１７はグラフＭ０２７のように抽象化され、リファクタリング後正規化ソースコード情報１００６であるグラフＭ０２２はグラフＭ０２８のように抽象化される。グラフＭ０２７はリファクタリング前抽象化ソースコード情報１４０３に、グラフＭ０２８はリファクタリング後抽象化ソースコード情報１４０４に該当する。ここで、この抽象化は、グラフＭ０１７、Ｍ０２２の各々において、ノード数が減少しており、各々のグラフが記号実行されたときには、その計算量が減ることに留意する。【０１２２】
次に、図５の記号実行Ｓ１０４５のステップについて説明する。
記号実行検証処理部１４００では、抽象化部１４０１において抽象化を行った後、リファクタリング前抽象化ソースコード情報１４０３とリファクタリング後抽象化ソースコード情報１４０４のそれぞれに対して、記号実行部１４０２において、記号実行を実施し、その結果としてリファクタリング前記号実行結果１４０５とリファクタリング後記号実行結果１４０６を生成する。このリファクタリングの例において、記号実行部１４０２にて、前記リファクタリング前抽象化ソースコード情報１４０３とリファクタリング後抽象化ソースコード情報１４０４のそれぞれの関数ｆｏｏ１を記号実行した結果は、図２６に示されるようになる。このリファクタリングの例では、リファクタリング前抽象化ソースコード情報１４０３は、図２５の構造グラフＭ０２７に該当する。構造グラフＭ０２７に対して記号実行を行うと、図２６における実行木Ｅ３００ができる。また、図２６の実行木Ｅ３００における記号実行サマリであるＥ３０１が、リファクタリング前抽象化ソースコード情報１４０３に対するリファクタリング前記号実行結果１４０５となる。リファクタリング後抽象化ソースコード情報１４０４は、図２１のリファクタリングの例では、図２５の構造グラフＭ０２８に該当し、構造グラフＭ０２８に対して記号実行を行うと、図２６における実行木Ｅ４００ができる。また、図２６の実行木Ｅ４００における記号実行サマリであるＥ４０１，Ｅ４０２が、リファクタリング後抽象化ソースコード情報１４０４に対するリファクタリング後記号実行結果１４０６となる。関数ｆｏｏ２に関しても、記号実行部１４０２ではリファクタリング前抽象化ソースコード情報１４０３と、リファクタリング後抽象化ソースコード情報１４０４に対して、それぞれ同様に記号実行を行う。リファクタリング前抽象化ソースコード情報１４０３に対して実行木Ｅ３５０を生成し、実行木Ｅ３５０における記号実行サマリであるＥ３５１が、リファクタリング前記号実行結果１４０５となる。リファクタリング後抽象化ソースコード情報１４０４に対しては実行木Ｅ４５０を生成し、その記号実行サマリであるＥ４５１およびＥ４５２がリファクタリング後記号実行結果１４０６となる。【０１２３】
次に、図５の記号実行結果比較Ｓ１０４６のステップについて説明する。
記号実行検証処理部１４００の記号実行結果比較部１４０７では、リファクタリング前記号実行結果１４０５とリファクタリング後記号実行結果１４０６の比較を行い、リファクタリング前後のソースコードが等価か非等価かの判定を行う。図２１のリファクタリングの例では、関数ｆｏｏ１に対するリファクタリング前記号実行結果１４０５は、Ｅ３０１であり、リファクタリング後記号実行結果１４０６は、Ｅ４０１，Ｅ４０２である。これらの二つの記号実行結果をＳＡＴソルバを用いて比較することにより、記号実行結果比較部１４０７は、関数ｆｏｏ１についてソースコードが等価と判定する。この例においては、Ｅ４０２のパス制約が矛盾式であるためＥ４０２が存在しないと考えても良いこと、および、Ｅ３０１とＥ４０１の変数状態が一致し、パス制約がどちらも恒真式であることからも、記号実行サマリが等価であることが分かる。このとき、リファクタリング前の記号実行木Ｅ３００とリファクタリング後の記号実行木Ｅ４００の間には構造上の差異が生じているが、記号実行の最終的な記号実行サマリが論理的に等価であるため。ソースコードを等価と判定する。記号実行結果比較部１４０７では、関数ｆｏｏ２についても同様にして比較を行い、等価と判定する。関数ｆｏｏ２に対する記号実行サマリが等価であることは、Ｅ４５１のパス制約が矛盾式であるためＥ４５１が存在しないと考えても良いこと、および、Ｅ３５１とＥ４５２の変数状態が一致し、パス制約がどちらも恒等式であることからも分かる。記号実行比較部は判定した結果を出力部１５００に送る。【０１２４】
次に、図５の等価非等価出力Ｓ１０５のステップについて説明する。
出力部１５００は、記号実行結果比較部１４０７が、ソースコードが等価と判定した結果を受けて、検証結果０００４として、ソースコードが等価であることを出力する。出力部１５００が出力する検証結果０００４の例を図２７に示す。【０１２５】
図２７に示す表示例には、判定結果Ｐ３００として記号実行により判定したこと、および、その結果等価と判定されたことを示している。また、構造比較に用いた構造グラフデータとして、正規化を実施した後のリファクタリング前正規化ソースコード情報１００５の構造グラフＰ３１１とリファクタリング後正規化ソースコード情報１００６の構造グラフＰ３１２を表示している。構造グラフＰ３１１とＰ３１２においては、構造比較の結果、相違と判断されたノードに対して色を変化させることにより、ソースコード中のどの部分が構造比較の結果、等価でないと判断されたのかが分かるようになっている。また、構造グラフを見ることにより、どのように正規化が実施されたのかが分かるようになっている。【０１２６】
図２７では、さらに、リファクタリング適用情報Ｐ３２０として、適用された正規化リファクタリングパターンである「Ｐａｒａｍｅｔｅｒｉｚｅｄ  Ｍｅｔｈｏｄ」と、対象関数名の情報としてｂａｚを、適用箇所情報としてリファクタリング適用前後それぞれについてリファクタリングが適用されているファイル名と行番号を表示している。これにより、開発者は等価性検証装置が処理したリファクタリングパターンおよび適用箇所が意図した結果と一致しているかどうかを確認することができる。【０１２７】
図２７に示す表示例では、記号実行による判定に特有な情報として、リファクタリング前のソースコードに対する記号実行サマリ情報Ｐ３３０、および、リファクタリング後のソースコードに対する記号実行サマリ情報Ｐ３３１を表示している。記号実行サマリ情報Ｐ３３０およびＰ３３１では、それぞれＥ３０１、Ｅ３５１、および、Ｅ４０１、Ｅ４０２、Ｅ４５１、Ｅ４５２におけるパス制約および変数状態を一行ずつ表示している。これにより、開発者は記号実行の結果を知ることができ、かつ、どのような論理式を用いて等価性を判定したかを知ることができる。そして、これにより、ユーザは、リファクタリングが妥当なものであることを判断できる。【０１２８】
図２７に示す表示例は、記号実行により等価と判定された場合の表示例である。記号実行により非等価と判定された場合には、図２７に示す情報に加えて、反例情報も表示する。反例情報とは、ＳＡＴソルバによって得られる、リファクタリング前の記号実行サマリとリファクタリング後の記号実行サマリとが等価でないような入力の例である。この反例情報を示すことにより、開発者はどのような入力に対してリファクタリング前のソースコードとリファクタリング後のソースコードとが異なる出力をするのかを知ることができる。これにより、不適切なリファクタリングとなっている原因を分析することが可能となる。【０１２９】
本例では、Ｓ１０４７の判定で、ソースコード情報である構造グラフ上の構造の差異を生じるため、ソースコードが等価であることを検証するために、記号実行する必要があるが、ソースコード情報の抽象化を行い、ソースコード情報の縮減を行うために、記号実行における計算量を削減することができる。
【符号の説明】
【０１３０】
０００１…リファクタリング前ソースコード
０００２…リファクタリング後ソースコード
０００３…リファクタリングパターン
０００４…検証結果
１０１…ＣＰＵ
１０２…主記憶装置
１０３…ネットワークＩ／Ｆ
１０４…グラフィックＩ／Ｆ
１０５…入出力Ｉ／Ｆ
１０６…補助記憶装置Ｉ／Ｆ
１１０…制御部
１２０…表示・出力装置
１３０…入力装置
１３１…キーボード
１３２…マウス
１４１…ＨＤＤ（Hard Disk Drive）
１４２…ＤＶＤドライブ装置
１５０…外部ネットワーク
１６０…外部計算機
２００…ソースコード等価性検証プログラム
１０００…ソースコード等価性検証装置
１１００…入力部
１１２０…リファクタリングパターン登録情報
１２００…正規化部
１３００…構造比較検証処理部
１４００…記号実行検証処理部
１５００…出力部
１６００…記憶部
１６０１…正規化データベース
１６０２…抽象化データベース
１６０３…リファクタリング前／後ソースコード記憶領域
１６０４…リファクタリング前／後ソースコード情報記憶領域
１６０５…リファクタリング前／後記号実行結果記憶領域
１６０６…検証結果記憶領域
１７００…記号実行実施判定部
１００１…リファクタリング前ソースコード情報
１００２…リファクタリング後ソースコード情報
１００３…リファクタリングパターン情報
１００４…変更箇所情報
１００５…リファクタリング前正規化ソースコード情報
１００６…リファクタリング後正規化ソースコード情報
１００７ａ…正規化情報
１００７ｂ…変更箇所特定情報
１００８…構造比較結果
１００９…記号実行開始指示
１０１０…抽象化情報
１１０１…ソースコード入力部
１１０２…リファクタリングパターン入力部
１２０１…変更箇所特定部
１２０２…ソースコード正規化部
１４０１…抽象化部
１４０２…記号実行部
１４０３…リファクタリング前抽象化ソースコード情報
１４０４…リファクタリング後抽象化ソースコード情報
１４０５…リファクタリング前記号実行結果
１４０６…リファクタリング後記号実行結果
１４０７…記号実行結果比較部
１６０１…正規化データベース
１６０２…抽象化データベース
Ｓ１０１…リファクタリング前ソースコード入力ステップ
Ｓ１０２…リファクタリング後ソースコード入力ステップ
Ｓ１０３…リファクタリングパターン入力情報入力ステップ
Ｓ１０４１…変更箇所特定ステップ
Ｓ１０４２…ソースコード正規化ステップ
Ｓ１０４３…構造比較ステップ
Ｓ１０４４…ソースコード抽象化ステップ
Ｓ１０４５…記号実行ステップ
Ｓ１０４６…記号実行結果比較ステップ
Ｓ１０４７…記号実行実施判定ステップ
Ｓ１０５…等価非等価出力ステップ
Ｃ００１…リファクタリング適用前のソースコード
Ｃ００２…リファクタリング適用後のソースコード
Ｃ００３…リファクタリング適用前のソースコード
Ｃ００４…リファクタリング適用後のソースコード
Ｃ００５…Ｃ００３における関数ｆｏｏ内のソースコードの前半部
Ｃ００６…Ｃ００３における関数ｆｏｏ内のソースコードの後半部
Ｃ００７…Ｃ００４における関数ｆｏｏ内のソースコードの前半部
Ｃ００８…Ｃ００４における関数ｆｏｏ内のソースコードの後半部
Ｃ００９…リファクタリング適用前のソースコード
Ｃ０１０…リファクタリング適用後のソースコード
Ｃ０１１…Ｃ００９における関数ｆｏｏ１内のソースコードの前半部
Ｃ０１２…Ｃ００９における関数ｆｏｏ１内のソースコードの後半部
Ｃ０１３…Ｃ００９における関数ｆｏｏ２内のソースコードの前半部
Ｃ０１４…Ｃ００９における関数ｆｏｏ２内のソースコードの後半部
Ｃ０１５…Ｃ０１０における関数ｆｏｏ１内のソースコードの前半部
Ｃ０１６…Ｃ０１０における関数ｆｏｏ１内のソースコードの後半部
Ｃ０１７…Ｃ０１０における関数ｆｏｏ２内のソースコードの前半部
Ｃ０１８…Ｃ０１０における関数ｆｏｏ２内のソースコードの後半部
Ｃ０１９…Ｃ０１０における関数ｂａｚ内のソースコードの前半部
Ｃ０２０…Ｃ０１０における関数ｂａｚ内のソースコードの後半部
Ｅ００１…記号実行を説明するためのソースコード
Ｅ００２…ソースコードの構造グラフ
Ｅ００３…構造グラフにおける関数ｆｏｏのエントリーを示すノード
Ｅ００４…構造グラフにおけるＥ００３の遷移先のノード
Ｅ００５…構造グラフにおけるＥ００４の遷移先のノード
Ｅ００６…構造グラフにおけるＥ００５の分岐先のノード
Ｅ００７…構造グラフにおけるＥ００５の分岐先のノード
Ｅ００８…構造グラフにおけるＥ００６と７の遷移先のノード
Ｅ００９ａ…構造グラフにおけるＥ００８の分岐先のノード
Ｅ００９ｂ…構造グラフにおけるＥ００８の分岐先のノード
Ｅ０１０…Ｅ００３に対応する実行木ノード
Ｅ０１０ａ…Ｅ０１０のパス制約
Ｅ０１０ｂ…Ｅ０１０の変数状態
Ｅ０１１…Ｅ００４に対応する実行木ノード
Ｅ０１１ａ…Ｅ０１１のパス制約
Ｅ０１１ｂ…Ｅ０１１の変数状態
Ｅ０１２…Ｅ００６に対応する実行木ノード
Ｅ０１２ａ…Ｅ０１２のパス制約
Ｅ０１２ｂ…Ｅ０１２の変数状態
Ｅ０１３…Ｅ００７に対応する実行木ノード
Ｅ０１３ａ…Ｅ０１３のパス制約
Ｅ０１３ｂ…Ｅ０１３の変数状態
Ｅ０１４…Ｅ００６を経由した場合のＥ００９に対応する実行木ノード
Ｅ０１５…Ｅ００６を経由した場合のＥ００９ａに対応する実行木ノード
Ｅ０１６…Ｅ００７を経由した場合のＥ００９に対応する実行木ノード
Ｅ０１７…Ｅ００７を経由した場合のＥ００９ａに対応する実行木ノード
Ｅ０２０…記号実行の実行木
Ｅ１００…リファクタリング適用前のソースコード情報の記号実行の実行木
Ｅ１０１…Ｅ１００における記号実行サマリに含まれるノード
Ｅ１０２…Ｅ１００における記号実行サマリに含まれるノード
Ｅ１０３…Ｅ１００における記号実行サマリに含まれるノード
Ｅ１０４…Ｅ１００における記号実行サマリに含まれるノード
Ｅ２００…リファクタリング適用後のソースコード情報の記号実行の実行木
Ｅ２０１…Ｅ２００における記号実行サマリに含まれるノード
Ｅ２０２…Ｅ２００における記号実行サマリに含まれるノード
Ｅ２０３…Ｅ２００における記号実行サマリに含まれるノード
Ｅ２０４…Ｅ２００における記号実行サマリに含まれるノード
Ｅ３００…リファクタリング適用前の関数ｆｏｏ１の抽象化ソースコード情報に対する記号実行の実行木
Ｅ３０１…Ｅ３００における記号実行サマリに含まれるノード
Ｅ３５０…リファクタリング適用前の関数ｆｏｏ２の抽象化ソースコード情報に対する記号実行の実行木
Ｅ３５１…Ｅ３５０における記号実行サマリに含まれるノード
Ｅ４００…リファクタリング適用後の関数ｆｏｏ１の抽象化ソースコード情報に対する記号実行の実行木
Ｅ４０１…Ｅ４００における記号実行サマリに含まれるノード
Ｅ４０２…Ｅ４００における記号実行サマリに含まれるノード
Ｅ４５０…リファクタリング適用後の関数ｆｏｏ２の抽象化ソースコード情報に対する記号実行の実行木
Ｅ４５１…Ｅ４５０における記号実行サマリに含まれるノード
Ｅ４５２…Ｅ４５０における記号実行サマリに含まれるノード
Ｍ００１…リファクタリング適用前のソースコードの構造グラフ
Ｍ００２…リファクタリング適用後のソースコードの構造グラフ
Ｍ００３…リファクタリングによって追加された関数を示すノード
Ｍ００４…リファクタリングによって追加された関数を呼び出すノード
Ｍ００５…リファクタリング適用前のソースコード情報の正規化済みの構造グラフ
Ｍ００６…リファクタリング適用後のソースコード情報の正規化済みの構造グラフ
Ｍ００７…正規化によって関数が展開された結果のリンク
Ｍ００８…リファクタリング適用前のソースコードの構造グラフ
Ｍ００９…リファクタリング適用後のソースコードの構造グラフ
Ｍ０１０…Ｍ００８における関数ｖａｒを示すノード
Ｍ０１１…Ｍ００８における関数ｖａｒを呼び出すノード
Ｍ０１２…Ｍ００９における関数ｖａｒを示すノード
Ｍ０１３…Ｍ００９における関数ｖａｒを呼び出すノード
Ｍ０１４…リファクタリング適用前のソースコード情報の抽象化済みの構造グラフ
Ｍ０１５…リファクタリング適用後のソースコード情報の抽象化済みの構造グラフ
Ｍ０１６…Ｍ０１４における抽象化された箇所を示すノード
Ｍ０１７…リファクタリング適用前のソースコードの構造グラフ
Ｍ０１８…リファクタリング適用後のソースコードの構造グラフ
Ｍ０１９…リファクタリングによって追加された関数を示すノード
Ｍ０２０…リファクタリングによって追加された関数を呼び出すノード
Ｍ０２１…リファクタリングによって追加された関数を呼び出すノード
Ｍ０２２…リファクタリング適用後のソースコード情報の正規化済みの構造グラフ
Ｍ０２３…Ｍ０１７における関数ｂａｒを呼び出すノード
Ｍ０２４…Ｍ０１７における関数ｑｕｘ１を呼び出すノード
Ｍ０２５…Ｍ０２２における関数ｂａｒを呼び出すノード
Ｍ０２６…Ｍ０２２における関数ｑｕｘ１を呼び出すノード
Ｐ１００…Ｃ００１とＣ００２に対する等価性検証の検証結果表示における判定結果
Ｐ１１１…Ｃ００１とＣ００２に対する等価性検証の検証結果表示におけるＣ００１の正規化済みの構造グラフ
Ｐ１１２…Ｃ００１とＣ００２に対する等価性検証の検証結果表示におけるＣ００２の正規化済みの構造グラフ
Ｐ１２０…Ｃ００１とＣ００２に対する等価性検証の検証結果表示におけるリファクタリング適用情報
Ｐ２００…Ｃ００３とＣ００４に対する等価性検証の検証結果表示における判定結果
Ｐ２１１…Ｃ００３とＣ００４に対する等価性検証の検証結果表示におけるＣ００３の正規化済みの構造グラフ
Ｐ２１２…Ｃ００３とＣ００４に対する等価性検証の検証結果表示におけるＣ００４の正規化済みの構造グラフ
Ｐ２２０…Ｃ００３とＣ００４に対する等価性検証の検証結果表示におけるリファクタリング適用情報
Ｐ２３０…Ｃ００３とＣ００４に対する等価性検証の検証結果表示におけるＣ００３の記号実行サマリ表示
Ｐ２３１…Ｃ００３とＣ００４に対する等価性検証の検証結果表示におけるＣ００４の記号実行サマリ表示
Ｐ３００…Ｃ００９とＣ０１０に対する等価性検証の検証結果表示における判定結果
Ｐ３１１…Ｃ００９とＣ０１０に対する等価性検証の検証結果表示におけるＣ００９の正規化済みの構造グラフ
Ｐ３１２…Ｃ００９とＣ０１０に対する等価性検証の検証結果表示におけるＣ０１０の正規化済みの構造グラフ
Ｐ３２０…Ｃ００９とＣ０１０に対する等価性検証の検証結果表示におけるリファクタリング適用情報
Ｐ３３０…Ｃ００９とＣ０１０に対する等価性検証の検証結果表示におけるＣ００９の記号実行サマリ表示
Ｐ３３１…Ｃ００９とＣ０１０に対する等価性検証の検証結果表示におけるＣ０１０の記号実行サマリ表示
【図１】
0006001791.tif 000002
【図２】
0006001791.tif 000003
【図３】
0006001791.tif 000004
【図４】
0006001791.tif 000005
【図５】
0006001791.tif 000006
【図６】
0006001791.tif 000007
【図７】
0006001791.tif 000008
【図８】
0006001791.tif 000009
【図９】
0006001791.tif 000010
【図１０】
0006001791.tif 000011
【図１１】
0006001791.tif 000012
【図１２】
0006001791.tif 000013
【図１３】
0006001791.tif 000014
【図１４】
0006001791.tif 000015
【図１５】
0006001791.tif 000016
【図１６】
0006001791.tif 000017
【図１７】
0006001791.tif 000018
【図１８】
0006001791.tif 000019
【図１９】
0006001791.tif 000020
【図２０】
0006001791.tif 000021
【図２１】
0006001791.tif 000022
【図２２】
0006001791.tif 000023
【図２３】
0006001791.tif 000024
【図２４】
0006001791.tif 000025
【図２５】
0006001791.tif 000026
【図２６】
0006001791.tif 000027
【図２７】
0006001791.tif 000028