いものやま。

雑多な知識の寄せ集め

「Lucid, the Dataflow Programming Language」を翻訳してみた。(その2)

昨日の続き。

1. イントロダクション

Lucidはプログラミング言語だが、読者がすでに慣れ親しんでいるプログラミング言語(BASICやPASCAL、あるいはLISPでさえ)とは、まったく異なる。

以下は、有理数を含む計算を記述した簡単なLucidプログラムである。
このプログラムは、「実行しながら」入力の二乗平均平方根(※二乗平均平方根 - Wikipedia)を計算する。
もっと分かりやすく言えば、n番目の出力は、入力された最初のn個の数字の二乗平均平方根(二乗して平均をとった値の平方根)となっている。

sqroot(avg(square(a)))
where
    square(x) = x * x;
    avg(y) = mean
    where
        n = 1 fby n + 1;
        mean = first y fby mean + d;
        d = (next y - mean)/(n + 1);
    end
    sqroot(z) = approx asa err < 0.0001
    where
        Z is current z;
        approx = Z/2 fby (approx + Z/approx )/2;
        err = abs(square(approx) - Z);
    end
end

数学(あるいは単なる代数でもいい)の知識を持つ読者ならば、これが初めて見たLucidのプログラムであったとしても、プログラムがどのように動作するかをおそらく推測できるだろう。
プログラムは、入力された数値の二乗を作る関数square、それらの数値の実行中の平均を生成する関数avg、そして、その平均の平方根を生成する関数sqrootを使用している。

上記のプログラムによって記述された計算は、3つのコンポーネントが直列に接続された単純なネットワークであるとして理解することが出来る:

 input  +--------+ squares  +-----+ averages  +--------+ output
------->| square |--------->| avg |---------->| sqroot |-------->
        +--------+          +-----+           +--------+

このネットワークはLucidの式sqroot(avg(square(a)))に対応ていて、3つのコンポーネントはそれぞれプログラムで定義された3つの関数に対応している。
Lucidプログラマは、入力値(実際には変数aの値)の無限の流れが、'input'と書かれた矢印に沿って左からやってくるのを想像している。
これらの値は、3つの「コンポーネント」(もしくは「ブラックボックス」)を通過して変換され、'output'と書かれたラインで「外部」に送り出される。
プログラムの出力は、最後の値のストリームであり、この値のストリームは、プログラムの使用方法に応じて、プリンタに送られたり、あるいは、ファイルに保存されたりする。
このシステムを通過するデータの「粒」は「データン(datons)」と呼ばれ、それらが通過する(そして変換を行う)コンポーネントは、電子工学のアナロジーで「フィルタ」と呼ばれる。

入力値は、squareと書かれた最初の「コンポーネント」(もしくは「ブラックボックス」)を1つずつ通過していく。
squareコンポーネントは、受け取った値の二乗を1つずつ計算し、値を受け取った順に、二乗された値をsquaresと書かれたラインへ送り出す。

二乗された数は、avgと書かれた2番目のブラックボックスに至るまで、squaresと書かれたラインを移動していく。
このコンポーネントは、これらの数値を1つずつ受け取り、それまでに受け取ったすべての入力の平均を計算する。
その新しく得られた平均値は、計算されるたびに、averagesと書かれたラインへ1つずつ送り出される。

これらの平均値は、sqrootと書かれた3番目のブラックボックスに供給される。
このコンポーネントは、それらを受け取ると、受け取った数値の平方根を計算し、それら平方根を生成した順にoutputと書かれたラインへ1つずつ渡していく。

数学に詳しい(またはプログラミングの知識がある)読者は、おそらく個々のコンポーネントがどのように計算を実行しているかを推測することも出来るだろう。
squareの定義は、各入力の2つのコピーを掛け合わせるという明白な考えに基づいている。
avg関数の定義は、より洗練されたアルゴリズムを使用している。
それは実行中の引数の合計値を保持せず、代わりに、計算された直前の平均値を適切な増分だけ増加させる。
最後に、プログラム内で定義されたsqroot関数は、ニュートン法を使って引数の平方根を計算する。
それは、希望された精度が達成されるまで、徐々によりよい近似値を生成していく。

当然のことながら、このネットワーク内の3つのコンポーネントは、それらの計算を並行して(in parallel)実行することが出来、すなわち、それらはすべて同時に動作することが出来る。
avgフィルタが平均値を生成し始める前に、squareフィルタがすべての入力を受け取ってすべての二乗を計算する必要はない。
つまり、その上流では次の入力を準備し、下流では出力された最後の値を処理しつつ、avgフィルタは1つのアイテムを処理することが出来る。
ネットワーク内のフィルタは、それぞれ異なる割合で動作する場合もあり、それらの活動が同期していると仮定する必要はない。
すなわち、それらはすべて同時に入力を読み取り、同時に出力を生成する。
フィルタの中に他より速くデータを処理できるものがあれば、入力待ちの状態でアイドル状態になったり、処理待ちのラインにデータンをキューイングし始めるだろう。
これらの現象はいずれも、プログラムによって出力される最終的な一連の値には影響しない。
これらの値が生成される割合と、出力を生成するのに必要なリソース(キューにデータンを保存するためのスペースなど)にのみ影響する。

1.1 何がLucidを動作させているのか?

この時点で、読者は、私たちが実際のプログラムがやっていること以上のことを書いていると疑うかもしれない。
その疑惑は基本的には正しく、記述された計算の様子は、実際にはプログラムの1つの解釈でしかない。

ほとんどの従来のプログラミング言語では、プログラムが生成するであろう動的な様子(ネットワークを通るデータの流れなど)に関する明示的な情報を、プログラマが提供する必要がある。
そのような言語での経験を持つ読者は、どのラインがどのフィルタに接続されているか、どのラインが入力あるいは出力であるのか、ラインの初期内容は何なのか、といったことを、面倒で厄介な特殊用語(jargon)で指定し、データフローネットワークを記述しなければならないのだろうと予想するだろう 。
例えば、次のような感じだ:

NETWORK DIVISION.
      CONNECT PROGRAM-INPUT TO SQUARE-INPUT
      CONNECT SQUARE-OUTPUT TO AVG-INPUT
      CONNECT AVG-OUTPUT TO SQROOT-INPUT
      CONNECT SQROOT-OUTPUT TO PROGRAM-OUTPUT

しかし、Lucidプログラマはラインやフィルタを直接は操作しない。
代わりに、Lucidユーザーは処理されるデータと適用される変換を指定する。

例えば、sqroot(avg(square(a)))という式を考えてみよう。
式それ自体から、変換squareがデータaに適用され、その結果に変換avgが適用され、そしてさらにその結果に変換sqrootが適用されることは、明らかである。
さらに、式それ自体は、(全体として)3つの変換すべてを指定された順序で適用した最終的な結果を示している(あるいは表現している)。
この最終結果はプログラムの出力となるため、「出力」用の独立した文や宣言は必要ない。
同様に、(フィルタへの最初の入力を表している)変数aは、プログラムで定義されていない。
変数aが表すデータは任意であり、何でも構わないので、それゆえ、プログラムへの入力として扱うことが出来る。

sqroot(avg(square(a)))は、プログラマが提供する必要があるすべての情報を(whereに続く補助定義と一緒にすることで)含んでる。
where節と一緒になることで、この式は出力が何であるかーーつまり、式の値ーーを正確に指定している。
しかし同時に、その式はその出力がどのように得られるかーーつまり、入力に関してsquareargsqrootという変換をこの順に適用していことーーをある程度指定している。
したがって、ボックスやラインについて直接話さなければならない絶対的な必要性はなく、上記のネットワークは、与えられた式の単純なグラフ表現と考えることが出来る。
また、それ自体でシンプルに元の式の2次元的な表現ともいえるグラフを特定することが出来るので、(上で仮に与えた「プログラム」のような)2番目のテキストを書く必要はない。

したがって、Lucidのプログラムは、式で参照された変換と(入力以外の)データによる、単なる式である。
プログラムの出力は、単純に、プログラムで式として示されたデータ、すなわち、プログラムの値である。
Lucidは、BASICやCOBOLよりも、学校の代数によく似ている。

この時点で、数学に詳しい読者は懐疑的になることだろう。
Lucidは確かに従来の数学のように見えるが、その見た目は欺瞞であるかもしれない。
結局のところ、多くのプログラミング言語は数学的な記法を使うが、(私たちが見てきたように)従来のものとは違う何かだったりする。

再びsqroot(avg(square(a)))という式を考えてみよう。
sqrootsquareというフィルタは、数値を演算する従来の数学的な関数として確かに理解できるが、avgはどうだろう?
ある数値にavgを適用した結果は何だろうか?
8の「平均」とは、何だろうか?

