助詞「を」のprolog処理

次に、助詞「を」を処理しよう。前と同じ「ニワトリは卵を生む」というデータの中には「を」が入っている。先には、

は(ニワトリ,産む(卵)).

と知識化したのだが、この後半が良くなかった。そこで、そこを改良して、助詞「を」をオペレータ化をすることにする。つまり、

は(ニワトリ,を(卵,生む)).

とても、文章データを基にしたprolog知識としていい線をいっている。ほとんど、文章そのものを形にした感じがある。
この知識に対して問い合わせした結果は次のようになる。

?- は(X,を(卵,Y)).
X = ニワトリ,
Y = 生む.

?- は(ニワトリ,を(Z,生む)).
Z = 卵.

前半は、「卵というのは、ニワトリが生むものである」というわけである。後半は「ニワトリが生むとしたら、それは卵である」ということになる。少し面白いのは次の問い合わせである。

?- は(ニワトリ,Z).
Z = を(卵, 生む).

ニワトリとは何かに対して、卵を生むものであるという、意味を返してきているのである。ここには、プログラム自体と、データを同じように扱うという特色が現れているのだと思う。

さらに次のようなことを考える。元々の「ニワトリは卵を生む」という情報の中には、「卵」は「生む」という動詞に結びつくのだという大切な「知識」が含まれている。これも、prolog化できそうな気がする。

そこで、

を(卵,Z)

のユニフィケーションを求めると、次のようにエラーになる。

?- を(卵,Z).
ERROR: Undefined procedure: を/2 (DWIM could not correct goal)

当然なのは当然なのだが、なんとしたものか。もちろん、を(卵, 生む).を宣言してしまえば、問題はないのだが。なんか方法はあるはずだが、今の私のprologの知識では、なんともならない。

宣言文の中にある、相対的に独立した部分知識を取り出す手続きがあればいい。(要検討)

格助詞「は」のprolog処理

先の記事で、助詞「の」の prolog処理の例を示したが、格助詞「は」の処理例は以下のようになる。

は(ニワトリ, 鳥).
生む(A, 卵) :- は(A, 鳥).

一行目は、宣言文である。すなわち「ニワトリは鳥である」。二行目は、規則となるで、「鳥は卵を生む」を表している。もう少し丁寧に文に即して言えば「卵を生むものであるためには、それが鳥であれば良い」とも言える。

この知識を利用すると、次のように質問に答えることができる。

?- 生む(ニワトリ,卵).  %一つ目の問い合わせ
true.

?- 生む(ニワトリ,Y).   % 二つ目の問い合わせ
Y = 卵.

となる。一つ目は、ニワトリは卵を生むというのは正しい、二つ目は、ニワトリが生むとしたら、それは卵だろうということを表している。

ただ、ちょっと気に入らないところがある。元々は、「ニワトリは卵を生む」という文章をprolog化したかったのだが、少し趣旨が違ってきたように思う。

は(ニワトリ,生む(卵)).

書けば上記のようになるはずだ。これだけを prologの宣言文とする。すると次のような、問い合わせに対応できる。

%(1)
?- は(X,生む(Y)). 
X = ニワトリ,
Y = 卵.
%(2)
?- は(ニワトリ,生む(Y)).
Y = 卵.
%(3)
?- は(X,生む(卵)). 
X = ニワトリ.

(1)は、現状の知識では、何かを生む何者とは、という問い合わせに、ニワトリならば卵を生むけれどね、という答えしか出さない。(2)ニワトリが何かを生むとしたら、それは卵であると答える。(3)卵を生むものであるならば、それはニワトリであろう、というわけである。

知識が増えたらどうなるだろう。「アヒルも卵を生む」というわけである。宣言文が二つになる。

% 知識の表現
は(ニワトリ,生む(卵)).
は(アヒル,生む(卵)).

すると、先の答えが少し違ってくる。

?- は(ニワトリ,生む(卵)).
true.

?- は(アヒル,生む(卵)).
true.

?- は(X,生む(卵)).
X = ニワトリ ;
X = アヒル.

卵を生むものには、ニワトリもいるがアヒルもいる、というわけである。前者の場合は、

% 知識の表現
は(ニワトリ, 鳥).
は(アヒル, 鳥).
生む(A, 卵) :- は(A, 鳥).

