1:- module(basic, [
    2	iterated_deepening/4,
    3	completing_options/3,
    4	kleene_star/3, kleene_star_greedy/3, kleene_plus_greedy/3,
    5	kleene_string_codes/3,
    6	term_codes/2, term_codes/3,
    7	concat/2, flatten/3,
    8	pipe_create/2, pipe_create/3, pipe_to_obj/2, obj_to_pipe/2,
    9	assocq/3, memq/2, clear/2,
   10	clear/3, collect/3, current/3, env/3,
   11    herbrand/2, herbrand/3, herbrand/4, herbrand0/2,
   12	herbrand_in_context/3,
   13	id/2, if/2, if/3,
   14	listcast/2, listsubst/3,
   15	prepend/3,
   16	ordered_pair/3,
   17	paragraph/2,
   18	listp/1,
   19	peek/3, peek/4,
   20	remove/3, remove_last/3,
   21	smash/1, smash/2, smash_codes/2,
   22	fst/2, fst/3, snd/2, snd/3, split/2, split/3,
   23	split/4, split/6, split_rest/6, stack_init/0,
   24	split_by_string/3,
   25	scan_prefix/4, scan_prefix/5,
   26	remove_comment/2, remove_comment/3,
   27	stack_pop/2, stack_push/1, stack_push/2,
   28	stack_top/1, stack_top/2, stack_update/1,
   29	residue/3,
   30	stack_update/2,
   31	union/2, flatten_dl/3,
   32	herbrand_opp/2, herbrand_opp/3, variant/4, cons/3
   33	]).   34
   35:- include(op).
 iterated_deepening(G:pred, +D:int, +N:int, -R) is nondet
Iterate at most N times call_with_depth_limit(G, D, R), incrementing D to twice larger for each iteration step.
   41% ?- iterated_deepening(append([a,b,c,d,e,f],[g,h], X), 10, 2, R).
   42%@ X = [a, b, c, d, e, f, g, h],
   43%@ R = 7.
   44:- meta_predicate iterated_deepening(0, ?, ?, ?).   45iterated_deepening(_,  _, 0, depth_limit_reached):-!.
   46iterated_deepening(G,  D, N, S):-  succ(N0, N),
   47	call_with_depth_limit(G, D, R),
   48	(  R == depth_limit_exceeded
   49	->	D1 is D + D,
   50		iterated_deepening(G, D1, N0, S)
   51	;	R = S
   52	).
 completing_options(+X:list, +Y:list, -Z:list) is det
Update options list Y with X to Z.
   57% ?- completing_options([i(2)], [], X).
   58% ?- completing_options([i(2), j(1)], [i(1), j(A)], X).
   59completing_options([D|R], X, Y):-
   60	functor(D, F, 1),
   61	functor(D0,F, 1),
   62	(	memberchk(D0, X)
   63	->	completing_options(R, X, Y)
   64	;	completing_options(R, [D|X], Y)
   65	).
   66completing_options([], X, X).
 if(+X, +Y, +Z) is nondet
