VOCの拡張 - 場の導入
昨日の記事でちらっと出てきた、VOCについて。1年半前にこんな記事を書いた。
VOC(Vision Oriented Communication)を初めて紹介した記事だが、それ以来VOCについてたまに考えていて、よりわかりやすい説明を思いついたことと、IoTへの応用を見据えた再定義を行いたいので、この記事をもってVOCの定義を改訂する。
メッセージは波であり、宛先は持たない
電話やメールと言ったテクノロジーの助けがないプリミティブな世界では、真に1対1のコミュニケーションは(接触以外に)あり得ない。
- 眼はおおまかに400nm~800nmの波長の電磁波を受信して検波する。電磁波は波であり、ある程度の指向性こそ持たせられても特定の宛先を持つものではない。
- 耳も音波について同様である。
- 口はAM+FM変調した音波を送信する。
- 身振りは可視光線を反射するパターンを変えることで、情報を光にエンコードする。
前にも言った喩えだと、信号が車のbrakeメソッドを呼ぶわけじゃなくて、ドライバーが信号を見てブレーキを踏むか否か判断する。
宛先を持ったメッセージが電話なら、宛先を持たないメッセージはアマチュア無線だ。
空間は場だ
波は場を伝わる。場は全ての地点になんらかの値を割り振られたグリッドと考える。場は、音場、電磁場等自然由来の場を使ってもいいし、シミュレーションでもいい。例えば文字列が値となる場があったって良いし、音場に方向を追加してベクトルにしたっていい。場をコミュニケーションの媒体として使う。シミュレートする方法は問わない。
受信 -> 計算 -> ブロードキャスト -> 再帰
1年半前の記事ではVOCのコンセプトと、その実装の一例を一つの記事にまとめてしまっていた。ここでは改めてコンセプトだけを説明する。
AI
VOCを実装するモノは、REPLの亜種REBLを実装する。REPLはRead Eval Print Loopで、通常Rは標準入力、Pは標準出力や標準エラーと、限定されたストリームに対する読み書きを指すが、VOCではReadとPrintを拡張し、多対多のコミュニケーションのため、それぞれReceiveとBroadcastとする。
Receive Eval Broadcast LoopでREBLだ。
Receive (受信)
自分が持つあらゆるセンサーそれぞれについて値を解析する。
シミュレーションの場合は自分の周りの場の値を読む。
Eval (評価)
受信した情報と、自分の状態から、自分の次の状態を計算する。
Broadcast (ブロードキャスト)
Evalされた自分の次の状態に応じて、影響を与える場を振動させる。「場を振動させる」っていってもそれほど難しく考えないこと。ようするに近くの誰にでも受け取れるメッセージを送り出すってことだ。本文に宛名は入ってもいいが、他のモノが見るのを妨げることはない。
Loop (再帰)
また受信待機に戻る。
アクターとの違い
VOCは実際Erlangのアクターによく似ている。違いはメールボックスの代わりに場を読み、メッセージを特定のプロセスに送る代わりに特定の場を振動させるという2点だ。
場のシミュレーションについて
実際のところ、場のシミュレーションは愚直にやると無駄が多いと思うので、実装方法は処理系に一任する。モノがある場所の値だけ計算すればいい。時間(光速度や音速)についてもシミュレートするのが理想だがなくて困らないならいらない。
Pseudo Code
改訂版VOCの実装はまだないので、ナイーブな疑似コード。
100℃の太陽と猫2匹の世界
;;気温がちょうど良いとニャーと鳴く(音場を揺らす)猫 (defn cat-with-no-mass [fields cat] (let [temp (read-field :temperature (:address @cat) fields)] (vibrate-field fields :sound (:address @cat) inverse-square (cond (> temp 30) "too hot meow!" (< temp 15) "too cold meow!" :else "warm and nice meow"))) ;;温度場を照らす太陽 (defn sun [fields sun] (vibrate-field fields :temperature (:address @sun) inverse-square (:intensity @sun))) ;;減衰曲線を使って場を計算する (defn vibrate-field [fields layer address decay val] ;; ...omitted... fields) ;;メインループ -- とりあえず相対論は無視して絶対時間 (defn run-space [things] (loop [fields] (recur (merge-fields (pmap #((:ai %) fields (:property %)) things)))) ;;初期設定 (run-space #{{:ai cat-with-no-mass :property (atom {:address [0 0 0]}) {:ai cat-with-no-mass :property (atom {:address [100 100 100]}) {:ai sun :property (atom {:address [10 10 10] :intensity 100})}}} #{:temperature [[[...]]] :sound [[[...]]]})
シミュレーションと、IoTデバイスのネットワーク両方に同じコードが使えるとアツい。
本当はアドレスと、グローバルな場をなくしたい。場のバケツリレー(相互作用するローカルな場)とか、いくつか案はある。
とりあえず以上です。