標高+1m

Make, Hack, Think

宇宙API Part1

f:id:ympbyc:20100303114100j:plain

僕は今頭がhyperactiveになってるからとっておきの考えを書く。これは僕が暇なときにいつも考えてることで、これからも何回か書くことになると思う。

宇宙というソフトウェアのコードを、なるべく簡潔に記述するとしたらどんな風になるのか考えてみる。この宇宙にはオッカムの剃刀という便利なカミソリがあって、同じ結果を説明するのに、簡潔な解法と複雑な解法があったら、複雑な方は無視してもいいことになっている。この宇宙が本当はPerlで書かれたなら、それは明らかにLispで書かれたんだ!*1

先に断っておくと、この記事ではあなたが信じている言語やパラダイムがある状況で優位だ不利だという話が頻繁に出てくる。僕はHaskellLispSmalltalkも大好きだからある程度中立的な立場を取れると思う。でも一番好きなのはLispだし、C++Javaは嫌いだからやはりそれなりにバイアスはかかる。もしあなたが僕の考えを気に入らなかったら、別のバイアスをかけて同じテーマでブログしてくれたら僕は大喜びしてあなたのtwitterをフォローしてあげる。

また、これはこの宇宙について考えた時限定の話であって、そうじゃないソフトウェア開発一般に適用できる話ではないということも宣言しておく。

宇宙関数

僕の頭の中で宇宙はひどくシンプルな再帰関数で、電化やスピンや質量などを持った粒子を配置した3次元配列と力を引数にして呼ぶと、各種の物理法則を粒子の集合や粒子そのものに適用した新しい配列を作って自身を呼び出す。

(synonym Forces    (Map Keyword Number))
(synonym Particle  (Map Keyword Number))
(synonym Snapshot  (List (List (List Particle))))

(= (universe Snapshot Forces _|_)          ;;   / ̄ ̄\
   state force                             ;;  |     ^  時間
   (universe (map (physics force)          ;;  |     |
             (particles->materials state)) ;;  v     |
     force))                               ;;   \__/


;;              y1         y2         y3
;;           z1 z2 z3   z1 z2 z3   z1 z2 z3
(universe [[[{} {} {}] [{} {} {}] [{} {} {}]]   ;; x1
           [[{} {} {}] [{} {} {}] [{} {} {}]]   ;; x2
           [[{} {} {}] [{} {} {}] [{} {} {}]]]  ;; x3
          {:strong          0
           :weak            0
           :gravity         0
           :electromagnetic 0})

この記事では、このシンプルなフレームワークの上で、どんな選択をすればエレガントに宇宙を記述できるかを考えていく。

型付けと型システム

ガラスのコップで釘を打つことは禁止されていない。

このことを、宇宙は動的型付けなのか静的型付けなのか、直和型を使っているのかオブジェクトを使っているのかという視点から見てみる。最初は型付けについてだ。

型付け

ガラスのコップで釘を打つことが出来る。醤油を飲むことだって出来るし、うさぎを枕にして寝転がることもできる。

-- 2014 ympbyc

これを見ると反射的に、おっ!動的型付けかな?と思ってしまう。コップは金槌ではないし。醤油はジュースじゃないし、うさぎは枕じゃない。だが次の事実を確認すると、そうとは限らないことがわかる。

ガラスのコップを金槌の代わりに使うと手を怪我する。醤油を飲んだら死ぬ。うさぎを枕にしたら逃げられて床に頭を打つ。

-- 2014 ympbyc

これを型エラーと見るなら、宇宙は動的型付けだ。型エラーが実行中に起きるのは動的型付けの場合だけだからだ。怪我をしたり、死んだり、頭を打ったり、いかにも例外処理を適当に書いた時に起きそうなことだ。

これは型エラーじゃないと考えることも出来る。金槌の型とガラスのコップの型が同じ型クラスのインスタンスhit :: Stuff a => a -> a -> Either b bという関数に釘とガラスのコップを渡した結果Leftが返ってきたってだけかもしれない