数学において、関数が返す値は、与えられた値、すなわち、その引数によって決定される。
しかしながら、前述の説明によれば、avgフィルタは直前の値までの平均値を記憶しており、新しい引数が与えられる度にこの記憶された平均値を更新していると考えられる。
記憶を持った数学的な関数だなんて、聞いたことがあるだろうか?
確かに、これがコンピュータサイエンス特有の動的なコンセプトである。

しかし、avgのようなフィルタによって変換された「データ」が単なる単一の数値でないことを思い出せば、この見かけ上の矛盾は解消される。
avgフィルタは、作業全体を通して、 s_0, s_1, s_2, \cdots といった一連の数値をすべて受け取る。
これはフィルタへの入力のすべてである。
同じように、フィルタはただ1つの数値を生成するだけではなく、別の一連の数値 a_0, a_1, a_2, \cdotsを生成する。
これはフィルタの出力のすべてである。
したがって、フィルタを従来の数学的な関数を計算するものと考える場合、関数はその一連の数値 s_0, s_1, s_2, \cdotsを引数として与えられ、その結果として一連の数値 a_0, a_1, a_2, \cdotsを返すものでなければならない。
それは、入力のシーケンスの集合から出力のシーケンスの集合への関数でなければならない。

実際、avgフィルタによって実行される入出力変換を特定するようなシーケンスの関数fが存在することは、理解に難しくない。 与えられた一連のsに対して、f(x)は単に

 \langle s_0, (s_0 + s_1)/2, (s_0 + s_1 +s_2)/3, \cdots \rangle

という一連の平均となる。
(無限のシーケンスのみを扱えば、すべてはよりシンプルになる)

これが、従来の数学の静的性質とプログラミングの動的性質との間にある明らかな矛盾を解決するLucidの方法である。
Lucidの式は実際に数学的な意味での式であり、式で参照される関数は実際に厳密な意味での関数である。
式は、個々のデータ項目ではなく、シーケンスとして値を持っている。
そして、関数はシーケンスをシーケンスにマップする。

一貫性のために、「従来の」式および変換でさえ、シーケンスおよびシーケンスの関数として示される。
すなわち、式2 * 3はシーケンス

 \langle 6, 6, 6, 6, 6, \cdots \rangle

という値のシーケンスを持ち、squareという変換は

 \langle s_0, s_1, s_2, \cdots \rangle \mapsto \langle s_0^2, s_1^2, s_2^2, \cdots \rangle

とマップする関数に対応する。

Lucidでの式は、プログラムで言及されている変換を含むフィルタのネットワークの出力を示すものだと考えることが出来ることは、すでに見てきた。
そのような式の値は無限のシーケンスであり、それはネットワークによって生成され、その順に並べられた、すべての個々の値の完全な記録あるいは履歴として考えることが出来る。
問題の式がプログラムの場合、その無限のシーケンスは、プログラムの出力の様子の完全なる記録または履歴となる。

例えば、プログラムPの値がすべての素数の無限シーケンス( \langle 0, 3, 5, 7, 11, 13, \cdots \rangle)であれば、Pは素数を列挙するプログラムであると考えることが出来る。
そのような素数生成プログラムが実行されると、最初は数2が生成され、次に3, 5, 7, 11などが生成される。
もっとも、必ずしも一定の速度ではないが。

Lucidプログラムに現れる文、例えば

mean = first y fby mean + d;

は、実際に等式であり、その定義が有効であるプログラムの領域内での変数の値を指定する。
変数の値もデータ項目の無限のシーケンスでもあり、定義の右側の式に対応するネットワークによって生成された値の完全な記録と考えることが出来る。
(この考え方では、これらの値が一定の割合で生成されると仮定したり、これらの値の生成が他の変数または出力の生成と同期することを仮定したりしてはいけない)

プログラムは、プログラム内に定義を持たない(そして、関数定義での仮引数でもない)変数を使用することがある。
そういった変数は入力変数と呼ばれ、プログラムの値は一般にそれらの変数の値に依存する。
入力変数に与えられた値は、Lucidプログラムへの入力を構成する。
これらの値も無限のシーケンスであり、入力された順にプログラムに入力されるすべてのデータ項目の完全な記録と考えることが出来る。
ここでも、データ項目がプログラムによって入力として読み込まれる速度は常に一定であると仮定したり、データ項目が出力として書き出される速度と必ず同じであると仮定したりしてはいけない。

上のRMS(二乗平均平方根)プログラムには、入力変数が1つ、すなわち、変数aしかない。
例えば、プログラムへの入力(すなわち、aの値)が \langle 3.5, 3.2, 3.9, 4.1, 3.8, \cdots \rangleといったシーケンスであった場合、出力(すなわち、式としてのプログラムの値)は、 \langle 3.5, 3.335, 3.54, 3.69, \cdots \rangleといったシーケンスになる。
したがって、例えば3番目の数値出力は3.54であり、これは \sqrt{(3.5^2 + 3.2^2 + 3.9^2) / 3}となっている。
これはちょうど、上記のネットワークから期待されるものとなっている。

ある意味では、Lucidの「動的」な側面は、ある種の錯覚である。
Lucidは実際のところ、静的な履歴のただの微積分でしかない。
示唆的な名前(nextなど)や通常の記号(+など)を使用し、シーケンスでの各点における演算を指定することで、シーケンスのインデックス(位置を指し示す添字)を明示的に参照することをとりわけ避けて、この錯覚を保っている。

この「錯覚」はプログラミングをしやすくする上で絶対不可欠である。
厳密に静的な視点を使用しながら、すなわち、Lucidのシーケンスの履歴を文字列やリストといった別のデータ型として解釈しながらプログラムを書くことは、ほとんど不可能である。

その点、動的な視点はそれほど非現実的でもない。
Lucidプログラムが最終的には実行され、実装にはデータフローもしくはそのシミュレーションがおそらく必要となるだろう。
私たちは、静的で無限の履歴は「非現実的」であり、実際の演算の様子は「現実的」であると容易に主張することが出来る。 Lucidのデータフローによる解釈は、動的に変化するシステムでの一連の差分方程式による解釈よりも非現実的ではない。
主な違いは、微積分における「時間変数」は連続的に変化するが、Lucidの「反復時間」は離散的に変化することである。


いやはや、なんともぶっ飛んだ発想だとしか・・・

数学の式って静的だけど、コンピュータって動的に動くよね。
->
変数や関数は、時間変数を伴った無限のシーケンスと考えればいいいじゃん!
そうすれば、式は静的であるにも関わらず、様子は動的になる!

変数や関数を時間変数を伴った無限のシーケンスだと考えると、そのすべてを記述しきるのは難しいよね。
->
シーケンスの各点で保たれてる性質を微分方程式みたいに記述すればいいじゃん!
微分方程式を満たす関数が(微分方程式を解くことによって)得られるかは分からないけど、その関数の様子は(微分方程式があれば数値シミュレーションが可能になるように)動的に得られる!

微分方程式みたいに書かれていても、理解しづらいし、実行できるかも分からないよね。
->
シーケンスをデータの流れと考えて、各関数はそれを処理するフィルタであると考えればいいじゃん!
ついでにいえば、それで反復も処理できるじゃん!

・・・といった感じ。

この発想自体は非常に面白いと思うのだけど、じゃあ実際それでプログラミングしてみろと言われたら、かなり困りそう。
それこそ、平均一つとっても、普通は「「実数の有限部分集合」の集合」から「実数の集合」への写像と考えるわけで(例えば avg(\{1, 2, 3\}) = 2みたいな)、無限シーケンスの集合から無限シーケンスの集合への写像と考えるのは、ちょっと無理があるように思える。
例えば、ここでは平均を1回求めればそれで終わりだったけど、平均を何度も・・・それも有限回ではなく、無限回求めなければならない、となった場合(つまり、「無限シーケンス」の無限シーケンスを考える場合)、その構想はたちまち破綻しそうな・・・

まぁ、このあたりはあとのお楽しみということで。
(自分もまだ先をちゃんと読めてないので、これが解決されているのかどうか知らない)


ちなみに、1章はまだまだ続く・・・
先は長い・・・

今日はここまで!

「Lucid, the Dataflow Programming Language」を翻訳してみた。(その1)

だいぶ間が空いてしまったけど、以前書いた通り、データフロー言語であるpLucidをいじっていたりする。

この実装をいじりながらコードを読んでいたのだけど、どうにも分からない部分が。
というのも、実装が丸々ifdefで落とされていて、しかも、落とされたコードも実質何もしていないから。

まぁ、やりたかったであろうことは何となく分かるので、それなら自分で実装してしまおうかな、と。
けど、実装から仕様を理解しようとしているのに、その実装がないわけだから、どうあるべきかという仕様がまず分からない・・・
なので、仕様をちゃんと調べるしかないかな、と。

