Software Engineering Lecture 5/8
Menu Menu
先週の復習
- 集合の表し方
- 写像、関数
- 論理
- プログラムの意味
- Perlを実行して見る
動けば良いだけのプログラミングから、良いプログラムへ
動かせるだけが精一杯、人のプログラムをコピーして手直し。それでいいのか?例えば、「プログラム書法第二版」Brian W.Kernighan ISBN4-320-02085-5 C3041 は、Fortan を使ったすごく古い本だが、今でも有効な規則が多く載っている。
最近だと、「プログラム作法」というのが良い本だと思われる。
もし、もう少し、チームプログラミングや、深い知識を得たいのならば、「コード・コンプリート」という本が良い。
良いプログラムとは何か?
どんなにきれいに書いてあり、どんなに規則に従っていても、間違ったプログラムは、良いプログラムとはいえない。
正しいプログラムかどうかを調べる
仕様は論理式により記述し、プログラムはそれを関数を使って実現する。プログラムが正しく仕様を満たしているかどうかを調べる方法はいろいろある。一つは、プログラムのステートメントごとに、その前後で満たしている性質を論理式で記述する方法である。これはHoare logic と呼ばれる。
{Pre Condition} S {Post Condition}例えば、
{b!=0 ∧ gcd(a,b) = gcd(x,y)} a := a mod b {gcd(a,b) = gcd(x,y)}この場合は、gcd(a,b)=gcd(x,y) というのがstatement a:= a mod b の前後で保存されている。このようなものを、不変式という。
証明、健全性、完全性
このようにプログラムが正しく動作することは、論理式の変形として理解することができる。プログラムが正しく動作することと、それを証明できることには以下のような関係がある。健全性:
証明されたプログラムは、正しく動作する完全性:
正しく動作するプログラムには、必ず証明がある実際にはループの間で、どのような不変式が成り立つかを見付けることが、Hoare logic によるプログラムの検証の重要な部分になる。これを使って理論的にはほとんどのプログラムを正しさを証明することができるはずである。でも、実際にやってみると、
- すごく手間がかかる
- この証明自身にバグないともいいきれない
- 有限な入出力に対してしか有効で無い
さらに、正しく動作するかどうか決定できないプログラムがある言うことががゲーデルによって示されている。なので、プログラム検証には本質的な限界がある。
Perlの構文
条件文
- if ($i++ <10 ) { print $i; }
- print $i if ($i++ <10 );
- print $i unless ($i++ > 9 );
- open(FD,"<test") || die("error $@\n");
- open(FD,"<test") or die("error $@\n");
練習1
それぞれの条件文をdebuggerで動作を確認せよ。
制御構造
- while(<>) { $i++; }; print $i;
- print $_ while(<>);
- while(<>) { print $_; last if ($i++ > 10); }
- while(<>) { next if ($i++ < 10); print $_; last if ($i++ > 20); }
- while(<>) { print if (10..20); }
- do { print "$i\n"; } until($i++ < 10) ;
練習2
それぞれの制御構造をdebuggerで動作を確認せよ。
subroutine の作り方
sub gcd0 { my ($a,$b) = @_; return ($a > $b) ? $a % $b : $b % $a; }
練習3
gcd0 の役割をdebugger で確認せよ。
問1
gcd を計算するプログラムをPerlで記述し、不変式が実際に保存されていることをdebuggerでチェックせよ。ヒント : debugger のコマンドを使う。
perldoc
Perldoc の使い方を調べよう。
$@ などの意味
特別変数の使い方を理解しょう。$_, @_, $@ とは何か?
Perlのデータ型
Perlでは、変数には型を表す記号が付けられている。これには、以下のようなものがある。
記号 | 意味 |
$a | スカラ (0次元の値) |
@a | 配列全体 ベクタ (1次元の値) |
$a[1] | 配列の値 |
%a | 連想配列全体 |
$a{1} | 連想配列の値 |
<a> | ファイルハンドル |
&a | 手続き呼び出し |
\$a | 参照の取り出し |
$$a | 参照の値 |
() | リスト |
[] | 無名の配列 |
{} | 無名の連想配列 |
-- | 真理値は、if(), while()などで使われる |
これら、相互の型の変換は、整合性が損なわれないように、極めて自由に設定されている。例えば、
$a = @a; ($a,$b,@c) = (1,2,3,4,5,6); print "yes\n" if($a) ; $c = ("12"."23") + 1;Perlのデータ構造のマニュアル を見て、Perl のデータ構造を理解しよう。
練習4
上の例で、どのような型変換が起きているのかを指摘せよ。
宿題
このプログラム検証の限界と、最初にあげたプログラミングの規則にはどういう関係があるのか300文字程度で記述せよ。Perl の宿題は、メールでSubjectを
Subject: Report on Software Engineering Lecture 5/8 <br>として提出すること。この講義の問題を提出する時には、
Subject: Practice on Software Engineering Lecture 5/8 <br>とすること。