Пытаясь лучше понять пролог, списки и рекурсию в целом, я прорабатываю различные простые задачи, которые возложил на себя. Среди прочего, удаление двойных записей из списка.
Я определил правило:
is_on(Item, [Ah|At]) :- Ah = Item; is_on(Item, At).
Это проверяет, находится ли «Item» в списке X или нет. Поэтому я подумал, что могу расширить это, чтобы также определить предикат filter_double:
filter_doubles([Ah|At], Result) :-
(not(is_on(Ah, At)) ->
Result = [Ah|Result]
;
filter_doubles(At, Result)
).
Для меня это имело смысл: если Ah не встречается в остальной части списка (его хвосте), то добавьте a в начало результата, используя построение списка, в противном случае выполните рекурсию по остальной части списка. Видимо Пролог думает иначе:
47 ?- filter_doubles([1,2,3,3,4,2,1,1], Z).
Z = [3|**].
Неужели я считаю это слишком настоятельным?
is_on(Item, [H|T]) :- Item = H; is_on(Item, T).
илиis_on(X,L) :- memberchk(X,L).
- person Fred Foo   schedule 07.03.2011filter_double
илиfilter_doubles
? - person Fred Foo   schedule 07.03.2011