Prolog - 如何返回每个元素仅出现一次的列表?

问题描述

我有一个谓词 set/2 ,它应该将第二个参数实例化为一个列表,该列表的元素只是第一个参数中每个术语的一次出现。到目前为止,我所拥有的是:

set([],OutList).
set([X|InList],OutList) :- \+member(X,InList),append([X],OutList,OutListNew),set(InList,OutListNew).                      
set([X|InList],OutList) :- member(X,OutList).

调用 set/2:

set([1,1,2,3],X).

返回真。这已经进行了一半 - 我希望 X 被实例化为 [1,3] - 但我不确定在这种情况下如何使 X 为真。任何帮助和解释将不胜感激。

解决方法

您的 Prolog 应该警告您在第一个子句中有一个单例,即

set([],OutList).

这意味着当执行遇到此类子句时,它成功,但 OutList 保持未绑定。

现在应该清楚您需要用空列表替换 OutList

另一个错误位于第二个子句中。

append([X],OutList,OutListNew) 应该改为 append([X],OutListNew,OutList)。作为样式说明,它可以用这个统一替换:[X|OutListNew]=OutList,然后移入头部。

,

sort/2 删除重复项(msort/2 会留下重复项,如果这是您想要的。

还有:https://www.swi-prolog.org/pldoc/man?predicate=list_to_set/2