如果一个列表具有相同的元素,我想检查prolog

时间:2014-02-19 13:16:22

标签: list prolog

我想在prolog中写一下“检查一个列表是否具有相同的元素”,例如list [a,a,a,a]为真。 list [a,c,a,a]为false。 我怎么能这样做?

4 个答案:

答案 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个项目,[_]谓词统一将失败。

这显然不适用于空列表 - 需要单独的规则。