防止列表中变量的统一

Tau*_*aut 5 prolog

我正在尝试编写一个谓词,如果变量X和谓词f(X)都是输入列表的元素,则返回1,如果L缺少其中一个,则返回0.

这就是谓词应该做的事情:

?- 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.
Run Code Online (Sandbox Code Playgroud)

我写了这个简单的代码:

f_in_list(L, 1) :-
    member(X, L),
    member(f(X), L),
    !.
f_in_list(_, 0).
Run Code Online (Sandbox Code Playgroud)

我的问题是Prolog总是试图统一输入变量,所以它分别返回X = f(X)X = f(Y).
我试图用来dif(X, f(X))绕过这个问题,但即使这样也行不通.Val如果列表包含至少两个元素,则始终为1.

有没有办法将变量转换为原子或字符串,所以Prolog无法统一变量?或者更好的是,有没有办法阻止同名变量的统一?

lur*_*ker 1

这可能是一个很好的用途==/2。该运算符不统一,但它检查其参数是否相同。这是一些==/2行为:

2 ?- X == X
|    .
true.

3 ?- X == Y.
false.

4 ?- X = Y, Z = Y, X == Z, write('yes'), nl.
yes
X = Y, Y = Z.

5 ?- X = Y, Z = W, X == Z.
false.

6 ?-
Run Code Online (Sandbox Code Playgroud)

我们可以用它来创建一个非统一nu_member/2谓词:

nu_member(X, [Y|_]) :- X == Y.
nu_member(X, [_|T]) :- nu_member(X, T).
Run Code Online (Sandbox Code Playgroud)

我们将其用于f_in_list/2

f_in_list(L, 1) :-
    member(X, L),
    nu_member(f(X), L),
    !.
f_in_list(_, 0).
Run Code Online (Sandbox Code Playgroud)

结果是:

2 ?- f_in_list([X,f(X), Z], B).
B = 1.

3 ?- f_in_list([X,f(Y), Z], B).
B = 0.

4 ?- f_in_list([X,f(Y), f(Z)], B).
B = 0.

5 ?- f_in_list([X,f(Y), f(Z),Z], B).
B = 1.
Run Code Online (Sandbox Code Playgroud)