AI同士の対話が当面のターゲットなのだが、そのサーバー部分の作成とテストを実行した。相変わらず知識は「アトムはロボットです」しか持っていない。
まず、ネットワーク上で質問を受け取って、自らの持つ知識でそれに返答するというprologを示すと次のようになる。すでに示している reply.swi を組み込む。私は、ロボット同士のTCP-IPの通信システムは、基本、Telepathyという名前をつけている。
%%%% %% telepathy_server.swi %% prologサーバー %% 参照: %% http://www.swi-prolog.org/pldoc/man?section=stream-pools %% utf8string.swiを使用する %% 記事 http://www.ibot.co.jp/wpibot/?p=2681 %%%% :- ['reply.swi']. %% home brewでインストールしたswi-prologでは、次のライブラリが読めない可能性がある %% その場合は、ソースからコンパイルし直し、最新バージョンを入れる :- use_module(library(streampool)). server(Port) :- %% tcpソケットの作成 tcp_socket(Socket), %% ソケットをアドレスにつなげる 第二引数は、portのみか、HostPort tcp_bind(Socket, Port), %% ソケットからリクエストを受け取る、第二引数は、ペンディングリクエストの上限 tcp_listen(Socket, 5), %% ソケットとコミュニケーションのためのストリームを作成する tcp_open_socket(Socket, In, _Out), %% Inが利用可能になったら、accept(Socket)が呼び出される add_stream_to_pool(In, accept(Socket)), %% loopが空になるまでdispatch_stream_poolが呼び出される %% dispatch_stream_poolは入力があるとadd_stream_to_poolのGoalを呼び出す stream_pool_main_loop. accept(Socket) :- %% ソケットからのクライアントからのリクエストを待つ tcp_accept(Socket, Slave, Peer), tcp_open_socket(Slave, In, Out), add_stream_to_pool(In, client(In, Out, Peer)). client(In, Out, _Peer) :- %% 入力ストリームから次の行を読み出す 結果はCommandにユニファイされる %% 改行までか、ファイルの終わりまで読み込まれる 改行コードは削除される %% 改行を含むブロックを読み込むときは read_line_to_codes/3 を使う read_line_to_codes(In, Codes), %% 入力ストリームを閉じる close(In), %% バイトシーケンスを文字列に変換する utf8tring(Codes,Request), %% コンソール出力 format('Receive = > ~s ~n',[Request]), %% 回答を取得 wsreply(Request,Reply), %% 回答を送信 utf8tring(ReplyCodes,Reply), %% write(Out,ReplyCodes),nl(Out), %% write(Out,Reply),nl(Out), format(Out, '~s~n', [ReplyCodes]), format('Send = > ~s~n',[Reply]), flush_output(Out), %% 出力ストリームを閉じる close(Out), %%write('Close socket stream ...'), %% プールからストリームを削除する delete_stream_from_pool(In).
このサーバー、立ち上げるとターミナルをブロックして、他のプロセスを実行させる余地がない感じになるが、prologは、簡単に実行をスレッド化できるので、大きな問題ではない。
クライアントは、ここではjavaで書いた簡単なものを使う(次の段階でこちらもprologにする)。
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.Socket; /** * * @author washida */ public class JPClient { /** * @param args the command line arguments */ public static void main(String[] args) { try { String server = "localhost"; int port = 30000; Socket soc = new Socket(server, port); OutputStream os = soc.getOutputStream(); PrintWriter pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(os, "UTF-8"))); InputStream is = soc.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(is)); String question = "アトムとはなんですか"; System.out.println("質問: "+question); pw.print(question+"\r\n"); pw.flush(); String line; while((line = br.readLine()) != null){ System.out.println("回答: "+line); } pw.close(); os.close(); br.close(); is.close(); } catch (IOException e) { System.out.println("Exception: " + e); } } }
実行結果を示す。まず、javaクライアント側のコンソールは次のようになる。
質問: アトムとはなんですか 回答: アトムはロボットです
回答は、prologサーバーから送り返されてきたものである。
telepathy_server側のコンソールは次のようになる。
?- ['telepathy_server.swi']. true. ?- server(30000). Receive = > アトムとはなんですか Send = > アトムはロボットです
ということである。