Рассмотрим
?- length(L, 4), foreach(member(M,L),(length(M,4))).
L = [_28602, _28608, _28614, _28620].
против
?- 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))).
Это просто немного неуклюже. Возможно, специфика хорошая,хотя.)
Использование SWI-Prolog версии 8.0.3 для x64-win64.