foldnum
is a macro included in my pack package pac about ten years ago. I have fixed a bug of foldnum
macro expansion related to global variable.
foldnum
is a version of foldl
for integer interval in stead of lists. I tried to find in SWIPL builtin library, but failed. Fortunately it is an easy routine for pac library to define such macros as the source is listed below. foldnum
is handy so far, but it must have a bug for general use. If foldnum is useful and new for Prolog, I hope SWI-Prolog officially includes complete vesion as the foldl
macro for lists.
Sample Use of foldnum.
% ?- foldnum(plus, 1-10, 0, X).
%@ X = 55.
% ?- foldnum(pred([X,Y,Z]:- Z is X*Y), 1-4, 1, R).
%@ R = 24.
% ?- F = plus, foldnum(F, 1-100, 0, R).
%@ F = plus,
%@ R = 5050.
% ?- N=100, functor(A, #, N),
% forall(between(1, N, I), nb_setarg(I, A, I)),
% foldnum(pred(A, ([J, C, D]:- arg(J, A, Aj), D is C * Aj) ),
% 1 - N, 1, S).
%@ N = 100,
%@ A = #(..),
%@ S = 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000.
Definition of foldnum macro
Details is omitted here.
etc(foldnum, [F|As], _, meta:G, P, P):- var(F), !,
complete_args(foldnum, [F|As], G).
etc(foldnum, [F, I-J|As], M, G, P, Q):-
expand_arg(F, M, F0, P, P0),
term_variables([I, J, F0], Vs),
expand_core(
rec(R, Vs,
([A, U, U]:- A>J, !)
&
([A, U, V]:- call(F, A, U, U0),
A0 is A + 1,
call(R, A0, U0, V))),
M, G0, P0, Q),
complete_args(G0, [I|As], G).
Expanded codes of a foldnum use.
% ?- show(foldnum(plus, 1-10, 0, X)).
%@ pac:pac#68(1,0,_), where
%@ pac:pac#68(A,B,B):-pac:(A>10),!
%@ pac:pac#68(A,B,C):-pac:plus(A,B,D),pac:(E is A+1),pac:pac#68(E,D,C)
%@ X = _.