考虑
?- 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 = ...
The documentation实际上说出您所相信的正在发生的事情: