I want to create a rule in prolog that checks if there's a repeated number in a list.
For example:
- for
[1,2,3,4]
it will returntrue
. - for
[1,2,3,3]
it will returnfalse
because the3
is repeated
I came up with this rule but it doesn't work
Different([]).
Different([H|T]):-
Member(H,T),
Different(T).
Any ideas?
Very Simple Answer...
The code:
unique([]). unique([_,[]]). unique([H|T]):-not(member(H,T)),unique(T).
Tests:
?-unique([1,2,3,4]). true. ?-unique([1,2,3,3]). false. ?-unique([a,b,12,d]). true ?-unique([a,b,a]). false
A neat way I came up with is the following:
If all members of a list are different from each other, then if I tell prolog to choose all pairs
(I,J)
such thatI,J
are members of the list and alsoI
is equal toJ
, then for each element in the list it will only be able to find one such pair, which is the element with itself.Therefore, if we can put all such pairs in a list, then the length of this list should be of the same length of the original list.
Here's my prolog code:
The simplest way to check that all list members are unique is to sort list and check that length of the sorted list is equal of length of the original list.
Your solution doesn't work because of wrong syntax (facts and predicates should not begin with a capital letter) and a logic error. List is unique if head
H
is not a member of a tailT
of a list and tailT
is unique:If all numbers in that list are integers, and if your Prolog implementation offers clpfd, there's no need to write new predicates of your own---simply use the predefined predicate
all_different/1
!Sample use:
a compact definition could be
i.e. all elements are different if we can't peek one and find it in the rest...
edit
Let's (marginally) improve efficiency: it's useless to check if X is member of the prefix sublist, so:
The rule provided in the question is very close to a correct answer with minimal library usage. Here's a working version that required only one change, the addition of \+ in the third row:
Explanation of the code for Prolog beginners: The member(H,L) predicate checks if element H is a member of the list L. \+ is Prolog's negation function, so the above code amounts to:
Whereas the code by the original asker didn't work because it amounted to:
*I renamed Different() to uniqueList() because it reads better. Convention is to reserve capital letters for variables.