Prolog 为列表的元素赋值

Prolog assigning values to elements of a list

我是 Prolog 的新手,我正在处理的问题如下:给定一个变量列表,我想为该列表的每个元素分配一个值,然后检查是否包含其中一些的限制变量为真。这是我认为它应该如何工作的示例:

predicate(L1, Restriction) :-
    foreach(member(Var,L1), Var = 1),
    Restriction.

但是当我在控制台写的时候:

? - predicate([A,B,C], A==1).

? - predicate([A,B,C], B==1).

? - predicate([A,B,C], A==B).

他们都是return错误的。

难道ABC在foreach循环后都等于1吗?

问题在于 foreach/2 谓词的工作方式。第一个参数用作 generator,第二个参数用作生成器每个解的 test。但是谓词创建了一个 conjunction,其中每个元素都是第二个参数的 copy。由于这种复制,生成器中的变量永远不会被实例化(因为您正在实例化副本)。这种语义可以通过以下查询来说明:

?- foreach(member(Var, [A,B,C]), Var = 1), var(A), var(B), var(C).
true.

由于您的限制是 predicate/2 调用是 相等性 测试并且变量不等于整数,因此所有调用都会失败。

如果您打算创建一个给定长度的列表,其中所有元素都等于给定项,有多种方法可以实现。例如,仅使用标准内置谓词:

?- findall(1, between(1, 3, _), List).
List = [1, 1, 1].

Paulo 很好地解释了问题所在 (+1)。也许你应该更正你的代码

predicate(L1, Restriction) :-
    maplist(=(1), L1),
    Restriction.

产生预期的输出

?- predicate([A,B,C], A==1).
A = B, B = C, C = 1.