Meta predicate for conditional senteces.
   71:-meta_predicate if(0, 0, 0).   72
   73if(X, Y, Z)	:-	( call(X)   ->  call(Y); call(Z) ).
   74if(X, Y)	:-	( call(X)   ->  call(Y); true  ).
   75
   76%
   77cast_to_list(X, Y):- var(X) -> Y = [X]
   78	; (X == []; X = [_|_]) -> Y = X
   79	; Y = [X].
   80
   81listp([]):-!.
   82listp([_|_]).
   83
   84% refresh_term(A, X, Y):- copy_term((A,X), (A,Y)).
   85% fs_fresh(fs_alt(_Fs, Gs, M, Cnt), fs_alt(Gs, Gs, M, Cnt)).
   86
   87fst(F) --> main(F).
   88snd(F) --> env(F).
   89main(F, (X, Y), (X0, Y)):- phrase(F, X, X0).
   90env(F, (X, Y), (X, Y0)):- phrase(F, Y, Y0).
   91pipe_init(X, (X, [])).
   94pipe_create(X, (X, [])).
   95%
   96pipe_create(X, Y, (Y, X)).
   97%
   98pipe_to_obj(P, Ob):- var(P), !,
   99	obj_pull([acc(X)], Ob, Ob0),
  100	P = (X, Ob0).
  101%
  102pipe_to_obj((X, Y), [acc(X)|Y]).
  103
  104%
  105obj_to_pipe(X, Y):- pipe_to_obj(Y, X).
  106
  107% helpers
  108unary(F, A, T)	:- T =.. [F, A].
  109unary(F, T)	:- functor(T, F, 1).
  110n_ary(F, As, T)	:- T =.. [F | As].
  111
  112%
  113list_to_comma([], true).
  114list_to_comma([X], X):-!.
  115list_to_comma([X|Y], (X,Z)):- list_to_comma(Y,Z).
  116%
  117binary_term(F, A, B, C):- C =.. [F, A, B].
  118
  119% ?- binary_term(f, [a], R).
  120%@ R = f(a,f(b,c)).
  121binary_term(_, [A], A):-!.
  122binary_term(F, [A|B], C):- binary_term(F, B, C0),
  123	binary_term(F, A, C0, C).
  124
  125% basic predicates
  126% for handling internal prolog variable preventing unexpected unification.
  127% narrowing(X, Y)
  128% ?- narrowing(X, Y).
  129% X = Y.
  130% ?- narrowing(X, (Y)).
  131% X = Y.
  132% ?- narrowing(X, f(Y)).
  133% false.
  134% ?- narrowing(f(a), f(Y)).
  135% Y = a.
  136narrowing(X, Y) :-  subsumes(Y, X).
  137
  138%
  139memq(X, [Y|_]):- X==Y, !.
  140memq(X, [_|Ys]):- memq(X, Ys).
  141
  142%
  143assocq([(A0, B)|_], A, B):- A==A0, !.
  144assocq([_ |Ps], A, B):- assocq(Ps, A, B).
  145
  146% ?- assoc([a = b], a, R).
  147assoc([A0 = B |_], A, B):- A==A0, !.
  148assoc([_ |Ps], A, B):- assoc(Ps, A, B).
  149
  150%
  151unlist([X], X):-!.
  152unlist(X, X).
  153
  154% ?- member(X, Y, [a,b,c], Z).
  155
  156member(X, Y, [X|Xs], [Y|Xs]).
  157member(X, Y, [A|Xs], [A|Ys]):- member(X, Y, Xs, Ys).
  158
  159%%%
  160appear(X, X).
  161appear(X, Y):- Y=..[_|Y0], member(Z, Y0), appear(X, Z).
  162
  163%
  164list([])    --> [].
  165list([X|Y]) --> [X], list(Y).
  166
  167listcast(X,X) :- listp(X),!.
  168listcast(X,[X]).
  169
  170% ?- basic:prepend(a, S, R).
  171%@ S = [a|R].
  172% ?- basic:prepend([a,[b,c]], S, R).
  173%@ S = [a, b, c|R] .
