I recently started learning Prolog
and have come across an issue.
The following has been loaded into Prolog
:
likes(john, apple).
likes(john, pear).
likes(john, grapes).
likes(bill, mango).
likes(bill, apple).
I am writing a predicate all_like(What, List)
that should return True
if all the people in List
like the fruit in What
.
Eg:
all_like(apple,[john, bill]).
should return:
true ;
false.
all_like(grapes,[john, bill]).
should return:
false.
I have the following code:
all_like(What,List) :- check_list(What,List).
check_list(What,[]) :- write('true').
check_list(What, [X|Rest]) :- likes(X,What), check_list(What,Rest).
check_list(What, [X|Rest]) :- \+ likes(X,What), write('false').
My results are:
1st Query
true
true .
2nd Query
false
true .
Would anyone know why I'm getting these results?
What is the significance of the second boolean value being outputted?
Finally, is the .
appearing after a space of significance?
Thank you for your help.
Prolog already indicates whether a predicate succeeds (true
or yes
) or fails (false
or no
), so you're doing too much work in your predicate when you (a) explicitly write out "true" on success, and (b) you try to succeed on a failure case and write out failure. It's best to let the failing case just fail, then Prolog will show the failure.
As an aside, your check_list
predicate is superfluous and you can just use all_likes
. So this is really all you need:
all_likes(_, []). % An empty list likes anything
all_likes(What, [X|Rest]) :- % All of [X|Rest] likes What if...
likes(X, What), % X likes What and...
all_likes(What, Rest). % All of Rest likes What
In SWI Prolog, you'll see these results:
?- all_likes(apple,[john, bill]).
true ;
false.
?- all_likes(grapes,[john, bill]).
false.
In GNU Prolog, the output looks like this:
| ?- all_likes(apple,[john, bill]).
true ? ;
no
| ?- all_likes(grapes,[john, bill]).
no
| ?-