Как найти человека, который опубликовал только одну книгу? - PullRequest
0 голосов
/ 20 сентября 2018

Здравствуйте. Я использую ECliPSe Prolog для выполнения домашней работы, и у меня возникла проблема с одним из моих вопросов.Я хочу найти людей, которые опубликовали только одну книгу, используя созданную мною программу Prolog ниже.

hasBook(markham_library,dave,"Artifical Intelligence: A Modern Approach",1).
hasBook(indigo,levesque,"the two",2).
hasBook(union_library,dave,"the three",3).
hasBook(somewhere_library,bob,"Thinking as Computation",4).
hasBook(amazon,robert,"the five",5).
hasBook(ajax_library,daniel ,"the six",6).
hasBook(markham_library,evan,"Computational Intelligence",7).
hasBook(stouffvile_library,john ,"the eight",8).
hasBook(ajax_library,sam,"the nine",9).
hasBook(kitchner_library,david,"the ten",10).
hasBook(amazon,chad,"the eleven",105).
hasBook(amazon,chad, "the twelve", 107).
hasBook(amazon,chad, "the thirteen",10).
hasBook(amazon,chad, "the fourteen", 20).
hasBook(amazon,jkrowling,"harrypotter",10).
hasBook(markham_library,jkrowling,"harrypotter",5).

lives(brad,markham).
lives(joyce,stouffville).
lives(opal,union).
lives(delia,ajax).
lives(verna,ville).
lives(sean,ajax).
lives(william,kitchner).
lives(casey,ajax).
lives(courtney,markham).
lives(garrett,stouffville).
lives(chad,newyork).

shipping(markham_library, union, 1).
shipping(stouffville_library, toronto, 2).
shipping(markham_library, stouffville, 3).
shipping(stouffville_library, stouffville, 4).
shipping(markham_library, markham, 5).
shipping(stouffville_library, ajax, 6).
shipping(markham_library, kitchner, 7).
shipping(stouffville_library, kitchner, 11).
shipping(union_library, markham, 9).
shipping(union_library, stouffville, 2).
shipping(amazon, stouffville, 5).
shipping(amazon, markham, 17).
shipping(amazon, toronto, 20).
shipping(markham_library, toronto, 5).

Я не понимаю, почему запрос hasBook(V,W,X,Y), not hasBook(L,W,N,M).не возвращает результат.Вместо этого он возвращает false.Может кто-нибудь, пожалуйста, объясните.

Ответы [ 2 ]

0 голосов
/ 21 сентября 2018

Не уверен, что это решение, которое вы должны придумать, но вы можете использовать предикат setof / 3 , чтобы сгруппировать все решения по автору и выбрать только те, в которых список результатов содержит один элемент:

?- Xs = [_], setof(Book, Lib^N^hasBook(Lib,Name,Book,N), Xs).
Xs = ["Thinking as Computation"],
Name = bob ;
Xs = ["the six"],
Name = daniel ;
Xs = ["the ten"],
Name = david ;
Xs = ["Computational Intelligence"],
Name = evan ;
Xs = ["the eight"],
Name = john ;
Xs = ["the two"],
Name = levesque ;
Xs = ["the five"],
Name = robert ;
Xs = ["the nine"],
Name = sam.

Шаблон Lib^N^ связывает две переменные в hasBook(Lib,Name,Book,N) так, что если одна и та же книга появится в разных библиотеках, она не даст отдельного результата.Использование setof/3 вместо bagof/3 гарантирует, что возвращается только один результат для пары Имя / Книга.

Редактировать: извините, я забыл объяснить, почему ваше решение не работает.Позвольте мне переписать старый стиль not в \+ и скрыть все одноэлементные переменные в вашем запросе:

?- hasBook(_,W,B1,_), \+ hasBook(_,W,B2,_).
false.

Вы ищете назначение, которое находит книгу B1 от Wно потом вы утверждаете, что W не написал ни одной книги, которая не может быть правдой, потому что мы уже нашли B1.Как указал @Ruzihm, вам не хватает информации о том, что второй запрос не о B1.Их решение использует \=, но это работает только после того, как второй запрос достаточно инстанцировал B2, чтобы сравнить его с B1.Альтернативой является использование dif/2:

?- dif(B1,B2), hasBook(_,W,B1,_), \+ hasBook(_,W,B2,_).

Разница в том, что dif/2 вводит ограничение, что B1 и B2 различны.Пока один из них все еще является переменной, это еще не может быть решено.Ваша база данных содержит только основные факты, где проблема не возникает.В целом, использование dif/2 менее проблематично.

0 голосов
/ 21 сентября 2018

Вы должны указать, что книги, N и X должны быть разными, чтобы быть выброшенными.

hasBook(_,X,A,_), not(( hasBook(_,X,B,_), B\=A) ) отбрасывает любые результаты с тем же автором и другой книгой, и не заботится о 1-м или 4-м аргументах.

Подтверждение на https://swish.swi -прогноз.org / р / fkukVFSw.swinb

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...