Prolog findall实现

我的任务是在Prolog中实现findall的一个版本,而不使用任何Prolog内置函数,除非没有剪切 - 所以基本上在纯Prolog中。

我试图为所有直接后代搜索一棵树,并将结果返回列表

parent(a, b).
parent(b, c).
parent(b, d).
parent(e, d).

我到目前为止是:

find(X, L) :- find2(X, [], L).
find2(X, Acc, L) :- parent(Y, X), find2(Y, [Y|Acc], L).
find2(_, Acc, Acc).

例如,我想要输入的内容是:

find(a,X).

将会:

X = [b, c, d]

(顺序不重要)

但是,我得到:

X = [b, c] ;
X = [b, d] ;
X = [b] ;
X = [].

我是Prolog的新手,所以对此有任何帮助都将非常感激。

谢谢


除了断言数据之外,还可以使用额外逻辑谓词,例如nb_setarg / 3。 然后,一旦找到父母,你就会失败回nb_setarg并找到另一个父母。 以前找到的所有解决方案都应该保持在你做nb_setarg的期限内,然后在所有结果都用尽之后,nb_setarg术语就是答案。 SWI-Prolog的例子很好,但它只是一个计数器。 尝试用一个列表(或更好的:差异列表),随着你的进展而建立。


看看这个解决方案。 请注意,此解决方案使用名为队列的动态谓词来缓存所有解决方案,直到所有可能耗尽。 一旦没有更多的解决方案存在,实现将收回所有事实并编写列表。

这当然是一个简单的解决方案,想象一下,如果两个findall会同时激活,会发生什么。 在特定的序言实现中,对于断言和撤销的确切语义也有点脆弱


感谢你帮助每个人。 我最终通过添加一个谓词来检查每个项目与当前列表,并且如果它已经存在则失败:

find(X, Loa) :- find(X, [], Loa), !.
find(X, Acc, Loa) :- dec(Y, X), uList(Y, Acc, AccNew), find(X, AccNew, Loa).
find(_, Acc, Acc).

dec(X,Y) :- parent(X,Y).
dec(X,Y) :- parent(X,Z), dec(Z,Y).

uList(X, [], [X])  :- !.
uList(H, [H|_], _) :- !, fail.
uList(X, [H|T], L) :- uList(X, T, Rtn), L = [H|Rtn].
链接地址: http://www.djcxy.com/p/55233.html

上一篇: Prolog findall Implementation

下一篇: Some changes on Soundex Algorithm