如何在Prolog中编写/编辑自己的协程?

如何在Prolog中编写/编辑自己的协程?,prolog,freeze,coroutine,prolog-coroutining,Prolog,Freeze,Coroutine,Prolog Coroutining,我想在Prolog中构建我自己的协同程序。 我想添加一些额外的功能。一个可能的解决方案是使用一些Prolog系统和Logtalk提供的术语扩展机制来重写调用,例如,freeze/2谓词来执行您想要的额外步骤。但是,必须小心,不要将对谓词的调用扩展到调用同一谓词的另一个目标,因为目标扩展是递归应用的,直到达到一个定点为止。术语扩展机制的Logtalk实现通过使用编译器旁路控制结构{}/1很容易避免这个陷阱(具有可移植性的额外优势,因为您可以在大多数Prolog系统中使用Logtalk)。一个愚蠢的

我想在Prolog中构建我自己的协同程序。
我想添加一些额外的功能。

一个可能的解决方案是使用一些Prolog系统和Logtalk提供的术语扩展机制来重写调用,例如,
freeze/2
谓词来执行您想要的额外步骤。但是,必须小心,不要将对谓词的调用扩展到调用同一谓词的另一个目标,因为目标扩展是递归应用的,直到达到一个定点为止。术语扩展机制的Logtalk实现通过使用编译器旁路控制结构
{}/1
很容易避免这个陷阱(具有可移植性的额外优势,因为您可以在大多数Prolog系统中使用Logtalk)。一个愚蠢的例子是:

:- 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文档和示例


可能有一种清洁的方式,我不知道使用Prolog系统自己的术语扩展机制实现也会这样做。有人吗?

为合作项目编写一个普通的解释器应该在每门Prolog课程的教学清单上。这很简单,在这里你可以看到普通的香草解释器,简化的:

% solve(+Term)
solve(true).
solve((A,B)) :- solve(A), solve(B).
solve(H) :- clause(H, B), solve(B).
现在对于协同路由,在通过freeze/2暂停目标的意义上,只需添加一个额外的输入输出参数对和延迟的目标,有关select/3的规范,请参见(*):

您可以使用上面的普通解释器来研究不同的唤醒策略。我不确定它是否捕获了现有的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).
需要“true”来检查最后一次醒来的目标。如果L是空的,那么所有冻结的目标都会被唤醒。否则就会有一些悬而未决的冻结目标。这有时被称为挣扎

上述原型还通过精简属性、undo/1和目标注入队列对解释器的一些小支持,自然地实现了协同路由。我很快会把这件事发到其他地方

再见

(*)

好的。你能解释一下冷冻是如何工作的吗。我真的希望模拟Prolog执行的操作。查看有关属性变量的Prolog系统文档部分。我是否可以使用目标扩展来扩展=/2的功能?简短回答,是的。只要您使用的Prolog系统提供术语扩展机制,您就应该能够为
goal\u expansion/2
定义子句,将调用扩展到正在编译的源文件上,例如
=/2
。是否您发布的代码不起作用?至少我的堆栈用完了。例如,在这里可以找到其他元解释器,例如第167页:
?- 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).