Reputation: 329
I haven't programmed in Prolog for years and am struggling with a simple block of test code (I'm trying to solve a logic puzzle for fun...):
aboard(jack, blackbird).
aboard(jim, blackbird).
aboard(donna, blackbird).
aboard(david, north_star).
aboard(sandy, north_star).
shipmates(A, B) :- A \= B, aboard(A, X), aboard(B, X).
shipmates1(A, A) :- !, fail.
shipmates1(A, B) :- aboard(A, X), aboard(B, X).
The shipmates
and shipmates1
rules are two different attempts to accomplish the following: I want to pair all passengers who are on the same ship but are not equivalent to each other.
For example, I want shipmates(jack, jack).
to be false
.
When I query this with fully-qualified arguments, I get the expected answers:
3 ?- shipmates(jack, david).
false.
4 ?- shipmates(jack, jack).
false.
5 ?- shipmates(jack, jim).
true.
However, when I want all of Donna's shipmates, it doesn't seem to work:
6 ?- shipmates(donna, X).
false.
I was expecting:
X = jack ;
X = jim ;
NOTE: I get the same wrong results with shipmates1
.
So please take pity on a very amateur Prolog programmer (who is not doing homework for a class!) What very obvious thing am I doing wrong?
Version: SWI-Prolog (threaded, 64 bits, version 8.0.2)
Upvotes: 1
Views: 205
Reputation: 18683
Try:
shipmates(A, B) :-
aboard(A, X),
aboard(B, X),
A \= B.
By calling the aboard/2
predicate before the A \= B
goal, you ensure that both A
and B
will be instantiated, thus making the comparison meaningful.
Upvotes: 1