Search code examples
if-statementprologconditional-statements

prolog query ignores if conditional


First and foremost I am a 'noob' with regards to Prolog, and currently finding it difficult to find information online appropriate to my skill level. Anyway here is a sample of my code:

book(brave_new_world).
book(lord_of_the_flies).
book(fight_club).
book(wind_in_the_willows).
book(the_hobbit).
cat_num(111) :- book(brave_new_world).
cat_num(222) :-book(lord_of_the_flies).
cat_num(333) :- book(fight_club).
cat_num(444) :- book(wind_in_the_willows).
cat_num(555) :-book(the_hobbit).
author(huxley_aldus) :- book(brave_new_world).
author(golding_william) :- book(lord_of_the_flies).
author(palahniuk) :- book(fight_club).
author(palahniuk_chuck) :- book(fight_club).
author(tolkien_jrr) :- book(the_hobbit).
author_sur(palahniuk) :- book(fight_club).
author_sur(golding) :- book(lord_of_the_flies).
author_sur(huxley) :- book(brave_new_world).
author_sur(grahame) :-book(wind_in_the_willows).
author_sur(tolkien) :-book(the_hobbit).
author_fore(aldus) :- book(brave_new_world).
author_fore(william) :- book(lord_of_the_flies).
author_fore(chuck) :- book(fight_club).
author_fore(kenneth) :- book(wind_in_the_willows).
author_fore(jrr) :-book(the_hobbit).

However when querying the KB with say ?- cat_num(222), book(X). it does not return the result I want (lord_of_the_flies). Any guidance in where I'm going wrong would be greatly appreciated.

After doing the changes suggested, I have reached another hurdle: how do I set a rule to determine whether a book is borrowed or overdue? (code follows)

number_book(111, brave_new_world).
number_book(222, lord_of_the_flies).
number_book(333, fight_club).
number_book(444, wind_in_the_willows).
number_book(555, the_hobbit).
author_book(huxley_aldus, brave_new_world).
author_book(golding_william, lord_of_the_flies).
author_book(palahniuk_chuck, fight_club).
author_book(grahame_kenneth, wind_in_the_willows).
author_book(tolkien_jrr, the_hobbit).
author_fore_sur(huxley_aldus, aldus, huxley).
author_fore_sur(golding_william, william, golding).
author_fore_sur(palahniuk_chuck, chuck, palahniuk).
author_fore_sur(grahame_kenneth, kenneth, grahame).
author_fore_sur(tolkien_jrr, jrr, tolkien).

id_sur_fore(1202, smith, john).
id_sur_fore(1332, thompson, kevin).
id_sur_fore(4556, anderson, edward).
house_post_id(5, dh1_3pr, 1202).
house_post_id(123, ne3_4ty, 1332).
house_post_id(45, dh3_6kl, 4556).

borrowed_id(333, 1202).
borrowed_id(222, 1332).
borrowed_id(555, 4556).

loan_due_id(11_06_2014, 27_06_2014, 333).
loan_due_id(15_06_2014, 01_07_2014, 222).
loan_due_id(17_06_2014, 13_07_2014, 555).

Solution

  • In your program, you have only predicates with a single argument. That does not make much sense since you want to establish relations between things. Like catalog number and book title. So instead, you want:

    number_book(111, brave_new_workd).
    number_book(222, lord_of_the_flies).
    ...
    author_book(golding_william, lord_of_the_flies).
    ...
    author_fore_sur(golding_william, william,golding).
    

    alternatively you might want one single table:

    number_book_author(222, lord_of_the_flies, golding_william).
    

    Now you can ask:

    ?- number_book(222, X).
       X = lord_of_the_flies.
    

    Rules come into play only later, say

    number_book_author(Nr, B, A) :-
       number_book(Nr, B),
       author_book(A, B).