となる。増えた分は単純だ。問い合わせの例は次のようになる

?- 生む(X,卵).
X = ニワトリ ;
X = アヒル.

となる。こっちの方が、単純に思える。ただ、単純な文章が持つ「知識」が、単純に表現されていないから、しっくりいかないのである。

prologと自然言語解析

ニューラルネットワークを基にしたシステムでは、word2vecくらいしか、役に立たなかった。word2vecはとても優れているが、結局、言葉を低次元ベクトルに変換し、言葉の親近度を計るところまでである。

結局、例えば、wikipediaのデータ、情報を知識化するのにはそう言う、ネットワーク系のシステムでは対応できない気がして悩んだ。

なぜ対応できないのか、とどのつまり、言葉がロジック、論理であって、画像認識のような直感的なものとは異なるからなのだ。人間が直感的にやっていること、例えば、画像認識以外にも、将棋や囲碁の形成の判断のようなものには、人間を上回る力を発揮する。しかし、言葉は違う。直感があったとしても、ベースには論理がある。逆かもしれない。直感をベースにした論理というべきか。

wikipediaのデータも、すべて、「論理的な言い換え」、「極端に複雑なトートロジー」である。これを表現するのにふさわしい言語は、論理型の言語だと思った。そして、prologに至った。

prologは、古い、カビの生えたような言語だ。何しろ、私が神戸大学の大学院経済学研究科の最初のゼミで、発表したのがprologを使って経済データのトレンドを判定する、しかも単純に上昇か下降かだけだが、そんな結果を発表するために使った言語だ。指導教員にダメ出しをされて、すぐにその方向はやめてしまったが。それは正しい判断だった。そんなものに使うべきではない。

例えば「ニワトリは卵を生む」という知識があったとしよう。これを、「ニワトリの卵」という表現が正しいかどうかを調べることができる知識に変換することを考える。

(prologは、swi-prologを使用する。Macの場合、brew install swi-prolog で、簡単にインストールできる。)

2 ?- [user].
|: の(X,Y) :- 産む(X,Y).
|: ^D
% user://1 compiled 0.00 sec, 1 clauses
true.

3 ?- [user].
|: 産む(ニワトリ,卵).
|: ^D
% user://2 compiled 0.00 sec, 1 clauses
true.

3 ?- の(ニワトリ,Y).
Y = 卵.

4 ?- の(ニワトリ,卵).
true.

5 ?- 

となる。?-がprologのプロンプトで、[user].は、論理や宣言をプロンプトから付け加えるための、疑似ストリームである。「ニワトリは卵を生む」を
産む(ニワトリ,卵).
という宣言に変換している。
そして、〇〇の〇〇という表現は可能になれば、trueが帰ってくるというわけである。

ここでは、「の」という助詞と、「産む」という動詞をoperatorにしているが、「は」とか「で」なんかも、そのようにして、文章が含意している知識を定式化したいと思うわけだ。

wikipediaの 本文データのほとんどを、prologの宣言とルールに変換できないかというのが、今、考えていることの中心点である。

あらゆる説明は、言い換えに過ぎない:「知っている」という現象(2)

ある対象に対する知識を持っているとは、ある対象を「説明できる」と言えるだろう。説明はある意味きりがない。

「私はなぜ失敗したのですか?」
「君には能力がなかったからだ」
「私にはどうして能力がないのですか?」
「必要な努力を怠ったからだ」
普通この辺りでやめるか・・・・・・
「必要な努力とはどれくらいの努力なのですか」
「結果、失敗しないような努力だ」
こうなると、一種のトートロジーである。

なんでもそうだと思うが、結局説明されるがわが「なるほど」と納得できるほどに、違った言い換えができることが知識の条件なのである。

「卵ってなんですか」
「にわとりが産むものだ」
ここで納得すれば終わりとなる。
「にわとりってなんですか」
「卵から生まれたものだ」

これもまた説明である。後の二つの文は、無意味なものではない。ただ、全体は、トートロジーと言われても仕方がない。

unable to launch "cinnamon-session-cinnamon" X session - 云々

タイトルのエラーを吐いて、突然、ロボット制御用に使っているLinux Mint (32ビット)が立ち上がらくなった。ネットには色々書かれているが、私の場合、次の方法で解決した。

