call(ClassName, MethodName, Argumentsm Result)
アトム : abc atom(abc)
整数 : 1 integer(1)
文字列 : "alpha" string("alpha")
ファンクタ : f(a, 1) functor(f(atom(a), integer(1)))
図 1: wrapped-term形式によるデータの表現
まず、データ変換 で述べたような共通のデータ型をソケット通信でやりと りするために、データを文字列に変換する機構が必要である。今回 は、データ型の区別するために、識別子を頭部に付加した wrapped-term形式 (図1)によりデータを文字列に変換し、通信を 行うこととした。また、Java側では、これらの型を扱うためのData クラスを用意し、アトムなどのデータを扱えるようにした。
wrapped-term 形式で送られた文字列を、各言語によって変換・解析 し、これをKLIC側ではジェネリックオブジェクトの機構を利用しデー タを生成し、Javaではこれらのデータを扱うオブジェクトを生成す ることにより、言語間でデータをやり取りすることができる。
データストリーム で述べたデータストリームは、上記のデータ変換の機能を用い て実現される。データの送信順を保存するために、各言語で読み込 んだデータはバッファに保存して扱うようにしてある。また、Java 側で、データを受け取っていない場合に、データを要求した場合に は、データを受け取るまでその要求をしたスレッドをサスペンドす る、同期機構を実装した。
今回の実装では、KLICとJavaの双方で、データストリームを扱う機 構を用意した。KLIC側に jkstrea/2という述語を用意し、こ れにソケットストリームを渡すことにより、データをやり取りする ストリームを取得できる。このストリームに、
put(Term), get(Result)などのメッセージを指定することにより、データストリームを利用 できる。また、Java側では JK クラスのインスタンスをソケットを 指定して生成した後、このオブジェクトに対して、
void put(Data Term), Data get()というメソッドを呼び出すことによりデータを送受する。
手続き呼出し で述べた手続き呼出し型のメッセージインタフェースは、ゴー ル名やクラス名、メソッド名などを文字列で指定し、それらを用い て、KLICのジェネリックオブジェクトの機構やJavaのリフレクショ ン機能を用いてゴールのやメソッドの呼出しを行うようにする。も ちろん、この手続き呼出しの引数や戻り値は、先に述べたデータ変 換の機能を利用し、それぞれの言語のデータに変換され利用される。
KLICとJavaは、内部で並列動作が可能である。よって、同時に複数 の手続き呼出しが発生することが考えられる。その場合に、呼出し と戻り値を1対1に対応させるための識別子を付与することとした。 手続き呼出しをする際には、呼出しの内容とともにこの識子も渡し、 戻り値を返すときには、この識別子を使って対応する呼出しを特定 するようにした。これにより、データストリームや、他の手続き呼 出しなどを同時に利用することが可能となった。
今回作成したインターフェースはGUIの利用を念頭に設計している。 そのため、メッセージが頻繁にやりとりされると考え、データグラ ム型ソケットではなく、ストリーム型ソケットを利用した。そのた めに、手続き呼出しの際には、確認応答をする必要がないため、要 求/応答プロトコル[4]を採用した。
実際の利用方法であるが、KLIC側から手続き呼出しをする場合には、 先ほど述べたストリームに
call(ClassName, MethodName, Arguments, Result)というメッセージを送ることによ りメソッド呼出しが行われ、その実行結果が Resultに具体 化される。また、Java側から手続き呼出しをする際には、JKクラス のインスタンスに対して
Data call(String module_name, String goal_name, Data arguments[])というメソッドを呼び出すことにより、指定されたゴールが実行さ れ、その戻り値を利用することができる。