Transcript jlect13

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