2007-11-06

Prolog (6)

なんかunfoldの定義を少し間違って記憶してたように思います。Haskellでリスト用の定義を見るとこんな感じ。

unfold p f g x =
if p x
then []
else f x : unfold p f g (g x)

Prologでは前回示したようにunfoldの外のゴールでバックトラック制御を行えますから、終了判定は要らないですね。アレはアレで使い道はあるのでunfold2とかにリネームしておいて、リスト用unfoldlを正しく書くとこんな感じですかね?

% unfoldl/5
unfoldl(Fn1, _, X, L, L1) :-
G =.. [Fn1, X, Y],
call(G),
append(L, Y, L1).
unfoldl(Fn1, Fn2, X, L, L2) :-
unfoldl(Fn1, Fn2, X, L, L1),
G =.. [Fn2, X, Y],
call(G),
unfoldl(Fn1, Fn2, Y, L1, L2).

% make_list/2
make_list(X, [X]).

?- unfoldl(make_list, inc, 1, [], L), length(L, 100), foldl(plus, 0, L, Sum).
L = [1, 2, 3, 4, 5, 6, 7, 8, 9|...],
Sum = 5050

ただHaskellだと型システムのチェックが働く部分や、カリー化された関数が書き易い部分が組み合わさって強力なfold/unfoldですが、Prologだとその辺りでメリットが無いので正直なところ使い勝手は微妙です。

ところで最近都内でProlog勉強会をやっています。ご興味をお持ちの方が居られましたら是非ご一報を。隔週で長期的にやっております。
次回開催概要
場所: 中目黒GTタワー
日時: 11/10(Sat) 14:00-
内容: Prologへの入門 4-5章
連絡: hiro.kosh@gmail.com

0 件のコメント: