Как насчет этого:
listmax(L, M):-
listmax(L, [], [], M).
listmax([], Seen, MMax, Max):-
MMax=[] -> Max=Seen ; listmax(MMax, [], [], Max).
listmax([H|T], Seen, MMax, Max):-
(member(H, Seen) ->
listmax(T, Seen, [H|MMax], Max) ;
listmax(T, [H|Seen], MMax, Max)).
Вот небольшое объяснение этого алгоритма:
Идея состоит в том, чтобы перебрать список, удаляя первое вхождение каждого элемента, которое приводит к новомусписок.Затем рекурсивно применяйте тот же алгоритм к этому новому списку, пока в результате мы не получим пустой список.На данный момент мы знаем, что предыдущий список - это список, который мы ищем.
Второе предложение listmax / 4 - это итеративное предложение, которое проверяет, отображается ли элемент в первый раз.Список видимых предметов хранится во втором аргументе этого предиката.Третий аргумент собирает оставшиеся элементы (те, которые не видны в первый раз).
Первый пункт listmax / 4 является базовым случаем.Это вступает в игру, когда мы закончим итерацию по списку.На этом этапе он проверяет, является ли список оставшихся элементов пустым, и в этом случае мы знаем, что список увиденных - это список, который мы ищем.В противном случае мы снова применяем алгоритм, но в качестве входного списка используем «оставшийся список».