2016-10-27 76 views
1

我GOOGLE了这一点,但不能找到答案,所以在这里你去:统一名单列表的Prolog

我在序言中这样的功能:

ing(Lis) :- findall(I,(recipe2(_,ingredients(I,_))),Lis). 

此功能搜索和返回我列出的清单像这样:

L = [['wheat flour', egg, salt], ['wheat flour', cheese, olives, tomato, salt, basil], ['wheat flour', potatoes, salt], [milk, egg, sugar]]. 

我想统一列表列表只在一个列表中,所以我可以得出重复。我知道我必须使用递归,但这就是我所知道的。

在此先感谢。

回答

0

您可能只需修改谓词像这样:

ing(Lis) :- 
    setof(E, X^Y^I^(recipe2(X, ingredients(I,Y)), member(E, I)), Lis). 

member/2是一个内置的谓词统一与第二个参数列表中的一个元素的第一个参数。它是非确定性的。

使用X^Y^I^是存在量化符,以确保您只能在一个解决方案中获得结果。它基本上说,

作为 成分表,(I)的一部分的任何元素E存在X,Y和I.

使用setof/3还可确保您获得的任何解决方案都是独特元素的集合。


文档(SWI-Prolog的)为 member/2setof/3

+3

权,但由于OP的需求,是的findall/3 – CapelliC

+0

@CapelliC之后,除去重复,更好地利用SETOF/3,或排序/ 2,感谢指出了这一点。涉及处理重复的问题部分由于某种奇怪的原因完全逃脱了我的想法。我编辑了我的答案。 – eazar001