Reputation: 13
I want to implement a predicate in my cod that finds all the lists that contain a certain element, in my case, that element is a variable, P3 for example. The problem is that using the predicate member doesn't work because it keeps unifying the variable with the elements of the list:
?- member(P3, [P1,P3]). P3 = P1 ; true.
I want it to return True because P3 is a member of the list and not because P1 is. Is there a way for me to check if the variable P3 is a member of a list without unifying it? Thanks.
Upvotes: 1
Views: 108
Reputation: 3765
There is (==)/2
which does what you require.
@Term1 == @Term2
True if Term1 is equivalent to Term2. A variable is only identical to a sharing variable.
?- X == Y.
false.
?- X=a, Y=b, X == Y.
false.
?- X=a, Y=a, X == Y.
X = Y, Y = a.
So you can implement it as
membersame(X, [A|_]) :-
X == A.
membersame(X, [_|Rest]) :-
membersame(X, Rest).
Or you can also use member/2
for implicit iteration over the list and use (==)/2
for restriction (thanks @TA_intern).
membersame(X, Xs) :-
member(Y, Xs), X == Y.
Examples:
?- membersame(X, [A, B, C, X, a, b, c]).
true ;
false.
?- membersame(X, [A, B, C, a, b, c]).
false.
Upvotes: 1
Reputation: 5519
In Prolog, a variable can be unified with a value only once. Consequently, if variable V
can be unified with this
and variable W
can be unified with that
, then those variables are distinct (otherwise, they are the same variable).
samevar(V, W) :- var(V), var(W), not((V=this, W=that)).
Here are some examples:
?- samevar(A,B).
false.
?- samevar(A,A).
true.
Using samevar/2
, we can define the following predicate:
varmember(V, [W|_]) :- samevar(V, W).
varmember(V, [_|T]) :- varmember(V, T).
Here are some examples:
?- varmember(a, [V1, a, V3, V4, V5]).
false.
?- varmember(V2, [V1, V3, V4, V5]).
false.
?- varmember(V2, [V1, V2, V3, V4, V5]).
true ;
false.
?- varmember(V2, [V1, V2, V3, V2, V4, V5]).
true ;
true ;
false.
?- varmember(V2, [V1, V2, V3, V2, V4, V2, V5]).
true ;
true ;
true ;
false.
?- varmember(V2, [this, V2, that, V2, V3, V4, V5]).
true ;
true ;
false.
Upvotes: 0