view 3-Prolog/day1-self-study.pl @ 103:98be775c533c default tip

An odd "non-determinism" example from StackOverflow It is clever, but doesn't make much sense as to how it gets its results
author IBBoard <dev@ibboard.co.uk>
date Sun, 14 Jul 2019 13:44:13 +0100
parents 96e77f914f9b
children
line wrap: on
line source

% Make a KB of books and authors and query it.
book(the_long_earth).
book(night_watch).
book(science_of_discworld).
book(lord_of_the_rings).
book(route_666).
book(krokodil_tears).
author(terry_pratchett).
author(stephen_baxter).
author(jack_cohen).
author(ian_stewart).
author(jrr_tolkein).
author(jack_yeovil).
wrote(terry_pratchett, the_long_earth).
wrote(stephen_baxter, the_long_earth).
wrote(terry_pratchett, night_watch).
wrote(terry_pratchett, science_of_discworld).
wrote(jack_cohen, science_of_discworld).
wrote(ian_stewart, science_of_discworld).
wrote(jrr_tolkein, lord_of_the_rings).
wrote(jack_yeovil, route_666).
wrote(jack_yeovil, krokodil_tears).

collaborated(Author1, Author2, Book) :- wrote(Author1, Book), wrote(Author2, Book), Author1 \== Author2.

collaborated(Author1, Author2) :- collaborated(Author1, Author2, Book).
% collaborated(terry_pratchett, stephen_baxter). returns true, but collaborated(Author1, Author2).  just says "no", as does
% collaborated(terry_pratchett, OtherAuthor). - for some reason it isn't filling in answers. It does, however, correctly
% say that Pratchett never collaborated with Pratchett.
%
% If I remove "\+(Author1 = Author2)" then it successfully returns stephen_baxter for terry_pratchett but also returns
% Pratchett himself as a valid answer as well.
%
% wrote(terry_pratchett, Book). works to return all books by an author, though.
%
% However, having added a three-argument version, it can correctly identify the books that someone collaborated on if
% you supply both authors but it won't supply an author when given one author and the book title.
%
% On tracing this and the W&G example then it seems that "\+(…)" doesn't play nicely with variables. The W&G examples
% worked because we only asked "are these two people friends" questions, not "who is friends with" questions.
%
% What we actually need is "\==" (not equal/equivalent). Also, we need to put it at the end so that Author1 and Author2 have
% been assigned by that point.