SWI Prolog foreach / 2

问题描述 投票:1回答:1

考虑

?- length(L, 4), foreach(member(M,L),(length(M,4))).
L = [_28602, _28608, _28614, _28620].

vs

?- length(L, 4), foreach(between(1,4,I),call({L}/[I]>>(nth1(I,L,M),length(M,4)),I)).
L = [[_6010, _6016, _6022, _6028], [_6358, _6364, _6370, _6376], [_6754, _6760, _6766, _6772], [_7198, _7204, _7210, _7216]].

我想得到后一个结果,但是使用member是表达“所有内容”的一种简洁方法。

我尝试添加一些日志记录来进行调试,但无法对此进行正面或反面。

?- length(L, 4), foreach((member(M,L),write(M),writeln(L)),(length(M,4))).
_3400[_3400,_4060,_4066,_4072]
_3400[_4054,_3400,_4066,_4072]
_3400[_4054,_4060,_3400,_4072]
_3400[_4054,_4060,_4066,_3400]
L = [_4054, _4060, _4066, _4072].

还有更多复杂的日志记录和修改:

?- length(L, 3), foreach((member(M,L),write((m,M," ")),write((l,L," ")),length(M,3),write((m,M," ")),writeln((l,L))),(true)).
m,_60830, l,[_60830,_61872,_61878], m,[_61944,_61950,_61956], l,[[_61944,_61950,_61956],_61872,_61878]
m,_60830, l,[_61866,_60830,_61878], m,[_61944,_61950,_61956], l,[_61866,[_61944,_61950,_61956],_61878]
m,_60830, l,[_61866,_61872,_60830], m,[_61944,_61950,_61956], l,[_61866,_61872,[_61944,_61950,_61956]]
L = [_61866, _61872, _61878].

特别是最后一点,使我怀疑在调用foreach时,生成器中的任何变量(foreach的第一项)都有效地被深复制,并且在每个循环上都将副本重置。它将保留已经绑定的结构,但是将它们中的任何一个统一在foreach内只是统一副本,而不是原始副本。这是正确的推论吗?关于foreach的运作方式,我是否应该了解其他信息?该文档非常苗条。

((我确实想出一种方法来做我本来想要的,]:>

loop(Gen, Cond) :-
    aggregate(bag(X),call(Gen,X),L),maplist(Cond,L).

?- length(L,4),loop({L}/[X]>>(member(X,L)),[X]>>(length(X,4))).

这有点笨拙。不过,也许特异性很好。)

为x64-win64使用SWI-Prolog版本8.0.3。

考虑?-length(L,4),foreach(成员(M,L),(length(M,4)))。 L = [_28602,_28608,_28614,_28620]。 vs?-length(L,4),foreach(介于(1,4,I),call({L} / [I] >>(nth1(I,L,M),length(M,4)),一世))。 L = ...

loops prolog swi-prolog
1个回答
0
投票

The documentation实际上说出您所相信的正在发生的事情:

© www.soinside.com 2019 - 2024. All rights reserved.