2

パイプを使用して 2 つの Prolog プロセスを通信していますが、パイプからメッセージを読み取る述語に到達するたびにread/2、プログラムがブロックされ、そのままでした。なぜそうなったのか理解できませんでしたが (非常に単純なプログラムで試しました)、最終的に次の 3 つのことに気付きました。

  1. write/2を使用してメッセージを送信するたびに、送信者プロセスはそのメッセージを で終了する必要があります.\n。メッセージがこのように終わらない場合、受信プロセスはread/2述語でスタックします。
  2. 送信者が出力をフラッシュしない場合、メッセージはパイプ バッファに残されません。当たり前のように思えるかもしれませんが、最初はそうではありませんでした。
  3. メッセージがフラッシュされていない場合read/2はブロックされていますが、wait_for_input/3まったくブロックされていないためflush_output/1、そのような場合は必要ありません。

例:

これは動作しません:

example1 :-
    pipe(R,W),
    write(W,hello),
    read(R,S). % The program is blocked here.

それも機能しません:

example2 :-
    pipe(R,W),
    write(W,'hello.\n'), 
    read(R,S). % The program is blocked here.

これら2つが機能している間:

example3 :-
    pipe(R,W),
    write(W,'hello.\n'),
    flush_output(W),
    read(R,S).
example4 :-
    pipe(R,W),
    write(W,'hello.\n'),
    wait_for_input([W],L,infinite).

今私の質問はなぜですか?Prolog がパイプからの読み取り時にピリオドで終わる行全体を「受け入れる」だけである理由はありますか (実際には、読み取りたいストリームから読み取ります)。readそして、ブロックしないのにブロックするのはなぜwait_for_input/3ですか (メッセージがフラッシュされていないと仮定して)?

ありがとう!

4

1 に答える 1

2

有効な Prolog read-term は、常に と呼ばれるピリオドで終わりend char (* 6.4.8 *)ます。また、6.4.8 その他のトークンでは、標準は次のように読みます。

終了文字の後には、レイアウト文字または%.

したがって、これは標準が要求するものです。

ピリオドの後の改行は、スペース、タブ、その他のレイアウト文字、%. ただし、tty と関連するバッファリングが普及しているため、改行のみを使用するのが適切な規則のようです。

end char が必要な理由は、Prolog 構文が中置演算子と後置演算子を許可するためです。入力とみなす

f(1) + g(2).

読んf(1)でいると、これで用語全体が終わったと思うかもしれませんが、その後は中置記号や後置記号がないことを確認するために、その期間を待つ必要があります。

また、読み取り可能な出力を生成するにはwriteq/1、 orを使用する必要があることに注意してください。write_canonical/1を使用することはできませんwrite/1

例として、write([(.)+ .]).まず、これは有効な構文です。ドットの直後に別の文字が続きます。これ.は通常、末尾のピリオドと呼ばれますが、Prolog テキスト内ではドットと呼ばれます。

write/1と書きます[. + .].最初の文字の後にスペースが続くことに注意してください。したがって、このテキストが読み返されると、のみ[.が読み取られます。

このような醜い例は他にもたくさんありますが、通常、それらはあなたを襲うことはありません。でも一度叩かれたら叩かれる…

于 2013-04-03T17:17:16.467 に答える