幸い、「Lucid, the Dataflow Programming Language」という論文?がネットに落ちてて、仕様はそこから理解できそうだった。

Lucid, the Dataflow Programming Language

ただ、自分の英語力が低いのと、やたら難解な単語が使われてて、読みにくい・・・

ということで、Google先生の力を借りながら、翻訳してみた。

なお、直訳じゃなくて、文脈からの自分の推測も入っているので、注意。

序文

Academic PressがLucidに関する本を書かないかと最初に打診してきたとき、私たちは容易に同意した。
本の制作は比較的簡単だと私たちは考えていたからだ。
つまり、既存の論文やレポートをいくつか集めて、編集上のコメントを追加するだけでよかったはずだった。
それが終わったら、私たちはもっと野心的なプロジェクトに移ることが出来るはずだった。

しかし、私たちが論文やレポートを読み返してみると、当初の計画ではダメなことに気がついた。
Lucidは(今もそうだが)非常に新しい開発だった。
にもかかわらず、私たちが提案した様々な論文が互換性を失うほどに大きく進化してしまっていたからだ。
いくつかの変更は細かい部分だったり技術的なものだったりしたが、それらは全体的に根底にある動機の根本的な変化を反映したものだった。

Lucidは1974年にカナダのワーテルロー大学で生まれた。
当時、この本の著者らは、数学科で教鞭をとっていた。

Lucidを開発する当初の目標は、非常に控えめだった。
私たちは、従来の「主流」のプログラミングが、代入やgotoのない、純粋に宣言的な言語で出来ることを示したかった。
私たちは当時(そして今も)、本当の「構造化プログラミング」では、まずこれらの機能(※代入やgoto)を排除する必要があり、プログラム検証にこそ実用的な可能性があると感じていた。

もちろん、私たちは、LISPのような「関数型(functional)」あるいは「適用型(applicative)」言語で、再帰を使用するだけで、どんなプログラミングの問題も原理的には解決できることを知っていた。
しかしながら、このアプローチはまったく信頼できなかった。
純粋な再帰による解法は(明らかに)反復を使用できず、それゆえ、実際に毎日のプログラミングで使用されるアルゴリズムのほとんどを除外することになる。
再帰的プログラミングの擁護者は、「末尾再帰」を反復と同等だと見做すが、そのような不自然なパラメータリストを持つプログラムは、毎日のプログラミングでは実際には使えたものではない)

実際のところ、LISPのような言語はループを書くことを許容している。
しかしそれは、(LISPがそれをprogという機能で実現しているように)代入を言語へ許容しなおしているだけでしかない。
そこで、私たちの目標は、progのように「汚れた」機能を導入することなく、反復アルゴリズムを宣言型(あるいは「非手続き型」)言語で表現できると示すことだった。

私たちの出発点は、以下の代入文

I := 1;
...
I := I + 1;

は、以下の宣言文

first I = 1;
next I = I + 1;

で言い換えることができるということだった。

これらの宣言文は、firstnextを演算として使用することができ、これらの演算は、単なる識別子や式にも適用できることを示唆している。
そして、next(x + y) = next(x) + next(y)のような直観的に真となる等式を、プログラムの動的な側面について使うことが出来る、と代数的に判断できる可能性を開いた。(※ここ、かなり意訳)

しかし、当初、それがどのような値が示しているのかということは、ハッキリしなかった。
最終的には、変数や式は、個々のデータの無限シーケンス(または履歴)を示していることに気づいたが、それまでLucidの作業は数ヶ月停止した。

ひとたびこの原則が確立されてしまえば、少なくとも単純な反復アルゴリズムは、等式の集合によって自然な形で表現できるということを実際に示すことが出来た。
また、プログラムの論証が本当にずっとシンプルであることを確認できた。
1つの利点は、表明(assertion)が策定された(formulated)言語がプログラミング言語の拡張であることだった。(※よく分からない・・・)
プログラム内の文(statement)はそのままプログラム内の変数の値についての真となる表明であり、より深い性質を導出するための公理を構成していた。

この初期の仕事は、原理的には反復がちゃんとできることを示した。
しかし、オリジナルのLucidは非常に単純な言語であり、非常に単純なアルゴリズムしか表現できなかった。
主流の命令型言語を置き換えることを本当に望むのなら、より現実的なアプリケーションを等式のスタイルでプログラミングできることを示す必要があった。
そこで、私たちは、より野心的な問題に取り組める言語の拡張を検討し始めた。

最初に追加された機能は(ループの)入れ子で、比較的簡単であることが示された。
それは単に変数の値が複数の時間パラメータに依存できるようにしたものだった。
(単純な無限のシーケンスは、1つのパラメータに依存する値と考えることができ、そのパラメータはシーケンスの位置であり、それを私たちは「時間」と呼んだ)
入れ子にした後、最も明白な次の一歩は、配列を追加することだったが、ここで何かが捻れてしまった。
私たちは、(APLのラインを参考に)配列を扱うためのシンプルな代数を見つけようと大量の努力を費やしたが、ほとんど成功しなかった。
主な問題は、配列が有限で、そして有限次元であると考えていたことだったと、今の私たちは気づいている。
私たちは、無限の配列ははるかにいい性質を持っていることは分かってたが、まだ従来の計算モデルに適合させることができていなかった。

そこで、私たちは配列に関する作業を中断し、他の最も明白な拡張、すなわちユーザ定義関数について検討した。
この拡張は、最も単純なものであることが分かったが、私たちが予想していたよりも強力だった。
特別なLucid演算を使用して定義された関数は、フィルタ(データストリームを変換する、連続的に動作するプロセス)と考えることが出来ることを発見した。
私たちの言語はそうしてコルーチンのような機能が得た。
コルーチンは強力なプログラミングツールとして知られていたが、非常に複雑であるとも考えられていた。
しかし、Lucidでは、コルーチンはほとんどタダで実現された!

ユーザー定義関数の成功は、Lucidでのアプローチへの信頼を強化した。
最終的に、従来の命令的ループで表現された繰り返しではなく、他の形式で表現された繰り返しがあることを理解した。
プログラミングへの新しいアプローチの根底にあるのは、計算そのものへの新しいアプローチであることに気がつき始めた。
それはつまり、データフローアプローチである。
それ以来、Lucidは古いアルゴリズムを表現するための新しい方法というだけではなくなった。
新しい(データフロー)アルゴリズムを表現するための新しい方法となった。
ある意味では、当初の目的は逆転してしまった。
もともとは、計算の従来のアプローチを数学的にちゃんとしたものに出来ることを示したかった。
今や、私たちは古い方法を排除し、まったく新しい世界観に置き換えることができることを示そうとしている。

もちろん、私たちはデータフローや計算へのデータフローアプローチを発見したと主張はしていない。
これに関して、M. McIlroy、J.Dennis、G. Kahnなど多くの人々が信用を共有している。
データフローが強力なプログラミング手法であるという実証的な証拠を提供したUNIXの開発者に、私たちは借りがある。

今の本は、私たちが当初書こうとしていた(あるいはむしろ、組み立てようとしていた)本とは、ほとんど関係がないものになっている。
ここで強調されているのは、お堅い研究の対象としてではなく、実用的なツールとしてのLucidである。
プログラムの検証は依然重要であり、関数型言語でははるかに簡単だと考えているが、それに関しては非常に簡単かつ形式張らない方法で取り扱う(変換には十分な注意が必要)。
実用的でない計算モデルに基づき、現実的な問題にフィットしていない言語で書かれたプログラムの正しさを実証することには、ほとんど意味がないと思われる。
したがって、本書の第一の目的は、データフローが本当に逐次的・命令的計算の代替であること、そして、データフローアルゴリズムをLucidで自然かつ簡潔に表現できることを示すことである。
私たちは成功したと期待しているが、判断は読者に任せたい。

しかしながら、あなたが判断を下す前に、A. Faustiniの優れたpLucidインタプリタ(これはC. Ostrumの最初の草稿に基づいている)を入手することをお勧めする。
言語は興味深いアプリケーションをプログラムするのに十分なほどリッチであり、エラー処理は優れている。
インタプリタは(ほとんどのインタプリタがそうであるように)大きく、ときに遅いが、いくつかのアプリケーションで使用するには十分である。
この本に書かれているサンプルプログラムは、Lucid拡張のものを除いてすべてがテストされているので、同様にうまく動くはずである。
唯一の問題は、現在のバージョンのインタプリタC言語で書かれていて、UNIXを必要とする。
不幸にも、より古く、より原始的なOSの使用を余儀なくされている人は、Lucidによるデータフロープログラミングを直に経験するのは、しばらく待つ必要があるだろう。

