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错误的。
难道A
、B
、C
在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.
我是 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错误的。
难道A
、B
、C
在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.