setof/3 не удаляет дубликаты
Я пытаюсь найти дополнение списка, учитывая список L1 и универсальный список L2 со следующим кодом:
complement(L1, L2, Res):-
setof(X, (nth0(N, L2, X), not(member(X,L1))),Res).
Тем не менее, мои результаты включают дубликаты и не приведены в виде списка, как я бы предпочел:
23 ?- complement([1,3], [-1,1,3,5,2,4,2,55,1,0], Res).
Res = [-1] ;
Res = [5] ;
Res = [2] ;
Res = [4] ;
Res = [2] ;
Res = [55] ;
Res = [0].
Я подумал, что это, вероятно, из-за встроенного обратного отслеживания в Прологе, но я не уверен, как обойти это, чтобы правильно отформатировать результат и заставить его удалить все дублирующиеся элементы в результате.
1 ответ
Вы получаете предупреждение из своего кода, о N
будучи одноэлементным, и setof/3 требует, чтобы каждая переменная, "универсально определенная", была объявлена. Итак, у вас есть две проблемы, которые уходят вместе: замените nth0/3 на member/2:
complement(L1, L2, Res):-
setof(X, (member(X, L2), not(member(X, L1))), Res).
редактировать
симметричная разница может быть
symdiff(L1,L2,Diff) :-
setof(X,(eldiff(L1,L2,X);eldiff(L2,L1,X)),Diff).
eldiff(L1,L2,X) :-
member(X,L1), \+member(X,L2).
если L1 и L2 - упорядоченные множества, гораздо лучше использовать ord_symdiff