でも考えてみると、ある行動の結果はだいたい 1. うまくいく 2. 手ひどく失敗したうえ、なにかしらブッ壊れる のどちらかだ。うさぎに逃げられたところに突然枕が現れたりはしないし、もし現れたならあなたは夢を見ているんだ。全ての行動がEitherを返すとしたら行動を起こす方はたまったもんじゃない。毎回いちいち行動を起こしたやつを得意げにさせたりぶちのめしたりしなきゃいけない。もっともこれはモナドを使えばある程度楽できるし、例外処理だって似たようなものだ。

宇宙が実行時に型情報を持っていて、物の型を見るAPIを提供してくれていたらいいのに!もしかしたら型なしなのかもしれない。

宇宙の型付け戦略がどうなっているのかを知るのは難しそうだ。いい実験を思いついたら教えてほしい。結論としては、型付け戦略に付いては好きな物を選んでいいってこと。

直和型かオブジェクトか

次に、この宇宙が代数的データ型でできているのかオブジェクトでできているのかを見る。ここでオブジェクトと言っているのはSmalltalk的な意味でのオブジェクトではなくprocedural data abstraction(手続き的データ抽象)のことだ。Object-Oriented Programming Versus Abstract Data Typesを読むこと!

そもそもガラスのコップも金槌も、醤油も水も、うさぎも枕も、同じ直和型なのかもしれない (ケースA)。それか物質型クラスがnaildrinksleep_on関数を要求しているのかもしれない (ケースB)。

でもこれはかなりバッドなアイディアだ。ケースAの場合は新しいコンストラクタを作るたびに色んな関数の中身をいじってケースを追加しなきゃいけないし、そもそもこれじゃあ動的型付けと一緒だ。ケースBの場合なら新しく型を作るたびに膨大な数の関数を定義しなきゃいけない。一個でもderivingできない行動があったら本当にひどい目に遭うんだ。

反対に、サブタイプポリモーフィズムをサポートするクラスを使っていればもう少しましになる。クラス階層の上の方で寝心地の悪いsleep_onメソッドを定義しておけば、たいていの物ではそのまま使える。良い寝心地は枕オブジェクトだけが提供すればいい。

これはオブジェクトがコンストラクタの追加を簡単にするのに対し、代数的データ型は手続きの追加を簡単にするものだからだ。この二つは直行する戦略で、今回のケースではオブジェクトが適していたというだけで普遍的にオブジェクトが代数的データ型に対して優位であるということではないから注意されたし。(もう一度言うけどObject-Oriented Programming Versus Abstract Data Typesを読んで!)

今まで目を瞑っていたけど、一つ困ったことがある。動物によっては石の上でよく寝れるかもしれないし、枕の上ではよく寝れないかもしれないし、その両方かもしれないんだ。メソッドの選択が枕とか石とかうさぎとかの、頭を乗せるものしか考慮しないとしたら、石のsleep_onメソッドでも枕のsleep_onメソッドでもうさぎのsleep_onメソッドでも、頭を乗せる動物について場合分けしなきゃいけない。せっかく克服したと思った手続き内での分岐がまた必要になるんだ。Shit is coming back again!*2 最悪だ。

幸いこの問題は1980年代に解決されている。メソッドをオブジェクトではなく手続きに所属させればいいんだ。Common Lisp Object System (CLOS)では、石の上で寝るトカゲのためのsleep-onメソッドや、うさぎの上で寝る人間のためのsleep-onメソッドを書ける。素晴らしい!やっぱり宇宙はLispで書かれているのかもしれない。

データ型もオブジェクトもなくて、全てがリストで表現されていたり全てがマップで表現されているという可能性もある。この話は根が深くて考えがまとまっていないので次の機会に回すことにする。

more on パラダイム

f:id:ympbyc:20140317060818j:plain

このセクションは本当はCLOSを出す前に書きたかった。でも前のセクションとこのセクションは相互依存なモジュールみたいなことになっているのでうまくいかなかった。一旦CLOSについては忘れて読んでほしい

型システムについて考えた時にはオブジェクトを使うと都合が良さそうに見えた。でも物がメッセージに応答するというモデルはそうだろうか?ここではさっきと違ってSmalltalk的な意味での自身が何を出来るか知っていてメッセージに応答できるオブジェクトを考える。

物になにか聞いても応答は得られない。動物やロボットは応答する。

冷蔵庫に高さを聞いてみたことはある?ないならやってみるといい。答えは返ってこない。代わりに僕ら人間や、視覚センサと三角関数の知識を持ったコンピュータが測る必要がある。

