创建一个谓词,用于检测列表是否包含Prolog中的重复元素

时间:2014-02-19 23:46:13

标签: prolog duplicates

我需要定义一个谓词来检测列表是否包含重复的元素。我无法使用findall/3或相关谓词。我不想删除副本,我想弄清楚是否有重复或重复的元素然后如果一组中有重复则Prolog输出'yes'或如果没有则为'no'。我是Prolog的新手,如果不使用Prolog中的谓词,我无法弄清楚如何做到这一点。我需要提出一个新的(如冗余/ 1或某种性质)。有人能帮忙吗?

2 个答案:

答案 0 :(得分:2)

一种有趣的方法:使用sort/2对列表进行排序,删除重复项。检查初始列表的长度是否大于排序列表的长度。

redundant(List) :-
    sort(List, Sorted),
    length(List, A),
    length(Sorted, B),
    A > B.

答案 1 :(得分:2)

你的问题含糊不清:重复元素是什么意思?根据{{​​1}}(逻辑相等),(=)/2(语法相等)或(==)/2(算术相等),它们是否相等。

我将假设第一个。

采取语法立场:

(=:=)/2

现在,我们不仅可以测试具有某些元素的具体列表,而且我们甚至可以提出一般性问题(我将在这里使用GNU-Prolog,因为它的综合输出):

contains_duplicate(L) :-
    phrase( ( ..., [E], ..., [E], ... ), L).

... --> [] | [_], ... .

因此,Prolog为我们提供了前两个元素作为重复的所有列表。其他可能性在哪里?不幸的是,它们隐藏在这个无限的答案序列之后。但我们有运气,我们可以对所有答案进行公平的列举,如下:

| ?- contains_duplicate(L).
L = [A,A] ? a
L = [A,A,_]
L = [A,A,_,_]
L = [A,A,_,_,_]
L = [A,A,_,_,_,_]
L = [A,A,_,_,_,_,_]
L = [A,A,_,_,_,_,_,_]
L = [A,A,_,_,_,_,_,_,_]
L = [A,A,_,_,_,_,_,_,_,_] ...