Disciplined Software Engineering Lecture #13 Software Engineering Institute Carnegie Mellon University Pittsburgh, PA 15213 Sponsored by the U.S. Department of Defense Copyright © 1994 Carnegie Mellon University1 設計検証, 第2部 この講義は設計検証の第2部である。 話題は: •トレース表 -シンボリック実行 -ケースチェッキング •数学的なプログラム検証 •プログラムの証明 Copyright © 1994 Carnegie Mellon University2 トレース表 トレース表は実行表と似ているがより一般的である。 トレース表は個々のケースの検証よりもむしろ一般的 なプログラム動作を調べる。 トレース表は以下を使用する •シンボリック実行 •ケースチェッキング Copyright © 1994 Carnegie Mellon University3 シンボリック実行- 1 シンボリック実行では •プログラムはシンボリックに表現される。 •プログラム動作は分析的に調べられる。 シンボリック実行により一般的検証をする事が出来る。 シンボリック実行は常に実際的であるとは限らない。 Copyright © 1994 Carnegie Mellon University4 シンボリック実行- 2 シンボリック実行のアプローチ手順は以下のとおりであ る •代数的シンボルをプログラム変数に割り当てる •これらのシンボルを用いて1つ以上の方程式でプログラ ムを記述し直す •これらの方程式の動作を分析する Copyright © 1994 Carnegie Mellon University5 シンボリック実行- 3 尋ねるべきいくつかの質問 •プログラムはある結果に収束するか? •プログラムは正常および異常の双方の入力値に対して どのように動作するか? •プログラムは常に望ましい結果を作り出すか? Copyright © 1994 Carnegie Mellon University6 シンボリック実行例 次のような簡単なプログラム部分が与えられるとする begin V1 = V2 V2 = V4 V3 = V1 V4 = V3 end V1, V2, V3, and V4のいろいろな値に対する結果は どんなものになるだろうか? Copyright © 1994 Carnegie Mellon University7 シンボリックトレース表 この例に対するトレース表このようになる: # 命令 1 初期値 V1 = V2 2 3 V2 = V4 4 V4 = V3 最終値 V1 V2 V3 V4 A B C D B D B V3 = V1 B B D B B したがって、入力 A, B, C, Dに対する結果は B, D, B, B である。 Copyright © 1994 Carnegie Mellon University8 シンボリック実行演習 次のようなプログラムがどの値で終了するか決定せよ。 Calculate(x: real) if x > 0 x = sqrt(x)-1 else x = -x if x<>0 Calculate(x) end. Copyright © 1994 Carnegie Mellon University9 演習結果- 1 変数は x1 および x2 によって表現することが出来る。 各サイクルの結果に対する方程式は if x1>0: x2 = sqrt(x1) -1 if x1 <= 0: x2 = -x1 である。 Copyright © 1994 Carnegie Mellon University10 演習結果- 2 x1 = 0 に対して, プログラムは第1サイクルで終了する。 x1 = 1 に対して, プログラムは第1サイクルで終了する。 x1 = -1 に対して, プログラムは第2サイクルで終了する。 Copyright © 1994 Carnegie Mellon University11 演習結果- 3 後ろ向きに動かすと •x2が1であるためには, x1は4であるべきであろう。 •x2が4であるためには, x1は25であるべきであろう。 •X2が25であるためには, x1は676になるべきであろ う。 •X2が676であるためには, x1は458329であるべきで あろう。 •など したがって、プログラムは入力値 +/- の 1, 4, 25, 676, 458329, 等に対して終了する。 Copyright © 1994 Carnegie Mellon University12 演習結果- 4 X1の他の大きな正または負の値に対して, x2 の値は -1 と +1の間のゼロでないある数に収束するであろう。 -1と +1の間のゼロでない値に対して何が起こるか? Copyright © 1994 Carnegie Mellon University13 演習結果- 5 x1=a, a は非常に小さな数とすると •x2=sqrt(a)-1, 負の数 •次に、 x2 は正にする •次の2サイクルで, x2 は近似的に sqrt(a)/2, あるいは aより少し大きな数になる。 したがって、小さな x1に対して, x2の値は、次第にx1 より大きくなる。 したがって X2 の値は 0に到達せず、1より小さなある 数に収束するであろう。 Copyright © 1994 Carnegie Mellon University14 演習結果- 6 値が収束する時, x1 = x2 = x でかつその結果は 次の 方程式で与えられるであろう sqrt(x) - 1 = -x この方程式に対する解はつぎである x = [3 - sqrt(5)]/2 = 0.381966 したがって, プログラムは +/- 0.381966 の間を巡回する ことになるであろう。 Copyright © 1994 Carnegie Mellon University15 シンボリック実行の利点 シンボリックな証明は一般性を持ち得る シンボリックな証明は典型的には他の方法より少ない 作業で済む シンボリックな証明はテストケースを実行するよりエラ ーを起こすことが少ない Copyright © 1994 Carnegie Mellon University16 シンボリック実行の欠点 シンボリック実行はアルゴリズム的かつ代入問題を除いて使 用することは難しい。 シンボリック実行の証明は手作業であり、したがってエラー を起こしやすい。 シンボリック実行は複雑な論理に対して使用することは 難しい。 Copyright © 1994 Carnegie Mellon University17 ケースチェッキング - 1 ケースチェッキングには次のステップがある 1. プログラムを調べ、プログラム動作のいろいろな カテゴリを決定する 2. これらのカテゴリに対して、チェックすべきケースを 識別する 3. 各ケースをチェックしそれらが全ての可能な状況を カバーしていることを保証する Copyright © 1994 Carnegie Mellon University18 ケースチェッキング - 2 4. トレース表をそれだけでか、シンボリック実行 あるいは帰納法による証明を併用するかによって 、各ケースについてプログラム動作を調べる 5. 全てのケースが検証されるとプログラム動作が 検証されたことになる Copyright © 1994 Carnegie Mellon University19 トレース表の例- 1 ClearSpacesプログラムの要求は •文字列から先頭および末尾の空白を除く •埋め込まれた空白はそのままにしておく •空の文字列に対しては状態値を0にする •1空白からなる文字列に対しては状態値を1にする •2つ以上の空白の文字列に対しては状態値を2にする •空白以外の文字を含む文字列に対しては状態値を 3にする Copyright © 1994 Carnegie Mellon University20 トレース表の例- 2 プログラムで末尾の空白を取り除くための部分は次であ る。 ClearSpaces(var Input: string; State: int) Length = length(Input) if Length > 0 repeat(until State=3 or Length=0) if Input[Length-1] = ‘ ‘ Length = Length - 1 if State < 2 State=State+1 else State = 3 until State=3 or Length=0 Copyright © 1994 Carnegie Mellon University21 トレース表の例- 3 末尾の空白のケースを定義するため次の約束事を確 立する 1. メッセージ文字列は非空白文字で始まりかつ 終わる文字列である 2. 入力文字列はm個のメッセージ文字とt個の後続 空白文字からなる 3. m は >0 または 0 である 4. t は >0 または 0 である Copyright © 1994 Carnegie Mellon University22 トレース表の例- 4 従って、全部で4つのケースがある。 1. 0-0: m = 0, t = 0 2. 0-t: m = 0, t > 0 3. m-0: m > 0, t = 0 4. m-t: m > 0, t > 0 Copyright © 1994 Carnegie Mellon University23 トレース表の例- 5 戦略は最も適当な手法を何でも使うことによって 各ケースでのプログラム動作を検証することである 1. 0-0のケースは実行テーブルを用いて単独で チェックする 2. 他のケースでは帰納的な証明を用いてチェック する 3. 第12講で述べた実行表の手法を使って、 トレース表で各証明を行いなさい Copyright © 1994 Carnegie Mellon University24 プログラムの正当性の検証 これらの手法はプログラムを数学の定理として扱うこと に基づく 設計や設計レビューで特に有用である プログラム検証にはしばしば高度な推論が必要となる ので、作業を注意深くチェックすることが重要である。 Copyright © 1994 Carnegie Mellon University25 正当性検証 正当性検証アプローチでは次のことを行う. •すべてのプログラムケースを識別する •トレース表を用いて、全てのケースに対してプログラム が満足しなければならない全ての条件を評価する •適切な所では帰納法による証明を用いる 全てのケースについて全ての条件が満足されたら プログラムは検証されたことになる この検証アプローチはほとんどの設計構成体に適用で きるが、本講ではループについてのみ述べる Copyright © 1994 Carnegie Mellon University26 ForLoop の検証- 1 ForLoopは次の形式であると仮定する ForLoop for n = First to Last begin nPart end Copyright © 1994 Carnegie Mellon University27 ForLoop の検証- 2 for-loop条件では次の質問に対する答えが真であるこ とが必要である ForLoop = FirstPart+SecondPart+...+LastPart であるか? Copyright © 1994 Carnegie Mellon University28 ForLoop の例 - 1 次のプログラムがnの階乗を生成することを検証せよ factorial(n) begin x=1 for i=1 to n x = x*i return = x end Copyright © 1994 Carnegie Mellon University29 ForLoop の例- 2 第一にケースを識別する。 ケースはn=1とn>1である n = 1 のケースに対しては ForLoop = 1! = 1 FirstPart+SecondPart+...=FirstPart = 1*1=1 n=1のケースはかくして正しい Copyright © 1994 Carnegie Mellon University30 ForLoop の例- 3 n>1 例えば3 に対しては ForLoop = 3! = 6 FirstPart+SecondPart+ThirdPart = 1*1*2*3 = 6 n=3のケースはかくして真である Copyright © 1994 Carnegie Mellon University31 ForLoop の例- 4 次に、nの全てのより大きな値に対しての実行を検証 するため、帰納法による証明を用いなさい n=kに対して動作が検証されたと仮定する ForLoop = k! そして FirstPart+...LastPart = 1*1*2*3*4*...*k = k! Copyright © 1994 Carnegie Mellon University32 ForLoop の例- 5 さて、k+1に対しては ForLoop = k!*(k+1) = (k+1)! FirstPart+...LastPart = 1*1*2*3*4*...*k*(k+1) = (k+1)! かくてプログラムはk+1のとき正しい。従って帰納法 によりn>=1なる全ての値に対して正しい Copyright © 1994 Carnegie Mellon University33 WhileLoop の検証- 1 WhileLoopは次の形式を持つと仮定する WhileLoop while WhileTest begin LoopPart end Copyright © 1994 Carnegie Mellon University34 WhileLoop の検証- 2 質問1。 WhileTestのどんなアーギュメントに対しても ループが終了することが保証されるか? 質問2。 WhileTestが真の時、次が成り立つか? WhileLoop = LoopPart followed by WhileLoop? (注: WhileLoop は LoopPart に WhileLoop が続く) 質問3. WhileTestが偽の時、次が起こるか? WhileLoop はidentityであるか (注:identityとは条件が全く変わらないことをいう) Copyright © 1994 Carnegie Mellon University35 WhileLoop の例- 1 浮動小数点数を標準形にするため、プログラムの最初 の部分を使いなさい。 •Expは正の整数である •Mant は小数点の前にゼロ以外の正の10進数字が 来る NormalizeReal(Mant, Exp, NegEx) while Mant >= 10 do Mant = Mant/10 if NegEx then Exp=Exp-1 else Exp = Exp + 1 Copyright © 1994 Carnegie Mellon University36 WhileLoop の例- 2 Expの値は重要ではないので、関心があるのは3つ のケースである。 1. Mant <10 2. Mant = 10 3. Mant > 10 これらのケースのそれぞれがNegEx が真と偽に対し て調べられる Copyright © 1994 Carnegie Mellon University37 WhileLoop の例- 3 質問1. WhileTestのどんなアーギュメントに対しても ループの終了が保証されるか ? ケース1. Mant < 10ならwhileテストは直ちに成立し ないのでループは終了する ケース2.Mant = 10 ならwhileテストは1サイクルの 後に成立しないのでループは終了する どちらのケースでもNegExの値に関係なく終了する Copyright © 1994 Carnegie Mellon University38 WhileLoop の例- 4 質問1。続き ケース3, Mant > 10のときは帰納法で示される •Mant = k*10**n, ここで 1 <= k < 10 •n=1なら1サイクル後にテストは条件が成立しなくな る •ある値n=mに対してテストが真ならmサイクル後に Mant=k になる •かくてn=m+1に対してはmサイクル後にMant = k*10 となりもう1サイクル後にWhileTestは条件が 成立しなくなる NegExの値は結果に影響しないので質問1は全ての n>=1に対して成立する Copyright © 1994 Carnegie Mellon University39 WhileLoop の例- 5 質問2。 WhileTest が真の時、次は起こるか? WhileLoop = LoopPart followed by WhileLoop? (注: WhileLoop は LoopPart に WhileLoop が続く) ケース1. Mant < 10は、WhileTestが決して真になら ないのでこの条件はあてはまらない Copyright © 1994 Carnegie Mellon University40 WhileLoop の例- 6 他のケースを調べるため、このプログラムが WhileLoopと同じ結果になることをチェックしなさい(次 のOHPで述べる) Mant = Mant/10 if NegEx then Exp=Exp-1 else Exp = Exp + 1 while Mant >= 10 do Mant = Mant/10 if NegEx then Exp=Exp-1 else Exp = Exp + 1 Copyright © 1994 Carnegie Mellon University41 WhileLoop の例- 7 質問2. WhileTestが真の時、次がおこるか? WhileLoop = LoopPart followed by WhileLoop? (注: WhileLoop は LoopPart に WhileLoop が続く) ケース2 Mant = 10の時、NegExの値は関係ない •WhileLoop は1サイクルおこり, Mant = 1になる •LoopPart followed by WhileLoop はMant = 10で 始まり LoopPart は値1で, そして WhileLoop は同 じく値1で終わる。 どちらも同じ結果になるので、答えは真である。 Copyright © 1994 Carnegie Mellon University42 WhileLoop の例- 8 質問2。続き ケース3、Mant > 10 の場合は帰納法で示される •Mant = k*10**n, ここで 1<=k<10 •n = 1の時は WhileLoop は1サイクルおこり、そして LoopPart followed by WhileLoopは一度もおこらな い。 • n > 1 のときは LoopPart followed by WhileLoop は1つ少ないサイクルおこり同じ結果となる。 質問2はかくて全てのケースで満足される。 Copyright © 1994 Carnegie Mellon University43 WhileLoop の例 - 9 質問3 . WhileTestが偽のとき、WhileLoop は identityであるか? ケース1. Mant < 10 はWhileTestが偽となる唯一の ケースである. このケースはプログラムが実行されないので、条件は 乱されないままである。それがIdentityの定義である。 質問3はかくて満足される。 Copyright © 1994 Carnegie Mellon University44 RepeatUntil の検証- 1 RepeatUntil は次の形式を持つ。 RepeatUntil begin LoopPart UntilTest end Copyright © 1994 Carnegie Mellon University45 RepeatUntil の検証- 2 Repeat-untilの検証は 次の3つの質問に対する答え が真の時満足される。 質問1. ループの終了がUntilTestのいかなるアーギュ メントに対しても保証されるか? 質問2. LoopPart のあとのUntilTest が偽のとき, RepeatUntil = LoopPart followed by RepeatUntil であるか? Copyright © 1994 Carnegie Mellon University46 RepeatUntil の検証- 3 質問 3. LoopPart のあとのUntilTest が真のとき RepeatUntil = LoopPartであるか? The repeat-until の検証はWhileLoop と同じ論理 形式に従うので例を示すことは省略する。 Copyright © 1994 Carnegie Mellon University47 プログラム検証に対するコメント- 1 正しく行えば、これらの検証法は全く一般性を有してお り、従ってプログラムの正当性を保証できる。 検証法は技巧が必要であり、スキルを必要とする。 これらの手法を使おうとするのが望ましいが、疑いが あるときはトレース表や実行表を使ってチェックしなさ い。 Copyright © 1994 Carnegie Mellon University48 プログラム検証に対するコメント- 2 訓練をつめば、プログラム検証を非常に素早く行うこと ができるようになる。 起こり得る全てのケースを注意深く実行することで、 ほとんどの欠陥を手早く見つけることができる ループ終了テストは他の方法では無限ループを確認す ることが困難なので特に重要である。 Copyright © 1994 Carnegie Mellon University49 講義13の演習課題 さあ、最後レポートにとりかかろう 中間レポートを作成したプロセスを更新して、それを使 って最後レポートを作成しよう。 更新したプロセス、作業の計画、作業の実データ、そし て最後レポートを提出しよう。 レポートの仕様は付録Dにある。 Copyright © 1994 Carnegie Mellon University50 講義13 で覚えておくべきメッセージ 1. いろいろの強力な検証技法がある。 2.. これらの技法を試し、自分に最も効果的なものを 見つけ、それを使いなさい。 3. 設計を検証するために使う時間はテスト時間の節 約となって何倍も報われる。 Copyright © 1994 Carnegie Mellon University51
© Copyright 2025 ExpyDoc