-- 2014 ympbyc

 

学校の先生が知っていることを知りたいとき、彼女の頭を開けて脳スキャナに掛けて調べたことは? そんな頭が破裂しそうなほど高価スキャナなんて使わなくても、丁寧に質問すれば彼女は快く教えてくれるし、ともすれば褒めてくれるかもしれない。

-- 2014 ympbyc

この二つの喩えがなにについてなのかは説明しなくてもわかると思う。でもわからない人にも続きを読んでほしいから一応書くと、それぞれオブジェクト指向プログラミングと関数型プログラミングについてだ。これらの喩えは、両方ともになにかしらこの宇宙での直感に反するところがあるという例だ。

オブジェクト指向での「全てはオブジェクトである」とか、関数型での「全てはデータと関数である」といった一般化は早計過ぎたのかもしれない。動物やロボットやソフトウェアなどの、知性とコミュニケーションのチャネルを持った物と、そうでない机や空や超新星などの物という分類が的を射ているように思う。

とは言え、単に関数もデータもオブジェクトも書けるという環境が欲しいわけじゃない。結局、僕ら人間だってロボットだって枕代わりのうさぎだって、ハンマーを持ってきて十分な回数叩けば返事をしない物になる。つまり僕らの知性は物が複雑な形に積み上がった構造物から発生したんだ。特定の粒子の配置に物理法則を適用するとオブジェクトができるみたいな環境が近いかもしれない。これは、詳しくは知らないけど初期のオブジェクト指向界隈でオブジェクトのネットワークから知性が生まれることを期待していたのに似ている気がする。

脳はユニフィケーションが得意である。

さて、知性という言葉を雑に使い始めたところで一度知性の要件を考えてみたい。知性がある物として挙げた動物、コンピュータ、ロボットには全て脳がある。ロボットの脳と人間の脳の間にははもちろん大きな違いがあって、人工知能研究の、特に強いAIというのはこのギャップをソフトウェア的、またはハードウェア的に埋めようという試みなわけだけれど、コンピュータのCPUがある程度脳に似ているということは同意してもらえると思う。

地球にいる動物の脳について考えると、これは素晴らしいユニフィケーションマシンだ。「りんご」と言われてりんごに結びついた甘さや色や大きさを言い当てられるのと同じくらい簡単に、「赤いもの」と言われてりんごやトマトや共産党を思い浮かべることが出来る。

ユニフィケーションを中心に置いたプログラミングパラダイムと言えば、論理型プログラミングの事だ。ここまでの話をまとめると、

データ(粒子)の集合に地球上の物理法則(関数群)が適用されて、論理推論エンジンを持つ脳を備えたオブジェクトができた。

-- 2014 ympbyc

ということになる。

僕は別に最初から有名な三つのパラダイムを全て登場させようと考えていた訳ではないので、こうして全てが絡み合ってしまったことにはあなたと同様とても驚いている。

MV*

五感はデータではなくUIに反応する

さっき学校の先生の脳を取り出してみてわかったことはもう一つある。僕らはデータを見れないってことだ。でも僕らはもの言わぬ月の色を知っている。太陽から出発して月にあたった光子が跳ね返って僕らの網膜に描画する像を脳が解釈するからだ。僕らが住んでいるのはModelの中ではなくViewの中なんだ。

これはなにも視覚に限った事ではない。匂いも音も痛みも、時空間に並んだ粒子の並びを脳が解釈しているんだ。僕らにはデータが見えない。もしかしたら僕らのModelはこの宇宙(View)にはないのかもしれない。

相対性理論

この記事の最初の方で僕の頭の中の宇宙関数を紹介した。このモデルには一つ問題がある。宇宙全体で時間が同じように進んでしまうのだ。残念ながらこれはこの宇宙の物理法則と矛盾する。

僕は先週ドイツ語の授業中にこんな落書きをしていた。おかげでNameの読み方を聞きそびれてしまったが、日本人の青年がアメリカでドイツ語をしゃべることと同じくらいには、宇宙とコンピュータと相対性理論について考えることは重要だと思うので問題ないだろう。

f:id:ympbyc:20140128122229j:plain

それからこれも。これはどちらかというと一個前のセクションに属する落書きだ。

