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

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

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

find (TEAM, PLAYERS)

и если моя цель - найти (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 = [милан, милан, милан, милан, интер] .... Как я могу исправить этот код. ?:

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).

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


person Palindrom    schedule 11.05.2011    source источник
comment
Чтобы уточнить, предикат find / 2 должен возвращать все (непустые?) Подмножества команд (в виде списка в первом аргументе) и соответствующий список игроков, общий для всех этих команд. Основываясь на примерах, кажется, что вы не смогли бы успешно вернуться, если бы список игроков был пуст (но вы можете выполнить это требование).   -  person hardmath    schedule 11.05.2011
comment
я не понял? я пишу код, который смотрит списки не пустые. но он по-прежнему возвращает дубликаты ...   -  person Palindrom    schedule 11.05.2011
comment
Привет, Майкл ... Ясно, что вам не нужны дубликаты результатов. Мой комментарий был направлен на то, чтобы прояснить то, что вы действительно хотите. Вам может быть ясно, для чего предназначен предикат, но ваше описание (оно возвращает список команд, X и список игроков, Y, без каких-либо дубликатов) не является спецификацией того, что он должен делать. Читателю предоставляется возможность заполнить пробелы на основе ваших примеров, и есть место для неправильной интерпретации спецификации. Отсюда мой вопрос: должен ли быть результат (конечно, не дублированный), когда подмножество команд создает пустой список игроков?   -  person hardmath    schedule 11.05.2011


Ответы (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).

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

person pad    schedule 11.05.2011