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