f:id:ympbyc:20140128122141j:plain

スペシャルリレティビティ、特殊相対性理論について少しでも読んだ事がある人ならだれでも知っているように、どうもこの宇宙では速度が違うと時間の進み方も違うらしい。このことをソフトウェアでどう表現するのがいいのかは僕はまだ知らないが、一つだけ言える事がある。これはクロックスピードが違うコンピュータで走っているソフトウェアの群れに似ているってことだ。

ランダム性

最後に一つ、大事なトピックが残っている。僕らの未来は既に決まっているのか、それとも僕らはどの未来を見るかを選べるのか。

前者なら、宇宙はセルオートマトンだ。ライフゲームのように、粒子の配置に繰り返し単純なルールを適用することで驚くほど複雑なことが起きる。ブラジルで羽ばたいた蝶がテキサスでトルネードを引き起こすことだってできる。ライフゲームの世界 - ニコニコ動画は是非見るべきだ。初めて見た時は心が震えて涙が出てきた。

考え方によっては僕らが行うほぼ全ての行動はセルオートマトン的だ。お腹が空いた時にピーナッツが手近にあったのでたくさん食べる、消化が進んでピーナッツの成分が体中に行き渡る、背中のかゆさを脳が認識する。僕らは背中を掻こうとする、手が届かない、記憶をたよりに孫の手を探す、見つける、背中を掻く、一時的な快感を得る。ある行動が次の行動を引き起こすのだ。

今あなたは背中がかゆいことに気づくが、運命に逆らおうとして掻かずに我慢するかもしれない。そんなことをしても無駄だ。僕は「あなたが背中を掻かなかったのはあなたがこの記事を読んだからだ」と言えるし、きっとそれは正しい。この宇宙は決定論的な複雑系でも十分に近似できるのかもしれない。

僕はちょうど一年前の今頃、突き詰めると未来に選択の余地があるか否かは、この宇宙に真正乱数が存在するか否かという問題に帰結するのではないか、と考えていた。サイコロを振ると乱数のような数が得られるが、振り方、空気の状態、重力、地球の自転スピード、地球の公転スピード、銀河系での太陽系の位置、銀河団での天の川銀河の位置などの変数をすべて同じにしてもう一度サイコロを振ったら同じ目が出るのではないか?

僕の乏しすぎる物理学の知識では、こうしたコントロールできない変数を除去した実験を考えることはできない。でも一つSF小説のネタにしたら面白そうな考えが浮かぶ。

この宇宙は本当は決定論的だが、銀河系や恒星系や惑星系や電子雲などをぐるぐるかき混ぜて変数を増やす事で、十分にフェアな擬似乱数を作れるようにしていて、これは本当の乱数と同じくらいよく機能する。

-- 2014 ympbyc

この擬似乱数のせいで、サイコロの出る目はすでに決まっているにも関わらずカジノが大儲けしたり僕が金を失ったするんだ。僕が宇宙を作るとしたら絶対こうすると思う。

次回に続く

僕が二年以上にわたって暇があれば考えてきたことのかなりの部分を約8000文字でまとめた。こんなに長い文章を書いたのは生まれて初めてだ。読んでくれてありがとう。あなたが少しは面白いと思ってくれたら嬉しい。コメント、トラックバックは大歓迎!

もしあなたがこの記事を嫌いで、建設的でないコメントを書き込もうと思っているならちょっと待ってほしい。あなたの貴重な時間をそんなことのために浪費させてしまうのはもったいないので、代わりにamazonで僕に本を贈るというのはどうだろう。僕は本をもらえて嬉しいし、あなたは無駄にしようとした時間と同じくらいの価値のお金を投資できる。win-winな取引だと思わない?

午後8時頃に書き始めたと思ったらいつのまにかもう朝の5時半だ。今から寝たら8時に起きることは絶対にできないとわかっているのでこのままあと3時間書き続けてもいいが、その代わりに今公開するボタンを押して、あとの3時間は誤字脱字の修正に充てようと思う。

次回は、今回の記事のセクション間を埋めることを目標にしたい。

ではまた。

2014 Minori Yamashita ympbyc+blog@gmail.com

*1:http://xkcd.com/224/

*2:これは僕のルームメイトの口癖だ。聞くたびに笑う