1:- module(meta,
    2	  [foldr/4, iterate/3,
    3	   for/3, foldnum/4,
    4	   fold/3, fold/4, fold/5,
    5	   do/3,
    6	   fold_args/4, fold_args/5,
    7	   mapterm_rec/3,
    8	   maplist_opp/3,
    9	   repeat/2, monad/3, time/3,
   10	   until/4, while/4,
   11	  iff/2, cputime/1, cputime/0,
   12	  pred_eval/2, pred_eval/3
   13	  ]
   14	 ).   15
   16:- use_module(pac(basic)).   17:- use_module(pac(op)).
 do(+F, +A, -B) is det
Similar to meta predicate phrase/2,3, but works not only for list processing. F must not contain ! (cut), mainly simplicity for interpretation.
   24:- meta_predicate do(:, ?, ?).   25
   26% ?- do((append([a,b]), append([c,d])), [x,y], R).
   27
   28do(M:X, A, B):- once(do(X, A, B, M)).
   29%
   30do(M:X, A, B, _)	:-!, do(X, A, B, M).
   31do((X,Y), A, B, M)	:-!, do(X, A, C, M), do(Y, C, B, M).
   32do((X;Y), A, B, M)	:-!, ( do(X, A, B, M);  do(Y, A, B, M)).
   33do((X->Y), A, B, M)	:-!, ( do(X, A, C, M) ->  do(Y, C, B, M)).
   34do({G}, A, A, M)	:-!, call(M:G).
   35do(X, A, B, M)		:- call(M:X, A, B).
   36
   37% Experimental [2023/10/30]
   38% ?-  maplist(=([_,_]), [[a,b],[a,c]]).			% false
   39% ?-  maplist(local(=([_,_])), [[a,b],[a,c]]).	% true
   40% ?-  maplist(pred([[_,_]]), [[a,b],[a,c]]).	% true
   41% ?-  maplist(local(pred([[_,_]])), [[a,b],[a,c]]).	% true
   42% ?-  maplist(local(local(pred([[_,_]])), [[a,b],[a,c]])).	% true
   43user:local(X):- copy_term(X, Y), call(Y).
   44user:local(X,A):- copy_term(X, Y), call(Y,A).
   45user:local(X,A,B):- copy_term(X, Y), call(Y,A,B).
   46user:local(X,A,B,C):- copy_term(X, Y), call(Y,A,B,C).
   47user:local(X,A,B,C,D):- copy_term(X, Y), call(Y,A,B,C,D).
   48user:local(X,A,B,C,D,E):- copy_term(X, Y), call(Y,A,B,C,D,E).
   49
   50% if-and-only-if condition test.
   51% ?- meta:iff(true, member(X, [1,2])).
   52iff(C0, C1) :- \+( (C0,\+C1) ; (C1, \+C0)).
   53
   54% ?- flip_call([2,1], 1+2 is X).
   55% ?- flip_call([1,2], 1+2 is X, A is B).
   56% ?- flip_call([1, 3, 2], between(4, X, 6)).
   57% ?- flip_call(1+2 is X).
   58% ?- flip_call([3,2,1], append(A, [1,2], [3,4])).
   59
   60:- meta_predicate user:flip_arg(2, ?, ?).   61user:flip_arg(F, X, Y):- call(F, Y, X).
   62
   63% ?- listing(flip).
   64user:flip_call(G) :- flip_call([2,1], G).  % Binary is default.
   65%
   66user:flip_call(Is, G):- flip_call(Is, G, G0), call(G0).
   67
   68%
   69flip_call(Is, M:X, M:Y):-!, flip_call(Is, X, Y).
   70flip_call(Is, X, Y):- length(Is, N),
   71	functor(X, F, N),
   72	functor(Y, F, N),
   73	flip_call(Is, 1, X, Y).
   74
   75%
   76flip_call([], _, _, _).
   77flip_call([I|Is], J, X, Y):-
   78	arg(J, X, A),
   79	arg(I, Y, A),
   80	!,
   81	J0 is J + 1,
   82	flip_call(Is, J0, X, Y).
   83
   84:- meta_predicate foldr(3, ?, ?, ?).   85foldr(_, [], X, X):-!.
   86foldr(F, [A|L], X, Y):- call(F, A, Y, Y0), foldr(F, L, X, Y0).
   87
   88% ?- foldl(cons, [a,b,c,d], [], R).
   89% ?- foldl(pred([X, Y, [X|Y]]), [1,2,3,4], [], R).
   90% ?- foldr(pred([X, [X|Y], Y]), [1,2,3,4], R, []).
   91% ?- foldr(flip([1,3,2], pred([X, [X|Y], Y])), [1,2,3,4], [], R).
   92% ?- foldl(flip([1,3,2], pred([X, Y, [X|Y]])), [1,2,3,4], R, []).
   93% ?- foldr(pred([X, Y, [X|Y]]), [1,2,3,4], [], R).
   94% ?- fold_paths_of_term(pred([A,[A|B], B]), f(1,2), X, []).
   95fold_paths_of_term(G, T, X, Y):- fold_paths_of_term([[T]], [], X, Y, G).
   96%
   97fold_paths_of_term([], _, X, X, _):-!.
   98fold_paths_of_term([Ts|L], P, X, Y, G):-
   99	(	Ts==[]
  100	->	fold_paths_of_term(L, P, X, Y, G)
  101	;	Ts=[T|Rs],
  102		fold_paths_of_term(T, [Rs|L], P,  X, Y, G)
  103	).
  104%
  105fold_paths_of_term(T, Ls, P, X, Y, G):- atomic(T), !,
  106	call(G, [T|P], X, Xtp),
  107	fold_paths_of_term(Ls, P, Xtp, Y, G).
  108fold_paths_of_term(T, Ls, P, X, Y, G):- T=..[F,A|As],
  109	fold_paths_of_term(A, [As|Ls], [F|P], X, Y, G).
  110
  111:- meta_predicate fold_args(?, 3, ?, ?).  112:- meta_predicate fold_args(?, 3, ?, ?, ?).  113% ?- fold_args(plus, f(1,2,3,4), 0, S).
  114% ?- fold_args(pred([X, Y, Z]:- Z is X + Y), f(1,2,3,4), 0, S).
  115% ?- fold_args(append, f([],[1],[2]), [], R).
  116% ?- fold_args(pred([X, [X|Y], Y]), f(1,2,3), R, []).
  117
  118fold_args(F, V, A, B):-
  119	fold_args(1, F, V, A, B).
  120%
  121fold_args(I, F, V, A, B):-	arg(I, V, Vi), !,
  122	call(F, Vi, A, Ai),
  123	I1 is I+1,
  124	fold_args(I1, F, V, Ai, B).
  125fold_args(_I, _F, _V, A, A).
  126
  127
  128% ?- mapargs(pred([A, [A, A]]), (a,b), Out).
  129% ?- mapterm(pred([A, [A, A]]), (a,b), Out).
  130% ?- mapsubterms(pred([A, [A, A]]), (a,b), Out).
  131% ?- mapsubterms(pred([A, [A, A]]), f(h(a),g(b)), Out).
  132%@ Out = [f(h(a), g(b)), f(h(a), g(b))].
  133
  134
  135% mapterm(F, A, B):-
  136% 	functor(A, Fa, Na),
  137% 	functor(B, Fa, Na),
  138% 	mapterm(1, F, A, B).
  139% %
  140% mapterm(I, F, A, B):- arg(I, A, Ai), !,
  141% 	call(F, Ai, Bi),
  142% 	arg(I, B, Bi),
  143% 	J is I+1,
  144% 	mapterm(J, F, A, B).
  145% mapterm(_, _, _, _).
  146
  147
  148% ?- callargs(write, (a,b)).
  149callargs(F, A):- callargs(1, F, A).
  150%
  151
  152callargs(I, F, A):- arg(I, A, Ai), !,
  153	call(F, Ai),
  154	J is I+1,
  155	callargs(J, F, A).
  156callargs(_, _, _).
  157
  158
  159% ?- Y = f(1, 2), trace, nopac((meta:mapargs(=, count(2, 1, 1), f(a,b), Y))).
  160%@    Call: (11) meta:mapargs(=, count(2, 1, 1), f(a, b), f(1, 2)) ? no debug
  161%@ Y = f(a, b).
  162
  163% ?- Y = f(1, 2), meta:mapargs(=, count(1, 2, 2), f(a,b), Y).
  164% ?- Y = g(1, 2), mapargs(=, count(1, 1, 2), f(a,b), Y).
  165% mapargs(F, count(N, I, J), A, B):- mapargs(N, I, J, F, A, B).
  166% %
  167% mapargs(0, _, _, _, _, _):-!.
  168% mapargs(N, I, J, F, A, B):- arg(I, A, Ai),
  169% 	call(F, Ai, Bj),
  170% 	setarg(J, B, Bj),
  171% 	N1 is N-1,
  172% 	I1 is I+1,
  173% 	J1 is J+1,
  174% 	mapargs(N1, I1, J1, F, A, B).
  175
  176% ?- help(mapterm).
  177
  178
  179% ?- meta:scanargs(pred([I, X, I-X]), f(a,b), Z).
  180scanargs(F, A, B):- ( var(A)
  181					->	functor(B, C, N),
  182						functor(A, C, N)
  183					;	functor(A, C, N),
  184						functor(B, C, N)
  185					),
  186	scanargs(1, N, F, A, B).
  187%
  188scanargs(I, N, _, _, _):- I > N, !.
  189scanargs(I, N, F, A, B):- arg(I, A, Ai),
  190	arg(I, B, Bi),
  191	call(F, I, Ai, Bi),
  192	J is I +1,
  193	scanargs(J, N, F, A, B).
  194
  195% ?- meta:scanargs(pred([I, I]), f(A, B)).
  196scanargs(F, A):- functor(A, _,  N),
  197	scanargs_(1, N, F, A).
  198%
  199scanargs_(I, N, _, _):- I > N, !.
  200scanargs_(I, N, F, A):- arg(I, A, Ai),
  201	call(F, I, Ai),
  202	J is I + 1,
  203	scanargs_(J, N, F, A).
  204
  205
  206% ?- Z = g(x,y), meta:setargs(pred([I, J, I-J]), f(a,b), Z).
  207setargs(F, A, B):-  functor(A, C, N),
  208		( var(B)
  209		->	functor(B, C, N)
  210		;	true
  211		),
  212		setargs(1, N, F, A, B).
  213%
  214setargs(I, N, _, _, _):- I > N, !.
  215setargs(I, N, F, A, B):- arg(I, A, Ai),
  216	call(F, I, Ai, Bi),
  217	setarg(I, B, Bi),
  218	J is I + 1,
  219	setargs(J, N, F, A, B).
  220
  221% ?- A = f(a,b), meta:setargs(pred([I, X, I-X]), A).
  222setargs(F, A):- functor(A, _,  N),
  223	setargs_(1, N, F, A).
  224%
  225setargs_(I, N, _, _):- I > N, !.
  226setargs_(I, N, F, A):- arg(I, A, Ai),
  227	call(F, I, Ai, Bi),
  228	setarg(I, A, Bi),
  229	J is I + 1,
  230	setargs_(J, N, F, A).
  231
  232% ?-  maprows(zdd:inner_prod(f(1,2)), m(f(1,2), f(3,4)), B).
  233%@ B = f(7, 10).
  234% ?-  maprows(zdd:inner_prod(f(1,2)), m(f(1,2,3), f(3,4,5)), B).
  235%@ B = f(7, 10, 13).
  236maprows(_, A, A):- atom(A), !.
  237maprows(F, A, B):- arg(1, A, A1),
  238	functor(A1, Fa, Na),
  239	functor(B, Fa, Na),
  240	maprows(Na, F, A, B).
  241%
  242maprows(0, _, _, _):-!.
  243maprows(I, F, A, B):- arg(I, B, Bi),
  244	call(F, I, A, Bi),
  245	J is I - 1,
  246	maprows(J, F, A, B).
  247
  248%
  249until(F, S, X, Y):- call(S, X, X0),
  250	(	call(F, X0) -> Y = X0
  251	;   until(F, S, X0, Y)
  252	).
  253%
  254iterate(_, stop(X), X):-!.
  255iterate(S, X, Y):-	call(S, X, X0),
  256	iterate(S, X0, Y).
  257
  258while(F, S, X, Y):-
  259	(	call(F, X) ->
  260		call(S, X, X0),
  261		while(F, S, X0, Y)
  262	;   Y = X
  263	).
  264
  265%	process(+Delta/2, +Final/1, ?S:state, ?S0:state) is semidet.
  266%	Starting with initial state S, repeat applying Delta
  267%	to the successive states until the state
  268%	satisfies the condition Final/1, with which S0 is unified.
  269
  270% :- meta_predicate process(1, 2, +, -).
  271% process(Final, _, S, S):- call(Final, S).
  272% process(Final, Delta, S, S0):-
  273% 		call(Delta, S, S1),
  274% 		process(Final, Delta, S1, S0).
  275
  276:- meta_predicate for(?, 1).  277for(I..J, F):-!, for(I, J, F).
  278for(I-J, F):-for(I, J, F).
  279
  280%
  281for(I, J, _):- I>J, !.
  282for(I, J, F):- call(F, I), !,
  283		I0 is I + 1,
  284		for(I0, J, F).
  285
  286% ?- F = plus, meta:foldnum(F, 1-2, 0, R).
  287% ?- foldnum(pred([X,Y,Z]:-plus(X, Y, Z)), 1-2, 0, R).
  288% ?- foldnum(plus, 1-2, 0, R).
  289% ?- let(X, pred([I,[I|U], U])), foldnum(X, 1-10, R, []).
  290
  291:- meta_predicate foldnum(3, ?, ?, ?).  292foldnum(F, I-J, U, V):-!, foldnum(I, J, U, V, F).
  293foldnum(F, I..J, U, V):- foldnum(I, J, U, V, F).
  294%
  295foldnum(I, J, U, U, _):- I>J, !.
  296foldnum(I, J, U, V, F):- call(F, I, U, U0),
  297	K is I + 1,
  298	foldnum(K, J, U0, V, F).
  299
  300% REMARK. ":- meta_predicate maplist_opp(:, ?, ?)" NOT work.
  301maplist_opp([F|Fs], X, [FX|Y]):- call(F, X, FX), !,
  302	maplist_opp(Fs, X, Y).
  303maplist_opp([], _, []).
  304
  305%
  306:- meta_predicate map(2, ?, ?).  307map(P) --> maplist(phrase(P)).
  308%
  309:- meta_predicate phrase_list(2, ?, ?).  310phrase_list(P) --> maplist(phrase(P)).
  311
  312% ?- repeat(_, write(.)).
  313% ?- repeat(10, write(.)).
  314% ?- repeat(between(1, 20, I), writeln(I)).
  315:- meta_predicate repeat(?, 0).  316repeat(1, G):-!, call(G).
  317repeat(N, G):- simple_int_exp(N), !,
  318			   N0 is N,
  319			   (between(1, N0, _), call(G), fail; true).
  320repeat(P, G):- (call(P), call(G), fail) ; true.
  321%
  322repeat_cond(N, between(1, N0, _)):- simple_int_exp(N), !,  N0 is N.
  323repeat_cond(X, X).
  324%
  325simple_int_exp(N):- integer(N).
  326simple_int_exp(E):- ground(E),
  327	functor(E, F, _),
  328	memberchk(F, [+,-,^,mod, //]).
  329
  330%%% for statistics
  331% ?- time(repeat(10^8, X is 1 + 2), Time).
  332%@ Time = 9.844715.
  333% ?- N is 10^8, time(repeat(between(1, N,_), X is 1 + 2), Time).
  334%@ N = 100000000,
  335%@ Time = 9.896004999999999.
  336
  337
  338:- meta_predicate time(0, ?).  339time(G, T):-  time(G, T0, T1), T is T1-T0.
  340%
  341time(G, T, T0):-  statistics(cputime, T),
  342	call(G),
  343	statistics(cputime, T0).
  344
  345% ?- apropos(variables).
  346% ?- cputime, A=(X=1), cputime(100, A, T), cputime(Total).
  347% ?- cputime, A=(X=1), cputime(10000000, A, T), cputime(Total).
  348% ?- cputime, cputime(10000000, X=1, T), cputime(Total).
  349% ?- cputime, cputime(10000000, (b_setval(x,1), b_getval(x, Y)), T), cputime(Total).
  350% ?- cputime, cputime(10000000, (X=1, Y=X), T), cputime(Total).
  351% ?- cputime, cputime(1000000, X=1, T), cputime(Total).
  352:- meta_predicate cputime(?, 0, ?).  353%
  354cputime(N, G, T):- writeln("Running pac runtime library cputime/3...  "),
  355				   cputime(N, G, 0.00, T).
  356%
  357cputime(0, _G,  T, T).
  358cputime(N, G, T, T0):-  succ(N0, N),
  359						cputime_for_step(G, S),
  360						T1 is T + S,
  361						cputime(N0, G, T1, T0).
  362%
  363cputime_for_step(G, T):-
  364	statistics(cputime, T0),
  365	call(G),
  366	statistics(cputime, T1),
  367	T is T1-T0.
  368%
  369cputime:- statistics(cputime, T), b_setval(cputime, T).
  370cputime(T):- statistics(cputime, Stop), b_getval(cputime, Start), T is Stop - Start.
  371
  372% ?- cputime(10000000, true, T).
  373% ?- meta:cputime(1000, (A=a, B=A), T).
  374% ?- meta:cputime(1000, (b_setval(a, b), b_getval(a, B)), T).
  375
  376% monad/3
  377:- meta_predicate monad(:, ?, ?).  378monad(G, X, Y):- once(ml:bind_context(G, (X, []), (Y, _))).
  379
  380% ?- trace.
  381% ?- pred_eval(=, f(a, b), V).
  382% ?- pred_eval(append(union([a],[b]), union([c],[d])), R).
  383%@ R = [a, b, c, d].
  384
  385pred_eval(X, Y):- pred_eval(call, X, Y).
  386
  387:- meta_predicate pred_eval(2, ?, ?).  388pred_eval(_, X, X):- ( var(X); number(X); string(X); is_list(X)), !.
  389pred_eval(P, X, V):- atom(X), !, call(P, X, V).
  390pred_eval(P, X, V):- functor(X, F, N),
  391	functor(Y, F, N),
  392	pred_eval_args(1, P, X, Y),
  393	call(P, Y, V).
  394%
  395pred_eval_args(I, P, X, Y):- arg(I, X, A), !,
  396	arg(I, Y, B),
  397	pred_eval(P, A, B),
  398	J is I + 1,
  399	pred_eval_args(J, P, X, Y).
  400pred_eval_args(_, _, _, _).
  401
  402
  403% recursive mapterm.
  404:- meta_predicate mapterm_rec(2, ?, ?).  405
  406% ?- mapterm_rec(=, f(g(a, b), h(c)), X).
  407
  408mapterm_rec(_, A, B):- var(A), !, B = A.
  409mapterm_rec(F, A, B):- atomic(A), !, call(F, A, B).
  410mapterm_rec(F, A, B):- functor(A, Fa, Na),
  411	functor(B, Fa, Na),
  412	mapterm_rec(F, 1, A, B).
  413%
  414mapterm_rec(F, I, A, B):- arg(I, A, Ai), !,
  415	arg(I, B, Bi),
  416	mapterm_rec(F, Ai, Bi),
  417	J is I + 1,
  418	mapterm_rec(F, J, A, B).
  419mapterm_rec(_, _, _, _):-!.
  420
  421% recursive maplist.
  422:- meta_predicate maplist_rec(2, ?, ?).  423maplist_rec(_, [], []):-!.
  424maplist_rec(F, [X|Xs], [Y|Ys]):-
  425	(	X = [_|_]
  426	->  maplist_rec(F, X, Y)
  427	;	call(F, X, Y)
  428	),
  429	maplist_rec(F, Xs, Ys).
  430
  431% ?- fold(M, member(M, [1,2,3]), cons, [], X).
  432%@ X = [3, 2, 1].
  433
  434:- meta_predicate fold(?, :, :, ?, ?).  435fold(V, G, A, X, Y):-	Acc = '$ACC'(X),
  436	(	call(G),
  437		arg(1, Acc, U),
  438		call(A, V, U, W),
  439		nb_setarg(1, Acc, W),
  440		fail
  441	;	arg(1, Acc, Y)
  442	).
  443
  444% ?- Sum = acc(0), fold(J,
  445%	between(1, 3, J), test_add_to_acc, Sum).
  446test_add_to_acc(X, Acc):- arg(1, Acc, V),
  447	V0 is X + V,
  448	nb_setarg(1, Acc, V0).
  449
  450:- meta_predicate fold(?, :, :, ?).  451fold(V, G, Fun, X):-
  452		(	call(G),
  453			call(Fun, V, X),
  454			fail
  455		;	true
  456		).
  457
  458% ?- fold(I, between(1, 3, I), writeln).
  459% ?- fold(I, between(1, 3, I), X^(Y is X*X, writeln(Y))).
  460:- meta_predicate fold(?, :, ?).  461fold(V, G, V^Act):-!,
  462	(	call(G),
  463		call(Act),
  464		fail
  465	;	true
  466	).
  467fold(V, G, A):-
  468	(	call(G),
  469		call(A, V),
  470		fail
  471	;	true
  472	).
  473
  474% ?- N=100, time(repeat(N, det_foreach(between(1,5,J), member(J, L)))).
  475%@ % 7,201 inferences, 0.001 CPU in 0.001 seconds (94% CPU, 8277011 Lips)
  476%@ N = 100.
  477% ?- det_foreach(between(1,5,N),  member(r(N),L)).
  478%@ L = [r(1), r(2), r(3), r(4), r(5)|_].
  479% exists M exists L forall J  (between(1,5, J) -> (member(J, L), member(J, M))).
  480% ?- det_foreach(between(1,5, J), (member(J, L), member(J, M))).
  481%@ L = [1, 2, 3, 4, 5|_],
  482% exists L forall J  (between(1,5, J), between(3, 7, J)  -> member(J, L))
  483% ?- det_foreach((between(1,5, J), between(3, 7, J)), member(J, L)).
  484%@ L = [3, 4, 5|_].
  485% exists L forall J  (between(1,5, J); between(3, 7, J))  -> member(J, L))
  486% ?- foreach((between(1,5, J); between(3, 7, J)), member(J, L)).
  487%@ L = [1, 2, 3, 4, 5, 6, 7|_].
  488% ?- foreach(between(1, 5, J), dif(L, J)), L = 3.
  489% ?- time(repeat(10^5, det_foreach(between(1, 5, J), (member(J, L),
  490%	det_foreach(between(6, 8, K), (member(K, L),
  491%	det_foreach(between(9, 10, M), member(M, L)))))))).
  492%@ % 99,800,001 inferences, 13.491 CPU in 14.710 seconds (92% CPU, 7397365 Lips)
  493%@ true.
  494% ?- time(repeat(10, det_foreach(between(1, 5, J), member(J, L)))).
  495% ?- time(repeat(10, foreach(between(1, 5, J), member(J, L)))). % stack limit.
  496
  497det_foreach(Gen, Con):-	term_variables(Gen, Vs),
  498	sort(Vs, Vs0),
  499	term_variables(Con, Ws),
  500	sort(Ws, Ws0),
  501	ord_subtr_var(Ws0, Vs0, Ws1),
  502	once(foreach_by_copy(Gen, Con, Vs0, Ws1)).
  503%
  504foreach(Gen, Con, Vs, Ws):-	once(foreach_by_copy(Gen, Con, Vs, Ws)).
  505
  506% ?- N=200, K = 5, time((repeat(N, once((foreach_by_copy(between(1,5, J), member(J, L), [J], [L]), writeln(L)))))).
  507foreach_by_copy(A, B, Vs, Ws):-
  508	findall(Vs, A, Sol),
  509	copy_of_goal(Sol, Vs, Ws, B, Cs),
  510	maplist(call, Cs).
  511%
  512copy_of_goal([], _, _, _, []).
  513copy_of_goal([A|As], Vs, Ws, B, [G|Gs]):-
  514	copy_term(Vs+Ws+B, A+Ws+G),
  515	copy_of_goal(As, Vs, Ws, B, Gs).
  516%
  517ord_subtr_var([], _, []):-!.
  518ord_subtr_var(X, [], X):-!.
  519ord_subtr_var([X|Xs], [Y|Ys], Zs):- X==Y, !,
  520	ord_subtr_var(Xs, Ys, Zs).
  521ord_subtr_var([X|Xs], [Y|Ys], [X|Zs]):- X@<Y, !,
  522	ord_subtr_var(Xs, [Y|Ys], Zs).
  523ord_subtr_var(Xs, [_|Ys], Zs):- ord_subtr_var(Xs, Ys, Zs).
  524
  525
  526
  527
  528
  529
  530		/**************************************************************
  531		*     foreach by assert/compile_aux: SLOWer than COPY_TERM    *
  532		**************************************************************/
  533
  534% ?- foreach_by_assert(between(1,2,J), member(J, L), [J], [L]).
  535% foreach_by_assert(Gen, Con, Vs, Ws):-
  536% 	retractall('$CONSUMER'(_,_)),
  537% 	assert(( '$CONSUMER'(Vs, Ws):- Con)),
  538% 	Stash = '$STASH'(Ws),
  539% 	(	call(Gen),
  540% 		arg(1, Stash, U),
  541% 		once('$CONSUMER'(Vs, U)),
  542% 		nb_setarg(1, Stash, U),
  543% 		fail
  544% 	;   arg(1, Stash, Ws)
  545% 	).
  546
  547% foreach_by_assert(Gen, Con, Vs, Ws):-
  548% 	context_module(M),
  549% 	pac:expand_core(pred([Vs, Ws]:- Con), M, G, P, []),
  550% 	maplist(assert, P),
  551% 	Stash = '$STASH'(Ws),
  552% 	(	call(Gen),
  553% 		arg(1, Stash, U),
  554% 		once(call(G, Vs, U)),
  555% 		nb_setarg(1, Stash, U),
  556% 		fail
  557% 	;   arg(1, Stash, Ws)
  558% 	).