Не уверен, что это домашнее задание / есть ограничения на то, какие предикаты вам разрешено использовать, но это дает пролог для выполнения рекурсии за вас.
Там написано .. найти все дубликаты т.е. где есть элемент с индексом списка I1, а другой - с индексом I2, так что оба они имеют одинаковое значение N, а индексы не совпадают, т.е. не следует рассматривать один и тот же элемент списка как дубликат.
Эти дубликаты помещаются (в порядке их нахождения, важно с самого начала) в список AllDups, и предикат истинен, если первый найденный дубликат объединяется с M, значением, которое вы проверяете.
Первая попытка: это работает, но очень неэффективно, составляет список ВСЕХ дубликатов
prep(M, List) :-
findall(N,
(nth0(I1, List, N),
nth0(I2, List, N),
not(I1 =:= I2)),
AllDups),
nth1(1, AllDups, M).
?- prep(3,[1,3,5,3,5]).
true.
?- prep(5,[1,3,5,3,5]).
false.
Даже если вам не разрешено использовать findall, это может помочь вам решить, как это сделать «вручную».
Вторая попытка: это не сработает / слишком большой откат, что дает ложное срабатывание
Вы даже можете сделать это без findall - используйте nth0, чтобы найти первый повторяющийся элемент, тогда, если он соответствует проверяемому вами значению, он вернет true, в противном случае - false.
prep(N, List) :-
nth0(I1, List, N),
nth0(I2, List, N),
not(I1 =:= I2).
Третья попытка: работает и возвращается, как только будет найден первый дубликат
prep(M, List) :-
nth0(I1, List, N),
nth0(I2, List, N),
not(I1 =:= I2), !,
M == N.
person
magus
schedule
21.04.2012