Rhys Duncan
Rhys Duncan

Reputation: 1

Prolog returning "true" instead of "yes"

My Prolog code is required to return yes (or no) after the query is inputted, but is instead returning "true ?" and requiring me to press enter to get the "yes".

The problem is about Russian dolls, the order of dolls from outer to inner is katrina->olga->natasha->irina. DirectlyIn(X,Y) is true if X is directly inside Y, and contains should be true if X contains Y.

directlyIn('irina', 'natasha').
directlyIn('natasha', 'olga').
directlyIn('olga', 'katrina').

///

contains(X, Y) :- directlyIn(Y, X).
contains(X, Y) :- directlyIn(Z, X), contains(Z, Y).

From the query ?- contains(katrina, irina). I expected the output to just be "yes", but instead it outputs "true ?" until I press enter, and then it outputs "yes".

Upvotes: 0

Views: 1375

Answers (2)

RobertBaron
RobertBaron

Reputation: 2854

If you are required to output yes or no, then you can generate the answer as follows. The cut! is used to forbid the answer no, whenever yes has been output.

directlyIn(irina, natasha).
directlyIn(natasha, olga).
directlyIn(olga, katrina).

contains(X, Y, yes) :- directlyIn(Y, X).
contains(X, Y, yes) :- directlyIn(Z, X), contains(Z, Y, yes), !.
contains(_, _, no).

Querying for contains(katrina, irina, Answer). yields:

Answer = yes

Querying for contains(irina, katrina, Answer). yields:

Answer = no

Upvotes: 0

Paweł
Paweł

Reputation: 138

This is due to the fact that you program is backtracking. Notice that each time Prolog interpreter is required to prove the predicate contains/2 it can choose between either the first or the second rule as both produce a match and it notes that fact, which can be used later if the user wishes to produce another proof. When it reaches a leaf in the proof tree it outputs this (by printing true in your case and awaits your input if it should continue the search for the proof. If you press Enter it starts that search and backtracks, but it cannot find any further proof, which results in false being output to the screen. You can force Prolog to forget the branching points by introducing a cut in the proof tree:

directlyIn('irina', 'natasha').
directlyIn('natasha', 'olga').
directlyIn('olga', 'katrina').

contains(X, Y) :- directlyIn(Z, X), contains(Z, Y), !.
contains(X, Y) :- directlyIn(Y, X).

This forces Prolog interpreter to 'forget' the fact that it had other alternatives to choose from while proving the body of the first rule.

Upvotes: 1

Related Questions