[SML 7113] Re: Smalltalkerのための初等数学

AOKI Atsushi aoki @ sra.co.jp
2005年 8月 9日 (火) 17:00:29 JST


SRA先端技術研究所(京都産業大学非常勤講師)の青木です。

オブジェクトの挙動を把握するのに状態遷移(有限状態マシン)を
用いることが多いと思います。そのため、大学の講義において、私
は下記のような「小舟」の問題を学生に課します。

------------------------------------------------------------

小舟に乗って川を渡ろうとしている人がいる。この人は狼と羊と菜
を持っている。しかし、川を渡るための小舟には、一回に持って渡
れるものがたった一つという制限がある。狼を持って渡ろうとする
と、渡っている間に羊が菜を食べてしまう。菜を持って渡ろうとす
ると、渡っている間に狼が羊を食べてしまう。すべてのものを安全
に対岸に渡すためのダイナミックモデル (状態遷移図) を作成せよ。

------------------------------------------------------------

しかしながら、なかなか、この問題を解ける学生がいません。他の
授業で高等数学を課しているわりには、初等数学のプログラミング
が下手なのです。見方というか考え方を実践に移せないのでしょう。

私ならば、{'人', '狼', '羊', '菜'} という全体集合を作り、さら
に無効となる集合を要素とする集合 {{'狼', '羊'}, {'羊', '菜'},
{'狼', '羊', '菜'}} を用意します。

そして、全体集合の「べき集合」すなわち、全体集合のすべて部分
集合を要素とする集合を作り、それぞれの部分集合および補集合が
無効となる集合に含まれていないか否かを調べます。

先日にアナウンスさせてもらった「Smalltalker のための初等数学」
http://www.sra.co.jp/people/aoki/Mathematics/PrimaryMath/
http://www.sra.co.jp/people/aoki/Mathematics/PrimaryMath/Set/
を用いれば、次のようにプログラミングすることができます。

| universalSet invalidSet powerSet |
universalSet := PrimaryMath.Set withAll: #('人' '狼' '羊' '菜').
invalidSet := PrimaryMath.Set
            with: (PrimaryMath.Set withAll: #('狼' '羊'))
            with: (PrimaryMath.Set withAll: #('羊' '菜'))
            with: (PrimaryMath.Set withAll: #('狼' '羊' '菜')).
powerSet := universalSet powerSet.
Transcript clear.
powerSet do:
        [:aSet |
        | complementarySet aBoolean |
        complementarySet := universalSet complement: aSet.
        aBoolean := (invalidSet
                        detect: [:each | each = aSet]
                        ifNone: [nil]) isNil
                    and:
                        [(invalidSet
                            detect: [:each | each = complementarySet]
                            ifNone: [nil]) isNil].
        Transcript
            nextPutAll: aSet printString , ' - ';
            nextPutAll: complementarySet printString;
            nextPutAll: ' ==> ' , aBoolean printString;
            cr;
            flush].
^powerSet

このプログラムを実行してみると、以下のようにトランスクリプト
へ出力されます。

{} - {'人', '狼', '羊', '菜'} ==> true
{'人'} - {'狼', '羊', '菜'} ==> false
{'狼'} - {'人', '羊', '菜'} ==> true
{'羊'} - {'人', '狼', '菜'} ==> true
{'菜'} - {'人', '狼', '羊'} ==> true
{'人', '狼'} - {'羊', '菜'} ==> false
{'人', '羊'} - {'狼', '菜'} ==> true
{'人', '菜'} - {'狼', '羊'} ==> false
{'狼', '羊'} - {'人', '菜'} ==> false
{'狼', '菜'} - {'人', '羊'} ==> true
{'羊', '菜'} - {'人', '狼'} ==> false
{'人', '狼', '羊'} - {'菜'} ==> true
{'人', '狼', '菜'} - {'羊'} ==> true
{'人', '羊', '菜'} - {'狼'} ==> true
{'狼', '羊', '菜'} - {'人'} ==> false
{'人', '狼', '羊', '菜'} - {} ==> true

あとは、真(true)になっているところを状態にして、それらを線
で結んで遷移にしてゆけば、状態遷移図のできあがり、となります。
http://www.sra.co.jp/people/aoki/misc/jpgs/kobune.jpg

------------------------------------------------------------
R2D2 (AOKI Atsushi)        http://www.sra.co.jp/people/aoki/




SML メーリングリストの案内