Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Is there a non-unifying alternative to member/2 in SWI-Prolog?

In prolog, the difference between A = B and A == B is that = tries to unify A with B, while == will only succeed if A and B are already unified.

member/2 does seem to perform unification.

Example session:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

?- A = B.
A = B.

?- A == B.
false.

?- member(A, [B]).
A = B.

I have been looking but I can’t find a non-unifying alternative to member/2, but not found anything. Is there something built in or do I have to invent my own thing? As I’m rather new to Prolog I don’t trust myself with writing a performant version of this.

EDIT:

I came up with the following, though I don’t know if the cut is correct. Without it, it seems to deliver two answers for that branch of the code (true, followed by false) though. I’d also still like to know if there is a standard library function for this.

member_eq(_, []) :-
    false.
member_eq(X, [H|_]) :-
    X == H,
    !.
member_eq(X, [_|T]) :-
    member_eq(X, T).

>Solution :

You may slightly modify builtin predicate member/2 to use ==/2 instead of unification:

member_not_bind(X, [H|T]) :-
    member_not_bind_(T, X, H).

member_not_bind_(_, X, Y):- X==Y.
member_not_bind_([H|T], X, _) :-
    member_not_bind_(T, X, H).

Sample run:

?- L=[a,b,c(E)], member_not_bind(A, L).
false.

?- A=c(E),L=[a,b,c(E)], member_not_bind(A, L).
A = c(E),
L = [a, b, c(E)].

I leave this here as it solves a related question (checking if X may unify with any item in L without actually performing the bindings)

You can use double negation like this:

member_not_bind(X, L):- \+(\+(member(X, L))).

Sample runs:

?- A=c(e),L=[a,b,c(E)], member_not_bind(A, L).
A = c(e),
L = [a, b, c(E)].

?- A=d(E),L=[a,b,c(E)], member_not_bind(A, L).
false.
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading