Создание списков не включает дубликаты в Prolog

#list #prolog #duplicate-removal

#Список #пролог #дубликаты

Вопрос:

 **FACTS**
player(milan,[seedorf,zambrotta,gattuso]).
player(inter,[seedorf,ronaldo,zambrotta]).
player(realmadrid,[seedorf,zidane,ronaldo]).
  

я хочу создать предикат таким образом, чтобы :

 find (TEAM, PLAYERS)
  

и если моя цель — find(X, Y), она вернет список команд X и список игроков Y без каких-либо дубликатов… Как показано ниже:

 X=[milan], Y=[seedorf,zambrotta,gattuso];
X=[inter], Y=[seedorf,ronaldo,zambrotta];
X=[realmadrid], Y=[seedorf,zidane,ronaldo]; 
X=[milan,inter] Y=[seedorf,zambrotta];
X=[milan,realmadri] Y=[seedorf]; 
...
X=[milan,inter,realmadrid] Y=[seedorf];
... 
  

я пытаюсь сделать это с помощью, но это выдает «ОШИБКА: отсутствует локальный стек»,
Если я не использую предикат remove_dups,
Список команд «X» будет содержать дубликаты, и программа не сможет остановиться…
продолжайте, как X=[Милан,milan,миланскийклуб,милан,интер] …. Как я могу исправить этот код. ?:

 find([X], Y) :- player(X1, Y),remove_dups(X1,X).
find([X|Xs], Y) :- player(X1, Y0),find(Xs, Y3), intersection(Y0, Y3, Y),remove_dups(X1,X).

remove_dups([],[]).
remove_dups([First|Rest],NewRest):-member(First, Rest),remove_dups(Rest, NewRest).
remove_dups([First|Rest],[First|NewRest]):-not(member(First, Rest)),remove_dups(Rest, NewRest).
  

Большое спасибо…

Комментарии:

1. Просто для пояснения, предикат find/2 должен возвращать все (непустое?) подмножества команд (в виде списка в первом аргументе) и соответствующий список игроков, общих для всех этих команд. Основываясь на примерах, кажется, что вы не вернули бы «успешно», если бы список игроков был пуст (но вы могли бы выполнить это требование).

2. я не понял? я пишу код, чтобы списки поиска не были пустыми. но он все равно возвращает дубликаты…

3. Привет, Майкл… Я понимаю, что вы не хотите дубликатов в результатах. Целью моего комментария было прояснить, чего вы действительно хотите. Вам может быть ясно, для чего предназначен предикат, но ваше описание («он вернет список команд X и список игроков Y без каких-либо дубликатов») не является спецификацией того, что он должен делать. Читателю остается заполнить пробелы на основе ваших примеров, и есть место для неправильного толкования спецификации. Отсюда мой вопрос: должен ли быть результат (не дублированный, конечно), когда подмножество команд выдает пустой список игроков?

Ответ №1:

Когда вы выполняете сопоставление с шаблоном в списке Xs , он всегда вводит одно и то же значение milan , поэтому дублируется много. Вы можете избежать этого, сначала убедившись в отсутствии дублирования в списке Xs и найдя соответствующих игроков:

 subset([], []).
subset(Xs, [_|Ys]) :- subset(Xs, Ys).
subset([X|Xs], [X|Ys]) :- subset(Xs, Ys).

allteams(Ts) :- findall(T, player(T, _), Ts).
teams(T) :- allteams(Ts), subset(T, Ts).

find1([T], L) :- player(T, L).
find1([T|Ts], L) :- player(T, L0), find1(Ts, L1), intersection(L0, L1, L).

find(X, Y) :- teams(X), find1(X, Y).
  

Здесь я сначала нахожу набор всех команд и пытаюсь найти подмножества, удовлетворяющие условию.