При чтении вашего вопроса вы сначала дали базу данных фактов
likes(josh,muse).
likes(sam,muse).
likes(josh,gnr).
likes(sam, radiohead).
, но затем использовали список для предиката
same([josh,muse], [sam,muse]).
Когда Пауло ответил, начиная со списка, я отвечу, начиная со спискас фактами.
Первым делом необходимо создать предикат, который читает факты, выполняет некоторую логику и возвращает результаты.
same_1(P1,P2,Item) :-
likes(P1,Item),
likes(P2,Item).
, что дает
?- same_1(P1,P2,Item).
P1 = P2, P2 = josh,
Item = muse ;
P1 = josh,
P2 = sam,
Item = muse ;
P1 = sam,
P2 = josh,
Item = muse ;
P1 = P2, P2 = sam,
Item = muse ;
P1 = P2, P2 = josh,
Item = gnr ;
P1 = P2, P2 = sam,
Item = radiohead.
Итакдля этого необходимо убедиться, что P1 не совпадает с P2.
same_2(P1,P2,Item) :-
likes(P1,Item),
likes(P2,Item),
P1 \= P2.
, что дает
?- same_2(P1,P2,Item).
P1 = josh,
P2 = sam,
Item = muse ;
P1 = sam,
P2 = josh,
Item = muse ;
false.
Все еще два ответа, которые являются действительными, но по сути являются дубликатами.Чтобы удалить эти дубликаты, необходимо сохранить все результаты, чтобы каждый новый результат можно было сравнить с существующими, а не добавить к текущим.Кроме того, перед сохранением результатов их необходимо нормализовать, чтобы независимо от того, каким образом упорядочены имена при первоначальном создании, они были в одном и том же порядке при сравнении их перед сохранением.
Изменение кода для создания нормализованных записей.
same_3(P1,P2,Item) :-
likes(T1,Item),
likes(T2,Item),
T1 \= T2,
normalize(T1,T2,P1,P2).
normalize(P1,P2,P1,P2) :- P1 @> P2.
normalize(P1,P2,P2,P1) :- P1 @=< P2.
, который возвращает
?- same_3(P1,P2,Item).
P1 = sam,
P2 = josh,
Item = muse ;
P1 = sam,
P2 = josh,
Item = muse ;
false.
Обратите внимание, что у этого результата есть имена в том же порядке.
Теперь просто сохраните результаты по мере их создания и толькодобавить уникальные предметы к результату.Это делается с помощью setof / 3 .
?- setof((P1,P2,Item),(same_3(P1,P2,Item)),Bag).
Bag = [(sam, josh, muse)].