Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent unification of variables within list

Tags:

prolog

I am trying to write a predicate that returns 1 if a variable X and a predicate f(X) are both elements of an input list L, and 0 if at least one of them is missing.

This is what the predicate is supposed to do:

?- f_in_list([X, f(X)], Val).
  should return Val = 1

?- f_in_list([X, f(Y), Z], Val).
  should return Val = 0, as X and Y are different variables.

I have written this simple code:

f_in_list(L, 1) :-
    member(X, L),
    member(f(X), L),
    !.
f_in_list(_, 0).

My problem is that Prolog is always trying to unify the input variables, so it returns X = f(X) and X = f(Y), respectively.
I tried to use dif(X, f(X)) in order to circumvent this issue, but even that did not work. Val will always be 1 if the list contains at least two elements.

Is there a way to convert the variables to atoms or strings, so Prolog cannot unify the variables? Or even better, is there a way to prevent the unification of variables with the same name?

like image 436
Taut Avatar asked Oct 17 '22 23:10

Taut


1 Answers

As referred by @lurker you should consider using ==/2 since it succeeds only if the two terms are already identical without further unification.

Her is my implementation:

f_in_list(L, 1) :-
    member(X, L),
    member(f(Y), L),
    X == Y ,!.

f_in_list(_, 0).

Example:

?- f_in_list([X, f(X)], Val).
Val = 1.

?- f_in_list([X, f(Y), Z], Val).
Val = 0.
like image 180
coder Avatar answered Oct 21 '22 03:10

coder