amori's blog

よろず技術系と趣味関係の雑記です。アニメの比重が高くなってます・・

バグのないプログラム

http://anond.hatelabo.jp/20170214233309
『二桁の整数の和を返すプログラムなら簡単に完璧に作れる。』
「・・それほど簡単じゃないなあ。」

「どこが難しいのよ?」
「まず『完璧』について合意された定義がないし、仕様も曖昧だし」

「完璧、とは完成したプログラムが仕様を完全に満たす、でいいでしょ。で、仕様のどこが曖昧?」

「んー、プログラムってのもまだ曖昧で、本当は要求の前提から始めたいとこだけど、まあ、わかりやすいところから確認していきましょうか、
まず、記述されていることの確認ね。
『二桁の整数の和』の『二桁』は『整数』と『和』のどっちにかかるの?」

「整数に決まってるじゃん。てか、結局同じでしょ。」
「いや、もし、『二桁の(整数の和)』なら演算結果が二桁に限定され、定義域と値域に条件がつく」

「はいはい、じゃあ『二桁の整数を入力として、入力の和を返すプログラム』でいいでしょ」
「まだ単語レベルで曖昧。二桁の整数だけ?一桁の入力はどうするの?」

「最大二桁の整数を入力として、入力の和を返すプログラム」
「じゃ次、『二桁の整数』。桁が規定されたから進数の定義もいるよ」

「最大二桁の10進数表現の整数を入力として、入力の和を返すプログラム」
「次、入力。これ確認するには、そろそろ要求の前提を決めなくてはならんね。この仕様、電卓みたいな人が入力するシステムの要求?それともサブシステム内の単体モジュールの要求?それによって『入力』の詳細変わってくるよ。」

「プログラムだから、もう関数モジュールでいいでしょ。『入力:最大二桁の10進数表現の整数、 出力:入力の和 である関数モジュール』でどうよ・・・」
「ふむ、モジュールね。では入力が条件外の値だったり整数でなかったらならどうするか?そもそも入力の型を想定するの?それに入力の数が不明。」

C言語前提、『入力 long:最大二桁の10進数表現の整数がふたつ、 入力値の条件判定は関数モジュール呼び出し側で行なうものとし、条件外の入力に対しては結果を保証しない。出力:2つの入力の値の和 をreturn値として返す関数モジュール』(-。-;」
「あれ、もう実装レベルの仕様に落としちゃうの? 動作保証しないのはバグがないという条件に反するのでは?あと細かいことだけど、Cのlongを前提にしたら、算術和、論理和排他的論理和があるんだけど・・・」

「・・もうさ、要求仕様どうたらでなくて直接プログラム書いた方が完璧になるでしょ。

#define ERROR -100
long add_2digit_integer( long m, long n)
{
if ( (m > -100) && ( m < 100 ) && ( n > -100 ) && ( n < 100 ) ){
return m+ n ;
} else {
return. ERROR ;
}
}
ほれ。入力エラー処理まで入って完璧なプログラムでしょ。」
「いや、ソースコードでしょ。そりゃ書いた通りにしか動くというのは完璧だろうけど、それトートロジーだよ。
あらためて『完璧』の定義を確認すると、例えば想定された条件において入力に対して正しい出力が返されること、という点で合意するとして・・」

「はいはい、さっきのソースコードにテスト追加すればいいんでしょ」
「テストの前に、想定された条件も確認しないと。条件にパフォーマンスも含まれる。レスポンスタイムの要求はソースじゃわかんないし。だからやっぱり要求仕様からやり直し」

「・・あとは・・?」
「じゃあ最初から順番に。
関数モジュール制作の手順計画
パフォーマンスも含む要求仕様および前提条件、開発環境、実行環境、試験環境の決定
試験仕様、モジュール試験環境の構築、
モジュール仕様、ソースコード
試験レポート、
あと、検証確認結果の顧客の確認を持って、合意の範囲で「完璧」と言える・・・かも」

「かも?」
「顧客要求はいつ変わるかわからんからねえ・・・・工程と見積もり出しましょうか?w」