はじめに
なんの需要があるかわかりませんが,あるとき突然,Prologサーバを立てたくなる時があります.例えば,サーバ側では,大量の述語をデータベース代わりに持っていて,TCP通信でクエリを投げてその結果を得ることができたらな,と思うわけです.
データとして以下の述語を与えます.
tag_name(oppai).
tag_name(bikini).
picture(aaa).
picture(bbb).
picture(ccc).
tag(X, Y) :- tag_name(X), picture(Y).
tag(oppai, aaa).
tag(oppai, bbb).
tag(oppai, ccc).
tag(bikini, bbb).
tag(bikini, ccc).
tagの第一引数はタグの名前で,第二引数は画像の名前です.特定のタグの付けられた画像を検索する場合,以下の述語で推定することができます.
tag(bikini, X).
% X = tag(bikini, bbb);
% X = tag(bikini, ccc);
速度的に何千万件のデータを扱うのは難しいかもしれませんが,NoSQLの試みとして面白いなと思ったわけです.
サーバ側の実装
サーバ側で起動しておくPrologのソースコードです.
create_server(Port) :-
tcp_socket(Socket),
tcp_bind(Socket, Port),
tcp_listen(Socket, 5),
tcp_open_socket(Socket, AcceptFd, _),
dispatch(AcceptFd).
dispatch(AcceptFd) :-
tcp_accept(AcceptFd, Socket, _Peer),
thread_create(process_client(Socket, Peer), _,
[ detached(true)
]),
dispatch(AcceptFd).
process_client(Socket, Peer) :-
setup_call_cleanup(tcp_open_socket(Socket, In, Out),
handle_service(In, Out),
close_connection(In, Out)).
close_connection(In, Out) :-
close(In, [force(true)]),
close(Out, [force(true)]).
handle_service(In, Out) :-
read(In, Chars),
findall(Chars, Chars, L),
write(Out, L),
writeln(L).
% 以下,データベース用の述語を定義する
Prologのコンソールから,以下のコードを実行すると,ポート3333でListenします.
create_server(3333).
クライアント側の実装
クライアント側はTCP通信でポートを指定して接続します.ここではRubyですが,他の言語については頑張って実装してください.
require "socket"
while gets
s = TCPSocket.open("localhost", 3333)
s.write($_)
puts s.gets
s.close
end
このソースコードを実行すると,TCPソケットを開いてユーザからの入力を待ちます.Prologの述語を書くと,localhostで実行しているPrologサーバに述語を送信し,その内容を推定し,結果を返します.
tag(X,Y).
[tag(oppai,a),tag(oppai,b),tag(oppai,c),tag(bikini,b),tag(bikini,c)]
Prologの将来
Prologの推定は,他のRDBMSやNoSQLにはない機能です.似たような処理は確かに他でも書くことは可能ですが,Prologほど簡潔には書けません.例えば,SQLであれば以下の様なクエリになると思います.
select picture.name from picture, tag where tag.picture_id = picture.id;
Prologと比べるといかに冗長であるということがわかると思います.
また,先のデータベース用の述語では,tag_nameとpictureを定義していましたが,別にきちんとスキーマが決まっていれば,この2種類の述語は必要ありません.その点で,NoSQL並みの柔軟さがあり,(使い方さえわかれば)簡潔なクエリを投げることが出来ます.
あとはほぼ速度やアーキテクチャの問題なので,いつかPrologがNoSQLで脚光を浴びるんじゃないかなぁとか思うのですがどうでしょう? Prologプログラミング自体は悟りが必要なので難しいかもしれませんが,シンプルな方法であれば十分に使用に耐えられると思います.