(1)エラーメッセージが出ている状態で、Ctrl-Alt-F1でXウィンドウを使わないCUIモードに変更する。

(2)ログインする

(3) $ sudo apt-get install mint-meta-cinnamon を実行する

なぜ、こんなことになるのか、なぜこの方法で解消するのか、一切不明。

両足ジャンプ with DCM

DCMを使ってジャンプさせてみた。

目に見えて飛び上がるまでになっていない。ただ、動きは前より格段に早くなった。ジャンプしそうな雰囲気を出しているし、実際 0.5mm くらいは浮いたような気がしないでもない(笑)

 

NAOQIに付属しているDCMサンプル

NAOQIにDCMのサンプルがついている。=> ココ
fastgetsetsample
という名前になっている。

このなかには、DCMの使い方のいろいろなノウハウが詰まっている。DCMは、単独の動作を直接アクチュエーターやセンサー、LEDに送ることができるが、ここには、同時に、10msecという短い周期で、DCMからよびだすことができるコールバック関数の書き方が示されている。

このコールバック関数に記載すれば、ロボットのボディの全体状況を細かく制御できる。

たとえば、NAOが倒れた瞬間に、すべての関節状態の硬直性を一瞬にゼロにして、破壊を出来る限り回避する力を持っている。これは、NAOが足が地面から離れることをセンサーで感知したり、体の急速な傾きを感知したりして、その瞬間に、Stiffnessをゼロにする操作をしているからである。10msecあれば、その対応は十分できるのだろう。

ジャンプには、このコールバック関数は使わなくてもいいと思った。なにしろ、瞬発力が問題なので。先にも書いたように、コールバックを使わなくても、DCMコマンドを単体で叩いても、高速な動きは作れるからである。

しかし、ジャンプしたあとの体制の制御や、着地のことを考えると、このコールバック関数を使わなくてはならなくなるときが来るような気もするのだ。

NAOのDCMを直接叩く

NAOをジャンプさせようとして、ぬるい関節の動きに失望したという話を前回に書いた。そして、高次のNAOQIのAPIを使うことをやめて、DCMを直接叩くことにした。

まだ、きちんとコントロールはできていないが、試してみた関節の動きは、「すさまじく高速」だった。これで、ジャンプをさせることはできそうだが、コントロールできるかどうかはわからない。

DCMモジュール利用のための独自モジュール

キレキレのダンスをやらせるためには、ジャンプは不可欠だ。少しでもジャンプできなければ、手と体を揺らしている、そこら辺の動画レベルになってしまう。さしあたって、この間作成したポーズのシーケンススクリプトでジャンプをやらせてみたら、つぎの動画だ。

関節の動きが鈍くて、ジャンプにはならない!!

ギリギリスピードを早めても、だめだ。色々調べると、どうも、NAOQI側で、動きをスムーズにしているようだ。モータに直接アクセスしたい。それをNAOQIのDCMモジュールを操作することで実現できるかもしれない。

そこで、DCMを操作する独自モジュールを作成することにした。

NAOの胴体角度(Torso Angle)を捉える

NAOの胴体角度を100msec単位で取得した。図は、NAOを前後左右に揺らした結果である。縦軸は角度で、単位はラジアンである。

次の3個のキーがあって、メモリイベントとして取得すれば、胴体の絶対角度を取得できる。

Device/SubDeviceList/InertialSensor/AngleX/Sensor/Value
Device/SubDeviceList/InertialSensor/AngleY/Sensor/Value
Device/SubDeviceList/InertialSensor/AngleZ/Sensor/Value

私が自分で作ったロボットの場合は、地磁気センサーを使って取得したが、NAOは、加速度センサーと角速度センサーから計算しているようだ。

上記の図で、前後の傾きがオレンジである。少しゼロから外れているのは、最初から少し傾いていたということだ。後半に極端な負になっているのは、誤って後側にNAOを倒してしまったからである。Zは、垂直軸の回転で、これは前後左右の傾きのように、直感的なゼロ度が不明である。地磁気の北かと思ったが、そうでもないようだ。地磁気センサーはないのだろう。しかし、縦軸の回転のゼロ度は大きな問題ではない。初期の向きをゼロ度にしておけば良いからだ。

これから、キレキレの踊りをさせるプロジェクトを始めるが、絶対角度は何かに使えるし、使わなくてはならないだろう。