roughly works like flatten(A, B), append(B, Y, X).
  179prepend(A, [A|X], X):- var(A), !.
  180prepend([], X, X).
  181prepend([A|R], X, Y) :- !, prepend(A, X, Z),
  182    prepend(R, Z, Y).
  183prepend(A, [A|X], X).
  184
  185% a la <br>
  186polish_reserved(br, A, [0'\n|A]).
  187
  188%
  189save_bc(X) :- prolog_load_context(module, M),
  190	scan(`.\n`, A, M, X, _), !,
  191	herbrand(_, A, G0),
  192	expand_arg(G0, M, G, P, []),
  193	maplist(assert, P),
  194	nb_setval(saved_bc, G).
  195
  196% ?- expand_arg((split,maplist(pred([A, [A,A]]))),user, G, P, []), maplist(assert, P), phrase(G, [a], R).
  197%@ G = (user:split, user:maplist(user:'pred#3')),
  198%@ P = [ (user:'pred#3'(A, [A, A]):-true)],
  199%@ R = [[[a], [a]]] .
  200
  201
  202		/******************
  203		*     herbrand    *
  204		******************/
  205% ?- herbrand("f(X,a)", S), smash(S).
  206% ?- herbrand(S, f(X,a)), smash(S).
  207% ?- herbrand(V, S, f(X,a)).
  208% ?- herbrand(V, "f(X,a)", T), herbrand(V, S, T).
  209% ?- herbrand(['X'= X], S, f(X,a)).
  210% ?- herbrand(V, `f(A)`, T), term_string(T, S, V).
  211% ?- herbrand([op(10, fx, ***)], V, `***a(X)`, R).
  212% ?- herbrand(V, `***a(X)`, R).
  213
  214% ?- herbrand_in_context(web, `a \\ b`, H).
  215%@ H = \(a, b).
  216
  217herbrand_in_context(M, X, Y):- herbrand(M, _, X, Y).
  218
  219%
  220herbrand(Mod, V_names, X, Y):-
  221	term_codes(Y, X, [variable_names(V_names), module(Mod)]).
  222%
  223herbrand(V_names, X, Y):-
  224	term_codes(Y, X, [variable_names(V_names)]).
  225%
  226herbrand(X, Y) :- herbrand(Eqs, X, Y),  maplist(call, Eqs).
  227%
  228herbrand0(X, Y) :- term_codes(Y, X, []).
  229
  230%
  231herbrand_opp(X, Y)	:- herbrand(Y, X).
  232herbrand_opp(V, X, Y)	:- herbrand(V, Y, X).
  233
  234%
  235save_current_op(op(_, A, Z), op(P0, A0, Z)):- current_op(P0, A0, Z),
  236	op_kind(A, Kind),
  237	op_kind(A0, Kind),
  238	!.
  239save_current_op(op(_, A, Z), op(0, A, Z)).
  240
  241% an operator may be infix, prefix, and postfix.
  242op_kind(xfx,	infix).
  243op_kind(xfy,	infix).
  244op_kind(yfx,	infix).
  245op_kind(fx,	prefix).
  246op_kind(fy,	prefix).
  247op_kind(xf,	postfix).
  248op_kind(yf,	postfix).
  249
  250%
  251term_codes(X, Y, Options):- nonvar(Y), !,
  252	string_codes(S, Y),
  253	term_string(X, S, Options).
  254term_codes(X, Y, Options):- memberchk(variable_names(V), Options), !,
  255	equate(V),
  256	term_string(X, S, Options),
  257	string_codes(S, Y).
  258term_codes(X, Y, Options):-
  259	term_string(X, S, Options),
  260	string_codes(S, Y).
  261
  262%
  263term_codes(X, Y):- term_codes(X, Y, []).
  264
  265%
  266equate( []) :- !.
  267equate([X = X| R]) :- equate(R).
  268
  269		/***************
  270		*     smash    *
  271		***************/
 smash(+X:text) is det
Write all elements of text to the standard output ignoring the null byte code.
  277% ?- smash(a).
  278% ?- smash(a+b).
  279% ?- smash(f([b,c])).
  280% ?- smash([b,c]).
  281% ?- smash([]).
  282% ?- smash('[]').
  283
  284smash([]):- !.
  285smash([X|Y]):- !, smash(X), smash(Y).
  286% smash(0):- !.		% ignore  null bytes.
  287smash(X):- integer(X), !, put_code(X).
  288smash(X):- write(X).
 smashq(+X:text) is det
Same as smasq, but use writeq/1 instead.
  293% ?- smashq(a).
  294% ?- smashq(a+b).
  295% ?- smashq(`a`).
  296% ?- smashq(f(`[b,c]`)).
  297% ?- smashq([b,c]).
  298% ?- smashq('[]').
  299% ?- smashq(`[]`).
  300
  301smashq([]):- !.
  302smashq([X|Y]):- !, smashq(X), smashq(Y).
  303% smashq(0):- !.    % null byte
  304smashq(X):- integer(X), !, put_code(X).
  305smashq(X):- writeq(X).
 smash(+X:text, -Y:string) is det
Same as smash/1, but unify Y with the output string instead.
  310% ?- smash(a, X).
  311% ?- smash("a", X).
  312% ?- smash(f("a",b), X).
  313% ?- smash([a,b,c], X).
  314
  315smash(X, Y):- once(smash_to_atomics(X, X0, [])),
  316	atomics_to_string(X0, Y).
  317
  318% ?- basic:smash_to_atomics([a,[],"b"+c], R,[]).
  319% ?- basic:smash_to_atomics([a,[97], b+c], R,[]).
  320% The input is supposed to be ground.
  321smash_to_atomics([X|Y], A, B):- smash_to_atomics(X, A, C),
  322	smash_to_atomics(Y, C, B).
  323smash_to_atomics([], A, A).
  324% smash_to_atomics(0, A, A).   % unnecessary for utf8 encoding ?
  325smash_to_atomics(X, [Y|A], A)	:- compound(X), term_string(X, Y).
  326smash_to_atomics(C, [C0|A], A)	:- integer(C), char_code(C0, C).
  327smash_to_atomics(X, [X|A], A).
 smash_codes(+X:text, -Y:codes) is det
Same as smash/2, but unify Y with the output codes instead.
  332% ?- smash_codes(a, X).
  333% ?- smash_codes([97,b,[c,d], f(a, b)], X), smash(X).
  334
  335smash_codes(X, Y):- once(smash_to_codes(X, Y, [])).
  336
  337%
  338smash_to_codes([], A, A).	% ground input is assumed.
  339smash_to_codes([X|Y], A, B):- smash_to_codes(X, A, C),
  340	smash_to_codes(Y, C, B).
  341% smash_to_codes(0, A, A).  % unnecessary for utf8 econding ?
  342smash_to_codes(C, [C|A], A):- integer(C).
  343smash_to_codes(X, A, B):- atom(X),
  344	atom_codes(X, X0),
  345	append(X0, B, A).
  346smash_to_codes(X, A, B):- string(X),
  347	string_codes(X, X0),
  348	append(X0, B, A).
  349smash_to_codes(X, A, B):- term_string(X, X0),
  350	string_codes(X0, X1),
  351	append(X1, B, A).
 zip(?X:list, ?Y:list, ?Z:list) is det
Zip X and Y into Z with comma (,).
  356zip([],_, []):-!.
  357zip(_, [], []):-!.
  358zip([A|X], [B|Y], [(A,B)|R]):- zip(X, Y, R).
  359
  360zip(F, X, Y, Z):- maplist(F, X, Y, Z).
  361
  362unzip([], [], []).
  363unzip([(A,B)|R], [A|X], [B|Y]):- unzip(R,X,Y).
  364
  365% ?- different_terms([X,1]), X=2.
  366%@ X = 2.
  367%  declare a constraint that all terms in the list are different.
  368different_terms([X|Y]) :- maplist(dif(X), Y),
  369	different_terms(Y).
  370different_terms([]).
  371
  372% tiny helpers
  373enter(E,_,Y) :- val(E, Y).
  374peek(X,_,X).
  375peek(X,Y,X,Y).
  376current(X,X,X).
  377empty([],_).
  378empty_list(_, []).
  379car([A|_], A).
  380cdr([_|A], A).
  381cons(A, B, [A|B]).
  382singleton(A, [A]).
  383ordered_pair(A, B, (A, B)).
  384ordered_pair_p(A, B, p(A, B)).
  385return(A, B, [A|B]).		% cons <==> return !!
  386swap([A,B],[B,A]).
  387promote(A,[A]).
  388result(A,X) --> phrase(A), current(X). % result(A,X,Y,Y) :- act(A,Y,X).
  389id --> [].		%  X=Y
  390clear --> peek([]).
  391clear(X) --> peek(X,[]). 
  392fst((A,_), A).
  393snd((_,B), B).
  394pair(A, B, (A,B)).
  395pair(A, B, X, (A0, B0) ):- call(A, X, A0), call(B, X, B0).
  396
  397			/******************
  398			*     splitting   *
  399			******************/
  400
  401% ?- paragraph(`a\n\nbc`, X).
  402%@ X = [[97], [98, 99]] .
  403% ?- paragraph(`a\n\nbc\n`, X).
  404%@ X = [[97], [98, 99, 10]] .
  405
  406paragraph(X, Y)		:-	split(plus, "\n\n", X, Y).
  407paragraph(E, X, Y)	:-	split(plus, E, X, Y).
  408
  409
  410% ?-basic:split_by_string("abadea", "a", X).
  411%@ X = ["", "b", "de", ""].
  412
  413
  414split_by_string(X, Y, Z):- string_length(Y, N),
  415		      split_by_string(X, Y, N, Z, []).
  416
  417%
  418split_by_string(X,Y,K,[U|R],S):- sub_string(X,H,K,T,Y),!,
  419		      sub_string(X,0,H,_,U),
  420		      sub_string(X,_,T,0,V),
  421		      split_by_string(V, Y, K, R, S).
  422split_by_string(X,_,_,[X|R],R).
  423
  424% ?- split(" ", ` a b c `, X).
  425%@ X = [[], [97], [98], [99], []] .
  426
  427split(X, Y)   :- split(=, `\n`, X, Y).
  428
  429split(E, X, Y):- split(=, E, X, Y).
  430
  431%
  432split(F, E, X, Y):- atom(E), !, atom_codes(E, E0),
  433	split(F, E0, Y, [], X, []).
  434split(F, E, X, Y):- string(E), !, string_codes(E, E0),
  435	split(F, E0, Y, [], X, []).
  436split(F, E, X, Y):- split(F, E, Y, [], X, []).
  437%
  438split(F, C, [A|X], Y) --> dot_star(A, []), split_rest(F, C, X, Y).
  439split(_, _, [[]|X], X, [], []).
  440
  441%
  442split_rest(F, C, X, Y) --> delimiter(F, C), !, split(F, C, X, Y).
  443split_rest(_, _, X, X, [], []).
  444
  445% ?- basic:delimiter(=, `a`, `a`, R).
  446% ?- basic:delimiter(=, `ab`, `ac`, R).
  447% ?- basic:delimiter(plus, `a`, `aaaac`, R).
  448% ?- basic:delimiter(plus, `aa`, `aaab`, R).
  449% ?- basic:delimiter(plus, `aa`, `ab`, R).
  450
  451delimiter(=, C, X, Y):- !,  delimiter(C, X, Y).
  452delimiter(_, C, X, Y):- delimiter(C, X, X0), !,
  453	delimiter_plus(C, C, X0, Y).
  454
  455%
  456delimiter_plus([], C, X, Y):- !, delimiter_plus(C, C, X, Y).
  457delimiter_plus([A|X], C, [A|Y], Z):- !, delimiter_plus(X, C, Y, Z).
  458delimiter_plus(_, _, X, X).
  459
  460%
  461delimiter([A|X], [A|Y], Z):- delimiter(X, Y, Z).
  462delimiter([], X, X).
  463
  464%
  465dot_star(X, X) --> [].
  466dot_star([A|X], Y)--> [A], dot_star(X, Y).
  467
  468%%
  469repeat_chars(X)--> [C], {memberchk(C, X)}, repeat_chars(X).
  470repeat_chars(_)--> [].
  471
  472remove_last(X,Y,Z) :- append(Z,[X],Y), !.
  473remove_last(_,Y,Y).
  474
  475%
  476append_lists([L|R], X, Y):- append_one(L, X, X0),
  477	append_lists(R, X0, Y).
  478append_lists([], X, X).
  479
  480append_one([A|R], [A|X], Y):- append_one(R, X, Y).
  481append_one([], X, X).
  482
  483concat --> append.
  484
  485fullstop  --> ".\n".
  486
  487union(X, Y) :- append(X, X0), sort(X0, Y).
  488
  489residue(X, Y, Z) :- append(X, Z, Y).
  490
  491residue(X,Y,Z,U,V) :- append(X,V,U), append(X,Z,Y).
  492
  493remove(X, Y, Z) :- delete(Y, X, Z).
  494
  495% ?- basic:scan_prefix([b], [a,b,c], A, B).
  496
  497scan_prefix(C, X, Y, Z):- once(scan_prefix(X, Z, C, Y, [])).
  498%
  499scan_prefix(R, S, C, A, A):- append(C, S, R).
  500scan_prefix([X|R], S, C, [X|A], B):-
  501	scan_prefix(R, S, C, A, B).
  502scan_prefix([], [], _, A, A).
  503
  504% ?- basic:scan_escape_to(b, [a,b], R, S, []).
  505% ?- basic:scan_escape_to(0'", `a\"bc"`, R, S, []), smash(R), nl, smash(S).
  506scan_escape_to(C, [C|R], R, [C|S], S).
  507scan_escape_to(C, [0'\\, A|X], X0, [0'\\, A|Y], Y0):-
  508	scan_escape_to(C, X, X0, Y, Y0).
  509scan_escape_to(C, [A|X], X0, [A|Y], Y0):-
  510	scan_escape_to(C, X, X0, Y, Y0).
  511scan_escape_to(_, X, X, Y, Y).
  512
  513%
  514comment_begin_end(`%`, `\n`, `\n`).
  515% comment_begin_end(`//`, `\n`,`\n`).
  516comment_begin_end(`/*`, `*/`, []).
  517
  518% ?- basic:remove_comment([a,b,c], X, []).
  519% ?- basic:remove_comment(`non comment%abc`, X, []), smash(X).
  520%@ X = [110, 111, 110, 32, 99, 111, 109, 109, 101|...] .
  521% ?- basic:remove_comment(`/***** abc ****/\nxyz`, X, []), smash(X).
  522% ?- basic:remove_comment(`/***** abc ****/xyz`, X, []), smash(X).
  523% ?- basic:remove_comment(`/**/\nxyz`, X, []), smash(X).
  524% ?- basic:remove_comment(`"/**/"\nxyz`, X, []), smash(X).
  525% ?- basic:remove_comment(`f("/**/")\nxyz`, X, []), smash(X).
  526% ?- basic:remove_comment(`f(0'\\\\, "/**/")\nxyz`, X, []), smash(X).
  527% ?- basic:remove_comment(`f(0'\\' , "/**/")\nxyz`, X, []), smash(X).
  528% ?- basic:remove_comment(`0'\\\\`, X, []), smash(X).
  529% ?- basic:remove_comment(`0'\\abc`, X, []), smash(X).
  530% ?- basic:remove_comment(`0'abc`, X, []), smash(X).
  531% ?- basic:remove_comment(`\\\\abc`, X, []), smash(X).
  532
  533remove_comment(X,Y):- remove_comment(X, Y, []).
  534
  535remove_comment([], X, X).
  536remove_comment(L, X, X0):-
  537	comment_begin_end(B, E, PushBack),
  538	append(B, L0, L),
  539	!,
  540	skip_to(E, L0, L1),
  541	append(PushBack, Y, X),
  542	remove_comment(L1, Y, X0).
  543remove_comment([Q|L], [Q|X], Y):- memq(Q,`"\`'`), !, % "
  544	scan_escape_to(Q, L, L0, X, X0),
  545	remove_comment(L0, X0, Y).
  546remove_comment([0'0, 0'\', A|L], [0'0, 0'\', A|X], Y):- !,
  547	(A == 0'\\
  548	 ->		L=[B|L0],
  549			X=[B|X0],
  550			remove_comment(L0, X0, Y)
  551	;	remove_comment(L, X, Y)).
  552% remove_comment([0'0, 0'\', A|L], [0'0, 0'\', A|X], Y):- !,
  553% 	remove_comment(L, X, Y).
  554remove_comment([A|L], [A|X], Y):-
  555	remove_comment(L, X, Y).
  556
  557%
  558skip_to(E, X, Y):- append(E, Y, X).
  559skip_to(E, [_|X], Y):- skip_to(E, X, Y).
  560skip_to(_,[],[]).
  561
  562:- meta_predicate delete_all(1,?,?).  563
  564delete_all(C, [X|Y], Z):- call(C, X), !, delete_all(C, Y, Z).
  565delete_all(C, [X|Y], [X|Z]):- delete_all(C, Y, Z).
  566delete_all(_, [], []).
  567
  568% ?-listsubst([([a],[b])],[a,a,a], R).
  569%@ R = [b,b,b]
  570
  571listsubst(_, [], []).
  572listsubst(X, Y, Z) :- member((A,B), X),
  573	append(A,Y1,Y),
  574	append(B,Z1,Z),
  575	listsubst(X, Y1, Z1).
  576listsubst(X, [A|Y], [A|Z]) :- listsubst(X,Y,Z).
  577
  578%%% Comment and Quotation
  579
  580comment(X) --> sandwich("/*", "*/", X)
  581	; sandwich("//", "\n", X)
  582	; sandwich("%", "\n", X).
  583
  584%%%%
  585% by W. Jan [2009/02/08]
  586% full-stop
  587% ?- basic:atom_to_term('a.\n', X, Y, user).
  588% ?- basic:atom_to_term('1.\n', X, Y, user).
  589
  590atom_to_term(Atom, Term, Bindings, Module) :-
  591	atom_to_memory_file(Atom, MF),
  592	open_memory_file(MF, read, Stream,
  593			 [ free_on_close(true)
  594			 ]),
  595	call_cleanup(read_term(Stream, Term,
  596			       [ variable_names(Bindings),
  597				 module(Module)
  598			       ]),
  599		     close(Stream)).
  600
  601:- meta_predicate collect(:,?,?).  602% ?- collect(=(1), [1,2,1,3], X).
  603% X = [1, 1]
  604% ?- collect([X]:- atom_concat(_,pdf,X), [a,b,xpdf,ypdf, c], L).
  605% L = [xpdf,ypdf]
  606collect(F, X, Y):- collect_(X, Y, F).
  607%
  608collect_([X|R0], [X|R], F):- call(F, X), !, collect_(R0, R, F).
  609collect_([_|R0], R, F):- collect_(R0, R, F).
  610collect_([], [], _).
  611
  612:- meta_predicate collect_suffix(1, ?, ?).  613
  614collect_files(Filter, Dir,Ls):-
  615	directory_files(Dir, L0),
  616	collect(Filter, L0, Ls).
  617
  618:- meta_predicate image(3,?,?,?).  619% ?- image([X,X,X], [1,2,3],[1,3,3], L).
  620% L = [1,3].
  621image(F, [X|R0], [Y|S0], U):- (call(F, X, Y, Z) ->  U=[Z|T0]; U=T0),
  622	image(F, R0, S0, T0).
  623
  624%
  625dual(X, Y) :-  call(Y, X).
  626dual(X, Y, Z):- call(Y, X, Z).
  627
  628:- meta_predicate rev(2,?,?), rev(3,?,?,?), rev(:).  629rev(F, X, Y) :- call(F, Y, X).
  630rev(F, X, Y, Z) :- call(F, X,  Z, Y).
  631
  632inverse(F, X, Y) :- call(F, Y, X).
  633inverse(F, X, Y, Z) :- call(F, X, Z, Y).
  634
  635% /**** course of values
  636% ?- course_of_values(n\l\n,  10, [1,1], X).
  637% X = [9, 8, 7, 6, 5, 4, 3, 2, 1|...].
  638% ?- eval(course_of_values(n\l\
  639%	(a\ (is:: ( a * n))@ car(l)), 10, [1,1]), X).
  640% X = [362880, 40320, 5040, 720, 120, 24, 6, 2, 1|...].
  641% ?- eval(course_of_values(n\fun([a],
  642%	is::( a * n)), 10, [1,1]), X).
  643% X = [362880, 40320, 5040, 720, 120, 24, 6, 2, 1|...].
  644% ****/
  645course_of_values(F, J, X, Y):-  cov(F, 1, J, X, Y).
  646
  647course_of_values(F, I, J, X, Y):-  cov(F, I, J, X, Y).
  648
  649% ?- cov(n\ fun([a], is:: (a*n)), 1, 5, [1, 1], X).
  650% X = [24, 6, 2, 1, 1, 1].
  651% ?- cov(n\ fun([], factorial(n,1)), 10, [1], X).
  652% X = [362880, 40320, 5040, 720, 120, 24, 6, 2, 1|...].
  653
  654cov(F, J, X, Y) :- cov(F, 1, J, X, Y).
  655
  656cov(_, N0, N, X, X):- N0 >= N, !.
  657cov(F, J,  N, X, Y):- eval:apply(F, [J, X], X0),
  658	J1 is J + 1,
  659	cov(F, J1, N, [X0|X], Y).
?- fun([x], x, [1,2,3], A). A = 1. ?- fun([x,y], set::(x+y), [[a,b], [c,d], [e]], X). X = [a, b, c, d].
  667% fun(P, F, X, A):- fresh_bind(P\F, P0\F0), append(P0, _, X), eval(F0,
  668% A).
  669
  670% ?-  list_rec(fun([a,b], (is::(a+b))), 10, [1,1], X).
  671% X = [144, 89, 55, 34, 21, 13, 8, 5, 3|...].
  672
  673list_rec(_, J, X, X):- J =< 0, !.
  674list_rec(F, J, X, Y):- eval:(F, [X], V),
  675	J1 is J - 1,
  676	list_rec(F, J1, [V|X], Y).
  677
  678% /***** nat_list_rec/[4,5]
  679% ?- nat_list_rec([j,l]\ ([x1, x2]\
  680%	(is:: (j+1)*x1*x2) @ nth1(1,l) @ nth1(2,l)), 5, [1,1], X).
  681% X = [1440, 48, 6, 2, 1, 1, 1].
  682% ?- nat_list_rec([j,l]\ some([x, y, r], (l=[x, y|r],
  683%	is:: (j+1)*x*y)), 5, [1,1], X).
  684% X = [1440, 48, 6, 2, 1, 1, 1].
  685% *******/
  686
  687nat_list_rec(F, N) --> nat_list_rec(F, 0, N).
  688
  689nat_list_rec(_, N, N, X, X):- !.
  690nat_list_rec(F, J, N, X, Y):-
  691	call(F, J, X, V),
  692	J1 is J + 1,
  693	nat_list_rec(F, J1, N, [V|X], Y).
is true if so is call(F, Y, X, Z).
  699:- meta_predicate variant(3, ?, ?, ?).  700% ?- variant(append, [a,b], [c, d], X).
  701% X = [c, d, a, b].
  702variant(X, Y, Z, U):- call(X, Z, Y, U).
  703
  704% ?- trace, eval(args(ev)::append(append([a,b],[c,d]), [e,f]), X).
  705% X = append([a, b, c, d], [e, f]).
  706% args(S, X, Y, [], [], true):- mapterm(eval(S), X, Y).
  707
  708%
  709with_order(Ord, G, X, Y):- sort(Ord, Ord0),
  710	zip(Ord, Ord0, A),
  711	subst(A, X, X0),
  712	call(G, X0, Y0),
  713	zip(Ord0, Ord, B),
  714	subst(B, Y0, Y).
  715
  716% ?- flatten(;, (a;b); c , X).
  717% X = [a, b, c]
  718
  719flatten(F, X, Xs):- flatten(F, X, Xs, []).
  720
  721flatten(F, X, A, B):- X=..[F, X1, X2], !,
  722	flatten(F, X1, A, A0),
  723	flatten(F, X2, A0, B).
  724flatten(_, X, [X|A], A).
  725
  726% ?- basic:flatten_dl([a,[b,c]], X, []).
  727flatten_dl([A|B], X, Y):- flatten_dl(A, X, Z),
  728	flatten_dl(B, Z, Y).
  729flatten_dl([], X, X).
  730flatten_dl(A, [A|X], X).
  731
  732% ?- flatten_more(f(a,[f(b,c)]), X).
  733% X = [f, a, f, b, c].
  734
  735flatten_more(A, [A|X], X):-var(A),!.
  736flatten_more([], X, X):-!.
  737flatten_more(A,[A|X], X):-  atomic(A),!.
  738flatten_more([A|B], X, Y):- !, flatten_more(A, X, X0),
  739	flatten_more(B, X0, Y).
  740flatten_more(A, [F|X], Y):- A =.. [F|As],
  741	flatten_more(As, X, Y).
  742
  743flatten_more(A, X):- once(flatten_more(A, X, [])).
  744
  745% ?- tree_path_set(f(1,g(2,3)), X).
  746% X = [[f,1],[f,g,2],[f,g,3]].
  747
  748tree_path_set(X, Y):- compound(X), !, X=..[F|A],
  749	maplist(tree_path_set, A, B),
  750	append(B, B0),
  751	maplist(cons(F), B0, Y).
  752tree_path_set(X, [[X]]).
  753
  754% push & pop
  755% ?- stack_push(1), stack_push(2), stack_pop(X), stack_pop(Y).
  756% X = 2,
  757% Y = 1.
  758
  759stack_init(S) :- nb_setval(S, []).
  760stack_push(X, S):- nb_getval(S, R), nb_linkval(S, [X|R]).
  761stack_pop(X, S):- nb_getval(S, [X|R]),  nb_linkval(S, R).
  762stack_update(X, S):- nb_getval(S, [_|R]),  nb_linkval(S, [X|R]).
  763stack_top(X, S):- nb_getval(S, [X|_]).
  764
  765stack_init :- stack_init('$STACK').
  766stack_push(X):- stack_push(X, '$STACK').
  767stack_pop(X):- stack_pop(X, '$STACK').
  768stack_update(X):- stack_update(X, '$STACK').
  769stack_top(X):- stack_top(X, '$STACK').
 scan(+A:list/atomic, ?B:list, ?C:list, +X:list, -Y:list) is nondet
True if X = (B-C) + A0 + Y, where A0 is the list of codes of A if A is atomic, otherwise A0 = A; and '+' operator means the list concatenation. ?- basic:scan([a,b],S,[],[1,2,a,b,3,4], R). @ S = [1, 2], @ R = [3, 4] ;
  779% ?- basic:scan(`.\n`,S,[],`aaaaaa.\n==\n`, R).
  780% ?- basic:scan(".\n",S,[],`aaaaaa.\n==\n`, R).
  781
  782%@ true.
  783%%  first_token_codes(+L:codes, -X:codes) is det.
  784%	True if  X is unified with the maximum first codes block
  785%	that has no white codes.
  786
  787scan(A, S, T, X, Y):- atomic(A), !,
  788	atom_codes(A, B),
  789	scan_codes(B, S, T, X, Y).
  790scan(A, S, T, X, Y):- scan_codes(A, S, T, X, Y).
  791
  792%
  793scan_codes(A, S, S, X, Y):- append(A, Y, X).
  794scan_codes(Key, [A|As], U, [A|Xs], Y):- scan_codes(Key, As, U, Xs, Y).
  795%
  796fill  --> chars(` \t\r\n`).
  797
  798filler(_) --> chars(` \t`). % for compatibility
  799
  800
  801% Tiny DCG
  802maybe_end --> chars(` \t`), peek([], end); herbrand(_).
  803
  804kleene_star(_, P, P).
  805kleene_star([X|Xs], [X|P], Q):-  append(Xs, P0, P),
  806	kleene_star([X|Xs], P0, Q).
  807
  808%
  809kleene_star_greedy([X|Xs], [X|P], Q):-  append(Xs, P0, P),
  810	kleene_star_greedy([X|Xs], P0, Q).
  811kleene_star_greedy(_, P, P).
  812
  813%
  814kleene_plus_greedy(X, Y, Z):- append(X, Z0, Y),
  815	kleene_star_greedy(X, Z0, Z).
  816
  817kleene_plus_greedy(X, Y, Z):- append(X, Z0, Y),
  818	kleene_star_greedy(X, Z0, Z).
  819
  820kleene_string_codes(S, C, D):- string_codes(S, Cs),
  821	kleene_plus_greedy(Cs, C, D).
  822
  823%
  824chars(_) --> [].
  825chars(L) --> [X], {memberchk(X, L)}, chars(L).
  826%
  827chars(L) --> [X], {memberchk(X, L)}, chars(L).
  828chars(_) --> []