Lyn*_*ynn 7 continuations haskell prolog swi-prolog delimited-continuations
我在这里找到了 Haskell 中移位重置分隔延续的示例:
Run Code Online (Sandbox Code Playgroud)resetT $ do alfa bravo x <- shiftT $ \esc -> do charlie lift $ esc 1 delta lift $ esc 2 return 0 zulu x这会:
履行
alfa履行
bravo履行
charlie绑定
x到1,从而执行zulu 1从末尾掉下来
resetT,然后跳回到后面esc 1履行
delta绑定
x到2,从而执行zulu 2从末尾掉下来
resetT,然后跳回到后面esc 2逃离
resetT,导致它产生 0
我不知道如何使用 SWI-Prolog 的shift/1和reset/3编写等效代码。
下面的代码是我的尝试。输出是相同的,但看起来很混乱和倒退,我觉得我误用了与Haskell 示例中的和Ball类似的东西。另外,我不知道该怎么办。esc 1esc 2return 0
% not sure about this...
example :-
reset(step, ball(X), Cont),
( writeln("charlie"), X=1, call(Cont), fail
; writeln("delta"), X=2, call(Cont)).
step :-
writeln("alfa"),
writeln("bravo"),
shift(ball(X)),
format("zulu ~w~n", X).
Run Code Online (Sandbox Code Playgroud)
我很困惑:Scheme/Haskell/ML 风格的移位重置和 Prolog 移位重置看起来几乎完全不同!例如,您将 lambda 传递到 Haskell 中shiftT,但没有将目标传递到 Prolog 的 shift/1 中。
Prolog 中 Haskell 的\esc -> ... esc 1or等价物在哪里return 0?BallProlog 的or的 Haskell 等价物在哪里call(Cont)?
我觉得上面 Haskell 示例的“正确”移植可以回答这些问题。
和运算符最初来自Danvyreset;菲林斯基,1990。\xe2\x80\x9c 抽象控制\xe2\x80\x9d。Haskell Control.Monad.Trans.Cont中对应的接口符合原始语义,除了一些类型限制之外。SWI-Prolog 中的分隔延续接口并不完全是原始的和。它们与Felleisen,1988 的提示和控制或Sitaram\xe2\x80\x99 的 fcontrol 和 run 操作符关系更密切。shiftresetshift
通常,将定界延续程序从 Haskell 转换为 Prolog 并不困难。您的示例中的困难在于它使用esc不同的值调用相同的延续两次。例如,
example :-\n reset(step, ball(X), Cont),\n X=1, call(Cont),\n X=2, call(Cont).\nRun Code Online (Sandbox Code Playgroud)\n第一个已经绑定后call(Cont),您无法将其重新绑定。X12
TomSchrijvers 的建议是使用copy_term/2使用新的统一变量创建延续的副本(是的,延续也是 SWI-Prolog 中的术语!),因此您的示例的 Prolog 等效项是
\nexample(X) :-\n reset(step, Ball, Cont),\n copy_term(Cont+Ball, Cont1+Ball1),\n copy_term(Cont+Ball, Cont2+Ball2),\n writeln("charlie"),\n ball(X1) = Ball1,\n X1=1, reset(Cont1, _, _),\n writeln("delta"),\n ball(X2) = Ball2,\n X2=2, reset(Cont2, _, _),\n X=0. \n\nstep :-\n writeln("alfa"),\n writeln("bravo"),\n shift(ball(X)),\n format("zulu ~w~n", X),\n shift(ball(X)).\n\n?- example(X).\nalfa\nbravo\ncharlie\nzulu 1\ndelta\nzulu 2\nX = 0.\nRun Code Online (Sandbox Code Playgroud)\n