Prolog为列表元素分配值

时间:2015-05-23 22:44:58

标签: prolog

我是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).

他们都返回假。

在foreach循环之后不应该ABC等于1吗?

2 个答案:

答案 0 :(得分:1)

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

?- 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].

答案 1 :(得分:1)

Paulo很清楚地解释了问题所在(+1)。也许你应该纠正你的代码,如

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

产生预期的输出

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