Prologサーバー
これまで、サーバーはクライアントの質問に答えるだけでした。
これを質問に対してサーバーが質問し返す仕様に変更してみましょ
%クライアント側 w3prolog/2は既に定義済みとします
対話質問(Network,Port,_質問) :-
w3prolog(Network,Port,対話(_質問,_応答)),
call(_応答).
myhostname(client1).
%サーバー側 shs/2はshellの標準出力からリストを構成する述語
対話(_質問,_応答) :-
対話応答項(_質問,_応答),
call(_質問).
対話応答項(pwd(_),(myhostname(client1),system(cal))).
pwd(X) :- shs(pwd,X).
%運用例 クライアントがclient1であることを確かめてから、
calはクライアント側資源として実行されます
?- 対話質問(server1,54211,pwd(X)).
3月 2006
日 月 火 水 木 金 土
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
X = ['/usr/prolog'].
yes.
?- クライアント側にも応答質問項/2を定義すれば
会話を継続する仕様へ変更することも簡単です。
何が書かれているのかさっぱりわかりません。
解説つきでお願いします。 >>30 このスレは、
1・・自分のProlog実行環境の他にProlog共用データベースを立てる
2・・この共用データベースに対してPrologクライアントは自由に
質問し、解を得ることができる。
3・・この質問-回答におけるメッセージ交換をPrologの項で行う。
このようなネットワークを築くための基礎について議論するところです。
>>29は質問-回答系がすでに築けているとして、
質問に対して、回答を返すほかに、サーバー側から、更に質問をプッシュし
この質問のクライアント側での実行を約束事とすることにより、
クライアントの環境に応じて、回答の条件付けをする可能性を図るものです。
たとえば、
「あなたの環境がこれこれの場合は私の回答は有効だが、そうでない場合は
偽と見なしなさい。」というようなアサーションなどが考えられます。
内容の解説は順次述べます。
サーバー名と質問(メソッド?)の間が::で区切られて
いますが、なぜ普通に:ではだめなのですか。
>>32
現在のPrologの規格(たとえばISO規格)では、
A:BだとAモジュールのB述語の意味となり、ここでの
サーバーの意味とは異なります。
Aをクラスと考えても、モジュールと理解しても、ノードと
解釈しても、意味的には近いと思いますが、処理系に
モジュールと先に解釈されてしまうと仮にモジュール定義
がされていなくても、エラーになってしまうのが普通です。
それで、モジュールと衝突しないようにオペレータを::に
してあります。 この環境だと、エージェントを
送り込んだり(受け入れたり)、
それを自由に移動させたりできる
ように思いますが、
ライブラリやサンプルプログラムは
ありますか。
>>34
エージェントについては詳しくありません。
一つ言えることは、イントラネットのように
管理者が端末の起動状態を完全に把握している場合は
よいのですが、このネットワークのように
何時、各ノードが電源offになるか解らない環境では
駐在型のエージェントというのは難しいのでは
ないかということです。長期間にわたり
他のノードでサンプリングを続けるためには、
そのマシン内でバッチタスクとして動作しなくては
なりません。セキュリティの問題もあり、
このようなことが安定して行えるかどうか疑問です。 サーバーに対し、
?- (reconsult(Local::File),program(Goal)).
と言う質問をすることによって、
クライアントのファイルをサーバー側にreconsultして、
指定のGoalを実行するということはできます。
このスレを立てた理由のひとつとして、
このとき、reconsultされる述語が既にサーバーに
定義されている場合の処置について規定を定めたい、
ということがあります。
つまり、現在はこの点が決まっていません。
エージェントの動作としてはこのGoalから始まる
サンプリングの中で、local(クライアント)側のサーバーに
対して蒐集したデータをassertすることで、エージェントを
送り込んだクライアントとは非同期に動作することが
できます。
>>36Goalの実行終了をクライアント側が待ち続けることになってしまいませんか。 そうですね。
述語program/1 は一般にProlog処理系は起動後の
最初の案の実行を :- program. と規定しています。
この規定を模して作った述語です。
それで、本当はprogramにしたかったのですが、
本来の述語と衝突してしまうため、利用者が自由に
この起動述語を定義できるように,program/1を
設けました。program/1はクライアントと通信して
いるスレッドに対し、子スレッドとして動作する
ようになっていて、質問Goalはこの子スレッドの
実行とは切り離されて、子スレッド起動後すぐに
終了してしまいます。Goalのなかに束縛されていない
論理変数があっても、解決されないまま、
クライアントに解として返されます。
ちょっと説明を間違えました。
質問 ?- program(Goal). は親スレッドで実行され、
直ぐに終了します。
program(Goal) :- 並列実行(( true; Goal )).
のようなイメージでtrueだけ実行するのが親、
子でGoalが実行されます。 ネットワークについては全くの素人ですが、
このシステムでは現在どんなことが課題と
なっていますか。
>>39
さらに間違っていた。
親は子の終了を待つから、終了するのはソケット通信だけか。
エージェントが生息している間は、
親はひたすら、子の終了を待って、存在している。
ということですね。
program/1のコードを見直してみたら、
サーバから見るとここでいう親が既に子スレッドで、
直ぐにソケットに質問のまま返信してソケットを
shutdownしてしまっています。
Goalはサーバから見て子スレッドとして、
普通に負節として、実行されている。
ということでした。
program/1の特徴はソケットへ未解決の質問を
そのまま応答して、ソケット通信を終了して
いる点にあるようです。 >>40
・ 述語定義の管理の問題。
・ リアルタイムに参照できるグローバルなlistingシステム(述語辞書)。 他のノードにあるPrologの定義域に自分と共有するもの、
基底クラスというかコモンセンスといった方が良いか、
そんなものがあるかというと、これがほとんどない。
暗い霧のなかで未知の人に遭遇したとき、どうすうれば
よいかというようなレベルです。探りをいれていく。
すこしづつ質問していって、相手の世界の輪郭から掴んでいく。
これをPrologシステムにも適用したいのだが、きっかけからして
わからない。
「あなたは何に興味があるの」
こういう質問への答えを的確に準備したシステムに出会ったことが
ない。
自分が利用できる関数を他の定義域で探すということは
コンピュータサイエンスのどんなカテゴリーに入るのですか。 コンピュータサイエンスでですか。
プログラムパターンともちょっと違うし、
わかりません。 一番普通にはtmpファイルにlistingして
ダウンロードして解析ということになると
思いますが、ファイル転送はftpですか。 ftpdが起動されていることは必要条件ですね。
単なる負節起動の他に、Upload and Go も
基本動作としているので、ftpdを基本要件と
するのが最もコストがかからず、安定する
ようです。
私は自分のサイトとの通信では自前の
転送述語で済ませていますが。 >>47
それから、サーバー側でファイルに書かずに
質問として扱う、
?- node_1 :: 述語表示(hoge).
や
?- node_1 :: 述語表示(hoge,X).
も勿論あります。 >>45
情報(この場合述語定義)の類似性や変更の推移に関する記述というと、
フレームでカバーできますね。多層フレームなんて、面白そうです。
あるメソッドがあるオブジェクトに属しているというのは考えてみれば
面白くありませんから。
並列実行は可能ですか。
1) 複数サーバにたいするOR並列
2) Prologを拡張してのAND並列 >>51
2)はやっていません。KLIC上にこれと同じネットワークを
構築しようとしてみましたが、現在の所失敗しています。
1)はそういう述語はあります。ただ、遅くてあまり使い物には
なっていません。
各ノードで1秒かかる質問を用意して、4ノードに質問して、
全ての解を蒐集すると5秒くらい掛かってしまいますw
各サーバがログを取っていて、その書き込み量が膨大に
なるせいですが、解を蒐集するのに自分のノードのサーバに
assertしてもらう方式をとっているので、書き込まれているかな、
とポーリング方式で問い合わせが必要でこれにコストがかかって
しまっています。
1分くらいかかる作業を要求すれば1分15秒くらいで終了しますから、
これはりっぱなものですが、現実にはこういう計算って発生しませんね。
最初に解を返したノードのものを解とするケースでは結構有用です。
>>52
1分15秒というのは10ノードの並列時のことでした。
4ノードだと、1分4秒くらいですね。 Ajaxなどで非同期通信ということが喧伝されていますが、
このネットワークで非同期通信は可能ですか。 >>54
>>36 以下で述べているエージェントとサンプルの
送信がそれに当たります。エージェントの場合は
サーバ側で永続しますが、質問が解決したら終了する
モードだと非同期処理と見なせます。
Ajaxがメジャーな技術になるなら、これ経由で
質問できるようにすれば面白そうですね。
w3mは開発が終っているし、Javascriptも
組み込めないからだめですが、
オープンソースのこの手のブラウザ経由という
可能性はあります。 ところで話は変わりますが、10年くらい前に、
事務処理のデータエントリーのプログラムで、
サーバーが側から、エントリー側に画面をpushし、
入力を促して、非同期にこれを受け取るという
システムの構築に困難を感じた事があります。
現在は、
1) アプリケーションタスクはエントリー側のサーバーに
mozillaのremote処理を要請
2) エントリー側でブラウザに入力画面の表示
3) アブケーションタスクは自ノードサーバへの入力待ち合わせ
4) formにより、データ処理サーバ側にデータ送付
4) アプリケーションは自ノードサーバからデータ受け取り
で簡単に実現しています。 一般的RPCコールに比べて、Prologであることの
優位性は何でしょう。 >>58
Prologであること。としか言い様がないです。
・ 頑強なインタプリタ。
・ 簡素な構文。
・ 強力な構文解析力。
・ 強力なデータベース。
・ 強力な論理的記述力。
・ 構造変換など強力なメタプログラミング。
どれをとっても(MLの系統を除くと)比類ないものです。 プログラム言語は最終的には
MLとPrologの一騎打ちになるとお考えですか。 ICOTの成果でPrologで書かれたものが公開されて
ますよね。あれが、
?- prolog_aitec_lib :: hoge(_).
みたいな感じで簡単に利用できたらいいですね。
昨年限りで、AITECも完全に廃止となり、サイトも消滅。
私は、ほとんどダウンロードしてあるのですが、
アーカイブしとかなかったから、何がなんだかわからない。
ひとつふたつ余りREADMEを読まずに動いたものがあった。
ただし,4-5年前の記憶。 1980-2000年の間に上記のものや
単行本を含む文献上のPrologソースコード量は
膨大なのですが、実際に質問として使用できる
状態のものはほとんどありません。
著作権上の問題がありますが、これを可能な限り
生き返らせることに余生を捧げましょうw
>>60 >>61
本当に高水準言語一辺倒の時代なんて
くるんですかねー
K-Prologを使っているのですが、system述語を実行するとき
ストリームを切り替えてPrologの引数に単一化したいのですが
なにか方法はありませんか。 >>66
C言語インターフェイスを使って、
system/2を作る。他ない?
シェルコマンドの出力をあるファイルに
リダイレクトして、制御が返ってきたら、
plc側でopen()する。この場合、ファイル名
が固定されるから、2システム以上の並列だと
具合が悪い。
C言語インターフェイスでtmpnam/1作って
おいた方がよい。
やはり、popenは組み込み述語として欲しいね。
OSに依存する余地から、避けたいというのは
わかるけれど。 他のノードでsystemなどは実行できるのですか。
>>70
できます。できますが、そのノード(サーバー)の設計によります。
セキュリティを重視して拒否することはできます。
一般には
?- node1 :: shs(free,X).
X = [' total used free shared buffers cach
,'Mem: 512588 492600 19988 0 26800 230236',
+ buffers/cache: 235564 277024','Swap: 1044216 92760 95
6'].
のように使います。
?- node1 :: !pwd.
/usr/local/prolog
yes
?-
この場合はnode1でバッファーに書き出された/usr/local/prolog
がクライアント側画面にで表示されています。
上流は省略します。
応答のソケットはHeaderの後、
2行改行の後、変数解決済みの質問がきます。
?- findall(append([a,b],[c,d],X),
append([a,b],[c,d],X),
[append([a,b],[c,d],[a,b,c,d])]).
この後にサーバ側の>>71に書いたバッファーの内容が続きます。
それだけです。 >>71 の後の例ですと
?- findall(!pwd,!pwd,[!pwd]).
/usr1/local/prolog
がソケットの中身です。
ここでは>>29のサーバ側からのpush(対話応答)は
行っていません。 クライアント -> サーバも
最初に2行連続して改行された後の文を
質問と見なしてparseします。
2行改行されるまではHeaderであり、
何が書かれていてもよいというルールです。 文字コードのエンコーディングやReferURL情報等
一切なしですか・・・。
いや、Headerを解析してhttpプロトコルのHeaderだったら、
当然取得しておく。
何を以てプロトコルを認識するかは決めていない。 以前ム板で、PrologのユーザやベンダはPrologは
libraryをあまり作りたがらない、実際その時に
書けばよいから、作る必要がない。
と書いたら、「正規表現は作れますか」ときた。
Prologで正規表現なんて使わないよ。なんで
そんなの覚えなくちゃならないの?って答える
べきところをオタフタして答え損なったw。
正規表現は一種の言語だから論外としても、
辞書引き問題はこういうネットワークでは
結構深刻ですね。辞書、ここでは他ノードに
たいするlistingですが、これを引くコストは
ばかにならない。自分で書いた方がとどうしても
思ってしまう。
Prologの場合要約っていうのができないからね。
コード自体が要約だw >>79
つまりperlとかの方が開発効率が良いと言うことですね。
>>81
一般論としてですが、ライブラリが揃っていて、
その使い方を熟知している場合、開発効率は
高くなりますね。
ここでの文脈で言うと、知識(たとえば正規表現の
記法)を得るためのコストとプログラム作成時の
速度差の累計で評価しなくてはならないでしょう。
Javaのように言語を熟知していても、クラス名や
メソッド名が妙に長くて、効率が上がらないケースも
ありますが。Eclipseとかを駆使しない場合ですが。
Prologのような言語はライブラリ知識獲得のコストは
ゼロだということになります。常にその場でリスト処理で
済ませますから。 Prologで使う述語といえば
member,repeat,forの他には、
副文字列を切り出す part_atom
文字列(atom)をリストに変換する
atom_chars,atom_codes
それから複数のatomを結合する concat_atom
くらいのものです。
これだけで、他のインタプリタと同等の
速度で対話実行ができるわけですから、
少なくとも初心者向きなのはこちら
ということになります。 先輩
true,fail,not,open,close,read,get_char,get_code,
consult,reconsult,assert,retract,abolish
が抜けてますよw
まあ、これで全部か。
ハハハ
まだあるぞ。write,put_code,put_char
fuctor,argも使うね。
30個くらいにはすぐなっちゃう。
結構、知識がいるね。
この際、思惑抜きに使う述語をあげてみよう。
上記の他に、
integer,float,number,atom,atomic,var,compound,の型判定述語
is,=も述語だ。
predicate_typeなんかも使うことがある。
それから述語ではないが関数も覚えなくちゃ。
まあ、こんなものだが、7-8割が
member,fail,true,atom_part,concat_atomで済むか。 もしかすると一番重要な述語 system が抜けていた。
ファイルから情報を読み取るか、Prologプログラムとして、
あらかじめconsultしておくか、流儀はいろいろあるが、
基本的な組み込み述語の使用頻度はどんなプログラマでも
大差ないのがPrologの特徴かな。 結局、Prologも使いこなすにはそれなりの知識がいる、と。
達人を集めて競わせるとどの言語も生産性に差はでない。
でも、PerlとPrologくらい目指す方向が異なると、
初心者、初級者、中級者、上級者とそれぞれの段階で
生産性に差が出てくるような気がする。実証というのは
難しいだろうが、面白いテーマなのでちょっと研究してみる。 初心者: 試合開始1秒 面が決まりPrologの勝ち。
3時間で全ての機能を覚えられるからね。 いや、PerlだってCGI絡みにしなければそのくらいで説明できないか。 無限に拡がる軟体動物みたいなやつです。
無理ですね。 ム板なんかにプログラムの基本っていうことをいう人がいる。
私はプログラミングに基本なんてないと思うが、この人達の
いう基本以外、Prologのプログラミングでは使わない。
一方、Perlの方は、ぜんぶ応用という感じで、基本部分の抽出
なんてばかばかしくなる。そういう意味で大変魅力ある言語
だと思う。 つまり、Perlの場合全部「逆引き」で攻めていくって感じ? わかったから、sage進行にしてくれない。なにか恥ずかしい。 ところで >>93
>この人達のいう基本以外、Prologのプログラミング使わない。
なんか、日本語がヘンなようで。
この人達のいう基本しか、Prologのプログラミングでは使わない。
じゃないか。 考えてみると、Perlのような言語がPrologより
生産性が高い?という議論にマジで応対している
のだから、驚くべき事だ。20年前にはPrologの
生産性は群を抜いていた。Lispの倍くらいの
速度で仕上がっている感覚だった。
私はRubyくらいしか使わないが、これもしかすると
Prologといい勝負いけるんじゃないかと思うことが
ある。
ここ二十年のプログラム言語のの記法レベルの洗練は
相当なものだ。 APLなどがそうだったと思うが、
素人が見ると何が書いてあるかさっぱりわからない。
達人から見るとこんな易しいものはない。
こういう言語は滅びる。Perlなどもちょっとこういう
臭いがする。 略記法に?というものは多いが、
基本的には、
Perlはただ書けばよいだけで、
素直なものだと思うが。 .NETではPrologは完全に無視されているようですが
その辺りの情報は何かありませんか。 マイクロソフトがPrologを避けている理由や
経緯については全く知りません。内部資料と
してはその理由が記述されたものがありの
だろうから、社員が書き込んでくれると
ありがたいのですが。 バッチ処理、Prologの負節実行をある時刻に
起動するような場合がありますね。他の
コンピュータのPrologの場合どんな手順に
なるのしょうか。 私はLinuxなのでatコマンドで説明します。
第一にどこでatコマンドを切るかの選択があります。
自ノードでも可能ですし、リモートノードにatコマンド
を起動することも可能なわけです。
それから、ここでいう、Prologサーバーで負節を実行
するのか、それとも別にPrologを起動して実行するのかの
選択もあり得ます。どれも、可能で組み合わせは多岐に
渡りますが、私の方法を述べます。コードを書いてしまいましょう。
% *** user: '予約' / 3 ***
'予約'(_時,_分,Network :: _副目標) :-
'整数から文字列'(2,_時,_時文字列),
'整数から文字列'(2,_分,_分文字列),
'cgi述語表現'(Network,80,_副目標,_CGI述語表現),
tmpnam(F),
open(F,write,FO),
wr(FO,'w3c %t\n',[_CGI述語表現]),
close,
concat(['chmod 777 ',F],S),
system(S),
concat_atom(['echo "',F,'" | at ',_時文字列,_分文字列],S2),
system(S2),
! .
要するに自ノードでatコマンドを実行しています。ポート番号はここでは80。
w3cのURLにform情報を付加して質問をしっぱなしの仕様です。 concat(['chmod 777 ',F],S),
は
concat_atom(['chmod 777 ',F],S),
の間違いです。 cgi述語表現(Network,PORTNO,_述語,_CGI述語表現) :-
url述語表現(_述語,_URL述語表現),
concat_atom(['http://',Network,:,PORTNO,prolog_file,'?query=%3F-+',_URL述
語表現],_CGI述語表現),
! .
url述語表現は例の漢字コードの変換です。 この場合はそうです。
基本的にサーバーが要求するポート番号は自由です。
80を指定しているサーバーだと、多分httpを期待してる
のだろうと考えてhttpのheaderを付加して送りますね。 遅いですw
でも、セッション数などは変わらないわけですし、
若干Headerの情報が多いという程度ですから、実際は
どんなプロトコルでも似たようなものですね。
インターネット経由の場合は。 クライアント側でmozillaのようなブラウザを介して、
ハンドリングすると極端に遅くなりますね。
コマンドの解読はたいしたコストではないと思いますが
やはりバッファーかなんかを確保するので時間がかかる
のでしょうか。w3cなんかそんなことしてないと思うの
ですが、やはり少しかかりますね。 socket関係が組込述語になっている処理系というと
どんなものがありますか。
私はIF/Prologを使っていて、最初からsocketは組み込みでした。
それで、直ぐにWebプログラムが書けました。現在でも、
メーラーなどに不満な点があると、Prologで書き直してしまいます。
K-Prolog、SWI-Prolog、Visial-prologについて、ちょっと確かめて
からお答えします。
IF/Prologの組み込み述語は、
socket/3,current_socket/3,select/3,socket_accept/3,
socket_bind/2,socket_connect/2,socket_listen/1/2,socket_close/1,
socket_receive/2/3,socket_raw_receive/4/5,
socket_send/2/3,socket_shutdown/1/2,alarm/1
です。 前にIF/Prologの販売は2004年で停止となったと
書きましたが、どうもヨーロッパでは販売されて
いるようです。日本のIF/PrologのB氏がそんな
ことをいっていました。
直接ヨーロッパ向けのWebサイトで購入できそうです。
ただ、個人で買うには高いですね。人に勧めるのを
躊躇する価格帯です。 最近IF/Prologのサイトを見たが、日本SGIのマシン上では
販売を続けるらしい。日本SGIのUNIXマシンにインストール
してということなので、日本SGIの将来が不透明でこの話も
どうなるかわからない。 GNUにPrologぐらいあるんだが。
http://pauillac.inria.fr/~diaz/gnu-prolog/
気に入らないなら、codeをcontributeしまくって、自分好み
に誘導するのがbestだよ。
...日本のprolog屋がC/C++なんて書けるはずもないか。
無意味な論文積み上げて、博士や大学教員になる事しか考えて
ないからな。
>>118 書き込みありがとうございます。
私は研究者ではありませんが、C/C++はほとんど使わないので、
gやSWIの拡張は日本語処理の部分以外試みたことがありません。
これまで使ってきたものを取り上げることが多くなります。
SWI-Prologの利用の方が優勢だと思いますが、gprologも大学での
利用は多いはずです。これこれの処理をするには、
どんな組込述語を用意すると便利かの一覧を用意するといいのでしょうね。 >120
てめー、腐れProlog屋と一緒にすると頃すぞ。
>>121
「上の」じゃなくて「上の方の」だろ。
>>22〜64あたり、
やたら丁寧な記者みたいな質問と
やたら早い反応の返答。
どう考えても不自然だ。 >>120 >>122
完全な自演ではありませんが、うちの社員との Q & A です。
質問者もかなりわかった人間です。 要するに、
Prologを利用するときは同時に
共用Prologデータベースも立ち上げるべきだ、
という主張をしているスレなのです。 実用上、特に重要と
思われる組込述語を列挙すると(IF/Prologによる)
predicate_type/2
current_predicate/1
parse_atom/6
functor/3 (=..)/2
arg/3
op/3
current_op/3
clause_with_names/3
read_with_names/2 ほか入出力
system/2
findall/3
member/2
open/3
close/1
atom_chars/2
atom_code/2
unify述語( =/2 , ==/2 など )
型判定述語 socket関係述語
(= や unify関係は除外したけれど)
最も重要なのは parse_atom/6 と findall/3 かな
PrologをServer+Clientで立ち上げるという趣旨には大賛成。
ただ、通信部分はPrologの項を生で送るのはどんなものか。
SOAPに変換したらどうだろう。 Linux上にIF/Prologで構築されているようですが、
WindowsでP#でもうまくいくでしょうか? およそ一年ぶりの書き込みになります。ageていただかなかったら
永久に気が付かなかったかも知れません
>>127
P# ! 知りません。3年くらい前にちらっとそんな話題が
あったような記憶があるのですが、マイクロソフトと関係が
あるのですか。 >>126
XMLでのデータ授受は有力ではないでしょうか。
私はSOAPの詳細を知らないので気の利いたコメントは
できませんが、Prolog以外の言語に対してサーバーの
立場を取るとなると、クライアントの処理言語に対して
Prologの解析系を持てというのは現実的でないでしょう。
Prolog-XML変換はどこにでもあるのだから、Prolog側で
XML変換してあげればよい。
実際私は、XBRL(XMLベースのビジネス用通信形式テンプレート)と
Prolog項の変換の仕事をしたばかりです。 1980年代のProlog資料をまとめてあるサイトないかな。 最近、Erlang との連携を始めました。TCP/IP経由で
Erlangをさらにサーバに見立てて、並列(平行)処理を
委託します。ただ今のところEUC-JPの漢字処理が
うまくいかず、Erlang側のプログラムはあまり凝った
ものが作れません。漢字処理が問題がある場合、
ソースに遡れば大概は上手くいくことが多いのですが、
Erlangはconfigure->make->make install で8時間くらい
かかる代物で、とても私が手を出せるものではありません。 ただ今のところ -> ただ、今のところ
漢字処理が問題がある場合、 -> 漢字処理に問題がある場合、 何故にErlangが出てきたかという話をしておきます。
これはスケジューリング問題と関係があります。
Prologはスケジューリング問題の解決に最適な言語ですが、
これは「勤務表」のようなあまり、時間的な要求の厳しくない
領域を対象とした場合です。
ライン制御のような部分でのスケジューリングとなると
コードとしては洗練されたものになりますが、やはり、
GCによる遅延の問題がある。ラインの流れに追いつけなく
なる可能性があります。これを回避する方法はやはり、
その遅延が致命傷になる部分だけは切り離して、Prolog外で
処理するほかない。
そこで、Prologからのコード変換が容易で、小プロセスを
生成できて、並列による非同期処理が書きやすいErlangが
でてくる。
今のところは、Prolog/Erlang変換の研究の域をでませんが
相当に有望なのではないかと思います。 INAP'96で日本では初めてのErlangチュートリアルが
あったのですが、当時10年の歴史がある言語なのに、
ほとんど知ってる人いなかったですね。最近の流行は
隔世の感ありです。 Wijaという環境上に構築されるオーバーレイGHCというものが
あります。例の未踏ソフトの一つなのですが、PrologとGHCの
違いはありますが、やりたいことはたいへん似ているようです。
残念ながらうまく起動できなくて、今のところ私のサーバーと
混在できていません。今週はこれがテーマ。 >>135
Wijaの方は進んで以内が、昨日、erlangサーバがevalしていなかったのを
ム板のErlangのスレのレスでのやりとりで、方法が分かったので書き換えて完成。
幸せ。
これまでは関数の機能番号と引数を一行づつ渡していた。functorで分解した
ような状態で。
Erlangサーバについてですが、
Prologサーバからさらに
Erlangサーバに要求をだすということですよね。
Erlangプログラムのuploadはどうやるの?
>>137
Prologクライアントから直接呼ぶこともできます。
Prolog -> Erlang のバイナリーファイル転送は作ってないので、
そこは FTP か Samba のお世話になる。
upload_and_eval(ErlangServer,ErlangModule,Eval_Function) :-
cp(ErlangModule.erl,ErlangServer::ErlangModule.erl),
ErlangServer :: (c:c(ErlangModule) -> _),
ErlangServer :: (ErlangModule:Eval_Function -> X).
ディレクトリはそれぞれホームディレクトリだとして。
すみません。
upload_and_eval(ErlangServer,ErlangModule,Eval_Function,X) :-
でした。 書き直します。
upload_and_eval(ErlangServer,ErlangModule,Eval_Function,X) :-
cp(ErlangModule.erl,ErlangServer::ErlangModule.erl),
ErlangServer :: (c:c(ErlangModule) -> {ok,ErlangModule}),
ErlangServer :: (ErlangModule:Eval_Function -> X). upload_and_eval(ErlangServer,ErlangModule:Eval_Function -> X) :-
cp(ErlangModule.erl,ErlangServer::ErlangModule.erl),
ErlangServer :: (c:c(ErlangModule) -> {ok,ErlangModule}),
ErlangServer :: (ErlangModule:Eval_Function -> X).
の方が分かり易いか。 >>141
コピー元は自分だからPrologサーバで
cp(ErlangModule.erl,ErlangServer::ErlangModule.erl),
を実行すると、Prologサーバのワーキングディレクトリから
ErlangModule.erlファイルをコピーしようとするはず。
これは具合が悪いから、cpはこの述語から切り離す他ないの
ではないか。
>>142
uload_and_eval(Myhostname,ErlangServer,ErlangModule:Eval_Function -> X) :-
cp(Myhostname::ErlangModule.erl,ErlangServer::ErlangModule.erl),
ErlangServer :: (c:c(ErlangModule) -> {ok,ErlangModule}),
ErlangServer :: (ErlangModule:Eval_Function -> X).
一引数増やしました。 Wijaの オーバレイ GHC 使ってみましたが、私のPrologサーバとはまったく違うものでした。
詳しい報告はあとで。 upload_and_eval は長いから u_eval とする。
クライアントノードが c1
Prologサーバが p1
Erlangサーバが e1 として、c1がp1にe1へのu_eval()を委託する場合.
モジュールはmy 関数はappend/2とする。
?- p1::u_eval(c1,e1,(X は my:append([a,b],[c]))).
X = [a,b,c]
yes
p1を経由せず直接質問するなら
?- u_eval(c1,e1,(X は my:append([a,b],[c]))).
X = [a,b,c]
yes
となる。大分すっきりした。 ErlangサーバにDownloadさせる仕様にできないか?
Erlangサーバの関数を d_eval() が モジュール erlang_server にあるとする。
?- X は e1::erlang_server:d_eval(c1,my:append([a,b],[c])).
これで良さそうだが、Erlang側でd_eval() を解析評価する時に、
append/2が先に評価されてしまって多分うまくいかない。 コンパイルするべきモジュールを引数に分離して、しかも評価される関数を
文字列として渡してe_evalの中でさらに評価させる。
?- X は e1::erlang_server:d_eval(c1,my,"my:append([a,b],[c])").
すっきりしない。 二回に分離して質問するところを、強引に一回に納めた感じだ。 crontabなんかで質問を予約する場合もサーバにリクエストするんだよね。
どんなコマンドになるの?
>>150
>>104 - >>108 当たりにcrontabではありませんが、atコマンドでの
話が出ています。 サーバがポート番号1212で立ち上がって入れば、
:- tell(foo),listing,told.
を定時に実行させたければ、
w3c http://localhost:1212/prolog.file?query=%3F-+tell%28foo%29+%2C+%28listin
g%29+%2C+told
という一行だけのバッチファイルを作ってこれをcrontab -e で登録すればいい。
予約は自分のマシンだが、実行は他のマシンと言う場合は、localhostが
実行マシンのドメイン名に置き換わるだけ。 Prologインタプリタの質問で予約する。
毎日自分のマシンで12時に上記のlistingを行うには、
?- 予約(毎日,12,0,(tell(foo),listing,told)).
yes
yahooというドメイン上のサーバでlistingを行うには、
?- 予約(毎日,12,0,yahoo :: (tell(foo),listing,told)).
yes
予約自体をyahoo上のサーバにするには、
?- yahoo :: 予約(毎日,12,0,(tell(foo),listing,told)).
yes
>>153 の場合はポート番号は明記されていないからDefault値が
使われる。ポート番号がDefault値以外の場合は、サーバを
(_ドメイン:_ポート番号) :: で表現する。 長い間関数評価述語として"is"の代わりに"は"を使ってきました。
しかし、Erlangサーバが充実してきたため、表記法を改めて、
今後は"<-"に統一しようと思います。
?- X <- append([1],[a,b]).
X = [1,a,b];
no
ですね。 失礼。適切でなかった。統一してというのではなく、
Erlangの変数へのunifyが "->" なので
これはPrologの評価述語であるということを明確にするため、
"<-"を採用しました。 そもそもPrologに P->Q1;Q2 なんていう構文があるのが間違ってる。 四人一首問題のつづきです。
そもそも、サーバーから一音、一音、取り手に送り出すのはどうすればよいか?
取り手が突っつけば簡単だがそれでは本当らしくない。
サーバーが送り出す。相手は、取り手付属のサーバー。
この取り手付属のサーバーと取り手はこの歌の一音情報を
共有する必要がある。 Erlangを関数呼び出しする場合、
関数評価述語として「は」を使っているようだが、
単純に中置演算子 erlang とした方がいいんじゃないかな。
>>159
_値 erlang _erlang関数 ですか。
...,
A は _式1,
B は _式2,
C は _式3, ... ,
で、ある時 _式2 を _erlangサーバ::_モジュール:_eralang関数,
として評価する。こういう想定がありうるとするとやはり「は」に
統一されている方が好ましいように思います。erlangであるかどうかは
_erlangサーバの定義に係かってくることになります。
サーバ 一単位あたりのプログラムサイズはどのくらいになるの? >>161
最小だと4MBくらいかな。
最初にスタックサイズを指定して起動するので、
そのデフォルト値をどう書き換えるかという問題に
なります。 swi-prologを商用利用すると
どれぐらいお金いるんだろう? Non-free (open or proprietary) software can be produced using SWI-Prolog, although contributed pure GPL components cannot be used.
作成したものを公開すればOKってことなのか? この翻訳から離れて、私が勝手に理解して
いるつもりになっているものは、
利用者からソースコードの開示を求められた
時には公開しなくてはならない。というこの一点。
以前は商用でソースの開示は考え難いことだったが、
現在ではごく当たり前のこと。商用であっても、
GPL、LGPL規約に「違反しない限り」課金されることはない。
SWI-Prologもこの範囲内にあるソフトだと思う。 ?- prologサーバ :: 生きている.
yes.
?- ?- prologサーバ :: 何してる(_何してる).
_何してる = 暇してる.
yes
?- Erlang が異様に流行りだしました。もう一度、PrologからErlangを呼び出す
インターフェイスの話をまとめてください。
ム板でスレたて荒らしが現れた所為で、最近たてられたスレが全部DAT落ち処分されている。
ここのように平和なスレでも書き込むことはもちろん、時々はageておいた方がいいかも。 Javascript上にPrologを建てて、
Prolog(Javascript) <-> Prolog <-> Prolog(Javascript)
という制御の勉強を復活させようと思います。
以前作っていたものは、ノートパソコンのディスククラッシュとともに
ほとんどが消え去ったので、もう一度作り直さなくてはならないから、
少し時間をください。 永くIF/Prologを使ってきたこのサーバーもSWI-Prologへの引越しが近くなってきた。 えっちぃ絵をリクエストすると誰かが描いてくれるかもしれない素敵なスレ【R-18】
http://hayabusa.o p e n 2ch.net/test/read.cgi/news4vip/1423739321/ >>152
最近のLinuxなんかだと、w3cが動かないものがあるようだ。
# w3m -debug http://localhost:1212/・・・
でよいのかな。 SWI-PrologのPrologサーバのトップ
サーバ(_ポート) :-
tcpソケットの準備(_ソケット,_ポート),
接続されたらソケットを開く(_ソケット, AcceptFd, _),
tcpインタプリタ(AcceptFd).
tcpソケットの準備(_ソケット,_ポート) :-
tcp_socket(_ソケット),
tcp_bind(_ソケット, _ポート),
tcp_listen(_ソケット, 5).
接続されたらソケットを開く(AcceptFd,_ソケット,_Peer,In,Out) :-
tcp_accept(AcceptFd, _ソケット, _Peer),
tcp_open_socket(_ソケット, In, Out).
tcpインタプリタ(AcceptFd) :-
repeat,
行を読みだして実行(AcceptFd),
fail. >>178 冒頭に以下の行が入るのだった。
:- use_module(library(socket)).
サーバ(_ポート) :-
・・・ % 以下つづく。本当は親タスクにassertできたりするがここでは省略。
tcpインタプリタ(AcceptFd) :-
repeat,
行を読みだして実行(AcceptFd),
fail.
行を読みだして実行(AcceptFd) :-
接続されたらソケットを開く(AcceptFd,_ソケット,_Peer,In,Out),
一行読み出し項に変換(In,_項),
インタプリタの実行(_ソケット,In,Out,_項).
インタプリタの実行(_ソケット,In,Out,_項) :-
thread_create(項を実行して結果を返す(In, Out, _項),_,[]).
項を実行して結果を返す(In, Out, _項) :-
( catch(_項,_エラー情報,エラー情報の送信(Out,_エラー情報));
_項=false),!,
情報を送信する(Out,_項),
ストリームを閉じる(In,Out). 一行読み出し項に変換(In,_項,_エラー情報) :-
行入力(In,_行),
行を解析して項を得る(_行,_項,_エラー情報).
行を解析して項を得る(_行,_項,_エラー情報) :-
catch(read_term_from_atom(_行,_項,[]),_エラー情報,_項 = false).
行入力(In,_行) :-
read_line_to_codes(In,Codes),
atom_codes(_行,Codes).
エラー情報の送信(Out,_エラー情報) :-
format('~w\n',[_エラー情報]),
format(Out,'~w\n',[_エラー情報]).
情報を送信する(Out,_項) :-
項を文字列に変換する(_項,_文字列),
書き出す(Out,_文字列).
書き出す(Out,_文字列) :-
format(Out,'~w\n',[_文字列]),
flush_output(Out).
項を文字列に変換する(_項,_文字列) :-
swritef(String,'%t',[_項]),
string_to_atom(String,_文字列).
ストリームを閉じる(In,Out) :-
close(In),
close(Out).
送信項と受信項の単一化(_項,_項).
エラー発生時はfail扱い :-
fail. >>178
ここの十数行がやはり大事で、ここさえ押さえれば、サーバプログラムは大丈夫。
同じく省略しているが 行を読みだして実行/1 の冒頭で GET/POST行の解析等が
来るから、ここからの分岐は実際はもう少し重くなる。Prolog項が取れてからは
単純だが、副作用として出力をどのように処理するか、クライアントとどこまで
協調するかなど、実際の設計は難しい。 「副作用としての出力をどのように処理するか」
だな。 クライアントから述語呼び出しを findall(_述語,_述語,L) に一皮被せて
対話(findall(_述語,_述語,L),Q) とするという方法もある。
サーバーはLに述語の解リストを返すが、それと共にQにクライアントが
次に取るべき行動を指示する。例えば
Q に see_other('http://xxx.org/tmp/fileaaa.html') が入ってきたりする。
このQをクライアントが受け取り、call(Q) することでサーバーが用意した
htmlファイルをクライアント側のブラウザに表示できる。 これでクライアントがProlog処理系である場合はうまく行く。それでは、
クライアントがChromeのようなブラウザであり、actionでサーバアドレスや
ポートを指定し、inputやselectタグで述語引数情報を送ってくる場合は
どうか。
対話の相手がブラウザてあると、対話/2もfindall/3も理解してくれない。
この場合はhtmlファイルを直接、Socketのストリームに出力する必要が
あるだろう。もしそうだとしたら、それではクライアントがProlog処理系
であるか、ブラウザであるかはどの見分ければよいのだうか。 最後の行を訂正する。「ブラウザであるかをどのように見分ければ良いのだろうか」
有力な方法としてinputとタグとしてname=定義域 value= に固有のブラウザ名~
入れておくという方法がある。サーバは定義域としてget/post情報の中の
定義域キーの情報を調べて、この中に登録済みのブラウザ名を値として発見
した場合はクライアントはブラウザとして振る舞う。これが一番簡単な解決法
であろう。 この話よくわからないのですが、
Prologクライアントからの質問には、質問の項を解決したものを返す。
ブラウザからの質問には、たとえば Moved Temporarily ステータスで
再度参照するべきファイル名を返す。というようなことですか。 >>187
基本的にはそういう話です。
ブラウザへの応答は必ずしも別ファイルに書いてから
Moved Temporarily や See Other を返すのではなく、直接
ストリーム出力するのでもよいと思います。
ここ暫くは、最も悪影響が少なくブラウザであるか、
Prologクライアントであるかを判断させるサインの出し方の
話でした。 ☆ 日本の、改憲を行いましょう。現在、衆議員と参議院の
両院で、改憲議員が3分の2を超えております。
『憲法改正国民投票法』、でググってみてください。国会の発議は
すでに可能です。平和は勝ち取るものです。お願い致します。☆☆ 目下、Prologサーバーの大幅書き換え中。
EUCだったIF/Prolog版からMTF8のSWI-Prolog版への書き換え。 >>177 -debug ではなくて
# w3m -dump http:// ・・・
ですね。 >>191
SWI-Prologだと
?- www_open_url('http://・・・').
でも行くことができます。ただこの場合、多分デスクトップにWEBブラウザが表示されてしまいますね。'. Google ChromeからSWI-Prologで書かれたサーバーから情報取得後、
表示されたHTMLファイルを<<更新>>しないとサーバー側の接続が切れないと
いう現象が発生しているのだが、何がいけないのだろうか。Firefoxでは起こらない。 >>193
20年も昔には、こういうトラベルが発生するとプロキシサーバーを介してやってみたりした。そうするとなぜかうまくいったり。