Reputation: 18979
I am trying to write an agent for determining what card a player has, and I am struggling to represent that each card can only have been dealt to a single player.
So have I have something^ like this:
player(p1).
player(p2).
card(ace).
card(king).
card(queen).
card(jack).
but I am struggling on writing the rule for uniqueness. Borrowing something from logic class, I though about defining uniqueness as "if X has Y, then if something has Y, that something must be X".
has_card(P, C) :-
player(P),
card(C),
not(player(P2),
P2 =\= P,
has_card(P2, C)
).
but this fails because not/3
is not defined.
I tried rewriting it as:
has_card(P, C) :-
player(P),
card(C),
player(P2),
P2 =\= P,
not(has_card(P2,C)).
but then the query (which I expect to return false
)
has_card(P, ace).
errors out with
ERROR: =\=/2: Arithmetic: `player1/0' is not a function
So, how can I represent uniqueness?
^ complicating --likely-- unnecessary details omitted
EDIT: in first attempt at has_card
I have P2==P
which should have been P2=\=P
, fixed now
Upvotes: 1
Views: 169
Reputation:
First off, as the error is telling you, you are using =\=
, which is arithmetic inequality. For comparing on standard order of terms, you should use \==
.
Then, the "not" as in "true when negated goal not true", you should probably use \+
, like this:
\+ a == b
which is the same as
a \== b
The not/1
predicate is still available in most Prolog implementations but not recommended.
Fixing these two things will sort out the problem you are having at the moment.
But, as it is at the moment, your has_card/2
at no point maps a card to a player, really (it uses circular logic as far as I can see). Since you are not showing how exactly you know which cards belong to which player at any given moment, it is difficult to comment on that. Either way, some sort of term that you pass around would be probably better than changing the database with assert
and retract
.
Upvotes: 2