1

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.

false
  • 10,264
  • 13
  • 101
  • 209

1 Answers1

3

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
| ?-
lurker
  • 56,987
  • 9
  • 69
  • 103
  • Thanks lurker, that makes a lot more sense. May I ask why `false` is displayed after `true ;` in the first example? –  Mar 19 '16 at 13:20
  • 2
    @Giri "false" is display after "true" because Prolog had a choice point to go back to and check for more solutions, but didn't find additional answers. So SWI Prolog outputs "false". You can see in the GNU Prolog case, you get "no" rather than "false", and it means the same thing: no more solutions. – lurker Mar 19 '16 at 13:30