(57)【要約】 【課題】  入力値に対する出力値の変更がされていないかを漏れなく検証することを支援するプログラム生成装置およびプログラム検証装置１を提供する。【解決手段】  入力値演算手段１６は、ソースコードに含まれる条件式が真になる入力値および偽になる入力値を演算する。プログラム生成手段は、演算された真および偽入力値に基づく出力値を出力させるテストプログラムを生成する。【選択図】      図１
2007041804.tif 000002
【特許請求の範囲】
【請求項１】
入力される入力値に基づいて出力値を出力させる検証対象プログラムのソースコードに含まれる条件式であって、その条件式の真偽によって処理が分岐する条件式が真および偽になる入力値を演算する入力値演算手段と、
検証対象プログラムを用いて、入力値演算手段によって演算される入力値に基づく出力値を出力させるテストプログラムを生成するプログラム生成手段とを含むことを特徴とするプログラム生成装置。
【請求項２】
入力される入力値に基づいて、出力値を出力させる複数の検証対象プログラムの入力値に対する出力値が同一であるか否かを検証するプログラム検証装置であって、
各検証対象プログラムのソースコードに含まれる条件式であって、その条件式の真偽によって処理が分岐する条件式が真および偽になる入力値を、検証対象プログラム毎に演算する入力値演算手段と、
入力値演算手段によって演算された入力値に基づいて、この入力値の演算に用いられた各検証対象プログラムを実行し、出力値を出力するプログラム実行手段と、
プログラム実行手段によって出力される各検証対象プログラムの出力値をそれぞれ比較する出力値比較手段と、
前記出力比較手段の比較結果に基づいて、各検証対象プログラムの出力値が同一であるか否かを検証する検証手段とを含むことを特徴とするプログラム検証装置。
【請求項３】
請求項２記載のプログラム検証装置を制御するための検証プログラム。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、内容が変更されたプログラムの不具合を検証する装置に関する。
【背景技術】
【０００２】
近年、ソフトウェア開発において、ソフトウェアのメンテナンス性を維持および向上する目的で、ソフトウェアの機能を変更せずに、たとえば入力値に対する出力値を変更せずに、ソースコードを改善するリファクタリングが実施されている。このリファクタリングでは、ソースコード書換時の誤記などによって、ソフトウェアの機能が変更されている場合があり、このようなソフトウェアの機能が変更されていないかを検証する必要がある。
【０００３】
従来では、リファクタリング前後でプログラムの一部を構成するモジュールの機能が変更されていないか、つまり入力値に対する出力値の同一性が損なわれていないかを検証するための検証テストとして、様々な方法が用いられている。その代表的テストとして、リファクタリング前後でモジュールを擬似的に実行して出力値を演算し、演算される出力値に基づいて、利用者が入力値に対する出力値の同一性を検証することが挙げられる。このような方法では、モジュールを擬似的に実行させるためのテストプログラムを生成する必要がある。このテストプログラムは、プログラマによって生成されている。利用者は、テストプログラムをリファクタリング後に生成されたモジュールに対して実行することによって、入力値に対する出力値に同一性について検証を行っている。
【０００４】
また従来の技術のモジュール試験支援装置は、リファクタリング後のモジュールの入力値に対する出力値の検証を支援するためのテストプログラムを生成可能な装置である。モジュール試験支援装置によって生成されるテストプログラムを実行すると、利用者にモジュールに必要な入力値を促し、入力される入力値に基づいて出力値を出力する。この出力値にも基づいて、モジュールの機能が変更されて、入力値に対する出力値が変更していないかを検証することができる（特許文献１参照）。
【０００５】
【特許文献１】特開２０００−１０９６４４号公報
【発明の開示】
【発明が解決しようとする課題】
【０００６】
従来のように、テストプログラムを生成する場合、モジュール毎にテストプログラムを生成される。それ故、プログラマが複数のモジュールを作成することに加えて、各モジュールに対応するテストプログラムを生成することも必要になり、プログラマの労力の負担が大きくなる。またプログラマは、想定し得る様々な入力値について検証可能なテストプログラムを生成する。しかしながら、これらの入力値によって、プログラムのすべての処理経路を網羅しているといえず、入力値に対する出力値の変更がされていないかを漏れなく検証可能なテストプログラムと言えない。したがって前記テストプログラムによって、すべてのバグを漏れなく検出することが困難であり、この検証結果に基づいて、プログラムのすべてのバグを修正することが困難である。
【０００７】
従来の技術のモジュール試験支援装置は、各モジュールに基づいてテストプログラムを生成する。したがってプログラマがテストプログラムを生成する必要がなく、プログラマの労力の負担を軽減することができる。しかしながらテストプログラムにおいて、利用者が入力値を入力するので、この装置についても、すべての処理経路が網羅されている検証であるとは言えない。モジュール試験支援装置で生成されるテストプログラムも、入力値に対する出力値の変更がされていないかを漏れなく検証するテストプログラムと言えない。したがって前記テストプログラムによって、すべてのバグを漏れなく検出することが困難であり、この検証結果に基づいて、プログラムのすべてのバグを修正することが困難である。
【０００８】
本発明の目的は、入力値に対する出力値が変更されていないかを漏れなく検証することを支援するプログラム生成装置およびプログラム検証装置を提供することである。
【課題を解決するための手段】
【０００９】
本発明は、入力される入力値に基づいて出力値を出力させる検証対象プログラムのソースコードに含まれる条件式であって、その条件式の真偽によって処理が分岐する条件式が真および偽になる入力値を演算する入力値演算手段と、
検証対象プログラムを用いて、入力値演算手段によって演算される入力値に基づく出力値を出力させるテストプログラムを生成するプログラム生成手段とを含むことを特徴とするプログラム生成装置である。
【００１０】
また本発明は、入力される入力値に基づいて、出力値を出力させる複数の検証対象プログラムの入力値に対する出力値が同一であるか否かを検証するプログラム検証装置であって、
各検証対象プログラムのソースコードに含まれる条件式であって、その条件式の真偽によって処理が分岐する条件式が真および偽になる入力値を、検証対象プログラム毎に演算する入力値演算手段と、
入力値演算手段によって演算された入力値に基づいて、この入力値の演算に用いられた各検証対象プログラムを実行し、出力値を出力するプログラム実行手段と、
プログラム実行手段によって出力される各検証対象プログラムの出力値をそれぞれ比較する出力値比較手段と、
前記出力比較手段の比較結果に基づいて、各検証対象プログラムの出力値が同一であるか否かを検証する検証手段とを含むことを特徴とするプログラム検証装置である。
また本発明は、前記プログラム検証装置を制御するための検証プログラムである。
【発明の効果】
【００１１】
本発明によれば、入力値演算手段によって、ソースコードに含まれる条件式が真になる入力値（以下、「真入力値」という場合がある）および偽になる入力値（以下、「偽入力値」という場合がある）を演算する。プログラム生成手段は、真および偽入力値に基づく出力値を出力させるテストプログラムを生成する。テストプログラムを実行することによって、真および偽入力値に基づいて出力される出力値を演算できる。複数の検証対象プログラムについて、同様にテストプログラムを生成し実行することによって、各検証対象プログラムの真および偽入力値ならびにこれらの入力値に基づく出力値を演算できる。このように演算された各検証対象プログラムの出力値を比較することによって、各検証対象プログラムの真および偽入力値に基づく出力値が相互に同一であるか否かを容易に検証できる。このように出力値の同一性を容易に検証できるので、たとえばリファクタリングによって変更された変更後のプログラムおよび変更前のプログラムの入力値に対する出力値の同一性を検証できる。すべての条件式の真および偽入力値を演算することによって、各検証対象プログラムで辿り得るすべての処理経路（フロー）について検証することができ、また出力し得るすべての出力値を検証できる。これによって漏れのない検証を実現できる。このような漏れのない検証結果に基づいて、利用者は、変更後のプログラムに含まれるバグを漏れなく検出し、バグを容易に修正できる。
【００１２】
本発明によれば、入力値演算手段によって、ソースコードに含まれる条件式が真になる真入力値および偽になる偽入力値を演算する。プログラム実行手段は、各真および偽入力値に基づいて、これら入力値が演算された検証対象プログラムを実行し、真および偽入力値に基づく出力値を出力する。出力値比較手段は、プログラム実行手段によって出力された各検証対象プログラムの出力値を相互に比較する。検証手段は、出力値比較手段の比較結果に基づいて、各検証対象プログラムの真および偽入力値に基づく出力値が同一であるか否かを検証する。真および偽入力値に基づく出力値が同一であるか否かを検証することによって、たとえばリファクタリングによって変更された変更後のプログラムおよび変更前のプログラムの入力値に対する出力値の同一性を利用者が検証する手間を省くことができる。検証について人の手が介在しないので、利用者の検証漏れを防ぐことができる。またすべての条件式の真および偽入力値を演算することによって、各検証対象プログラムで辿り得るすべての処理経路（フロー）について検証することができ、また出力し得るすべての出力値を検証できる。これによって漏れのない検証を実現できる。このような漏れのない検証結果に基づいて、変更後のプログラムに含まれるバグを漏れなく検出し、利用者が漏れなくバグを修正することを促進できる。
【００１３】
本発明によれば、各検証対象プログラムの真および偽出力値が相互に同一であるか否かを容易に検証できる装置を実現できる。
【発明を実施するための最良の形態】
【００１４】
以下、図面を参照しながら本発明を実施するための形態を、複数の形態について説明する。各形態で先行する形態で説明している事項に対応している部分には同一の参照符を付し、重複する説明を略する場合がある。構成の一部のみを説明している場合、構成の他の部分は、先行して説明している形態と同様とする。また実施の各形態で具体的に説明している部分の組合わせばかりではなく、特に組合わせに支障が生じなければ、実施の形態同士を部分的に組合わせることも可能である。
【００１５】
図１は、本実施の形態のプログラム検証装置１の機能をブロック毎に分けて示すブロック図である。プログラム検証装置１は、入力値に基づいて出力値を出力する複数の検証対象のプログラムの機能の同一性を検証する装置である。具体的には、プログラム検証装置１は、検証対象のプログラムの入力値に対する出力値が同一であるか否かを検証する装置である。プログラム検証装置１は、たとえばリファクタリング前後のプログラムの入力値に対する出力値が同一であるか否かを検証する装置である。プログラム検証装置１は、リファクタリング前後のプログラムを記憶させ、前述のような検証をするための検証プログラムを実行すると、各プログラムの入力値に対する出力値の同一性を検証する。
【００１６】
以下では、Ｃ言語に基づくプログラムの一部を構成するモジュールの検証について説明している。ただしＣ言語に基づくプログラムおよびモジュールに限定されず、ＦＯＲＴＲＡＮ，ＪＡＶＡ(登録商標)，Ｃ＋＋などの手続き型言語およびオブジェクト指向型言語に基づくプログラムおよびモジュールであってもよく、その言語は限定されない。プログラム検証装置１は、たとえばパーソナルコンピュータである。プログラム検証装置１は、装置本体２、記憶部３、入力部４および出力部５を含む。装置本体２は、たとえば中央演算処理装置（Central Processing Unit：略称ＣＰＵ）によって構成される。装置本体２は、記憶部３、入力部４および出力部５に電気的に接続される。装置本体２は、出力抽出部７、識別番号付加部８、分岐条件抽出部９、処理経路抽出部１０、入力変数検索部１１、テスト入力値生成部１２、テスト生成部１３、テスト実行部１４および出力値比較検証部１５を含む。
【００１７】
出力抽出部７は、識別番号付加部８およびテスト生成部１３に電気的に接続される。出力抽出部７は、ソースコードに基づいて、モジュール情報を抽出する機能を有する。モジュール情報は、検証対象のモジュール（以下、「検証対象モジュール」と称する場合がある）がこれ以外のモジュール（以下、「外部モジュール」と称する場合がある）に対して影響を与える関数、および引数などの有無を示す情報である。モジュール情報には、４つの情報が含まれる。４つの情報は、（１）モジュールに含まれる関数の有無、（２）モジュール内で値が変化する変数であって、引数にて参照渡しされる変数の有無、（３）グローバル変数の有無、および（４）検証対象モジュールから呼び出される外部モジュールに存在する関数（以下、「外部関数」と称する）の有無の情報である。これらの関数および変数は、検証対象モジュールでその値が変化すると、外部モジュールでもその値が維持されるために、これらの情報を抽出している。
【００１８】
識別番号付加部８は、テスト生成部１３に電気的に接続される。識別番号付加部８は、ソースコードに基づいて、外部関数を抽出し、この外部関数に識別番号を付与する機能を有する。さらに識別番号付加部８は、この付与した識別番号を外部関数の引数に加える機能を有する。識別番号付加部８は、互いの同一の外部関数であっても、ソースコードにおいて異なる位置に記述された外部関数に対して、異なる識別番号を付与する。
【００１９】
分岐条件抽出部９は、処理経路抽出部１０および入力変数検索部１１に電気的に接続される。分岐条件抽出部９は、ソースコードに基づいて、モジュールの処理経路を分岐させる分岐点およびその分岐させる分岐条件を抽出する機能を有する。処理経路は、各文を実行する順番を示すもの、いわゆるフローである。分岐条件抽出部９は、具体的には、ｉｆ文およびｓｗｉｃｔｈ文などの条件文に基づく分岐点および前記条件文の条件式を抽出する機能を有する。処理経路抽出部１０は、入力変数検索部１１に電気的に接続される。処理経路抽出部１０は、ソースコードに基づいて、モジュールにおいて、分岐点によって派生するすべての処理経路を抽出する機能を有する。
【００２０】
入力変数検索部１１は、テスト入力値生成部１２に電気的に接続される。入力変数検索部１１は、ソースコード、分岐条件抽出部９および処理経路抽出部１０で抽出される情報に基づいて、検証対象モジュールに入力すべき変数および外部関数（以下、「入力変数」と称する場合がある）、ならびにこの入力変数に入力すべき入力値（以下、「変数入力値」と称する場合がある）を演算するために必要な条件を検索する機能を有する。テスト入力値生成部１２は、テスト生成部１３に電気的に接続される。テスト入力値生成部１２は、入力変数検索部１１で探索される変数および条件に基づいて、変数入力値を演算する機能を有する。
【００２１】
テスト生成部１３は、テスト実行部１４に電気的に接続される。テスト生成部１３は、ソースコード、モジュール情報、識別番号、入力変数および変数入力値に基づいて、検証対象モジュールを模擬的に実行しテストするためのテストプログラムを生成する機能を有する。テストプログラムは、各変数入力値に基づく出力値を演算させ出力させるプログラムである。
【００２２】
テスト実行部１４は、出力値比較検証部１５に電気的に接続される。テスト実行部１４は、テスト生成部１３で生成されるテストプログラムを実行し、各検証対象モジュールの出力値を演算する機能を有する。出力値比較検証部１５は、テスト実行部１４で出力される各検証対象モジュールの出力値を比較し、同一の変数入力値に対して異なる出力値が演算された変数入力値、およびその出力値などの情報（以下、「検証結果」と称する場合がある）を抽出する機能を有する。さらに出力値比較検証部１５は、抽出された検証結果を出力部５に出力する機能を有する。
【００２３】
記憶部３は、複数の検証対象モジュールのソースコード、モジュール情報、条件式、処理経路、変数入力値、出力値、検証結果などを記憶する機能を有する。各構成部は、記憶部３に記憶されるソースコードに基づいて、演算などを行う。以下、特に記載がなければ、各構成部が各種情報を記憶させる構成部は、記憶部３である。入力部４は、利用者が入力などの操作をすることによって、装置本体２に命令を与えるために設けられる。入力部４は、たとえばキーボードである。出力部５は、変数入力値に基づく出力値および検証結果などを表示または印刷などして、利用者に前記出力値および検証結果を報知する機能を有する。出力部５は、たとえばディスプレイなどの表示部およびプリンタなどの印刷装置である。
【００２４】
プログラム検証装置１において、分岐条件抽出部９、処理経路抽出部１０、入力変数検索部１１およびテスト入力値生成部１２が入力値演算手段１６に相当する。テスト生成部１３は、プログラム生成手段に相当する。テスト生成部１３およびテスト実行部１４は、プログラム実行手段１７に相当する。出力値比較検証部１５は、出力値比較手段および検証手段に相当する。
【００２５】
以下では、このようなプログラム検証装置１の装置本体２の処理動作について説明する。まず、検証対象モジュールについて説明する。本実施の形態では、２つの検証対象モジュールの入力値に対する出力値の同一性を検証する。２つの検証対象モジュールは、モジュールに対しリファクタリングした後のモジュール（以下、「変更後モジュール」と称する場合がある）およびリファクタリングされる前のモジュール（以下、「変更前モジュール」と称する場合がある）である。以下では、これら２つの検証対象モジュールのソースコード（以下、「検証対象ソースコード」と称する場合がある）の記述内容について説明する。
【００２６】
まず変更前モジュールのソースコード（以下「変更前ソースコード」と称する場合がある）について説明する。変更前ソースコードを表１に示す。以下、説明の便宜上、ソースコードおよび出力結果などに、各行に行番号を付しているけれども、必ずしも行番号は必要ではない。行番号が付されていなくともよく、単に説明を容易にするためである。
【００２７】
【表１】
2007041804.tif 000003
【００２８】
変更前ソースコードは、変数ａおよび配列ｂ[１０]を引数とする関数ｆｕｎｃについて記述され、前記引数に基づいて関数ｆｕｎｃを演算するモジュールのソースコードである。変更前ソースコードは、１行目に関数ｆｕｎｃが定義されている。３行目〜９行目には、変数ｃ，ｄ，ｃｎｔが型宣言され、これら変数に値が代入されている。１０行目には、変数ａに値が代入されている。１２行目〜１７行目には、制御文のｉｆ文が記述され、ｉｆ文は、条件式「ａ≧１００かつａ＜２００」の真偽に基づいて、処理経路を分岐させる。１８行目〜２４行目には、制御文のｗｈｉｌｅ文が記述されている。ｗｈｉｌｅ文は、式「ｃｎｔ＜１０」を具備しなくなるまで、制御を繰返して行わせる。ｗｈｉｌｅ文内の１９行目〜２１行目には、ｉｆ文が記述されている。条件式「ｃｎｔ≧ｃ」の真偽に基づいて、処理経路を分岐させる。２６行目〜３５行目には、制御文のｓｗｉｔｃｈ文が記述されている。ｓｗｉｔｃｈ文は、条件式「ｓｕｂ（ａ）」の値に基づいて、処理経路を分岐させる。
【００２９】
次に変更後モジュールのソースコード（以下、「変更後ソースコード」と称する場合がある）について説明する。変更後ソースコードを表２に示す。
【００３０】
【表２】
2007041804.tif 000004
【００３１】
変更後ソースコードは、変更前ソースコードと同様に、変数ａおよび配列ｂ[１０]を引数とする関数ｆｕｎｃについて記述され、前記引数に基づいて関数ｆｕｎｃを演算するモジュールのソースコードである。変更後ソースコードは、１行目に関数ｆｕｎｃが定義されている。３行目には、変数ｄについて型宣言されている。６行目〜８行目には、ｉｆ文が記述され、ｉｆ文は、条件式「ａ≦１００またはａ＞２００」の真偽に基づいて、処理経路を分岐させる。１０行目には、変数ｄに値が代入され、１２行目には、関数ｆｕｎｃ２が、５および配列ｂを引数として、呼び出されている。１４行目〜２１行目には、ｉｆ文が記述されている。ｉｆ文は、条件式「ｓｕｂ（ａ−１）＝１」の真偽に基づいて、処理経路を分岐させる。２３行目〜３５行目には、関数ｆｕｎｃ２が変数ｃおよび配列ｂ[１０]を引数として定義されている。関数ｆｕｎｃ２では、２５行目〜２７行目に変数ｃｎｔが型宣言され、変数ｃｎｔに値が代入される。２８行目〜３５行目には、制御文のｗｈｉｌｅ文が記述されている。ｗｈｉｌｅ文は、式「ｃｎｔ＜１０」を具備しなくなるまで、制御を繰返して行わせる。ｗｈｉｌｅ文内の２９行目〜３１行目には、ｉｆ文が記述され、ｉｆ文は、条件式「ｃｎｔ≧ｃ」の真偽に基づいて、処理経路を分岐させる。本実施の形態では、プログラム検証装置１のプログラム検証処理の説明を容易にするために、変更前および変更後ソースコードは、ある入力値が入力されると、所定の同一の入力値に対して互いに異なる出力値が出力されるように作成されている。次に、具体的なプログラム検証装置１の具体的な処理動作について説明する。
【００３２】
図２は、プログラム検証処理の手順を示すフローチャートである。プログラム検証装置１のプログラム検証処理には、構文解析工程、出力抽出処理工程、識別番号付加処理工程、分岐条件抽出処理工程、処理経路抽出処理工程、入力変数検索処理工程、テスト入力値生成部処理工程、テスト生成工程、テスト実行処理工程、出力値比較検証処理工程および検証結果報知工程を含む。プログラム検証処理は、検証ソースコードを記憶部３に記憶させ、入力部４によって、検証対象ソースコードを指定すると、ステップｓ１へ移行する。本実施の形態において、検証対象ソースコードは、変更前および変更後ソースコードであり、以下、単に「ソ−スコード」と称する場合がある。
【００３３】
図３は、出力抽出処理の手順を示すフローチャートである。ステップｓ１の出力抽出処理工程では、出力抽出処理を開始し、出力抽出部７によって、各ソースコードに基づいて、各検証対象モジュールのモジュール情報を抽出する。出力抽出処理において、動作主体は、出力抽出部７である。以下、出力抽出処理において出力抽出部７が制御主体の場合、その記載を省略する場合がある。
【００３４】
以下では、出力抽出処理について具体的に説明する。出力抽出処理工程ｓ１に移行すると、出力抽出処理が開始し、ステップａ１へ移行する。ステップａ１では、各ソースコードに基づいて、最上位の関数が戻り値を返すか否かを検索し、検索結果を記憶させる。最上位の関数は、検証対象モジュールにおいて、プログラム構造上の最上位に位置する関数であり、外部モジュールから呼び出される関数である。関数は、検証対象モジュール内の処理によってその戻り値が変化する。このように関数の戻り値が変化するので、呼び出し元のモジュールの演算処理に影響を与える。関数が戻り値を返すか否かを検索することによって、検証対象モジュールが外部モジュールに影響を与えるモジュールであるか否かを判定できる。変更前ソースコードでは、１行目に関数ｆｕｎｃが戻り値を返すものとして定義され、変更後ソースコードでも、１行目に関数ｆｕｎｃが戻り値を返すものとして定義されている。したがって変更前および変更後ソースコードにおいて、関数が戻り値を返すことを検出し、記憶させる。関数の検索が終了すると、ステップａ１からステップａ２へ移行する。
【００３５】
ステップａ２は、参照渡しされる変数への代入の有無を検索する工程である。ステップａ２では、各ソースコードに基づいて、参照渡しされる変数への代入の有無を検索し、検索結果を記憶させる。参照渡しされる変数は、演算子「＆」を用いたアドレス参照、ポインタ変数および配列要素など、モジュール内で値が変更されると、外部モジュールでもその値が維持される変数である。参照渡しされる変数は、モジュール内でその値が変更されると、外部モジュールでもその値が維持されるので、外部モジュールでの演算に影響を与える。参照渡しされる変数への代入の有無を検索することによって、検証対象モジュールが外部モジュールに影響を与えるモジュールであるか否かを判定できる。
【００３６】
変更前ソースコードでは、２２行目に配列ｂ[１０]に値が代入され、変更後ソースコードでも、３３行目の配列ｂ[１０]に値が代入されている。したがって変更前および変更後ソースコードにおいて、参照渡しされる変数への代入ありと判定し、配列ｂ[１０]を抽出し、記憶させる。配列ｂ[１０]を抽出する際、その配列要素も抽出し記憶される。参照渡しされる変数への代入の有無の検索が終了すると、ステップａ２からステップａ３へ移行する。
【００３７】
ステップａ３では、各ソースコードに基づいて、グローバル変数を検索し、検索結果を記憶させる。グローバル変数は、検証対象モジュールおよび外部モジュールにおいて、有効な変数である。それ故、検証対象モジュール内でグローバル変数に値が変更されると、外部モジュールでもその値が維持されるので、外部モジュールでの演算に影響を与える。グローバル変数の有無を検索することによって、検証対象モジュールが外部モジュールに影響を与えるモジュールであるか否かを判定できる。変更前および変更後ソースコードでは、グローバル変数が記述されていない。したがって変更前および変更後ソースコードにおいて、グローバル変数なしと判定し、記憶させる。グローバル変数の検索が終了すると、ステップａ３からステップａ４へ移行する。
【００３８】
ステップａ４では、各ソースコードに基づいて、検証対象モジュールから呼ばれる外部関数の有無を検索し、検索結果を記憶させる。外部関数を呼び出すこと自体が外部モジュールへ影響を与えることになる。外部関数の有無を検索することによって、検証対象モジュールが外部モジュールに影響を与えるモジュールであるか否かを判定できる。変更前ソースコードでは、２６行目に外部関数「ｓｕｂ（ａ）」が呼び出され、変更後ソースコードでは、１４行目に外部関数「ｓｕｂ（ａ−１）」が呼び出されている。したがって変更前ソースコードにおいて、外部関数ありと判定し、外部関数「ｓｕｂ（ａ）」を抽出する。また変更後ソースコードにおいて、外部関数ありと判定し、外部関数「ｓｕｂ（ａ−１）」を抽出し、記憶させる。このようにしてステップａ１からステップａ４で検索して抽出されたモジュールを表３および４に示す。表３は、変更前モジュールのモジュール情報であり、表４が変更後モジュールのモジュール情報である。
【００３９】
【表３】
2007041804.tif 000005
【００４０】
【表４】
2007041804.tif 000006
【００４１】
外部関数の検索が終了すると、出力抽出処理が終了し、ステップｓ１からステップｓ２へ移行する。
【００４２】
図４は、識別番号付加処理の手順を示すフローチャートである。図５は、外部関数に識別番号を付与する前および付与した後のソースコードの一部を示す図である。ステップｓ２である識別番号付加処理工程では、識別番号付加処理を開始し、識別番号付加部８が、各ソースコードに基づいて、外部関数に識別番号を付与し、この付与される識別番号を外部関数の引数に加える。識別番号付加処理において、動作主体は、識別番号付加部８である。以下、識別番号付加処理において識別番号付加部８が制御主体の場合、その記載を省略する場合がある。
【００４３】
以下では、識別番号付加処理について具体的に説明する。出力抽出処理工程ｓ１から識別番号付加処理工程ｓ２に移行すると、識別番号付加処理が開始し、ステップｂ１へ移行する。ステップｂ１では、各ソースコードの１行目から順に外部関数を検索する。変更前ソースコードでは、２６行目に外部関数ｓｕｂ（ａ）が検出され、変更後ソースコードでは、１４行目に外部関数ｓｕｂ（ａ−１）が検出される。外部関数を検出すると、ステップｂ１からステップｂ２へ移行する。
【００４４】
ステップｂ２では、検出される外部関数に識別番号を付与する。識別番号を外部関数に付与し、この識別番号を外部関数の第１引数として加えられる。したがって外部関数の引数は、第１引数として識別番号が入力され、第２引数以降に従前に付与されていた引数が入力される。識別番号は、ソースコードのどの位置で外部関数が呼ばれているのかを明確にするために付与されている。識別番号の付与が終了すると、ステップｂ２からステップｂ１へ移行し、外部関数が検出された行の次の行から再度、外部関数の検索を開始する。
【００４５】
変更前ソースコードでは、２６行目の外部関数ｓｕｂ（ａ）に、識別番号１を付与し、この識別番号１を第１引数に加える。したがって変更前ソースコードでは、図５に示すように、外部関数ｓｕｂ（ａ）を外部関数ｓｕｂ（１，ａ）に変更する。変更後ソースコードでは、１４行目の外部関数ｓｕｂ（ａ−１）に、識別番号１を付与し、この識別番号１を第１引数に加える。したがって変更後ソースコードでは、外部関数ｓｕｂ（ａ−１）を外部関数ｓｕｂ（１，ａ−１）に変更する。識別番号の付与が終了すると、変更前ソースコードでは２７行目から、変更後ソースコードでは１５行目から検索を開始し、ステップｂ１に戻る。
【００４６】
ステップｂ１では、ソースコードの最終行まで検索し、外部関数が検出されない場合、識別番号付加処理を終了する。変更前および変更後ソースコードでは、それぞれ２７行目および１５行目以降に外部関数が呼び出されていないので、識別番号付加処理が終了し、ステップｓ２からステップｓ３へ移行する。
【００４７】
仮にステップｂ１で他の外部関数が検出されると、識別番号２を外部関数に付与し、第１引数に加える。他の外部関数についても同様に、検出順に識別番号を連番３，４，５，・・・で付与し、第１引数に加える。このとき外部関数および引数が同一であっても、呼び出される場所、つまり外部関数が記述される行が異なる場合、これらの外部関数には、異なる識別番号が付される。具体的には、同一の外部関数について、外部関数ｓｕｂ（１，ａ），ｓｕｂ（２，ａ），ｂｕｓ（３，ａ）・・・という様に異なる識別番号を付し、第１引数に加える。識別番号は、外部関数に連番で付与することに限定されず、互いに異なる番号であればよい。
【００４８】
図６は、分岐条件抽出処理の手順を示すフローチャートである。ステップｓ３である分岐条件抽出処理工程では、分岐条件抽出処理を開始し、各ソースコードに基づいて、各検証対象モジュールの処理経路を分岐させる分岐点および分岐させる分岐条件を抽出して、記憶させる。分岐条件抽出処理において、動作主体は、分岐条件抽出部９である。以下、分岐条件抽出処理において分岐条件抽出部９が制御主体の場合、その記載を省略する場合がある。
【００４９】
以下では、分岐条件抽出処理について具体的に説明する。識別番号付加処理工程ｓ２から分岐条件抽出処理工程ｓ３へ移行すると、分岐条件抽出処理が開始し、ステップｃ１へ移行する。ステップｃ１では、各検証対象モジュールで最初に実行すべき処理を記述する文を検出する。以下では、実行すべき処理を記述する文を「命令文」と称する場合がある最初の命令文を検出すると、ステップｃ１からステップｃ２へ移行する。
【００５０】
ステップｃ２である分岐数検出工程では、検出された命令文（以下、「検出文」と称する場合がある）を、処理経路を分岐させる分岐数に基づいて分類する。具体的には、分岐条件抽出部９は、変数の型を宣言する文、関数、代入式、ｒｅｔｕｒｎ文およびｂｒｅａｋ文などの処理経路を分岐させない命令文、ならびに条件を具備するまで処理が繰返させるｗｈｉｌｅ文やｆｏｒ文などの繰返し処理を行う命令文を無分岐処理文に分類する。またｉｆ文など、条件式の真偽に基づいて処理経路を分岐させる命令文を２分岐処理文に分類する。さらにｓｗｉｔｃｈ文など、条件式の値に基づいて処理経路を分岐させる命令文を多分岐処理文に分類する。検出文が無分岐処理文に分類されると、ステップｃ２からステップｃ３へ移行する。ステップｃ３では、各ソースコードについて、さらに他の命令文についての検出を行う。他の命令文が検出されない場合、分岐条件抽出処理が終了する。分岐条件抽出処理が終了すると、ステップｓ３からステップｓ４へ移行する。他の命令文を検出すると、ステップｃ２へ戻り、次に検出された文の分類作業を行う。
【００５１】
ステップｃ２で、検出文が２分岐処理文に分類されると、ステップｃ４へ移行する。ステップｃ４である条件抽出工程では、検出文の条件式を抽出し、記憶させる。条件式に論理演算子が含まれる場合、条件式を論理演算子によって複数の式に分割し、各式を記憶させる。たとえばｉｆ文の条件式が「ａ＞＝１００＆＆ａ＜２００」の場合、論理演算子「＆＆」に基づいて、「ａ＞＝１００」と「ａ＜２００」の２つの条件式に分割して、記憶させる。条件式を記憶させると、ステップｃ４からステップｃ３へ移行する。
【００５２】
ステップｃ２で、検出文が多分岐処理文に分類されると、ステップｃ５へ移行する。ステップｃ５である条件抽出工程では、検出文の条件式が場合分けされる値毎に、条件式およびその値を抽出し、記憶させる。たとえばｓｗｉｔｃｈ文の条件式「ｓｕｂ（ａ）」が「１」で第１命令文を実行し、ｓｗｉｔｃｈ文の条件式「ｓｕｂ（ａ）」が「２」で第２命令文を実行する場合、条件式「ｓｕｂ（ａ）＝＝１」および「ｓｕｂ（ａ）＝＝２」を記憶させる。条件式を記憶させると、ステップｃ５からステップｃ３へ移行する。
【００５３】
以下では、この分岐条件抽出処理について、変更前および変更後ソースコードを用いて具体的に説明する。変更前ソースコードでは、ステップｃ１において、３行目の型宣言文「ｉｎｔ  ｃ」を検出し、ステップｃ２へ移行する。ステップｃ２では、型宣言文「ｉｎｔ  ｃ」を無分岐処理文に分類し、ステップｃ３へ移行する。ステップｃ３では、４行目の型宣言文「ｉｎｔ  ｄ」を検出する。４行目から１０行目までの各型宣言文および式についても、３行目の型宣言文「ｉｎｔ  ｃ」と同様に、各行でステップｃ２とステップｃ３との処理を行う。ステップｃ２では、これらの検出文が無分岐処理文に分類される。
【００５４】
１０行目の代入式「ａ＝ａ−１」の分類後、ステップｃ３で１２行目のｉｆ文を検出し、ステップｃ２へ移行する。ステップｃ２では、検出されたｉｆ文を２分岐処理文に分類し、ステップｃ４へ移行する。ステップｃ４では、ｉｆ文の条件式「ａ＞＝１００＆＆ａ＜２００」を検出する。さらに前記ｉｆ文の条件式に論理演算子が含まれるので、ｉｆ文の条件式を論理演算子によって分割して２つの条件式「ａ＞＝１００」および「ａ＜２００」を抽出し、記憶させる。２つの条件式を記憶させると、ステップｃ３へ移行する。
【００５５】
１３行目の代入式「ｃ＝５」、１５行目のｒｅｔｕｒｎ文および１８行目のｗｈｉｌｅ文については、これらの文が無分岐処理文であるので、ステップｃ３で検出されてステップｃ２に戻る。ステップｃ２で無分岐処理文に分類され、ステップｃ３に移行する。各行でこの処理を行い、１８行目のｗｈｉｌｅ文を分類した後、ステップｃ３では、１９行目のｉｆ文を検出する。ステップｃ２では、検出されたｉｆ文を２分岐処理文に分類し、ステップｃ４へ移行する。ステップｃ４では、ｉｆ文の条件式「ｃｎｔ＞＝ｃ」を検出する。条件式「ｃｎｔ＞＝ｃ」を抽出し、記憶させ、ステップｃ３へ移行する。
【００５６】
２２行目の代入式「ｂ[ｃｎｔ]＝ｃｎｔ＊１０」および２３行目の代入式「ｃｎｔ＝ｃｎｔ＋１」については、これらの文が無分岐処理文であるので、ステップｃ３で検出されてステップｃ２に戻る。ステップｃ２で無分岐処理文に分類され、ステップｃ３に移行する。各行でこの処理を行い、２３行目の代入式を分類した後、ステップｃ３では、２６行目のｓｗｉｔｃｈ文を検出し、ステップｃ２へ戻る。ステップｃ２では、検出されたｓｗｉｔｃｈ文を多分岐処理文に分類し、ステップｃ５へ移行する。ステップｃ５では、ｓｗｉｔｃｈ文の条件式「ｓｕｂ（ａ）」とその値「１」および「２」とに基づいて、条件式「ｓｕｂ（ａ）＝＝１」および「ｓｕｂ（ａ）＝＝２」を抽出し、記憶させ、ステップｃ３へ移行する。
【００５７】
２８行目の代入式「ｄ＝３００００」、３０行目の代入式「ｄ＝ｄ＋１００００」、３１行目のｂｒｅａｋ文および３４行目のｒｅｔｕｒｎ文については、これらの文が無分岐処理文であるので、ステップｃ３で検出されてステップｃ２に戻る。ステップｃ２で無分岐処理文に分類され、ステップｃ３に移行する。各行でこの処理を行い、３４行目のｒｅｔｕｒｎ文を分類した後、ステップｃ３では、最終行まで他の文が検出できないので、分岐条件抽出処理が終了する。分岐条件抽出処理が終了すると、ステップｓ３からステップｓ４へ移行する。変更前ソースコードにおいて、この分岐条件抽出処理によって抽出される条件式（以下、「分岐条件式」と称する場合がある）を表５に示す。１列目が、分岐条件式が記述される行番号、２列目が、分岐条件式を示す。
【００５８】
【表５】
2007041804.tif 000007
【００５９】
変更後ソースコードでも、変更前ソースコードの場合と同様の分岐条件抽出処理を行い、各検出文毎に分類および抽出する。これによって表６に示される分岐条件式が抽出され、記憶される。１列目が、分岐条件式が記述される行番号、２列目が、分岐条件式を示す。変更前ソースコードの場合と同様に、処理経路抽出処理が終了すると、ステップｓ３からステップｓ４へ移行する。
【００６０】
【表６】
2007041804.tif 000008
【００６１】
図７は、処理経路抽出処理の手順を示すフローチャートである。ステップｓ４である処理経路抽出処理工程では、処理経路抽出処理を開始し、各ソースコードに基づいて、分岐点によって派生するすべての処理経路を抽出する。処理経路抽出処理において、動作主体は、処理経路抽出部１０である。以下、処理経路抽出処理において処理経路抽出部１０が制御主体の場合、その記載を省略する場合がある。
【００６２】
以下では、処理経路抽出処理について具体的に説明する。分岐条件抽出処理工程ｓ３から処理経路抽出処理工程ｓ４に移行すると、処理経路抽出処理が開始し、ステップｄ１へ移行する。ステップｄ１である処理ブロック抽出工程では、各ソースコードから処理ブロックを抽出する。以下に、処理ブロックを抽出する処理ブロック抽出方法を説明する。まず制御文の直前、論理演算子の直前、制御文に従って分岐した分岐先のブロックの直前、ｒｅｔｕｒｎ文の直前、ｇｏｔｏ文の直前、およびｂｒｅａｋ文の直前に、それぞれ区切りを入れる。制御文に従って分岐した分岐先のブロックの直前とは、たとえばｉｆ文においてｅｌｓｅ節を含まない場合のように制御文において分岐先が記述されていない場合、制御文の直後のブロックを分岐先のブロックの直前、またはｇｏｔｏ文において、ラベルの直前である。この区切られた各区間内の宣言文、代入式、条件式、およびこれらを組合わせたブロックを処理ブロックとしてそれぞれ抽出し、各処理ブロックに名称をつけて記憶させる。また空文も、処理ブロックとしてそれぞれ抽出し、名称をつけて記憶させる。このように文が含まれていない区間についても、処理ブロックとして抽出することによって、処理経路がいずれの条件式に基づいて、処理されているのかを明確にさせることができる。このような処理ブロック抽出方法によって、処理ブロックが抽出され記憶されると、ステップｄ１からステップｄ２へ移行する。
【００６３】
ステップｄ２である処理経路探索開始工程では、ソースコードの１行目から順に、処理ブロックの検出を開始する。処理ブロックを検出すると、検出された処理ブロック（以下、「検出処理ブロック」と称する場合がある）を、処理経路において最初に実行すべき処理ブロックとして記憶させる。検出処理ブロックを記憶させると、ステップｄ２からステップｄ３へ移行する。
【００６４】
ステップｄ３では、検出処理ブロックの直前の文が、無分岐処理文、２分岐処理文および多分岐処理文のいずれの文であるか否かを判定する。処理ブロックの直前に文がない場合、無分岐処理文であると判定される。無分岐処理文であると判定すると、ステップｄ３からステップｄ４へ移行する。
【００６５】
またステップｄ３では、２分岐処理文であると判定すると、ステップｄ５へ移行する。ステップｄ５では、処理ブロックの直後に論理演算子が記述されているか否かを判定する。論理演算子が記述されていないと判定すると、ステップｄ５からステップｄ６へ移行する。ステップｄ６では、検出処理ブロックが真および偽になる場合の２つの処理経路を検出する。具体的には、まず２分岐処理文の条件式が真になる場合の分岐先の処理ブロック（以下、「真処理ブロック」と称する場合がある）および前記条件式が偽になる場合の各分岐先の処理ブロック（以下、「偽処理ブロック」と称する場合がある）を検出する。次に検出処理ブロックの次に実行すべき処理ブロックとして、検出された真および偽処理ブロックをそれぞれ追加し、検出処理ブロックが真になる場合および偽になる場合の２つの処理経路を検出する。この２つの処理経路を記憶させ、検出された２つの分岐先の処理ブロックのうち一方の処理ブロックを検出処理ブロックに選出し、ステップｄ６からステップｄ３へ移行する。
【００６６】
ステップｄ５で、論理演算子が記述されていると判定すると、ステップｄ５からステップｄ７へ移行する。ステップｄ７では、検出処理ブロックが真および偽になる場合の２つの処理経路を検出する。具体的には、まず真処理ブロック、偽処理ブロックおよび前記論理演算子の直後の処理ブロックを検出する。次に論理演算子に基づいて、検出処理ブロックの次に実行すべき処理ブロックとして、検出された真処理ブロック、偽処理ブロックおよび論理演算子の直後の処理ブロックをそれぞれ追加し、検出処理ブロックが真になる場合および偽になる場合の２つの処理経路を検出する。たとえば論理演算子が論理積である場合、偽処理ブロックと論理演算子の直後の処理ブロックとを次に実行すべき処理ブロックとして追加し、論理和である場合、真処理ブロックと論理演算子の直後の処理ブロックとを次に実行すべき処理ブロックとして追加する。各場合において、２つの処理経路を記憶させ、検出された論理演算子の直後の処理ブロックを検出処理ブロックとし、ステップｄ７からステップｄ５へ戻る。
【００６７】
ステップｄ３で、多分岐処理文であると判定すると、ステップｄ８へ移行する。ステップｄ８では、多分岐処理文の分岐数の数の処理経路を検出する。具体的には、まず分岐先の処理ブロック（以下、「分岐先処理ブロック」と称する場合がある）をそれぞれ検出する。この分岐先処理ブロックは、分岐数と同数ある。次に検出処理ブロックの次に実行すべき処理ブロックとして、検出された各分岐先処理ブロックをそれぞれ追加し、検出処理ブロックの値によって分岐するすべての処理経路を検出する。これらすべての処理経路を記憶させ、複数の分岐先処理ブロックのうちいずれか１つの分岐先処理ブロックを検証処理ブロックに選出し、ステップｄ８からステップｄ３へ移行する。
【００６８】
ステップｄ４では、検出処理ブロックの直後にｒｅｔｕｒｎ文が検出されるか否かを判定する。ｒｅｔｕｒｎ文が検出されない場合、次の処理ブロックの検出を開始する。次の処理ブロックは、検出処理ブロックに関数が含まれかつ前記関数がモジュール内で定義されている場合、前記関数の最初の処理ブロックである。それ以外の場合は、検証処理ブロックの直後の処理ブロックである。つまり、処理ブロックの検出は、モジュールの処理の順番に沿って行われる。ただしｗｈｉｌｅ文のようなループ文では、１度の検出されると、ループ処理が完全に終了したものとして、その次の処理ブロックを検出する。
【００６９】
次の処理ブロックが検出されると、この処理ブロックを検出処理ブロックの次に実行すべき処理ブロックとして、処理経路に記憶させる。この次の処理ブロックを検出処理ブロックに選出し、ステップｄ４からステップｄ３へ戻る。ｒｅｔｕｒｎ文が検出される場合、ステップｄ４からステップｄ９へ移行する。ステップｄ９では、検出処理ブロックを実行すべき処理ブロックとして記憶させる処理経路について検索を終了し、この処理経路について、処理ブロックの実行順を確定する。前記処理経路が確定すると、ステップｄ９からステップｄ１０へ移行する。
【００７０】
ステップｄ１０では、すべての処理経路について処理ブロックの実行順が確定したか否かを判定する。具体的には、真処理ブロック、偽処理ブロックおよび複数の分岐先処理ブロックのうち検出処理ブロックに選出されていない処理ブロックを検出する。選出されていない処理ブロックを検出すると、処理ブロックの実行順が確定していない処理経路があると判定し、選出しされていない処理ブロック（複数の処理ブロックが選出しされていない場合、その複数の処理ブロックのうちいずれか１つの処理ブロック）を検出処理ブロックに選出し、ステップｄ１０からステップｄ３へ戻る。選出しされていない処理ブロックが検出されない場合、すべての処理経路について処理ブロックの実行順が確定していると判定し、処理経路抽出処理が終了する。処理経路抽出処理が終了すると、ステップｓ４からステップｓ５へ移行する。
【００７１】
以下では、この処理経路抽出処理について、変更前および変更後ソースコードを用いて具体的に説明する。本実施の形態の変更前ソースコードでは、ステップｄ１において、処理ブロック抽出方法に基づいて、処理ブロックを抽出する。まず変更前ソースコードを区切る。具体的には、３行目の「ｉｎｔ＝ｃ」の直前、１２行目のｉｆ文の直前、１２行目の論理演算子「＆＆」の直前、１３行目の「ｃ＝５」の直前、１５行目のｒｅｔｕｒｎ文直前に２つ、１８行目のｗｈｉｌｅ文の直前、１９行目のｉｆ文の直前、２０行目のｂｒｅａｋ文の直前に２つ、２２行目の「ｂ「ｃｎｔ」＝ｃｎｔ＊１０」の直前、２６行目のｓｗｉｔｃｈ文の直前、２７行目のｃａｓｅ文の直前、２９行目のｃａｓｅ文の直前、３１行目のｂｒｅａｋ文の直前および３４行目のｒｅｔｕｒｎ文の直前の計１６個の区切りを入れる。
【００７２】
次にこれら区切りに基づいて、この区切りで区切られた区間の型宣言文などを各処理ブロックとして抽出する。具体的には、３行目から１０行目の型宣言文および代入式を処理ブロックＡ１、１２行目の「ａ＞＝１００」を処理ブロックＢ１、１２行目の「ａ＜２００」を処理ブロックＣ１、１３行目の「ｃ＝５」を処理ブロックＤ１、１５行目のｒｅｔｕｒｎ文直前の空文を処理ブロックＥ１、１８行目の「ｃｎｔ＜１０」を処理ブロックＦ１、１９行目の「ｃｎｔ＞＝ｃ」を処理ブロックＧ１、２０行目のｂｒｅａｋ文の直前の空文を処理ブロックＨ１、２２行目から２３行目の２つの代入式を処理ブロックＩ１、２６行目の「ｓｕｂ（ａ）」を処理ブロックＪ１、２８行目の「ｄ＝３００００」を処理ブロックＫ１、３０行目の「ｄ＝ｄ＋１００００」を処理ブロックＬ１、３４行目のｒｅｔｕｒｎ文直前の空文を処理ブロックＭ１として抽出する。これら抽出される処理ブロックを用いて記述した変更前ソースコードを表７に示す。このようにして各処理ブロックを抽出すると、ステップｄ１からステップｄ２へ移行する。
【００７３】
【表７】
2007041804.tif 000009
【００７４】
ステップｄ２では、最初に検出される処理ブロックＡ１を、処理経路において最初に実行すべき処理ブロックとして記憶させる。処理ブロックＡ１を記憶させると、ステップｄ２からステップｄ３へ移行する。ステップｄ３では、処理ブロックＡ１の直前の文がないので、無分岐処理文と判定される。これによってステップｄ３からステップｄ４へ移行する。ステップｄ４では、処理ブロックの直後にｒｅｔｕｒｎ文が記述されていないので、次の処理ブロックの検出を開始する。次の処理ブロックとして処理ブロックＢ１が検出されると、処理ブロックＡ１の次に実行すべき処理ブロックとして、処理経路に追加し記憶させる。これによって処理経路Ａ１−Ｂ１が検出される。この処理ブロックＢ１を検出処理ブロックに選出し、ステップｄ４からステップｄ３へ戻る。
【００７５】
ステップｄ３では、処理ブロックＢ１の直前がｉｆ文であるので、処理ブロックＢ１の直前の文が２分岐処理文と判定される。これによってステップｄ３からステップｄ５へ移行する。ステップｄ５では、処理ブロックＢ１の直後に論理演算子が記述されていると判定する。これによってステップｄ５からステップｄ７へ移行する。ステップｄ７では、処理ブロックＢ１の論理演算子の直後の処理ブロックである処理ブロックＣ１と偽処理ブロックである処理ブロックＥ１とを検出する。各処理ブロックＣ１，Ｅ１を処理経路Ａ１−Ｂ１にそれぞれ追加し、処理経路Ａ１−Ｂ１−Ｃ１およびＡ１−Ｂ１−Ｅ１を検出する。処理ブロックＣ１を検出処理ブロックに選出し、ステップｄ７からステップｄ５へ戻る。
【００７６】
ステップｄ５では、処理ブロックＣ１の直後に論理演算子が記述されていないと判定する。これによってステップｄ５からステップｄ６へ移行する。ステップｄ６では、真処理ブロックである処理ブロックＤ１および偽処理ブロックである処理ブロックＥ１を検出する。各処理ブロックＤ１，Ｅ１を処理経路Ａ１−Ｂ１−Ｃ１にそれぞれ追加し、処理経路Ａ１−Ｂ１−Ｃ１−Ｄ１およびＡ１−Ｂ１−Ｃ１−Ｅ１を検出する。処理ブロックＤ１およびＥ１のうち一方の処理ブロック、本実施の形態では処理ブロックＤ１を検出処理ブロックに選出し、ステップｄ７からステップｄ３へ戻る。
【００７７】
ステップｄ３では、処理ブロックＤ１の直前の文が無分岐処理と判定される。これによってステップｄ３からステップｄ４へ移行する。ステップｄ４では、処理ブロックＤ１の直後にｒｅｔｕｒｎ文が記述されていないので、次の処理ブロックの検出を開始する。次の処理ブロックとして処理ブロックＦ１が検出されると、処理ブロックＤ１の次に実行すべき処理ブロックとして、処理ブロックＦ１を処理経路に追加し記憶させる。これによって処理経路Ａ１−Ｂ１−Ｃ１−Ｄ１−Ｆ１が検出される。この処理ブロックＦ１を検出処理ブロックに選出し、ステップｄ４からステップｄ３へ戻る。
【００７８】
処理ブロックＦ１も、その直前の文が無分岐処理であり直後にｒｅｔｕｒｎ文がないので、ステップｄ３からステップｄ４に移行し、次の処理ブロックとして処理ブロックＧ１が検出される。処理ブロックＧ１を処理ブロックＦ１の次に実行すべき処理ブロックとして、処理経路に記憶され、処理経路Ａ１−Ｂ１−Ｃ１−Ｄ１−Ｆ１−Ｇ１が検出される。この処理ブロックＧ１を検出処理ブロックに選出し、ステップｄ４からステップｄ３へ戻る。
【００７９】
ステップｄ３では、処理ブロックＧ１の直前の文がｉｆ文であるので、２分岐処理文と判定される。これによってステップｄ３からステップｄ５へ移行する。ステップｄ５では、処理ブロックの直後に論理演算子が記述されていないと判定する。これによってステップｄ５からステップｄ６へ移行する。ステップｄ６では、真処理ブロックである処理ブロックＨ１および偽処理ブロックである処理ブロックＩ１を検出する。各処理ブロックＨ１，Ｉ１を処理経路Ａ１−Ｂ１−Ｃ１−Ｄ１−Ｆ１−Ｇ１にそれぞれ追加し、処理経路Ａ１−Ｂ１−Ｃ１−Ｄ１−Ｆ１−Ｇ１−Ｈ１およびＡ１−Ｂ１−Ｃ１−Ｄ１−Ｆ１−Ｇ１―Ｉ１を検出する。処理ブロックＤ１およびＥ１のうち一方の処理ブロック、本実施の形態では処理ブロックＨ１を検出処理ブロックに選出し、ステップｄ７からステップｄ３へ戻る。
【００８０】
処理ブロックＨ１においても、ステップｄ３からステップｄ４に移行し、次の処理ブロックとして処理ブロックＪ１が検出される。処理ブロックＨ１の次に実行すべき処理ブロックとして、処理ブロックＪ１を処理経路に記憶し、処理経路Ａ１−Ｂ１−Ｃ１−Ｄ１−Ｆ１−Ｇ１−Ｈ１−Ｊ１が検出される。この処理ブロックＪ１を検出処理ブロックに選出し、ステップｄ４からステップｄ３へ戻る。
【００８１】
ステップｄ３では、処理ブロックＪ１の直前の文がｓｗｉｔｃｈ文であるので、多分岐処理文と判定される。これによってステップｄ３からステップｄ８へ移行する。ステップｄ８では、２つの分岐先処理ブロックである処理ブロックＫ１および処理ブロックＬ１を検出する。各処理ブロックＫ１，Ｌ１を処理経路Ａ１−Ｂ１−Ｃ１−Ｄ１−Ｆ１−Ｇ１−Ｈ１−Ｊ１にそれぞれ追加し、処理経路Ａ１−Ｂ１−Ｃ１−Ｄ１−Ｆ１−Ｇ１−Ｈ１−Ｊ１−Ｋ１およびＡ１−Ｂ１−Ｃ１−Ｄ１−Ｆ１−Ｇ１―Ｉ１−Ｌ１を検出する。処理ブロックＫ１およびＬ１のうち一方の処理ブロック、本実施の形態では処理ブロックＫ１を検出処理ブロックに選出し、ステップｄ８からステップｄ３へ戻る。
【００８２】
処理ブロックＫ１も、ステップｄ３からステップｄ４に移行し、次の処理ブロックとして処理ブロックＬ１が検出される。処理ブロックＬ１を処理ブロックＫ１の次に実行すべき処理ブロックとして、処理経路に記憶され、処理経路Ａ１−Ｂ１−Ｃ１−Ｄ１−Ｆ１−Ｇ１−Ｈ１−Ｊ１−Ｋ１−Ｌ１が検出される。この処理ブロックＬ１を検出処理ブロックに選出し、ステップｄ４からステップｄ３へ戻る。
【００８３】
処理ブロックＬ１も、ステップｄ３からステップｄ４に移行し、次の処理ブロックとして処理ブロックＭ１が検出される。処理ブロックＭ１を処理ブロックＬ１の次に実行すべき処理ブロックとして記憶され、処理経路Ａ１−Ｂ１−Ｃ１−Ｄ１−Ｆ１−Ｇ１−Ｈ１−Ｊ１−Ｋ１−Ｌ１−Ｍ１が検出される。この処理ブロックＭ１を検出処理ブロックに選出し、ステップｄ４からステップｄ３へ戻る。
【００８４】
処理ブロックＭ１も、ステップｄ３からステップｄ４に移行する。処理ブロックＭ１の直後の文がｒｅｔｕｒｎ文であるので、ステップｄ４からステップｄ９へ移行する。ステップｄ９では、この処理経路Ａ１−Ｂ１−Ｃ１−Ｄ１−Ｆ１−Ｇ１−Ｈ１−Ｊ１−Ｋ１−Ｌ１−Ｍ１の検索を終了し、処理経路の処理ブロックの実行順を確定する。確定すると、ステップｄ９からステップｄ１０へ移行する。ステップｄ１０では、確定していない処理経路があるので、選出されていない処理ブロックのうちいずれか１つを選出し、たとえば処理経路Ａ１−Ｂ１の処理ブロックＢ１を検出処理ブロックとして選出する。選出すると、ステップｄ３へ移行する。
【００８５】
同様にして、すべての処理経路が確定するまで、処理経路の検出を実行する。処理経路の検出を実行した結果、検出された処理経路を表８に示す。ステップｄ１０ではすべての処理経路が確定すると、処理経路抽出処理が終了し、ステップｓ５からステップｓ６へ移行する。以下では、表８に示す各処理経路について、説明の便宜上、上から順に第１変更前処理経路、第２変更前処理経路というように、序数および「変更前」の文字を付して称する場合がある。表８は、１列目が、処理経路の名称、２列目が、処理経路に含まれる処理ブロックおよびその処理ブロックの処理順を示す。
【００８６】
【表８】
2007041804.tif 000010
【００８７】
変更前ソースコードの場合と同様に変更後ソースコードに対して処理経路抽出処理を実行すると、１４の処理ブロックＡ２，Ｂ２，Ｃ２．Ｄ２，Ｅ２，Ｆ２，Ｇ２，Ｈ２，Ｉ２，Ｊ２，Ｋ２，Ｌ２，Ｍ２，Ｎ２が抽出される。具体的には、３行目の「ｉｎｔ  ｄ」を処理ブロックＡ２、６行目の「ａ＜＝１００」を処理ブロックＢ２、６行目の「ａ＞２００」を処理ブロックＣ１、７行目のｒｅｔｕｒｎ文直前の空文を処理ブロックＤ２、１０行目の代入式および１２行目の関数呼び出しを処理ブロックＥ２、２５行目の型宣言文および２７行目の代入式を処理ブロックＦ２、２８行目の「ｃｎｔ＜ｃ」を処理ブロックＧ２、２９行目の「ｃｎｔ＞＝ｃ」を処理ブロックＨ２、３０行目のｂｒｅａｋ文の直前の空文を処理ブロックＩ２、３２行目から３３行目の２つの代入式を処理ブロックＪ２、１４行目の「ｓｕｂ（ａ−１）＝＝１」を処理ブロックＫ２、１５行目の「ｄ＝３００００」を処理ブロックＬ２、１７行目の「ｄ＝ｄ＋１００００」を処理ブロックＭ２、２０行目のｒｅｔｕｒｎ文直前の空文を処理ブロックＮ２として抽出する。これら抽出される処理ブロックを用いて記述した変更後ソースコードを表９に示す。各処理ブロックを抽出すると、ステップｄ１からステップｄ２へ移行する。
【００８８】
【表９】
2007041804.tif 000011
【００８９】
変更前ソースコードと同様に、ステップｄ２〜ステップｄ１０に基づいて、処理経路を検出すると、表１０に示される処理経路が検出される。すべての処理経路が確定すると、処理経路抽出処理が終了し、ステップｓ４からステップｓ５へ移行する。このようにして変更前および変更後ソースコードのすべての処理経路を検出する。以下では、表１０に示す各処理経路について、説明の便宜上、上から順に第１変更後処理経路、第２変更後処理経路というように、序数および「変更後」の文字を付して称する場合がある。表１０は、１列目が、処理経路の名称、２列目が、処理経路に含まれる処理ブロックおよびその処理ブロックの処理順を示す。
【００９０】
【表１０】
2007041804.tif 000012
【００９１】
図８は、入力変数検索処理の手順を示すフローチャートである。図９は、分岐条件式の展開方法の手順を示すフローチャートである。ステップｓ５である入力変数検索処理工程では、入力変数検索処理を開始し、ソースコード、分岐条件式および各処理経路に基づいて、各検証対象モジュールの入力変数、および変数入力値を演算するために必要な条件を検索する。入力変数検索処理において、動作主体は、入力変数検索部１１である。以下、入力変数検索処理において入力変数検索部１１が制御主体の場合、その記載を省略する場合がある。
【００９２】
以下では、入力変数検索処理について具体的に説明する。処理経路抽出処理工程ｓ４から入力変数検索処理工程ｓ５に移行すると、入力変数検索処理を開始し、ステップｅ１へ移行する。ステップｅ１では、複数の分岐条件式のうちいずれか１つの分岐条件式を選出する。分岐条件式を選出すると、ステップｅ１からステップｅ２へ移行する。ステップｅ２では、複数の処理経路のうちいずれか１つの処理経路を選出する。処理経路が選出されると、ステップｅ２からステップｅ３移行する。ステップｅ３では、選出された処理経路のいずれかの処理ブロックに、選出された分岐条件式が含まれているか否かを判定する。選出された分岐条件式が含まれていると判定すると、ステップｅ３からステップｅ４へ移行する。
【００９３】
ステップｅ４では、選出された分岐条件式より前に実行すべき命令文に、分岐条件式に含まれる変数に対する値の代入があるか否か、前記変数の参照が取られているかを検出する。換言すると、選出された分岐条件式より前に実行すべき命令文に、選出された分岐条件式に含まれる変数に関する代入式および関数などの変換式が含まれるか否かを検出する。尚、複数の変換式が検出される場合は最後に実行される変換式が検出される。変換式を検出すると、ステップｅ４からステップｅ５へ移行する。
【００９４】
ステップｅ５では、検出された変換式が３つの特定条件のうち少なくともいずれか１つの特定条件を具備するか否かを判定する。３つの特定条件の１つである第１特定条件Ｓ１は、検出された変換式に外部関数を含み、その外部関数の引数において、分岐条件式に含まれる変数が参照渡しされていることである。表１１に示すソースコードに基づいて、具体的に説明する。「ａ＝＝１」が分岐条件式に選出されると、「ｓｕｂ（＆ａ）」が変換式として検出される。選出された分岐条件式の変数ａが変換式の外部関数の引数で参照渡しされているので、この変換式は、第１特定条件Ｓ１を具備している。
【００９５】
【表１１】
2007041804.tif 000013
【００９６】
３つの特定条件の１つである第２特定条件Ｓ２は、検出された変換式がループ文のブロックに含まれていることである。表１２に示すソースコードに基づいて、具体的に説明する。「ａ＝＝１」が分岐条件式に選出されると、「ａ＝ｂ」が変換式として検出される。検出された変換式がｆｏｒ文のブロックに含まれているので、この変換式は、第２特定条件Ｓ２を具備している。
【００９７】
【表１２】
2007041804.tif 000014
【００９８】
３つの特定条件の１つである第３特定条件Ｓ３は、検出された変換式において、分岐条件式に含まれる変数が参照渡しされていることである。表１３に示すソースコードに基づいて、具体的に説明する。「ａ＝＝１」が分岐条件式に選出されると、「ｂ＝＆ａ」が変換式として検出される。検出された変換式で分岐条件式の変数ａが参照渡しされているので、この変換式は、第３特定条件Ｓ１を具備している。
【００９９】
【表１３】
2007041804.tif 000015
【０１００】
これら特定条件を具備する変換式の変数は、その値が外部関数などの影響によって変わる可能性がある。このように特定条件として予め検出することによって、予め検証結果の確実性に影響を及ぼす要因を明確にすることができる。
【０１０１】
これら３つの特定条件のうちいずれかを具備すると判定すると、ステップｅ５からステップｅ６へ移行する、ステップｅ６では、変換式を３つの特定条件のうちいずれの特定条件を具備するかを分類する。分類された特定条件は、変換式、この変換式が記述される行数などの位置および特定条件を具備する変数と関連づけて記憶される。特定条件を分類し記憶させると、ステップｅ７へ移行する。
【０１０２】
ステップｅ７では、検出された変換式が特定条件Ｓ２を具備する場合、検出された変換式に基づいて、後述するステップｅ８と同等に分岐条件式を展開する。検出された変換式が特定条件Ｓ１，Ｓ３を具備する場合、検出された変換式で参照が渡されている変数は、外部関数および当該変数と直接関連の無い処理によって、変数の値が変わる場合がある。特定条件Ｓ１，Ｓ３を具備する場合、この分岐条件式に関する入力変数検索処理において今後当該変数の展開を行わない分岐条件式、および通常通り当該変数の展開を行う分岐条件式を抽出し、記憶させる。たとえば、この後に、「ａ＝ｃ」という変換式が検出された場合、前者の分岐条件式は「ａ＝＝１」の形のままで変化しないが、後者は展開して「ｃ＝＝１」と展開される。記憶された各分岐条件式は、互いに別個の分岐条件式として、以降の処理が行われる。このようにして変数を展開しない分岐条件式と、展開した分岐条件式を抽出し記憶させると、ステップｅ７からステップｅ９へ移行する。
【０１０３】
ステップｅ５で、３つの特定条件を具備しないと判定すると、ステップｅ８へ移行する。尚、検出されている変換式は、分岐条件式に含まれる変数に対する値の代入となっているものと、分岐条件式に含まれる変数の参照が取られている場合がある。後者は前記特定条件Ｓ１，Ｓ３を満たし、ステップｅ５からステップｅ６へ移行している。したがってステップｅ８に移行する場合、検出された変換式は、必ず分岐条件式に含まれる変数に対する値の代入となっている。ステップｅ８では、分岐条件式が特定の変数について今後展開を行わないものとして記憶されており、且つ検出された変換式が当該変数に対する代入である場合は、何も行わない。展開を行わないものとして記憶されていない場合は、検出された変換式に基づいて、分岐条件式を展開する。展開された分岐条件式は、記憶される。分岐条件式が展開され記憶されると、ステップｅ８からステップｅ９へ移行する。
【０１０４】
ステップｅ９では、さらに検出された変換式より前に実行すべき命令文に、展開された分岐条件式に含まれる変数に対する値などの代入があるか否かを検出する。換言すると、検出された変換式より前に実行すべき命令文に、展開された分岐条件式に含まれる変数に関する代入式および関数などの変換式が含まれるか否かを検出する。変換式が検出されると、この変換式を検出された変換式とし、ステップｅ９からステップｅ５へ戻る。
【０１０５】
ステップｅ５に戻りステップｅ７またはステップｅ８に進むと、ステップｅ７またはステップｅ８では、ステップｅ９で検出された変換式に基づいて、記憶された展開された分岐条件式を展開し、さらに展開された分岐条件式を記憶させる。このように展開された分岐条件式をさらに展開し記憶させると、ステップｅ８からステップｅ９へ移行し、同様のステップｅ９で同様の処理を行う。ステップｅ９で、変換式が検出されないと判定すると、変換式の検出を終了し、ステップｅ９からステップｅ１０へ移行する。
【０１０６】
表１４に示すソースコードに基づいて、分岐条件式の展開処理について、図９を参照しつつ説明する。説明の便宜上、「ｂ＝＝１」が分岐条件式に選出されているものとし、ステップｅ４から説明する。
【０１０７】
【表１４】
2007041804.tif 000016
【０１０８】
ステップｅ４では、選出される分岐条件式に変数ｂを含むので、変換式として「ｂ＝ａ＋１」を検出する。これによってステップｅ４からステップｅ５へ移行する。ステップｅ５では、変換式「ｂ＝ａ＋１」が３つの特定条件をいずれも具備しないと判定する。これによってステップｅ５からステップｅ８へ移行する。ステップｅ８では、変換式「ｂ＝ａ＋１」に基づいて、分岐条件式「ｂ＝１」を展開して展開された分岐条件式「ａ＋１＝１」を抽出し、記憶させる。これによってステップｅ８からステップｅ９へ移行する。ステップｅ９では、変換式「ｂ＝ａ＋１」の前に実行される処理を記述する文であり、展開された分岐条件式の変数ａを含むので、変換式として「ａ＝ｓｕｂ（３，ｘ，ｙ）」を検出する。これによってステップｅ９からステップｅ５へ移行する。
【０１０９】
ステップｅ５では、変換式「ａ＝ｓｕｂ（３，ｘ，ｙ）」が３つの特定条件をいずれも具備しないと判定する。これによってステップｅ５からステップｅ８へ移行する。ステップｅ８では、変換式「ａ＝ｓｕｂ（３，ｘ，ｙ）」に基づいて、分岐条件式「ａ＋１＝１」を展開して展開された分岐条件式「ｓｕｂ（３，ｘ，ｙ）＋１＝１」を抽出し、記憶させる。本検証において、外部関数は、それがとり得る値が必要となり、どのような変数が引数として用いられるか必要でない。したがって展開された分岐条件式を「ｓｕｂ（）＋１＝１」として、引数を記憶しなくてもよい。以下では、外部関数について引数を記載しない場合がある。これによってステップｅ８からステップｅ９へ移行する。ステップｅ９では、変換式「ｓｕｂ（）＋１＝１」より前に実行される処理を記述する文に、変数ｓｕｂ（）を含む代入式または関数が検出できない。これによってステップｅ９からステップｅ１０へ移行する。
【０１１０】
ステップｅ１０では、変換式の検出の終了処理が、２つの検出終了条件のうちいずれの条件を具備して終了したか分類する。２つの検出終了条件のうち一方の条件である第１検出終了条件Ｔ１は、展開された分岐条件式に変数が無い場合である。２つの検出終了条件のうち他方の条件である第２検出終了条件Ｔ２は、変換式より前に実行すべき命令文が無い場合である。第１検証終了条件Ｔ１を具備して検出を終了したと分類されると、ステップｅ１１へ移行する。
【０１１１】
ステップｅ１１では、展開された分岐条件式に外部関数が含まれているか否かを判定する。外部関数が含まれていると判定すると、この展開された分岐条件式を展開済みの分岐条件式として記憶し、ステップｅ１３へ移行する。外部関数が含まれていないと判定すると、何も処理せず、ステップｅ１３へ移行する。
【０１１２】
ステップｅ１０で、第２終了条件Ｔ２を具備して検出を終了したと分類されると、ステップｅ１２へ移行する。ステップｅ１２では、展開された分岐条件式においてローカル変数が含まれているか否か判定する。ローカル変数が含まれていると判定すると、ローカル変数検出情報として値が設定されていないローカル変数を検出したことを記憶させ、ローカル変数に０の値を代入する。前記値が設定されていないローカル変数は、実行時にその値が０に設定される。したがってローカル変数を０に設定することによって、実際の実行される場合と同様の出力値が演算されるからである。前記ローカル変数に０を代入して検出終了条件Ｔ１を具備する場合、ステップｅ１１と同様の処理を行い、ステップｅ１３へ移行する。０の値を代入しても検出終了条件Ｔ１を具備しない、またはローカル変数が含まれていないと判定すると、ローカル変数検出情報として値が設定されていないローカル変数がないことを記憶させ、変数を含む展開された分岐条件式を展開済み分岐条件式として記憶させる。展開済み分岐条件式を記憶させると、ステップｅ１２からステップｅ１３へ移行する。
【０１１３】
ステップｅ１３では、選出された分岐条件式において、すべての処理経路で処理が行われたか否かを判定する。すべての処理経路で処理が行われたと判定すると、ステップｅ１３からステップｅ１４へ移行する。ステップｅ１４では、すべての分岐条件式が選出されたか否かを判定する。すべての分岐条件式が選出されたと判定すると、入力変数検索処理が終了し、ステップｓ５からステップｓ６へ移行する。
【０１１４】
ステップｅ３で、選出された処理経路のいずれかの処理ブロックに、選出された分岐条件式が含まれていないと判定されると、ステップｅ３からステップｅ１３へ移行する。ステップｅ４で、変換式が無いと判定されると、ステップｅ４からステップｅ１０へ移行する。ステップｅ１３で、少なくともいずれか１つの処理経路が未処理である判定されると、未処理の処理経路のうちいずれか１つの処理経路を選出し、ステップｅ４へ戻る。ステップｅ１４で、少なくともいずれか１つの分岐条件式が未選出であると判定すると、未選出の分岐条件式のうちいずれか１つの分岐条件式を選出し、ステップｅ３へ戻る。
【０１１５】
以下では、この入力変数検索処理について、変更前および変更後ソースコードを用いて具体的に説明する。本実施の形態の変更前ソースコードでは、ステップｅ１において、表５に示される５つの分岐条件式のうち、変更前ソースコードの１２行目に記載される分岐条件式「ａ＞＝１００」を選出する。これによってステップｅ１からステップｅ２へ移行する。ステップｅ２では、第１変更前処理経路を選出する。これによってステップｅ２からステップｅ３へ移行する。ステップｅ３では、選出された分岐条件式が処理ブロックＢ１に含まれるので、選出された分岐条件式が含まれると判定する。これによってステップｅ３からステップｅ４へ移行する。
【０１１６】
ステップｅ４では、変更前ソースコードの１０行目に記載される「ａ＝ａ−１」を変換式として検出する。変換式が検出されたので、ステップｅ４からステップｅ５へ移行する。ステップｅ５では、検出された変換式が３つの特定条件Ｓ１，Ｓ２，Ｓ３のいずれも具備しないので、ステップｅ８へ移行する。ステップｅ８では、検出された変換式に基づいて、選出された分岐条件式を展開し、展開された分岐条件式「ａ−１＞＝１００」を抽出し、記憶させる。展開された分岐条件式を記憶させると、ステップｅ８からステップｅ９へ移行する。
【０１１７】
ステップｅ９では、変数ａを含む変換式が検出できないと判定される。これによってステップｅ９からステップｅ１０へ移行する。ステップｅ１０では、変数ａを含む変換式が検出できないとして検出が終了しているので、検出終了条件Ｔ２を具備すると判定する。これによってステップｅ１０からステップｅ１２へ移行する。ステップｅ１２では、展開された分岐条件式にローカル変数が含まれていないので、この展開された分岐条件式「ａ−１＞＝１００」を展開済みの分岐条件式として、記憶させる。これによってステップｅ１２からステップｅ１３へ移行する。
【０１１８】
ステップｅ１３では、選出された分岐条件式において、第１変更前処理経路以外の処理経路が未処理であるので、未処理の処理経路のうちいずれか１つの処理経路、たとえば第２変更前処理経路を選出し、ステップｅ３へ戻る。第１変更前処理経路の場合と同様にして、第２変更前処理経路〜第８変更前処理経路について処理すると、ステップｅ１３で、選出された分岐条件式において、すべての処理経路で処理が行われたと判定し、ステップｅ１４へ移行する。
【０１１９】
ステップｅ１４では、分岐条件式「ａ＞＝１００」以外の分岐条件式が選出されていないので、未選出の分岐条件式のうちいずれか１つの分岐条件式、たとえば変更前ソースコードの１２行目の分岐条件式「ａ＜２００」を選出し、ステップｅ２へ戻る。分岐条件式「ａ＞＝１００」の場合と同様にして、すべての分岐条件式に基づいて、展開済みの分岐条件式を抽出し、記憶させると、ステップｅ１４で、すべての分岐条件式について選出されたと判定し、変更前ソースコードについての入力変数検索処理が終了する。この入力変数検索処理によって、各処理経路で抽出し記憶された展開済みの分岐条件式を表１５に示す。表１５は、縦軸が処理経路を示し、横軸が分岐条件式を示す。また「−」は、展開済み分岐条件式が記憶されていないことを示す。
【０１２０】
【表１５】
2007041804.tif 000017
【０１２１】
本実施の形態の変更後ソースコードでも、変更前ソースコードと同様にして、入力変数検索処理を行うと、表６に示される分岐条件式に基づいて、展開済みの分岐条件式が表１０に示す各処理経路で抽出され記憶され、入力変数検索処理が終了する。各処理経路で抽出し記憶された展開済みの分岐条件式を表１６に示す。表１６は、縦軸が処理経路を示し、横軸が分岐条件式を示す。また表１６の「−」は、展開済み分岐条件式が記憶されていないことを示す。変更前および変更後ソースコードの両方の入力変数検索処理が終了すると、ステップｓ５からステップｓ６へ移行する。
【０１２２】
【表１６】
2007041804.tif 000018
【０１２３】
図１０は、入力値生成処理の手順を示すフローチャートである。図１１は、入力値決定処理の手順を示すフローチャートである。ステップｓ６であるテスト入力値生成処理工程では、テスト入力値生成処理を開始し、テスト入力値生成部１２によって、展開済み分岐条件式に基づいて、変数入力値を演算する。テスト入力値生成処理において、動作主体は、テスト入力値生成部１２である。以下、テスト入力値生成処理においてテスト入力値生成部１２が制御主体の場合、その記載を省略する場合がある。
【０１２４】
以下では、テスト入力値生成処理について具体的に説明する。入力変数検索処理工程ｓ５からテスト入力値生成処理工程ｓ６に移行すると、テスト入力値生成処理を開始し、ステップｆ１へ移行する。ステップｆ１では、各検証対象モジュールにおいて、記憶されている展開済みの分岐条件式のうち、同一内容の展開済みの分岐条件式を検出する。同一内容の展開済みの分岐条件式を検出すると、これらのうち１つの展開済みの分岐条件式を残して残りを削除する。削除すると、ステップｆ１からステップｆ２へ移行する。
【０１２５】
ステップｆ２である入力値決定処理工程では、入力値決定処理を開始し、入力値を決定する。以下では、入力決定処理について、図１１のフローチャートを参照して、具体的に説明する。ステップｆ１からステップｆ２へ移行すると、入力値決定処理が開始し、ステップｇ１へ移行する。ステップｇ１では、入力変数を１つだけ含む展開済みの分岐条件式、すなわち１変数の展開済みの分岐条件式を検出する。検出すると、ステップｇ１からステップｇ２へ移行する。ステップｇ２では、１変数の展開済みの分岐条件式を定数分離し、入力変数に対する解を演算する。入力変数の解を演算すると、ステップｇ２からステップｇ３へ移行する。
【０１２６】
ステップｇ３では、１変数の展開済みの分岐条件式の関係演算子に等号が含まれるか否かを判定する。換言すると、関係演算子が「＜＝」、「＝＝」または「＞＝」であるか否かを判定する。関係演算子に等号が含まれると判定すると、ステップｇ３からステップｇ４へ移行する。
【０１２７】
ステップｇ４では、入力変数の解を、分岐条件式が真になる入力値である真入力値として検出する。真入力値を検出すると、ステップｇ４からステップｇ５へ移行する。ステップｇ５では、関係演算子が「＜＝」、「＝＝」および「＞＝」のいずれであるかを判定する。関係演算子が「＝＝」または「＜＝」であると判定すると、ステップｇ５からステップｇ６へ移行する。関係演算子が「＞＝」であると判定すると、ステップｇ５からステップｇ７へ移行する。
【０１２８】
ステップｇ６では、入力変数の解に１を加算した値を、分岐条件式が偽になる入力値である偽入力値として検出する。この検出された真および偽入力値を記憶させる。真および偽入力値を記憶させると、ステップｇ６からステップｇ８へ移行する。ステップｇ７では、入力変数の解から１を減算した値を、偽入力値として検出する。この検出された真および偽入力値を記憶させる。真および偽入力値を記憶させると、ステップｇ７からステップｇ８へ移行する。
【０１２９】
ステップｇ３で、関係演算子に等号が含まれないと判定すると、ステップｇ３からステップｇ９へ移行する。ステップｇ９では、入力変数の解を偽入力値として検出する。偽入力値を検出すると、ステップｇ９からステップｇ１０へ移行する。ステップｇ１０では、関係演算子が「＜」、「！＝」および「＞」のいずれであるかを判定する。関係演算子が「！＝」または「＞」であると判定すると、ステップｇ１０からステップｇ１１へ移行する。関係演算子が「＜」であると判定すると、ステップｇ１０からステップｇ１２へ移行する。
【０１３０】
ステップｇ１１では、入力変数の解に１を加算した値を、真入力値として検出する。この検出された真および偽入力値を記憶させる。真および偽入力値を記憶させると、ステップｇ１１からステップｇ８へ移行する。ステップｇ１２では、入力変数の解から１を減算した値を、真入力値として検出する。この検出された真および偽入力値を記憶させる。真および偽入力値を記憶させると、ステップｇ１２からステップｇ８へ移行する。
【０１３１】
ステップｇ８では、すべての１変数の展開済みの分岐条件式について、真および偽入力値が決定したか否かを判定する。演算されていないと判定すると、真および偽入力値が演算されていない１変数の展開済み分岐条件式を検出し、ステップｇ８からステップｇ２へ戻る。決定していると判定すると、入力値決定処理が終了し、ステップｆ２からステップｆ３へ移行する。
【０１３２】
ステップｆ３では、真および偽入力値が決定していない入力変数があるか否かを判定する。決定していない入力変数があると判定すると、ステップｆ３からステップｆ４へ移行する。
【０１３３】
ステップｆ４では、真および偽入力値が未決定の入力変数（以下、「未決定の入力変数」と称する場合がある）を含む展開済みの分岐条件式において、未決定の入力変数の個数を判定する。たとえば、３つの入力変数を含む展開済みの分岐条件式において、ステップｆ２で、２つの変数入力の真および偽入力値が決定している場合、未決定の入力変数は、１つであると判定する。またステップｆ２で、１つの変数入力の真および偽入力値が決定している場合、未決定の入力変数は、２つであると判定する。このようにして未決定の入力変数の個数を判定する。未決定の入力変数の個数が１つの展開済みの分岐条件式があると判定すると、ステップｆ５へ移行する。
【０１３４】
ステップｆ５では、未決定の入力変数の入力値を決定する。具体的には、まず未決定の入力変数を変数とし、真および偽入力値が検出している入力変数を定数とみなして、展開済みの分岐条件式を定数分離する。次に真および偽入力値が検出している入力変数に、真および偽入力値をそれぞれ代入する。代入すると、代入によって未決定の入力変数だけの１変数の展開済みの分岐条件式になり、ステップｆ５からステップｆ２へ戻る。ステップｆ２に戻ると、未定数の入力変数の解を演算し、未決定の入力変数の真入力値および偽入力値を検出する。
【０１３５】
以下では、ステップｆ４からステップｆ５へ移行し、ステップｆ２へ戻る一連の流れについて、展開済みの分岐条件式が「ａ＋ｂ＋ｃ＝０」であり、入力変数ａ，ｂの入力値の組合わせが（ａ，ｂ）＝（０，２），（０，３）、入力変数ｃが未決定の入力変数である場合を例に挙げて説明する。まず、ステップｆ４で、未決定の入力変数の個数が１として、ステップｆ５へ移行する。ステップｆ５では、入力変数ｃについて定数分離し、式「ｃ＝−ａ−ｂ」を演算する。次に、入力変数ａ，ｂを組合わせ毎に代入し、２つの式「ｃ＝−２」および「ｃ＝−３」を得る。代入すると、入力変数ｃのステップｆ５からステップｆ２へ移行し、入力変数ｃの真入力値および偽入力値を検出する。検出された真および偽入力値および入力変数ａ，ｂとの組合わせは、変数ｃが真になる場合、（ａ，ｂ，ｃ）＝（０，２，−２），（０，３，−３）であり、偽になる組合わせは、（ａ，ｂ，ｃ）＝（０，２，−１），（０，３，−２）である。このようにして演算された真および偽入力値を、入力変数ｃの真および偽入力値に決定する。
【０１３６】
ステップｆ４で、未決定の入力変数が１つの展開済みの分岐条件式がない場合、ステップｆ６へ移行する。ステップｆ６では、複数の未決定の入力変数のうちいずれか１つの入力変数を選出し、この入力変数の入力値を１に決定する。その選出方法は、たとえば検出された展開済みの分岐条件式に最も使用されていない入力変数を選出する。このようにして未決定の入力変数の入力値を１に決定すると、ステップｆ６からステップｆ４へ戻る。
【０１３７】
ステップｆ３で、未決定の入力変数がないと判定すると、ステップｆ３からステップｆ７へ移行する。ステップｆ７では、各入力変数の偽入力値を変数入力値として記憶させる。検出された変数入力値のうち、すべての展開済みの分岐条件式に対し真および偽の結果が同一の変数入力値は、１つの変数入力値を除き他のすべての変数入力値を削除する。さらに各入力変数に対する変数入力値の組合わせ（以下、単に「組合わせ」と称する場合がある）を検出する。このようにして変数入力値を生成する。変数入力値を生成すると、入力値生成処理工程が終了し、ステップｓ６からステップｓ７へ移行する。
【０１３８】
このテスト入力値生成処理では、変更前および変更後ソースコードにおいて、変数名が変更されている入力変数を同一の入力変数とみなし、変数入力値を検出する。検出された変数入力値は、前記同一とみなされた各入力変数の変数入力値として記憶される。具体的に説明すると、たとえば同一関数において、変更前ソースコードおよび変更後ソースコードの引数の変数名が異なる場合、テスト入力値生成処理では、これら入力変数が同一の入力変数であるとみなし、これらの変数入力値を各入力変数に相互に入力すべき入力値であるとみなす。
【０１３９】
以下では、この入力変数検索処理について、変更前および変更後ソースコードを用いて、表１５および１６の展開済みの分岐条件式を参照しつつ具体的に説明する。ステップｆ１において、変更前および変更後ソースコードから得られる展開済みの分岐条件式に基づいて、６つの展開済みの分岐条件式が取得される。６つの展開済みの分岐条件式は、「ａ＜＝１００」、「ａ＞＝１０１」、「ａ＞２００」、「ａ＜２０１」、「ｓｕｂ（１）＝１」、「ｓｕｂ（１）＝２」である。ここで「ｓｕｂ（１）」の１は、識別番号である。この６つの展開済みの分岐条件式を取得すると、ステップｆ１からステップｆ２へ移行する。
【０１４０】
ステップｆ２へ移行すると、テスト入力値生成処理が開始する。ステップｇ１では、１変数の展開済みの分岐条件式「ａ＜＝１００」を検出する。検出すると、ステップｇ１からステップｇ２へ移行する。ステップｇ２では、「ａ＜＝１００」の関係演算子に等号が含まれると判定する。これによってステップｇ２からステップｇ３へ移行する。ステップｇ３では、入力変数ａの真入力値として、「ａ＜＝１００」の定数である１００を記憶させる。これによってステップｇ５へ移行する。
【０１４１】
ステップｇ５では、「ａ＜＝１００」の関係演算子が「＜＝」であると判定する。これによってステップｇ５からステップｇ６へ移行する。ステップｇ６では、入力変数ａの偽入力値として、「ａ＜＝１００」の定数である１００に１を加えた１０１を記憶させる。これによってステップｇ６からステップｇ８へ移行する。ステップｇ８では、真および偽入力値が検出されていない１変数の展開済みの分岐条件式があるので、ステップｇ８からステップｇ１へ戻る。
【０１４２】
ステップｇ１へ戻り、次の１変数の展開済みの分岐条件式「ａ＞＝１００」を検出し、この分岐条件式に基づいて入力変数ａの真および偽入力値を検出する。他の４つの展開済みの分岐条件式も、１変数の展開済みの分岐条件式であるので、同様にして、ステップｇ１で検出され、各入力変数の真および偽入力値が検出され記憶される。各展開済みの分岐条件式に基づいて検出された各入力変数の真および偽入力値を表１７に示す。すべての１変数の展開済みの分岐条件式を検出すると、テスト入力値生成処理が終了し、ステップｆ２からステップｆ３へ移行する。
【０１４３】
【表１７】
2007041804.tif 000019
【０１４４】
ステップｆ３では、変数入力値が決定していない入力変数がないと判定する。これによってステップｆ３からステップｆ８へ移行する。ステップｆ８では、表１７に示す各入力変数の真および偽入力値に基づいて、表１８に示す変数入力値が検出される。このとき、すべての展開済みの分岐条件式の真偽の結果が同一となる、変数入力値「ａ＝１０１」および「ａ＝２００」のうち「ａ＝２００」が削除される。表１８に示される変数入力値のそれぞれの組合わせを検出する。検出された組合わせを表１９に示す。このようにして変数入力値を生成すると、ステップｓ６からステップｓ７へ移行する。
【０１４５】
【表１８】
2007041804.tif 000020
【０１４６】
【表１９】
2007041804.tif 000021
【０１４７】
表１９は、縦の行に入力変数、横の行に各組合わせの組合わせ番号を示す。たとえば（ａ，ｓｕｂ（１））＝（１００，１）の組合わせ番号は、Ｐ１である。
【０１４８】
図１２は、生成されたテストプログラムのフローチャートである。ステップｓ７であるテスト生成工程では、テスト生成部１３によって、変更前および変更後ソースコード、モジュール情報、識別番号、入力変数ならびに変数入力値の組合わせに基づいて、テストプログラムを生成する。テストプログラムのフローについて、図１２を参照して説明する。
【０１４９】
まずステップｈ１では、テスト入力値生成処理工程で生成された、変数入力値の組合わせを選出し、各入力変数にその変数入力値を代入する。選出し代入すると、ステップｈ１からステップｈ２へ移行する。ステップｈ２では、検証対象モジュールを呼び出し、代入された各変数入力値に基づく出力値を演算させる。演算すると、ステップｈ２からステップｈ３へ移行する。ステップｈ３では、代入された各変数入力値と演算された出力値とを関連付けて出力させる。出力させると、ステップｈ３からステップｈ４へ移行する。
【０１５０】
ステップｈ４では、すべての組合わせが選出されたか否かを判定する。すべての組合わせが選出されたと判定すると、テストプログラムのフローが終了する。ステップｈ４で、すべての組合わせが選出されていないと判定すると、ステップｈ１へ戻り、選出されていない組合わせを選出し、各入力変数にその変数入力値を代入する。
【０１５１】
このようなステップｈ１からステップｈ４へ移行し、ステップｈ１へ戻るサイクルを、テストサイクルと称する。このテストサイクルを繰返すことによって、全ての組合わせの変数入力値に対する出力値が出力させる。
【０１５２】
テストプログラムには、さらに同一の識別番号が付与された外部関数の呼び出し回数を演算し、各呼び出しに対して異なる外部関数の変数入力値を代入させる。外部関数が同一の変数入力値であることによって、検証が不充分な場合がある。たとえばｆｏｒ文などのループ文内に外部関数が記述され、その外部関数の値に基づいてループ文を終了させる場合がある。この場合、外部関数の値が変化しなければ、無限ループに嵌り、検証が終了しない場合がある。呼び出し毎に、外部関数の入力変数値を変えることによって、検証が終了しないことを未然に防止し、前記モジュールによって、不充分な検証になることを防止できる。ただし、必ずしもこのモジュールを必要とするわけではなく、変更前および変更後ソースコードのようにループ文が無い場合、このような命令文を省略してもよい。また一定回数の呼び出しがあった場合、ループ文から抜け出すようにしてもよい。
【０１５３】
このようなテスト生成工程で、テスト生成部１３によって生成されたテストプログラムを表２０に示す。以下では、本実施の形態で生成されたテストプログラムのソースコード（以下、「テストソースコード」と称する場合がある）について、説明する。
【０１５４】
【表２０】
2007041804.tif 000022
【０１５５】
テストソースコードでは、まず入力変数ａおよび外部関数ｓｕｂ（）の変数入力値の各配列に入力させる（１行目から１３行目）。入力変数ａのすべての変数入力値が配列ｖａ[ａＮｕｍ]に入力され、外部関数のすべての変数入力値が配列ｖｓｕｂ[ｓｕｂＮｕｍ]に入力されている。
【０１５６】
１４行目から５３行目には、テストサイクルのフローのソースコード、つまりテストプログラムにおいてメインとなる関数が記述されている。メインとなる関数は、変更前および変更後ソースコードに含まれる関数名（ｆｕｎｃ（），ｓｕｂ（）など）と重複しない関数名（本実施の形態では、ｔｅｓｔ）を、テスト生成部１３によって付されている。これによって、関数名が同一のため検証が行えないことを防止する。
【０１５７】
１６行目から２０行目では、各ローカル変数の型宣言をしている。２２行目から５０行目では、各組合わせ（Ｐ１〜Ｐ９の組合わせ）を選出し、選出された組合わせに基づいて関数ｆｕｎｃの出力値を演算させる（４０行目）。選出された組合わせおよび前記出力値などを関連付けて出力させる。すべての変数入力値の組合わせについて、組合わせおよび出力値などを関連付けて出力させる。具体的には、入力変数ａと外部関数ｓｕｂ（）との組合わせ、出力値である関数ｆｕｎｃおよび関数を演算前後の配列ｂ[１０]が関連付けて出力される。すべての組合わせについて、この出力結果を取得する。
【０１５８】
５５行目から７５行目では、同一の識別番号の外部関数が呼び出される度に、その外部関数の変数入力値を変更させている。具体的には、変数入力値「ｓｕｂ（１）＝１」が選出された場合、最初に外部関数「ｓｕｂ（１）」に値の入力を要求されている際、この外部関数「ｓｕｂ（１）」に１を入力する。次に外部関数「ｓｕｂ（１）」の入力が要求されると、他の変数入力値「ｓｕｂ（１）＝２」を入力する。さらに次に外部関数「ｓｕｂ（１）」の入力が要求されると、他の変数入力値「ｓｕｂ（１）＝３」を入力する。検出された変数入力値が「ｓｕｂ（１）＝１，２，３」である場合、変数入力値「ｓｕｂ（１）＝３」を入力した後、さらに外部関数「ｓｕｂ（１）」の入力が要求されると、再度、変数入力値「ｓｕｂ（１）＝１」を入力する。このようなサイクルを繰り返し、無限ループなどに起因する不充分な検証を防止する。また入力させる値として２が選出されている場合、２を起点として「２」、「３」、「１」の順で、入力される。
【０１５９】
テスト生成部１３によって、このようなテストソースコードが生成されると、ステップｓ７からステップｓ８へ移行する。
【０１６０】
ステップｓ８であるテスト実行工程では、テスト生成工程ｓ７で生成されたテストプログラムを実行する。テストプログラムが実行されると、すべての組合わせについて、各組合わせ毎に前記出力結果を演算させる。テスト実行部１４は、これらの出力結果を記憶させる。出力結果が記憶されると、ステップｓ８からステップｓ９へ移行する。変更前ソースコードに基づいて、テストプログラムを実行して演算された出力結果を表２１に示す。
【０１６１】
各組合わせ毎に出力結果が示されている。たとえば「ａ＝１００，ｓｕｂ（）＝１」の組合わせＰ１の出力結果が、「Ｐａｔｔｅｒｎ１」として１行目から６行目に示されている。７行目から５７行目まで、同様に、組合わせＰ２〜Ｐ９の出力結果が「Ｐａｔｔｅｒｎ２」〜「Ｐａｔｔｅｒｎ９」として示されている。
【０１６２】
組合わせＰ４〜Ｐ６では、出力結果として「ｃａｌｌ  ｓｕｂ（１００）」が示されている。これは、前記組合わせＰ４〜Ｐ６において、外部関数「ｓｕｂ（）」が引数を「ａ＝１００」として呼び出されたことを示している。このようにして、各組合わせＰ１〜Ｐ９に基づく出力値および外部関数の呼び出しの有無について出力される。
【０１６３】
変更後ソースコードに基づいて、テストプログラムを実行して得られた出力結果を表２２に示す。変更後ソースコードでも、変更前ソースコードの場合と同様に、各組合わせＰ１〜Ｐ９に基づく出力値および外部関数の呼び出しの有無について出力される。
【０１６４】
【表２１】
2007041804.tif 000023
【０１６５】
【表２２】
2007041804.tif 000024
【０１６６】
図１３は、出力値比較検証処理の手順を示すフローチャートである。ステップｓ９である出力比較検証処理工程では、出力比較検証処理を開始し、出力値比較検証部１５によって、各検証対象モジュールに基づいて出力された出力結果を相互に比較し、検証対象モジュールの入力値に対する出力値の同一性を検証する。比較検証処理において、動作主体は、出力値比較検証部１５である。以下、比較検証処理において出力値比較検証部１５が制御主体の場合、その記載を省略する場合がある。
【０１６７】
以下では、比較検証処理について具体的に説明する。テスト実行工程ｓ８から比較検証処理工程ｓ９に移行すると、比較検証処理が開始し、ステップｊ１へ移行する。ステップｊ１では、変更前および変更後ソースコードの出力結果を、組合わせ毎に比較する。比較をすると、ステップｊ１からステップｊ２へ移行する。
【０１６８】
ステップｊ２では、変更前および変更後ソースコードの出力結果において、変数入力値が同一の組合わせであって、異なる出力値が出力がされる組合わせを検出する。組合わせが検出できないと判定すると、出力値比較検証処理が終了し、ステップｓ９からステップｓ１０へ移行する。組合わせが検出されたと判定すると、ステップｊ２からステップｊ３へ移行する。ステップｊ３では、検出された組合わせおよび変更前および変更後ソースコード出力値を記憶させ、検証結果として出力する。検証結果が出力されると、ステップｊ３からステップｊ４へ移行する。
【０１６９】
ステップｊ４では、モジュール情報、特定条件Ｓ１，Ｓ２，Ｓ３およびローカル変数検出情報に基づいて、４つの不充分条件のうちいずれか１つに該当するか否かを判定する。４つの不充分条件は、（１）各検証対象モジュールのモジュール情報が異なる（配列要素だけが異なる場合も含む）、（２）特定条件Ｓ１およびＳ３を具備すること、（３）特定条件Ｓ２を具備する、ことおよび（４）値の設定されていないローカル変数を検出したローカル変数検出情報が記憶されていることである。これら４つの不充分条件のいずれかに該当すると、検証が不充分である可能性がある。４つの不充分条件のいずれかに該当すると判定する、該当する不充分条件を記憶させ、検証結果として出力し、出力値比較検証処理が終了する。４つの不充分条件のいずれにも該当しないと判定すると、出力値比較検証処理が終了する。出力値比較検証処理が終了すると、出力値比較検証処理工程が終了し、ステップｓ９からステップｓ１０へ移行する。
【０１７０】
ステップｓ１０である検証結果報知工程では、テスト実行処理工程の出力結果および出力値比較検証処理工程の検証結果を、出力部５によって、利用者に報知する。報知すると、プログラム検証処理が終了する。
【０１７１】
以下には、検証結果報知工程で、変更前および変更後ソースコードの出力結果を比較して検証した検証結果を表２３に示す。検証結果では、Ｐ４およびＰ６の組合わせにおいて出力値が異なることが検出されている。
【０１７２】
【表２３】
2007041804.tif 000025
【０１７３】
利用者は、検証結果に基づいて、ソースコードのバグの修正を行う。検証結果に基づいて、バグの修正がされた変更後ソースコードを表２４に示す。検証結果に基づいて修正された部分は、修正後のソースコードの１５行目から２２行目であり、顕著な変更部分は、１９行目のｉｆ文を追加したことである。このようにして検証結果に基づいて修正することによって、正常にリファクタリングされたソースコードを得ることができる。
【０１７４】
装置本体２は、検証プログラムを実行することによって、プログラム検証処理を行っている。
【０１７５】
【表２４】
2007041804.tif 000026
【０１７６】
以下では、このようなプログラム検証装置１が奏する効果について説明する。本実施の形態のプログラム検証装置１によれば、入力値演算手段１６によって、真入力値および偽入力値を演算する。テスト生成部１３は、真および偽入力値に基づく出力値を出力させるテストプログラムを生成する。テストプログラムを実行することによって、真および偽入力値に基づいて出力される出力値を演算できる。変更前および変更後モジュールについて、同様にテストプログラムを生成し実行することによって、変更前および変更後モジュールの真および偽入力値ならびにこれらの入力値に基づく出力値を演算できる。演算された出力値を比較することによって、変更前および変更後モジュールの真および偽入力値に基づく出力値が相互に同一であるか否かを容易に検証できる。このように出力値の同一性を容易に検証できるので、たとえば変更後モジュールおよび変更前モジュールの入力値に対する出力値の同一性を検証できる。すべての条件式の真および偽入力値を演算することによって、変更前および変更後モジュールで辿り得るすべての処理経路について検証することができ、また出力し得るすべての出力値を検証できる。これによって漏れのない検証を実現できる。このような漏れのない検証結果に基づいて、利用者は、変更後モジュールに含まれるバグを漏れなく検出し、バグを容易に修正できる。
【０１７７】
本実施の形態のプログラム検証装置１によれば、入力値演算手段１６によって、真入力値および偽入力値を演算する。プログラム実行手段１７は、真および偽入力値に基づいて、これら入力値が演算された変更前および変更後モジュールを実行し、真および偽入力値に基づく出力値を出力する。出力値比較検証部１５は、プログラム実行手段１７によって出力された変更前および変更後モジュールの出力値を相互に比較する。出力値比較検証部１５は、比較結果に基づいて、変更前および変更後モジュールの真および偽入力値に基づく出力値が相互に同一であるか否かを検証する。真および偽入力値に基づく出力値が同一であるか否かを検証することによって、たとえば変更後モジュールおよび変更前モジュールの入力値に対する出力値の同一性を利用者が検証する手間を省くことができる。検証について人の手が介在しないので、利用者の検証漏れを防ぐことができる。またすべての条件式の真および偽入力値を演算することによって、各検証対象プログラムで辿り得るすべての処理経路（フロー）について検証することができ、また出力し得るすべての出力値を検証できる。これによって漏れのない検証を実現できる。このような漏れのない検証結果に基づいて、変更後のプログラムに含まれるバグを漏れなく検出し、利用者が漏れなくバグを修正することを促進できる。
【０１７８】
本実施の形態の検証プログラムによれば、各検証対象プログラムの真および偽入力値に基づく出力値が相互に同一であるか否かを容易に検証できる装置を実現できる。
【０１７９】
本実施の形態のプログラム検証装置１によれば、４つの不充分条件に該当するか否かを出力する。これによって充分な検証に基づいて検証結果が出力されているか否かを、利用者が容易に判断できる。また検証結果が不充分である場合、不充分条件に該当する部分にバグが含まれている可能性があることを利用者に報知できる。報知することによって、利用者に不充分条件に該当する部分を検討させることになり、バグ発見の補助的な役割も担う。
【０１８０】
本実施の形態のプログラム検証装置１によれば、テスト入力値生成部１２は、すべての展開済みの分岐条件式に対して真偽の結果が同じ、変数入力値の組合わせを削除している。これによってテスト実行部１４で演算すべき変数入力値の組合わせを低減することができ、検証速度を速めることができる。
【０１８１】
本発明の形態のプログラム検証装置１によれば、未決定の入力変数の入力値を１に設定する。これによって未決定の入力変数の入力値があっても、ソースコードの検証を続けられることができ、検証が実行不能になることが防止される。また未決定の入力変数の入力値を１に設定することによって、初等関数などにおいて演算が不可能になる場合が少なく、条件式および変換式において演算が不可能な場合の発生を少なくできる。これによってソースコードの検証を最後まで実行できる。また全分岐条件式に基づいて、未決定の入力変数の入力値の解を演算する場合、前記入力値の解が演算不可能な場合が多く、予め１に設定することによって、これらの演算を行うことなく、検証を実行させることができる。
【０１８２】
本実施の形態では、処理経路抽出処理は前述のような手順で処理を行っているけれども、特開２００１−１０９６４４に記載される方法で処理経路を抽出してもよい。
【０１８３】
本実施の形態では、処理経路抽出処理において、ループ文を検出すると、そのループ文内の処理ブロックを次の処理ブロックとして抽出している。しかしながらループ文の条件式によって、ループ文内の処理ブロックを次の処理ブロックとしない場合を含め、任意の回数だけループ文内の処理ブロックを連続して処理することがあるので、ループ文内の処理ブロックを次の処理ブロックとしない処理経路や、複数回処理する経路も生成することが好ましい。
【０１８４】
本実施の形態では、テスト生成部１３で、同一の展開済みの分岐条件式および同一の真偽の結果となる真および偽入力値は、１つの分岐条件式および入力値を残して削除されるけれども、必ずしも削除する必要は無い。これは、プログラム検証装置１のプログラム検証処理の処理を早くするためであり、削除しなくてもよい。
【０１８５】
本実施の形態では、入力値決定処理で真および偽入力値を決定する際、真または偽入力値に１を加減しているけれども、必ずしも加減する値が１に限定されない。正の整数であればよい。また本実施の形態のソースコードでは、入力変数が整数型であるので、加減する値が１であるけれども、実数型の入力変数であれば、その加減する値が正の実数であってもよい。この場合、１を加減すると、宣言されて型の制約上、入力変数のとり得る値を超える場合に有効となる。
【０１８６】
また変数入力値は、真および偽入力値だけであるけれども、必ずしもこれだけに限定されない。たとえば宣言された型の制約上、入力変数がとり得る最大値（１６ビットのｉｎｔ型の場合、３２７６７）および最小値（１６ビットのｉｎｔ型の場合、−３２７６８）を変数入力値として用いてもよい。また０も同様に変数入力値として用いてもよい。これらの値は、プログラムを実行する上で、不具合を生じやすい値であり、これらの検証も同時に行うことが好ましい。
【０１８７】
さらに列挙型（ｅｎｕｍ型）の入力変数の場合、これら列挙されるすべて入力値を変数入力値としてもよい。
【０１８８】
本実施の形態では、出力部５によって、出力結果および検証結果を報知しているけれども、このような結果だけを報知することに限定されない。たとえばモジュール情報を報知してもよく、これを報知すると、検証対象モジュールが外部モジュールに与える影響を利用者が知ることができる。
【０１８９】
本実施の形態では、２つの検証対象モジュールの同一性について検証しているけれども、２つの検証対象モジュールに限定されない。検証対象モジュールが３つ以上であってもよい。この場合、出力値比較検証部１５は、いずれの検証対象モジュールが異なる出力結果を演算したのかを出力する機能を有すれば、いずれの検証対象モジュールの出力結果が異なるのかが明確になる。
【０１９０】
また本発明では、制御文、たとえばｉｆ文の条件式を各分岐条件式で区切っているけれども、必ずしもこのような区切り方に限定されず、条件式毎に区切ってもよい。この場合、処理経路抽出処理では、各条件式について真偽をそれぞれ判定し、この条件式を検出処理ブロックとして処理経路に追加する。これによって条件式が複雑であっても、プログラムの処理経路を容易に検索できる。
【０１９１】
さらに本発明では、分岐条件式に対応する数式が１つの数式であるけれども、分岐条件式が複数の式および論理演算子を含むものであってもよい。たとえば、表２５に記載されるように、ｉｆ文の条件式が「（（ａ＝＝１｜｜ｂ＝＝１）＆＆ｃ＝＝１）」の場合、（ａ＝＝１＆＆ｂ＝＝１）を１つの処理ブロックとし、ｃ＝＝１を１つの処理ブロックとする。これによって、表２５のように分岐条件式に分岐条件が含まれるような場合であっても、分岐条件式に複数の数式と論理演算子とを含む処理ブロックに区切り、処理経路を検出することできる。
【０１９２】
【表２５】
2007041804.tif 000027
【図面の簡単な説明】
【０１９３】
【図１】本実施の形態のプログラム検証装置１の機能をブロック毎に分けて示すブロック図である。
【図２】プログラム検証処理の手順を示すフローチャートである。
【図３】出力抽出処理の手順を示すフローチャートである。
【図４】識別番号付加処理の手順を示すフローチャートである。
【図５】外部関数に識別番号を付与する前および付与した後のソースコードの一部を示す図である。
【図６】分岐条件抽出処理の手順を示すフローチャートである。
【図７】処理経路抽出処理の手順を示すフローチャートである。
【図８】入力変数検索処理の手順を示すフローチャートである。
【図９】分岐条件式の展開方法の手順を示すフローチャートである。
【図１０】入力値生成処理の手順を示すフローチャートである。
【図１１】入力値検出処理の手順を示すフローチャートである。
【図１２】生成されたテストプログラムのフローチャートである。
【図１３】出力値比較検証処理の手順を示すフローチャートである。
【符号の説明】
【０１９４】
１  プログラム検証装置
２  装置本体
１３  テスト生成部
１５  出力値比較検証部
１６  入力値演算手段
１７  プログラム実行手段
【図１】
2007041804.tif 000028
【図２】
2007041804.tif 000029
【図３】
2007041804.tif 000030
【図４】
2007041804.tif 000031
【図５】
2007041804.tif 000032
【図６】
2007041804.tif 000033
【図７】
2007041804.tif 000034
【図８】
2007041804.tif 000035
【図９】
2007041804.tif 000036
【図１０】
2007041804.tif 000037
【図１１】
2007041804.tif 000038
【図１２】
2007041804.tif 000039
【図１３】
2007041804.tif 000040