[Glue!] Glue Logic プログラミング


エージェントから見た Glue Logic

Glue Logic が提供する主なサービスには、
  1. 分散エージェント間で共有するデータベースの参照サービスと、
  2. あるエージェントがあらかじめ登録しておいた名前の値が変化した時に、 変更通知メッセージを指定したエージェントに送るサービス
とがある。 Glue Logic の分散エージェントは主にこの変更通知メッセージに注目し、 ある名前の値が変化した時に何らかの行動を取るような形式でプログラミングを行なう。

Glue Logic から各エージェントに送られてきた変更通知メッセージは、 そのエージェントの「メッセージ・キュー」と呼ばれる待ち行列に入る。 変更通知メッセージを送るように登録しておく名前は複数個であっても構わないし、 状態の変化に対応するプログラムを起動する手続きが繁雑にならない様に、 変更通知メッセージには値が変った名前も含まれている。 それで、エージェントはメッセージ・キューの内容を順に取り出し、 そこに含まれる状態が変化した名前の情報を取り出しては それに対応する処理手続きを起動すれば良い。
もしもメッセージ・キューが空になった時があれば、 それは制御対象に状態の変化が無い時であり、 そのエージェントは新しい状態の変化が発生するまで休止状態に入ることができる。 この状態はプログラムが入力データを待っているのと全く同じ状態で、 エージェントは CPU 時間を一切消費する事は無く、 そのエージェントが対応しなければならない状態変化が発生して 変更通知メッセージが到着すると、 入力待ち状態から抜け出して処理手続きを実行しはじめる。

一方、 到着した変更通知メッセージに対応して起動された処理手続きは、 まず Glue Logic のデータベースから必要な情報を引き出し、 どのような状態に変化したのかを解析する。 そしてどのように振る舞う事が必要なのかを判断して、 要求された動作を行なう事になる。
このため、一般には Glue Logic のデータベースの内部に、 現在の制御対象のモデルと目標とする制御対象のモデルとの 二つのモデルを保持しておく事が望ましい。 この様にする事で、 各エージェントは目標状態と現在の状態とを比較して、 必要な制御動作を行なう事ができる。

この他にエージェントが処理できるイベントとして、 標準入力からの入力がある。 各エージェントは、 メッセージキューと同様な待ち行列として「標準入力キュー」を持ち、 このキューには標準入力から与えられた情報が収められる。
各エージェントはこれら二つのキューが共に空になった時に、 入力待ち状態で休止する事ができる。


エージェントの動作モデル

制御対象の状態や変量を観測するエージェントの場合

制御を行なおうとする場合には、 まず現在の状態を把握するために制御対象を観測する事が必要である。 特に制御用のエージェントは Glue Logic 内に収容された情報に基づいて制御を行なうので、 観測用のエージェントは制御対象が変化する速度に比べて充分高速に 最新の観測値を Glue Logic に伝達しなければならない。

現在の観測値が直前の観測値と同じか否かは測定してみなければ判らないため、 観測用のエージェントでは一定時間間隔でデータを収集する事が必要となる。 また、観測値が複数ある場合にはそれらの間での整合性を維持するため、 同時に観測を行ない、 それらを一回のトランザクションで Glue Logic に書き込む必要がある。

Glue Logic への書き込みは、 値の変化が無ければ変更通知メッセージは発生しないため、 いくら速い速度で行なっても問題は無い。 しかし、不必要なほどに高い精度のデータを扱おうとすると 有効数字以下の桁の違いで変更通知メッセージが頻発するようになるため、 充分な注意が必要になる。

制御対象の特定の状態や変量を制御するエージェントの場合

エージェントは自分が制御する状態に付いて、 目標状態と現在の状態とを Glue Logic から取り込み、 どのように状態を遷移するべきかを決定してその状態遷移が起こるように制御する。
この場合には、変更通知メッセージの要求も、 目標状態と現在の状態との両方に対して行なっておき、 目標状態が変更されたり現状が変化した時に対応できるようにする。

しかし、高速に状態が変化する対象を制御する場合には、 制御対象の観測を Glue Logic を通さずに直接行なわないと、 安定した制御ができない。 このような場合であっても、 適当な時間間隔で現在の状態を Glue Logic に書き込んだ方が 知的な制御が効率的に行ないやすい。

また、このエージェントの動作に依存する他のエージェントに 制御状態に関する情報を伝達するため、 現在の状態が目標状態に充分追随している事を示す状態変数や、 現在の状態が管理限界から外れてしまっている事を示す状態変数を用意すると 便利な事が多い。

与えられた動作指示を実現するエージェントの場合

エージェントに組み込まれた特定の処理を実行させたい場合は、 目標となる状態を指定するよりも 動作コマンド(実行させたい処理の意味や名称など)を指定する方が便利である。

この様な場合には、 Glue Logic 内部の特定の名前に動作コマンドをメッセージとして書き込んでもらい、 そのコマンドに基づいて制御を行なったり、 あるいは Glue Logic 内の目標状態変数を更新するとよい。
この時、 動作コマンドを与えたエージェントにそのコマンドが受理されたことを示すため、 何らかの方法で応答を返す事が必要となる。
このような目的を達するためには、一般には、 コマンドを受け付ける変数がクリアされた状態でなければ 新しいコマンドを与える事を禁止するような約束を、 エージェント間で守るようにする事が有効である。

たとえば、 エージェントが連続して与えられる複数の動作コマンドを並列に処理できる場合には、 動作コマンドを受け付けた後すぐにコマンドを受け付ける変数をクリアする事によって、 後続のコマンドを受け付けられるようにする。
一方、エージェントが同時には一つのコマンドしか実行できない場合には、 与えられたコマンドの実行の完了後にコマンドを受け付ける変数をクリアする事によって、 先行するコマンドの完了を示すと同時に、 後続のコマンドを受け付けられる事を示す事ができる。
これは Glue Logic における、資源の排他制御の実現の一例である。


エージェント間のインタフェース

Glue Logic は エージェント同士がメッセージをやり取りしながら動作する事を前提としている。 このため、 ソフトウェアのモジュール性を高め、 後からモジュールの追加・変更・削除を行なえるようにするためにも、 エージェント間のインタフェースをしっかり規定する事が肝要となる。

エージェント間のメッセージ通信は、 全て名前に対するメッセージの代入によって行なわれる。 このため、あるエージェントのサービスを他のエージェントから利用する時には、 目的とするエージェントのメッセージの「受付」となる名前を知っておかなければならない。
Glue Logic ではこの様な働きをする名前を "anchor name" あるいは「アンカー名」または単に「アンカー」と呼んでいる。 各エージェントは自分のアンカー名 (アンカー名が構造を持つデータである場合はその要素であっても良い)に対して 変更通知メッセージの要求登録を行なっておき、 この名前あるいはその名前の示す構造の要素をメッセージの受付とすれば良い。

この様な方法で、 ひとつのエージェントは他のエージェントからは単なる名前として考える事ができる。

Glue Logic におけるメッセージ交換モデル

Glue Logic はメッセージ交換を基礎としているが、 たとえばオブジェクト指向型言語に見られるような メッセージ交換に関する制限は一切無い。
すなわち、 Glue Logic においては、 エージェントがメッセージを受け取って処理を行なった後に そのメッセージの送信者に値を送り返す必要は無いし、 メッセージを送り返した後に処理を継続しても良い。 もちろん複数回に渡ってメッセージを送り返すこともできる。
このように、エージェント同士の情報交換は 互いのエージェント同士で了解が取れている必要があるが、 非常に柔軟性に富んだ実現が可能となっている。

メッセージ

メッセージはエージェントに対して何らかの振る舞いを期待する時に送られる。 このメッセージには、一般に、 期待する振る舞いの指定(メッセージ・セレクタ)と、 それに必要なデータ(メッセージ・アーギュメント)とが含まれる。
メッセージの送り手は、 それによって得られる効果のみを想定して、 それがどのような手段によって実現されるかについては、 意識しない方が良い。 その理由としては、 最初のシステム構築時には想像できなかったような手段によって 同じ効果がより容易に実現できるようになった時に、 最小の変更で新しい手段を利用できるようにするため、などが挙げられる。

Glue Logic では、アンカー名によって 期待する振る舞いを指定する事も可能である。 この様なメッセージ交換を行ないたい場合には、 アンカー名にはメッセージ・アーギュメントのみを書き込めば良い。

特に、エージェントが並列して実現する事のできる振る舞いがあれば、 それらを書き込むアンカー名を異なったものにしておけば、 容易にそのエージェントを実現する事ができる。

メッセージに対する振る舞いの実現

メッセージに対応する振る舞いは、 そのメッセージを受け付けたエージェントによって行なわれる。

上述のように、 並列に実現可能な振る舞いはできるだけ異なったエージェントによって実現した方が、 同時に実現できない振る舞いの排他制御を容易に行なう事ができる。
また、並列に実行可能であるが意味的に深い関連のある振る舞いについては、 同じ構造の中にアンカー名を配置するようにすれば その論理構造を明確化する事ができる。

また、同一のアンカー名に対して送られるメッセージの処理を 複数のエージェントで実現する事もできる。 この場合には、 アンカー名にメッセージが送られた時に 複数のエージェントがその内容を読み出してメッセージ・セレクタをテストし、 それらのエージェントのうちの一つだけが メッセージに対応する動作を行なうようにすれば良い。

しかし、 メッセージ・セレクタの数の増加に伴ってエージェント数が増加した時には、 結果的には不要なエージェントが動作する事によって CPU やネットワーク資源を無駄づかいする恐れがあるため、 Glue Logic 側で条件判断を行なった結果によって メッセージを送信することも可能である。


 [M.T. HomePage]  [written & copyrighted by Masayuki Takata]