SWI-Prologのcoroutining

SWI-Prologのマニュアルを読んでいたら、面白そうな述語を見つけました。

6.2 Coroutining
Coroutining deals with having Prolog goals scheduled for execution as soon as some conditions is fulfilled. In Prolog the most commonly used conditions is the instantiation (binding) of a variable. Scheduling a goal to execute immediately after a variable is bound can be used to avoid instantiation errors for some built-in predicates (e.g. arithmetic), do work lazy, prevent the binding of a variable to a particular value, etc. Using freeze/2 for example we can define a variable can only be assigned an even number:

?- freeze(X, X mod 2 =:= 0), X = 3
No

( http://gollem.science.uva.nl/SWI-Prolog/Manual/coroutining.html )


freezeは第一引数に未束縛の変数を指定し、
第二引数に『第一引数の変数が束縛されたときに実行されるゴール』を指定します。
上の例ではXが3に束縛された時点で X mod 2 =:= 0 が実行されます。
とりあえず、使ってみました。

?- [user].
test(Y):- write(1), freeze(X, (write(a),Y is X + 1,write(b))), write(2), X = 3, write(3).
?- test(Y).
12ab3
Y = 4;
no

実行順序はこんな感じ。
1) write(1) が実行 (画面に1が出力)
2) freeze(X, (write(a),Y is X + 1,write(b))) が実行 (引数は評価されない)
3) write(2) が実行 (画面に2が出力)
4) X = 3 が実行
5) Xが束縛されるのをきっかけにfreezeの第二引数が実行される
5a) write(a) が実行 (画面にaが出力)
5b) Y is X + 1 が実行
5c) write(b) が実行 (画面にbが出力)
6) write(3) が実行 (画面に3が出力)
私自身はコルーチンについてはあまり知らないんですが、
これはむしろ変数の束縛をトリガとした遅延評価みたいに感じました。
Schemeのdelayがfreezeに対応して、forceが変数の束縛に対応する感じです。
他にもfrozenという述語があり、これは指定された変数をトリガとしている
freezeオブジェクト(?)を取得できます。

?- freeze(X, write(a)), frozen(X, Y).
X = _G397{freeze = user:write(a)},
Y = user:write(a) ;
No

使い道は現在はいまいち分かってません。
他にもcoroutining関連の述語はいくつかありますが、
それらはまたの機会にでも。
(条件を満たしたときに引数の実行を始めるwhenという述語があるんですが、
なぜか上手くいかなかったorz)

7 Responses to “SWI-Prologのcoroutining”

  1. m0h1can より:

    freeze/2はISO Prologには無いよ
    けれど遅延評価のために幾つかの処理系では昔から実装されてたよ
    デッドロックに注意してね

  2. zick より:

    SWI-Prologにしかない独自の述語かと思っていたんですが、
    実は複数の処理系で実装されていたんですね。
    確かに下手をしたらデットロックが起こりそうで怖いです。

  3. alohakun より:

    この間の natsutan 新年会ではどうもでした。
    古い本ですが、
    「制約論理プログラミング」
    http://www.amazon.co.jp/dp/4320024699
    あたりに、freeze や melt を使った制約ソルバーシステムの実装例が載っていたと思います。
    制約論理プログラミングでは、遅延評価というかデータ駆動計算が多用されるので、ここらへんの述語を使ったテクニックが発達してきた感じみたいですね。
    SCIP でも、scheme の delay と force を使って似たようなことをやっていたと思います。単一代入の論理変数を遅延オブジェクト(サンク)として使うので、Scheme とはまた違った趣きがあると思います。
    (なかなか Captcha 通らない…)

  4. zick より:

    こないだは面白い話をありがとうございました。
    確かにfreezeは「データ駆動計算」という感じですね。
    紹介されている本は、前から気になっていたので、
    機会があれば読んでみようと思います。
    (ただ、今は読むべき本が溜まっているので、
    読めるのは当分先になりそうです(笑))

  5. alohakun より:

    記事の内容と全然関係なくて恐縮ですが,大阪で Prolog な集まりがあるらしいので,いかがでしょうか ?
    http://atnd.org/events/447

  6. zick より:

    なんて素敵なイベントが!!!
    これは全力でいきます。

  7. alohakun より:

    おお、良かった良かった。m0h1can さんと zick さん面識あったと思ったので、ぜひ誘おうと思ったのです (なんか日本語おかしいな…)。
    では、リンク先に登録していただければ。gmail とかいろいろのアカウントで登録できるみたいです。

Leave a Reply