我想在prolog中写一下“检查一个列表是否具有相同的元素”,例如list [a,a,a,a]为真。 list [a,c,a,a]为false。 我怎么能这样做?
答案 0 :(得分:4)
可以使用一个简单的谓词来完成:
same([]). % You only need this one if you want the empty list to succeed
same([_]).
same([X,X|T]) :- same([X|T]).
结果:
| ?- same([a,b,a,a]).
no
| ?- same([a,a,a,a]).
true ? ;
no
| ?- same([]).
yes
ADDENDUM 1
更改子句的顺序以便首先允许基本案例:
| ?- same(L).
L = [] ? ;
L = [_] ? ;
L = [A,A] ? ;
L = [A,A,A] ? ;
...
ADDENDUM 2
另一种使用DCG的方法可能是:
same(_) --> [].
same(X) --> [X], same(X).
然后:
| ?- phrase(same(_), [a,b,a,a]).
no
| ?- phrase(same(_), [a,a,a,a]).
true ? a
(1 ms) no
| ?- phrase(same(X), L).
L = [] ? ;
L = [X] ? ;
L = [X,X] ? ;
L = [X,X,X] ? ;
...
答案 1 :(得分:3)
same(L) :-
maplist(=(_),L).
| ?- maplist(=(_),L).
L = []
L = [_]
L = [A,A]
L = [A,A,A]
L = [A,A,A,A]
L = [A,A,A,A,A]
另见this answer。
答案 2 :(得分:2)
好的,现在我理解了有关此问题的请求:
compare([X|Y]):-help(Y,X).
compare([]).
help([],_).
help([Y|X],Y) :- help(X,Y).
答案 3 :(得分:1)
使用内置list_to_set/2,可以在一行中完成:
?- list_to_set([a,a,a,a],[_]).
true.
?- list_to_set([a,a,c,a],[_]).
false.
将列表转换为集合会删除重复项..因此,如果您留下可以统一到一个项目[_]的列表,那么就没有重复项。
如果列表有重复,则会有>集合中的1个项目,[_]谓词统一将失败。
这显然不适用于空列表 - 需要单独的规则。