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