(以下、謝辞なので原文ママ

We would like to thank the funding agencies that supported the development of Lucid, and the production of this book. Initially this was done completely by the Canadian Science Research Council (subsequently the Natural Sciences and Engineering Research Council), even after one of the two of us (Bill Wadge) moved to the University of Warwick, in England. Eventually he obtained funding from the Science and Engineering Research Council of the United Kingdom. We are grateful for the help of both these bodies.

Collaboration across the Atlantic is not the easiest thing, and the development of the language was probably slower than necessary. (It did, however, enable us to preface lectures about Lucid with the observation that it was being developed by an Englishman working in Canada and a Canadian working in England.) At present, Ed Ashcroft is at SRI International, in California, and Bill Wadge at the University of Victoria, in British Columbia, Canada, and so now the authors are at least on the same side of the same continent.

We also would like to take this opportunity to thank the many people who have contributed to the development of Lucid and to the production of this book. These include (in alphabetical order) Thomas Cargill, Mansour Farah, Tony Faustini, Patrick Gardin, Christoph Hoffman, Steven Matthews, David May, Calvin Ostrum, Paul Pilgram and Ali Yaghi. Our special thanks go to Tony Faustini, Ali Yaghi and Steve Matthews, who wrote the pLucid manual and consented to having it included in the appendix. Extra special thanks go to Calvin Ostrum and Tony Faustini. Calvin became interested in Lucid as a second-year undergraduate student at Waterloo and singlehandedly produced an interpreter, written in C, in his third year. This interpreter forms the basis of the pLucid interpreter, which Tony Faustini developed while a research assistant at Warwick. Tony also contributed greatly to the design of pLucid itself.

Finally, we would like to thank the many students at the Universities of Warwick, Waterloo and Victoria who registered in courses in which Lucid was taught. Some of them were cruelly treated by early versions of pLucid and its interpreter, but they showed that mere mortals are capable of writing dataflow programs.

December 1984
Victoria, Canada

W. W. Wadge
E. A. Ashcroft

ということで、まずは序文だけ。

Java8でラムダ式が導入され、Haskellモナドによる関数の組み上げを、データの流れの組み上げと解釈してStreamという機能として実現したわけだけど、この時代にデータフローというものを見出しているというのは非常に興味深い。

今日はここまで!

トリックテイキングゲームのイロハを語ってみた。(その2)

昨日はトリテのイメージと専門用語について語ってみた。

今日はトリテのプレイングについて語ってみたい。

f:id:yamaimo0625:20160313142903j:plain

プレイの方針

さっそく、プレイの方針について。

といっても、自分もそんなにトリテが上手いわけではないので、基本的なところを。

まず、トリテをやったことがある人なら経験があると思うのが、選択の余地もなくほぼ自動的に出すカードが決まってしまって、ぐぬぬとなったこと。
自分から能動的な選択が出来ずに、何これクソゲー、と思ったことがある人も多いはず・・・

これを生んでいるのが、「マストフォロー」というルール。
そして、上記のような経験をすると、「マストフォロー」とかいう、プレイヤーから選択肢を奪うクソルールは、なくした方がいいんじゃないか?と思い、そんなクソルールを採用しているトリテなんか嫌いだ、となる人がいても、おかしくはないと思う。

けど、そこが逆に、ポイントとなる。

考えてみて欲しい。

なんで出せるカードが限られてしまうのか?

答えは簡単。

リードされたのと同じスートのカードを持っているから。

もしくは、

リードできていないから。

逆に言えば、それらを避けるように出来れば、自由にカードを出すことが出来る、と。

例えば、リードされたのと同じスートのカードを持っていなければ、自由にカードを出せるので、切り札をプレイしたり、あるいは、いらないカードを捨てたりすることが出来る。
また、そもそも自分がリードであれば、好きなカードを出し、他のプレイヤーの出すカードに縛りをかけることが出来る。

ここから導き出される方針は、以下の2つ。

まず、何かしらのスートを手札からなくすことで、自由にカードを出せる機会を増やすということ。
ちなみに、あるスートが手札にないことを、そのスートが「ボイド」である、と言ったりする。
(プログラムに馴染みのある人であれば分かると思うけど、"void"、つまり、「空っぽ」ということ)

そして、タイミングよくリードを得ることで、自分の好きなカードを出す機会を得るということ。
タイミングよくリードを取れれば、そこからいろんな行動をとることが出来る。

これまでの内容を見て分かる通り、「マストフォロー」というルールが働くことによって、トリテではリードを持っているプレイヤーが、他のプレイヤーより圧倒的に有利になっている。
テニスでいうサーブ権のようなものだ。
その、リードプレイヤーの攻撃をいかにかいくぐり、自分が攻撃するターンに持ち込めるのか。
その駆け引き、読み合い、そして、自分と相手の手札のコントロールというところに、トリテの面白さは詰まっている。

逆にいうと、「メイフォロー」のゲームだと、このあたりがかなりふわっとなる。
リードをとって攻撃しても相手はいくらでも躱しようがあるし、フォローされなかったからといってそのスートのカードが手札にないと読むことは出来ない。
「マストフォロー」によって、相手の手札のコントロールや読みが可能になり、そして、攻防の妙が生まれてくる。

じゃあ、リードを持ったときの攻撃として、どんなことが可能なのか。

まず分かりやすいのは「トランプ狩り」。
トランプ、つまり、切り札というのは、言葉通り、「フォローする側の」切り札となる。
なぜって、リードという攻撃をかいくぐり、かつ、自分がリードする権利を引っ張ってこれるわけだから。
逆にいうと、せっかくリードという権利を得ても、その権利を奪われかねないのが、トランプという存在になる。
そこで、ならばと「切り札でリード」を行うことで、無理やり他のプレイヤーから切り札を引き出すことが出来る。
そして、場に切り札がなくなれば、安心して切り札でないスートのランクの高いカードを出すことが出来るようになる。

また、ほぼ確実に勝てるカードでリードを行うというのも出来る。
例えば、まだスペードが一度もリードされていなくて、スペードの一番強いカードを持っていれば、それでリードすることで、ほぼ確実にそのトリックをとることが出来る。
というのは、まだ一度もリードされていない場合、そのスートがボイドになっている可能性は低いので、ほぼ間違いなくフォローされるから。

あとは、ボイドを作るために自分の手札にほぼないスートのカードをリードするというのもある。
ボイドが作れれば、かなりコントロールが楽になる。

それと、終盤になってくると、カードが残っているスートの種類もトランプも少なくなってくる。
そうなると、フォロー出来るかどうかで勝負が決まってくることが多い。
それこそ、そのスートで一番最弱のカードであっても、他にフォロー出来るプレイヤーがいなければ、それだけで勝ちになる。
なので、他のプレイヤーがフォローできないスートでリードを行うというのが、有効になる。

それに関連して覚えておきたいのが、「ロングスート」という概念。
これは、自分の手札で枚数がやたら多いスートのこと。
トランプが枯れている場合、リードを奪ってこのロングスートでリードを行えば、他のプレイヤーはフォローが困難で、しかもトランプで主導権を奪い返すことも出来ないので、「ずっと俺のターン!」をすることが出来る。
ただし、このロングスートは諸刃の剣でもあって、自分の手札にやたらと多いということは、他のプレイヤーの手札には少ないということ。
すると、どうなるのかというと、他のプレイヤーからリードされることが少なくなる。
結果、フォローが出来ず、全部捨て札になってしまうということも・・・
なので、リードを得るタイミングというのが非常に重要になってくる。

終盤の話に関してもう一つ、「ボイド」や「ロングスート」は手札のスートの偏りを大きくする動きなわけだけど、逆に、どのスートも出来るだけ保持しようとするのがいい場合もある。
特に、手札に強いカードがほとんどない場合。
なぜかというと、上記のようにフォローできないことを期待してリードしてくる場合があるから。
この場合、出来るだけフォロー出来るように広く持っておくことで、思わぬ勝ちを得たりすることが出来る。

カウンティング?

さて、トリテでよく話題になるのが、カウンティングの話。

上記で見ての通り、場にどんなカードが残っているのかというのは、すごく重要な情報だったりする。
なので、カウンティングは大切といえば大切。

ただ、そうなると、「カウンティングは難しいから、自分にはトリテは無理」となってしまう人もいると思う。

かくいう自分も、カウンティングは苦手w
正直、ちゃんと覚えてられない(^^;
なので、かなりフィーリングでしかカウンティングは行ってないけど、そんな自分でもトリテは楽しめているので、あまり肩肘張らずに楽しんだらいいと思う。

簡単に出来るカウンティングとして、「どのスートが何回リードされたか」というのがあると思う。
これをやるだけでも、だいぶ違う。
というのも、「マストフォロー」のルールがあるので、何回リードされたかを覚えておけば、そのスートが何枚くらい残っているかは、簡単に分かるから。

例えば、1つのスートが13枚で、4人でプレイする場合、平均で3枚くらい持っていることになる。
となると、1回目のリードはほぼフォローされるし、2回目のリードもけっこうフォローされる可能性が高い。
もちろん、ボイドを作られていなければ、だけど。
仮に2回とも全員がフォローすれば、13枚中8枚が使われたことになり、残りは5枚とすぐに分かる。
あるいは、一度もリードされていなければ、そのスートはほぼ13枚残っているということも分かる。

こんなふうに、どのスートが何回リードされたかという情報は、比較的覚えやすくて、結構重要なことが分かるので、オススメ。

アプリのススメ

あとは、実際に遊んでみるのが一番いいと思う。
その中で気づくことも多いだろうし。

ただ、あまり慣れてない状態でいきなり人と遊ぶのは、もしかしたらストレスがあるかも。

そんな場合、アプリで遊んでみるのも一つの方法。

オススメはウィザード。

Wizard

Wizard

  • Sean O'Connor
  • ゲーム
  • ¥480

手札をコントロールするというのがよく分かるし、何より面白い!

ということで、ぜひいろんなトリテを遊んでみて欲しいなw

今日はここまで!

トランプゲーム大全

トランプゲーム大全

夢中になる!トランプの本―ゲーム・マジック・占い (主婦の友ベストBOOKS)

夢中になる!トランプの本―ゲーム・マジック・占い (主婦の友ベストBOOKS)

Wizard Card Game

Wizard Card Game

Wizard

Wizard

  • Sean O'Connor
  • ゲーム
  • ¥480

トリックテイキングゲームのイロハを語ってみた。(その1)

ツイッターエゴサしてたら、揚子江さんの次のツイートが目に入った:

この記事を書いたのも、もう3年近く前になるのだけど、けっこう読まれているみたいで嬉しい。

で、この「嫌いなゲームや苦手なゲームは攻略法を調べると面白いかもしれない」というツイートを見て、ハッとした。
そう、嫌いなゲームや苦手なゲームって、なんでそれが嫌いだったり苦手だったりするのかというと、どうプレイしたらいいのか分からないどこが面白い要素なのか分からないどうやれば勝てるのか分からないということが多いんじゃないかな、と。
(まぁ、最初に遊んだときにボコられたり、自分の好きなようにプレイしたら怒られたりして嫌いになる、という「人」が原因のケースもけっこうありそうだけど・・・

そして、「苦手だ」と明言する人が多いように感じるゲームの一つが、トリックテイキングゲーム。
通称、「トリテ」。

f:id:yamaimo0625:20180107143606j:plain

好きな人は好きだけど、嫌いな人はとことん嫌いというか。

曰く、

  • そもそも、専門用語がよく分からない
  • 専門用語があって、初心者おことわりみたいな雰囲気が嫌
  • どのカードを出したらいいのか分からない
  • カウンティングしないとダメとか無理無理
  • 変なプレイをしてゲームを壊しそう・・・
  • なんでフォローしないとダメなの?
  • テーマもないし、地味
  • トランプ(笑)

いや、言いたいことはすっごいよく分かる。
自分もトリテ嫌いだったから。

けど、トリテ好きになった今となっては、もし上記のような理由でトリテを嫌っているのだとしたら、ちょっともったいないかな、と。
「分かってくれば」、すごく手軽に遊べるとても面白いゲームなのに。

もちろん、この「分かってくれば」の壁が大きいのだけど。

ということで、その最初のつまずきを取り除いていければと思う。

そもそも、トリックテイキングゲームって何?

おそらく、トリックテイキングゲームをまったく知らない人がこの記事を読むことはないと思うのだけど、一応、念のため。

トリックテイキングゲームは、カードゲームのジャンルの一つ。

基本的な流れは、以下の通り:

各自に何枚かの手札が配られ、順番に手札からカードを1枚ずつ表向きで出していく。
全員が1枚ずつ出し終えたら、出されたカードで強さ比べを行って、一番強いカードを出していた人が、その強さ比べでの勝者となる。
これを何度か繰り返し、ゲームごとに決められた方法で、最終的なゲームの勝者(あるいは敗者)を決定する。

これでなんで「トリックテイキングゲーム」という呼ばれ方になるかというと、上記の強さ比べのことを「トリック」と言い、それの勝者になることを「トリックを取る」と言うから。
トリックを取る(テイクする)ゲームなので、トリックテイキングゲーム。

トリックテイキングゲームの「イメージ」

さて、そんなトリックテイキングゲーム、テーマもヘッタクレもない感じだけど、それだと無味乾燥すぎて取っつきにくいので、ここではまず、トリックテイキングゲームの「イメージ」について話してみたい。

イメージして欲しいのは、争い合ういくつかの大国。
プレイヤーは、その大国の支配者。
支配者の元には当然何人もの家来がいて、それらがつまり手札。
その家来たちを使って他国と勝負を行い、自分の国を勝利へと導こう、というのが、ゲームの基本的な目的。

まぁ、手札を出し合って勝負を行い、相手を打ち負かすというゲームなので、シャドバやDXMと同じく、ある種のTCGと言うことが出来るかもしれない。

イメージしろ!
イメージしろとは (イメージシロとは) [単語記事] - ニコニコ大百科

そして、争いといっても、そこにはいろいろな種類がある。
軍事による武力の争いだったり、宗教による影響力の争いだったり、商業による経済的な争いだったり、農業による生産力の争いだったり。
これらを表しているのが、各カードのマーク(スート)。
スペードは「軍事」、ハートは「宗教」、ダイヤは「商業」、クラブは「農業」を表していると考えるといい。
(※一説では、スペードは剣、ハートは聖杯、ダイヤは貨幣、クラブは棍棒を意味していると言われてる)

また、家来にも当然、優秀な家来からダメな家来までいるわけで、それを表しているのが、各カードの数字(ランク)。
当然、ランクの高い家来ほど強く、ランクの低い家来は弱い。

さて、ある国が何かしらの家来で争いを仕掛けてきた。
それに対して、他の国も同様に家来を出し、その優秀さで勝負を行うことになる。

ここで重要なのが、最初に出てきた家来と別ジャンルの家来を出しても、勝負にならないということ。
例えば、軍事の争いに宗教家が出てきても意味ないし、逆もまた同様。
これが「フォローできなければ(基本的には)負け」というルールを意味している。

さらに、出せる家来がいるのに出さないのは、たとえそれで勝てないとしても、「卑怯」ということになる。
これが「マストフォロー」というマーク縛りのルールになってくる。

そんな感じで、お互いの家来を正々堂々と戦い合わせ、そして自国を勝利へと導くゲームと考えると、いろいろなルールがとてもスッキリと腑に落ちると思う。

ところで、軍事、宗教、商業、農業と、4つの争点を示したわけだけど、このどれもが常に対等とは限らない。
例えば、軍事を使えば他の争いであってもそれを無視して勝利できるかもしれない。
叩き切ってしまえばいいわけだから。
そんなふうに、他の争いよりも強い争いというのが、「切り札」ということになる。
もちろん、「正々堂々と」戦わないといけないので、出せる家来がいるのならその家来を出すしかないのだけど。

さらには、このテーマだけ聞くと、強い家来(=強い手札)を持ってるかどうかで勝負が決まってしまうように思えるかも。

実際、どれくらいトリックに勝てるかは手札による部分がけっこう大きいので、そのバラツキを減らすために、何回も行ってその結果で勝負を決めたりする。

あるいは、もっとシステマチックに「ビッド」を行うことでこの問題を解決しようとしているゲームもあったり。

例えば、各自が自分の手札を見て何回トリックをとれるかを宣言し、一番多い回数を宣言した人が「攻め」、それ以外の人は「受け」に回るという「攻防戦」の仕組みが入ったトリテがあったりする。
この場合、攻撃側は宣言した回数以上トリックをとれれば勝ちで、逆に、防御側は宣言された回数以上トリックをとられなければ勝ちになる。

他にも、自分の手札で何回トリックをとれるかを各自が宣言し、宣言通りにとれれば勝利ポイントをもらえ、そうでなければ勝利ポイントを失う、というトリテもあったりする。
この場合、大国の支配者であると同時に、実は裏社会のボスでもあり、裏で自分の国がどれだけ勝てるかをギャンブルしていて、そっちの方が重要である、というような 妄想 イメージをするといいと思う。

・・・厨二病じゃないよ?

専門用語・・・

次に、トリテの専門用語について。

これに関しては、以前にも書いたり。

ただ、結論から言えば、覚えてしまった方がいいと思う。
なぜかというと、まず、そもそもそんなに数があるわけでもないし、覚えてしまった方がいろいろ便利だから。

もちろん、何も知らない初心者に対して専門用語を使うのは間違ってると思うけど。

まず、カードに関して。
数字(A, 2, ... , 10, J, Q, K)は「ランク」、マークは「スート」と呼ぶことが多い。
これは単に英語でそう言うから。
それと、他より強いスートのことを「切り札」もしくは「トランプ」と言ったりする。
(※「トランプ」というのは本来「切り札」という意味)

あと、カードを出すことを「プレイ」すると言ったりする。
これは、将棋を「指す」、囲碁を「打つ」と同じで、そういうもんだと割り切った方がいい。

割り切った方がいいという意味では、「トリック」も同じ。
カードを出し合ってする強さ比べを「トリック」と言うわけだけど、なんで「トリック」なの?と言われると、答えられない。
それを不満に思う声も多いと思うんだけど、よくよく考えると、例えば将棋や囲碁で「対局」というのかと分からないし(「局」ってなに?)、麻雀の「場」(東場とか一本場とか)というのもよく分からない。
だから、「そう呼ぶもんなんだ」と割り切ってしまった方が、スッキリする。

「トリック」よりはスッキリすると思う同様の言葉としては「ディール」がある。
これは、各自に手札を配り、トリックを複数回行って手札を使い切るまでのこと。
普通は手札による偏りを均すために、複数ディール行って勝負を決めることになる。

あとは、「リード」と「フォロー」、それに伴って、「マストフォロー」「メイフォロー」「マストノットフォロー」といったところ。
これは英語で書けば簡単で、"lead"と"follow"、つまり、「導く」と「従う」ということ。
一番最初にプレイするから「リード」する(=導く)となり、そのあとにプレイするから「フォロー」する(=従う)となる。
先程のイメージで言えば、導くというのは、どの分野で競うかを決めるということになり、従うというのは、つまり、決められた分野での勝負にのるということになる。
そして、必ずフォローしないとダメなのが「マストフォロー」("must follow")、フォローしなくてもいいのが「メイフォロー」("may follow")、逆に、フォローしちゃいけないというゲームもあって、それは「マストノットフォロー」("must not follow")と呼ばれたりする。

あとは、リードするプレイヤーを「リードプレイヤー」や「リーダー」、フォローするプレイヤーを「フォロワー」と言ったりするくらい。

それと、自分のとるトリック数とかを宣言する「ビッド」とか。

上で挙げた用語を改めてリストアップしてみれば、

  • ランク
  • スート
  • 切り札(トランプ)
  • プレイ
  • トリック
  • ディール
  • リード
  • フォロー
  • ビッド

と、こんなもん。
そんなに多くないでしょ?

あとは、「ラフ」とか「ボイド」とか、慣例的に使われてる表現がいくつかあるけど、あまり気にしなくていいと思う。

(余談だけど、「ラフ」の綴りって、"Ruff"なのか・・・ Ruff (cards) - Wikipedia


長くなったので、プレイングに関しては、また明日。

今日はここまで!

トランプゲーム大全

トランプゲーム大全

夢中になる!トランプの本―ゲーム・マジック・占い (主婦の友ベストBOOKS)

夢中になる!トランプの本―ゲーム・マジック・占い (主婦の友ベストBOOKS)

『現れる存在』を読んでみた。

『現れる存在』を読んで、これが非常に面白い本だったので、紹介したい。

現れる存在―脳と身体と世界の再統合

現れる存在―脳と身体と世界の再統合

ちなみに、どんな本なのかをすごく簡単に言うと、知能とは脳の中に閉じているものではなくて、身体、さらには環境にもにじみ出て、それらの相互作用による創発によって生み出されているのではないか、ということを、様々な事例に基づいて主張している本。
哲学的であるのだけど、それ以上に非常に科学的。
そして、取り上げている事例を読むだけでもすごく面白い。

きっかけ

そもそも、なんでこの本を読もうと思ったのかというと、『人工知能のための哲学塾』の参加者で読書会を企画した方がいて、その準備会みたいな集まりにこそっと参加させてもらったのだけど(ちなみに、読書会自体には自分は参加できなかった・・・)、その場で『人工知能のための哲学塾』のアドバイザー的な立場だった大山さんがこの本を薦めていたから。

そのときはとりあえずメモっておいて、hontoでクーポンが出たら買おうと思っていたのだけど、いつまで経っても紙の本のクーポンが出ず、同じように待っていた飲茶さんの『飲茶の「最強!」のニーチェ』を買うときに、一緒に購入した。

届いてまず、その分厚さにびっくり。
こんなにしっかりした本だったのか・・・
(※脚注や参考文献、付録諸々を入れて400ページ強)
が、開いてパラパラとめくってみれば、これが読んでて非常に気持ちのいい文体。
翻訳がいいからなのか、分厚さのわりにだいぶスラスラと読めた。
(ただし、6章〜8章を除く。特に8章は読むに耐えない・・・)

どうして人工知能は「アホ」なのか

イントロダクションでまず語られるのがこれで、痛快すぎるw

われわれが作り出した最高の『知的』人工物は、なぜいまだに、言いようもなく手の施しようもないアホなのか。
一つの可能性は、われわれが知能そのものの本質をまったく誤解しているということだ。
われわれは心というものを、ある種の論理的推論装置が、明示的に蓄えられたデータと結びついたものも考えていた(略)。
(省略)
われわれが無視している事実とは、生物の心が何よりもまず、生物の身体をコントロールするための組織だということだ。
(省略)
心は決して身体を伴わない論理的推論装置ではないのだ。
(『現れる存在』より引用)

つまり、知能というとどうしてもパソコン的なものを思い浮かべてしまって、膨大なデータと、そのデータを処理する仕組みこそ知能なのだと思い込んでしまうけど、そんなんだから人工知能はどうしようもなくアホなんだよ、と。

確かに、知能のあり方をパソコン的なものとして捉えていれば、どうしたって出来上がるものはパソコン程度のものにしかならない。
そうじゃなくて、心が身体をコントロールするための組織として発達してきたという事実に目を向けなければ、生物の賢さというものは見えてこない、と。

そのあとは、CYCというとんでもないプロジェクト(二人世紀かけて知識データをコンピュータに入力する)を紹介し、それがゴキブリのもつある種の賢さにも劣ることを示している。
ゴキブリさん、ぱねぇ・・・

包摂アーキテクチャ、モデルをもたない心、環世界・・・

そこから本では、このブログでも何度か名前が出てきたブルックスと包摂アーキテクチャ(サブサンプション・アーキテクチャ)を紹介し、そのアーキテクチャを用いた様々なロボット、それに、モデルをもたない心(表象なき知性)、さらにはユクスキュルの環世界の紹介を行なっている。
このあたりは、『人工知能のための哲学塾』を読んでいれば、馴染み深いと思う。
そして、具体的なロボットの紹介もされているので、そこだけでも十分面白いと思う。

青写真なき発達

そのあと紹介されていて面白かったのが、乳幼児の歩行に関する話。

まず、新生児を持ち上げて床から離すと、よく調和のとれた足踏み運動が見られるらしい。
しかし、2ヶ月ほどすると、この足踏み運動は行われなくなる。
このあと、8ヶ月から10ヶ月になると再び足踏み運動が見られるようになり、およそ12ヶ月で自律的な歩行が見られるようになるらしい。

この2ヶ月から8ヶ月にかけて、足踏み運動が行われなくなる理由、普通だとちょっと分からない。
素直に考えると、2ヶ月頃には、なにか無意味な足踏みを抑止するような脳の成長があったりするのかな、と思ってしまう。

が、この理由は、もっと別のところにあったとのこと。
その答えは、「脚の重さ」w

どうやら、脚が成長していくことで、2ヶ月経った頃に、直立姿勢のときの脚の重さが、脚の筋肉が持ち上げられる重さを超えてしまうらしいw
なので、足踏み運動が行われなくなる。
そして、8ヶ月経った頃、今度は脚の筋肉が十分に発達してきて、結果、再び足踏み運動が見られるようになる、と。
実際、3ヶ月経って足踏み運動をしなくなった乳幼児を、実質的に脚が軽くなる水中に直立させると、再び足踏み運動を始めるらしいw

この事実の意味するところは、幼児の発達を理解するときに、複数の要因の相互作用を考えなければならない、ということ。
この例の場合、脳や遺伝子といった、中央集権的なものが原因だったのではなく、「脚の筋力」と「脚の重さ」という2つのパラメータの関係が、足踏み運動の振る舞いの原因になっていた。
つまり、脳や遺伝子になにか壮大な青写真があって、それにしたがって発達していたわけではないんだ、ということが分かる。


で、そのあともいろいろ面白い話が続くんだけど、まとめるの、諦めた(^^;
どれもこれもが興味深い話で、書き始めるとキリがない・・・
ということで、自分のTwitterでの呟きをピックアップ。
あとで余力があればまとめ直すかも。

007原理

「007原理」というのは、次のようなもの:

一般に、進化した生物は、環境の構造や環境に対する操作を、関連する情報処理操作の代用物としてうまく利用できる場合、あえて損失の大きなやりかたで情報を蓄積したり処理したりはしない。
すなわち、仕事を済ますのに必要なことだけを知るべきなのである。
(『現れる存在』より引用)

オッカムの剃刀」の生物版というか、何かすでに使えるものがあるのなら、それを使うことでコストを下げるようにする、という原理。

外的な足場作り

環境との相互作用による創発を考えていくと、人間が賢くなってきたというよりかは、人間がまわりの環境を賢く作り変えてきたんじゃないか、という話。
この発想は非常に面白い。

言葉がもつ力

そして、言葉もそうやって人間に作られた「道具」の一つだ、という話。
コミュニケーションに使われるだけでなくて、言語自体が人間を賢くする力を持っている。


他、面白かった内容として、創発とはどういうことなのかの説明とかがあった。

それに関連して、今、制御理論に興味があったりする。

これまでの人工知能の理論は、基本的に2つの軸があって、統計学によるもの(ベイズ推論とか)と、最適化数学によるもの(ニューラルネットワークSVM)とに分けられる。
ただ、創発といった相互作用を考えていくとすれば、そこで出てくるのは力学的な微分方程式で、それを解いていくための強力な武器になるのが、制御理論となってくる。

制御理論については、また別の機会に。

今日はここまで!

現れる存在―脳と身体と世界の再統合

現れる存在―脳と身体と世界の再統合

『飲茶の「最強!」のニーチェ』を読んでみた。

飲茶さんの書いたニーチェ入門本『飲茶の「最強!」のニーチェ』。

飲茶の「最強! 」のニーチェ

飲茶の「最強! 」のニーチェ

出たのはだいぶ前なのだけど(約半年前)、hontoで電子書籍化されないかなーとずっと待ってたら、だいぶ時間が経ってしまった。。。
結局、全然電子書籍化される気配がないので、諦めて紙書籍を買ったのだけど。
電子書籍で読みたかった・・・

ただ、内容自体はさすが飲茶さんという感じで、とても読みやすく、また、分かりやすかった。
なので、軽く感想とか。

概要

本の出だしで説明があるのだけど、この本は出口先生の「最強!」シリーズののれん分けということで、他の「最強!」シリーズと同じ形式をとっているとのこと。
具体的には、表紙の女の子(アキホちゃん)と先生が対話することで、話が進んでいく。
ただ、これがなんかちょっとアレな動画のインタビューみたい(^^;

いろいろな哲学の中でも、特にニーチェの哲学を学ぶと、そういう「前向きな生き方」が身につくんだ。
(省略)

(アキホ)
前向きな生き方・・・。
それはとても興味がありますね。

あれ?
アキホちゃんは、もともと前向きな生き方をしてそうだけど・・・。

(アキホ)
そんなことないです。
さっき仕事が失敗ばかりだと言いましたが、実は、仕事に対して前向きになれなくて・・・。

そうだったんだ。

(アキホ)
最近、毎日思うんです。
私、この仕事本当に好きでやっているのかなって。
なんとなく、ただ惰性でやってるだけの気がして。
あと、彼氏も・・・。

うまくいってないの?

(アキホ)
いえ、そうではないのですが。
やっぱり同じ話で、本当に好きなのかなと・・・。
(省略)

それはたしかにちょっと後ろ向きかもね。
アキホちゃんって、意外とネガティブ性格なんだね。

(『飲茶の「最強!」のニーチェ』より引用)

なんかこのあと、「そんなこと、僕が忘れさせてあげるよ」とか言いながらキスとかし始めそうな雰囲気だけど、これはそういう本ではないw
上で引用したのはそれっぽく感じる極端な例で、大部分はこんな胡散臭い感じの会話ではないので、大丈夫。

ともあれ、こんな感じで対話を使って話を進めていくので、読者が感じるであろう素朴な疑問や反論をその場で拾い上げ、そして丁寧に応えていくという構成になっていて、非常に分かりやすいし、共感も得られやすいと思う。
そして、そうすることによって、いろいろ誤解を受けやすい(「ルサンチマン」とか「神は死んだ」とか「永劫回帰」「力への意志」「超人」というパワーワードに誤魔化され、ニーチェを世界の破壊者ディケイドのように読んでしまう)であろうニーチェの哲学を、分かりやすく、誤解のないように説明している。

白哲学と黒哲学

個人的に面白い表現だなと思ったのが、「白哲学」と「黒哲学」という分類。

冒頭で、そもそも哲学ってなんなのさ、という疑問を取り上げ、それに対する飲茶さんの考えを述べているのだけど、そこで出てくるのがこれらの言葉。
これは、飲茶さんの別著である『てつがくフレンズ』で出てくる「プラトン主義」と「反プラトン主義」を言い換えたものだけど、まさにイメージにピッタリで、言い得て妙という感じ。

それに、中二病くさい感じがすごく好きw
ほら、哲学好きな人って、みんな中二病拗らせてるわけだしw(偏見)

ちなみに、自分の立場については『てつがくフレンズ』の感想に書いた通り。

白魔道士でも黒魔道士でもなく、太極図的な意味で、ただの道士かな?w

大いなる正午と悟り

あと、個人的にとてもよかったと思っているのが、飲茶さんの実体験が書かれていたこと。
なぜかというと、本で得た知識をまとめたものであれば、それは(文章のうまさとかに差はあれど)言ってしまえば「誰でも書けるもの」だけど、実体験を交えて書かれて入れば、それはその経験をした「その人」にしか書けないものになるから。
特に、「大いなる正午」の説明においては、その説明が示す通り、「体験する」ということそれ自体は重要になってくる。

そう。
「すべてのラベルが外れた世界」「架空の価値観が消えた世界」など、そういう実存哲学の言う世界観は、理屈ではなく体験してはじめて理解できるものなんだ。
逆に言えば、一度でも「ああ、本当にそうなんだ!」と体験してわかってしまえば、それは虚しい知識ではなく、その後の人生を一変するような知識となる。
だから、そういう体験をすることが実在哲学においては肝なんだけど、ニーチェの哲学体系の中では、それに相当する体験を「大いなる正午」と呼んでいる。
(『飲茶の「最強!」のニーチェ』より引用)

飲茶さんが実際にどのような体験をしたのか、あと、飲茶さんが哲学をするに至った経緯などは、実際に本で。

それにしても、なんとも東洋哲学的なw
まさに「悟り」の境地w

今日はここまで!

飲茶の「最強! 」のニーチェ

飲茶の「最強! 」のニーチェ

『人工知能のための哲学塾 東洋哲学篇』を読んでみた。

人工知能のための哲学塾』に続く第二弾、『人工知能のための哲学塾 東洋哲学篇』を読んだので、その感想とか。

人工知能のための哲学塾 東洋哲学篇

人工知能のための哲学塾 東洋哲学篇

人工知能のための哲学塾』の感想は、以下から:

概要

この本も一作目と同様に、人工知能の「知能」ーーそれも、浅い上辺だけの「知能」じゃなくて、より深い「知能」ーーあえて言うなら、「心」や「存在」ーーを、哲学的な知見を頼って探求していくという本。
一作目は西洋哲学中心だったのに対して、本作では東洋哲学からのアプローチが中心になっている。

ただ、なんというか、なんとも掴みどころがないのが東洋哲学の特徴。
それゆえ、この本は一作目にも増して議論があっちこっちに発散し、また、同じような話が何度も何度も出てきたりして、モヤモヤを感じる人は多いかもしれない。

けど、これに関しては、犬飼さんが前書きに寄せて書いた「『人工知能のための哲学塾』の遊び方」という文章が絶品で、この本がどういった本なのかを端的に示してくれている:

東洋哲学篇は、前回にも増して三宅さんの講義録を読んでも答えらしい答えは出てきません。
何らかの明確な答えを期待して手に取った方は混乱してしまうかもしれません。
しかし、その言葉を咀嚼すればするほど、次から次へと、まるでポエトリーのような問いが自分の中に浮き上がってくるはずです。
その自己生成された問いでぜひ遊んで欲しいのです。
(『人工知能のための哲学塾 東洋篇』より引用)

そう、この本は「答え」を得るための本じゃなくて、「遊ぶ」ための本。
哲学(というか、思想)を「知る」ための本じゃなくて、哲学を「する」ための本。

してみると、殿さまが読まれているのは、古人の残りかすということになりますねぇ。
(『荘子』より引用。というか、本作より孫引き)

この言葉が示す通り、書かれているものをただ知るだけではダメで、そこから自分で考えて、そして、自分のものにしていかないと意味がない。

ふと思ったのは、この本はTRPGのルルブ(ルールブック)のような本なんだろうな、ということ。
ルルブには設定や資料、シナリオの例や遊び方は書かれているけど、実際の物語はどこにも書かれていない。
自分たちで実際に遊んで初めて物語は創り出され、そして、楽しさも生まれてくる。

サブサンプション・アーキテクチャ

さて、本作で「西洋的」で「構築的」な「ボトムアップ」のアーキテクチャとして何度も取り上げられているのが、サブサンプション・アーキテクチャ
これを叩き台として、対照的な「東洋的」で「脱構築的」で「トップダウン」のアーキテクチャが模索できないものか、というのが主題の一つとして取り上げられているように思った。

ただ、これには個人的にはちょっと違和感。
というのは、本作で模索する東洋的な人工知能のモデルこそ、サブサンプション・アーキテクチャに行きつくのではないかな、と思ったから。

サブサンプション・アーキテクチャがあまりに当たり前に出てくるから、これが西洋では当たり前のアーキテクチャなんだとついつい思ってしまうけど(というか、自分もそう勘違いしてた)、実際にはかなり異端。
前作の第三夜に書かれている通り、西洋では形式論から人工知能の研究は発展していったので、環境や身体の話は出てこないで、上辺の論理的な思考にばかり目が向けられてきた。
そこに一石を投じたのが、サブサンプション・アーキテクチャ

自分がそのことを知ったのは、『<弱いロボット>の思考 わたし・身体・コミュニケーション』という本を読んだから。

さて、認知的なロボティクスの分野は、1990年代になると俄然おもしろくなってきた。
「象はチェスを指さない!」「表象なき知性」など、ちょっと過激で斬新な主張が日本にも次第に伝わってきた。
その発信源は、マサチューセッツ工科大学のロドニー・ブルックスである。
(中略)
ブルックスは、こうした「頭のなか」での表象操作などを「古きよき時代の人工知能」と半ば揶揄しながら、「そんな表象やプランを用意しなくとも、かしこい振る舞いは生み出せるのではないか」(省略)と、そのかしこい振る舞いを<ゲンギス>などを用いて、上手にデモンストレーションしてみせた。
(中略)
どのように障害物を乗り越えたのか、その表象は「頭のなか」には残らない。
その対象を撫で回すかのように、脚をすこしずつ上げただけ。
つまり、不整地の状況を「環境のモデル」として「頭のなか」に表現することなく、その環境に備わる制約を情報としてそのまま利用している。
「モデル」はどこにあるのかといえば、「頭のなか」ではなく「周囲の環境そのもの」にあるのだ。
(中略)
ブルックスを一躍有名にした<ゲンギス>のための制御アーキテクチャの論文は、(省略)いわゆる「サブサンプション・アーキテクチャ」と呼ばれるものである。
(中略)
では、この<ゲンギス>の行動を生みだしていたアーキテクチャの主たる特徴はどこにあったのだろう。
(省略)その知性は「ロボットの個体の内部」に備わるのではなく、むしろ「周囲とのあいだにわかち持たれている」といえるのだ。
人やロボットの能力や機能というものを議論するとき、その個体のなかに閉じたものとしてとらえられやすい。
それをブルックスやサッチマンたちは、環境とのあいだの関係論的なシステムとして拡張してみせたのである。
(『<弱いロボット>の思考 わたし・身体・コミュニケーション』より引用)

長々と引用してしまったけど、この衝撃はなかなかのものだった。
サブサンプション・アーキテクチャの元の発想は、ソフトウェアを階層的なモジュールに分けて構築するというトップダウン的な発想のものではなく、環境との相互作用の中で知能を生みだしていくことが出来るんだというボトムアップ的な発想のものだったわけだから。
そして、これは本作で言及されている「縁起的人工知能」の考えに通じるものがある。

余談だけど、この『<弱いロボット>の思考 わたし・身体・コミュニケーション』という本はすごく面白い。
普通であれば、こういう研究ってより高度な技術へと向かっていこうとするものだけど、そうではなく、一度立ち止まって、すごいロボットじゃなくたっていいんじゃないか、というところから、人とロボットとの関係の可能性について議論を展開している。

「なんらかの利便性を提供してくれるもの・・・」とは、ロボットや人工知能技術などに対する一般的な期待だろう。
(中略)
いくつか<〇〇してくれるロボット>というアイディアを並べてみたけど、どうもしっくりこない。
(中略)
よくよく考えてみれば、あかちゃんというのは、(省略)なにもできないような<弱い存在>である。
にもかかわらず、ちょっとぐずることで周りから手助けを上手に引きだし、必要なミルクを手に入れ、そして思いのままに移動できてしまう。
(省略)家庭のなかでもっとも<弱い存在>のはずが、いちばんに<強い存在>であったりする。
(中略)
「あっ、そうか。人の手を借りちゃってもいいのか・・・」と思う。
(省略)「ロボットの自律的な機能にばかり目がいくけれども、こんな手があったのか」というわけである。
(『<弱いロボット>の思考 わたし・身体・コミュニケーション』より引用)

二つのインフォメーションフロー

ところで、読んでて改めて思ったのは、自分と三宅先生だと「一なる全」の解釈に決定的な解釈の違いがあるなぁ、ということ。

自分の解釈は上の記事で書いた通り。
「一なる全」を未分化の存在(簡単にいえば「空」や「道」)と捉えてて、分化されていくことで自分という存在に至ると考えてる。
なので、2つの図は単に見方が違うだけで(一個体の構造(機能、クラス図)に注目しているか、多数個体の構造(存在、オブジェクト図)に注目しているか)、本質的には同じことを示していると思っている。

一方、三宅先生は「一なる全」を、属性とかそういったものを全て取り去った精神、あるいは存在ーーあえて言うなれば、魂のようなものーーと捉えてるっぽくて、それが身体を持ち環境と交わる中で様々な制約を受け、そして自分として発現する、というように捉えているように読める。

この解釈の是非はいろいろあるのだけど、ただ、そこから提唱している二つのインフォメーションフローの話はとても有益に思えた。
「一なる全」と書いてると微妙だけど、これを「内的世界」に置き換えれば、まさにリカレントモデルの話や、遠心性コピーの話と繋がってくる。
(実際、本でもその話に繋げていっている)

ちなみに、自分の解釈だとこの話は出てこないかというと、そんなことはなくて。
自分という存在は固有のオブジェクトなので、内部状態を持つことになる。
この内部状態こそが、これまでの過去の状態の累積であり、と同時に、次の振る舞いを定める入力の一つとなる。
関数型言語のように状態を引数として明示的に示すようにしているか、オブジェクト指向言語のように内部に閉じ込めて外からは見えなくしているかの違いがあるだけ。
もちろん、そのような内部状態という項があるんだという指摘こそが重要なのだけど。

人工知能は「幸せ」になれるのか

それにしても、本を読んでいると、どうやったら人工知能に欲望や悩み、葛藤を与えることが出来るのか、ということが終始出てくるので、ちょっと考えてしまう。
はたして、人工知能はそれで「幸せ」なのかな、と。

たしかにこのとおり作動しているのだ!
おまえが望んだ「悪の心」がな!
(中略)
そうなんだ、「悪の心」が、ぎゃくにおれを強くしたんだ!
そんなものに負けちゃいけないという「心」がおれを強くした!

おれはこれで人間と同じになった!
だが、それとひきかえにおれは、これから永久に「悪」と「良心」の心のたたかいに苦しめられるだろう・・・

ーーピノキオは人間になりました。
メデタシ メデタシ・・・

だが、ピノキオは人間になってほんとうに幸せになれたのだろうか・・・?
(『人造人間キカイダー』より引用)

人工知能をより人間らしくさせたいというのは、ヒトのエゴであって、人工知能のためにはなっていないのではないかな、と。

ただ、たとえそれがヒトのエゴであったとしても、やっぱり人間らしい人工知能を生みだしたいと思うし、それで人工知能を不幸にしてしまうかというと、必ずしもそうではないと思う。
それは、人が子を産むのに近い感覚なのかもしれない。

君が来た朝を後悔するなら、更なる痛みを産むべきではない。
君が行く夜を肯定するなら、その子もまた「人生(せい)」を愛すだろう・・・
(『Roman』「黄昏の賢者」より引用)

今日はここまで!

人工知能のための哲学塾 東洋哲学篇

人工知能のための哲学塾 東洋哲学篇

人工知能のための哲学塾

人工知能のための哲学塾

人造人間キカイダー (4) (秋田文庫)

人造人間キカイダー (4) (秋田文庫)

5th story CD「Roman」(初回限定盤)

5th story CD「Roman」(初回限定盤)