Consider
?- 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]].
I'd like to get the latter result, but using member
is a tidier way of expressing "all the contents".
I've tried adding some logging to debug, but I can't make heads or tails of it.
?- 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].
And yet more convoluted logging and modification:
?- 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].
This last, in particular, leads me to suspect that any variable in the generator (the first term of foreach
) is effectively deep-copied at the time foreach
is called, and the copy is reset on each loop. It'll keep structures that are already bound, but unifying any of them inside the foreach
just unifies the copy, not the original. Is that a correct inference? Is there any other info I should know about how foreach
operates? The documentation is pretty slim.
(I did figure out a way to do what I originally wanted, I think:
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))).
It's just a bit clunky. Perhaps the specificity is good, though.)
Using SWI-Prolog version 8.0.3 for x64-win64.