Ric*_*rdo 2 freeze prolog coroutine prolog-coroutining
我想在 Prolog 中构建我自己的协程。我想添加一些额外的功能。
为协程编写一个普通的解释器应该在每门 Prolog 课程的教学清单上。这很简单,在这里你可以看到普通的香草解释器,简化了:
% solve(+Term)
solve(true).
solve((A,B)) :- solve(A), solve(B).
solve(H) :- clause(H, B), solve(B).
Run Code Online (Sandbox Code Playgroud)
现在对于 coouting,在通过 freeze/2 暂停目标的意义上,只需添加一个额外的输入输出参数对与延迟目标,有关 select/3 的规范,请参见 (*):
% solve(+Term, +List, -List)
solve(G, L, R) :- select(freeze(V, F), L, H),
nonvar(V), !,
solve((F,G), H, R).
solve(freeze(V, G), L, [freeze(V,G)|L]) :- var(V), !.
solve(freeze(_, G), L, R) :- solve(G, L, R).
solve(true, L, L).
solve((A,B), L, R) :- solve(A, L, H), solve(B, H, R).
solve(H, L, R) :- clause(H, B), solve(B, L, R).
Run Code Online (Sandbox Code Playgroud)
您可以使用上面的 vanilla 解释器来研究不同的唤醒策略。我不确定它是否捕获了现有的 Prolog 系统。但是您可以运行以下示例:
?- freeze(X, member(X, [the(1), the(2)])), X = the(Y).
Run Code Online (Sandbox Code Playgroud)
成功,通过提出以下问题:
?- solve((freeze(X, member(X, [the(1), the(2)])), X = the(Y), true), [], L).
Run Code Online (Sandbox Code Playgroud)
需要“,真”来检查最后一次唤醒目标。如果 L 返回空,则所有冻结的目标都被唤醒。否则有一些悬而未决的冻结目标。这有时被称为挣扎。
上面的原型还通过瘦属性、undo/1 和目标注入队列对解释器的一些小支持导致了协程的自然实现。我很快会在其他地方发布这个。
再见
(*) https://www.complang.tuwien.ac.at/ulrich/iso-prolog/prologue