Учитывая следующие факты:
route(TubeLine, ListOfStations).
route(green, [a,b,c,d,e,f]).
route(blue, [g,b,c,h,i,j]).
...
Мне нужно найти все пары трубных линий, у которых нет общих станций, и получить следующее:
| ?- disjointed_lines(Ls).
Ls = [(yellow,blue),(yellow,green),(yellow,red),(yellow,silver)] ? ;
no
Я пришел к приведенному ниже ответу, однако он не только дает мне неправильный ответ, но и не применяет мое условие X ^ - т.е. он по-прежнему печатает результаты для каждого члена списков станций отдельно:
disjointed_lines(Ls) :-
route(W, Stations1),
route(Z, Stations2),
setof(
(W,Z),X^
(member(X, Stations1),nonmember(X, Stations2)),
Ls).
Это результат определения:
| ?- disjointed_lines(L).
L = [(green,green)] ? ;
L = [(green,blue)] ? ;
L = [(green,silver)] ? ;
...
Я считаю, что моя логика в отношении членства неверна, однако я не могу понять, что не так. Может ли кто-нибудь увидеть, в чем я ошибаюсь?
Я также прочитал главу 11 Learn Prolog Now о сборе результатов, как было предложено здесь , однако мне кажется, что я все еще не могу правильно использовать оператор ^. Любая помощь будет оценена по достоинству!
ОБНОВЛЕНИЕ:
По предложению пользователя CapelliC я изменил код на следующий:
disjointed_lines(Ls) :-
setof(
(W,Z),(Stations1, Stations2)^
((route(W, Stations1),
route(Z, Stations2),notMembers(Stations1,Stations2))),
Ls).
notMembers([],_).
notMembers([H|T],L):- notMembers(T,L), nonmember(H,L).
Следующее, однако, дает мне дубликаты (X, Y) и (Y, X), но следующим шагом будет удаление их в отдельном правиле. Спасибо вам за помощь!