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