我想建立自己的协同程序中的Prolog。 我想添加一些额外的功能。
Answer 1:
一个可行的办法是使用一些Prolog的系统提供的术语展开机构和Logtalk重写调用例如在freeze/2
谓词做你想要额外的步骤。 我们必须要小心,但是,不扩展到谓词调用到调用相同的谓词为目标,扩展递归应用,直到达到定点另一个目标。 所述Logtalk实施术语-膨胀机构的可以很容易地避免这种陷阱(可移植性的附加优点,因为可以用最Prolog的系统使用Logtalk)通过使用一个编译器旁路控制构建体, {}/1
。 一个愚蠢的例子是:
:- object(my_expansions,
implements(expanding)).
goal_expansion(
freeze(Var,Goal),
( write('If you instantiate me, I will run away!\n'),
{freeze(Var,Goal)}, % goal will not be further expanded
write('Bye!\n')
)
).
:- end_object.
该对象可被用作包含呼叫源文件编译的钩对象freeze/2
,你要扩大。 喜欢的东西(假设物体上面保存与名称的文件my_expansions.lgt
而且要展开源文件名为source.lgt
):
?- logtalk_load(my_expansions), logtalk_load(source, [hook(my_expansions)]).
有关详情请参阅Logtalk文档和示例。
有可能是一个干净的方式,我不知道用Prolog的系统自己长期展开机构实施做同样的。 任何人?
Answer 2:
写香草解释为协同程序应该是每一个序言课程的教学名单上。 这是很简单的,在这里你看到正常的香草解释,简化为:
% solve(+Term)
solve(true).
solve((A,B)) :- solve(A), solve(B).
solve(H) :- clause(H, B), solve(B).
现在对于corouting,在通过冷冻/ 2悬浮目标的意义上,仅仅增加一个额外的输入输出参数对与延迟的目标,对于选择/ 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).
您可以使用上面的香草解释,研究不同的唤醒策略。 我不知道它是否抓住现有的Prolog系统。 但是你可以运行的例子,如:
?- freeze(X, member(X, [the(1), the(2)])), X = the(Y).
成功,通过摆以下问题:
?- solve((freeze(X, member(X, [the(1), the(2)])), X = the(Y), true), [], L).
在“真”是需要检查唤醒目标最后一次。 如果L返回空又在哪里唤醒所有冻结目标。 否则,有一些悬而未决冻结目标。 有时被称为挣扎。
上述原型还经由薄属性导致天然协程执行的,撤消/ 1和由目标喷射队列一些很少支持解释的。 我很快会上传关于这个别的地方。
再见
(*) https://www.complang.tuwien.ac.at/ulrich/iso-prolog/prologue