Reputation: 1
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
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
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