我是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循环之后不应该A
,B
和C
等于1吗?
答案 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.