1:- module(misc, [
    2	 compile_pred_word/4
    3  ,  random_choice/2
    4  ,  collect_subterm/3
    5  ,  collect_subterm/4
    6  ,  completing_optional_args/3
    7  ,  cs/2
    8  ,  desugaring/2
    9  ,  dir_minus/3
   10  ,  dir_plus/3
   11  ,  directory_files/3
   12  ,  directory_remove_ymhms/1
   13  ,  drop3zw/2
   14  ,  find_exportables_from_calls/2
   15  ,  ignore/2
   16  ,  insert/3
   17  ,  insert_pause/2
   18  ,  kanji/3
   19  ,  list/2
   20  ,  map_directory_files/2
   21  ,  matrix_paths/2
   22  ,  parse_time/3
   23  ,  parse_utf8/2
   24  ,  predicate_arity/2
   25  ,  predicate_arity_for_export/2
   26  ,  rename_directory_suffix/3
   27  ,  set/2
   28  ,  skip_filler/2
   29  ,  split_by_filler/3
   30  ,  string/2
   31  ,  shell_string/2, shell_string/3, qshell_string/2
   32  ,  texadjust/2
   33  ,  texuncomment/2
   34  ,  token_and_split/3
   35  ,  try2problem/2
   36  ,  expand_sgn_brace/2			]).   37
   38:- use_module(pac(basic)).   39:- use_module(util(file)).   40:- use_module(util('meta2')).   41:- use_module(util(math)).   42
   43term_expansion --> pac:expand_pac.
   44:- use_module(pac(op)).   45%
   46:- use_module(pac('expand-pac')).   47
   48		/***********************************
   49		* Compile clause / DCG with regex  *
   50		***********************************/
   51
   52new_names([V|Vs], [A=V|Eqs], N, Prefix, As):-
   53	new_name(N, As, A, Prefix, K),
   54	new_names(Vs, Eqs, K, Prefix, As).
   55new_names([], [], _, _, _).
   56
   57%
   58new_name(N, As, B, Prx, K):- atom_concat(Prx, N, B),
   59						\+ memberchk(B, As),
   60						!,
   61						succ(N, K).
   62new_name(N, As, A, Prx, K):- succ(N, N1),
   63						new_name(N1, As, A, Prx, K).
   64
   65% ?- ejockey:subtractq([X,Y,X,Y,X,Y], [X], R).
   66subtractq([], _, []).
   67subtractq([A|As], B,  C):- memq(A, B), !,
   68	subtractq(As, B, C).
   69subtractq([A|As], B, [A|C]):- subtractq(As, B, C).
   70
   71%
   72expand_clause_slim(X, Y):-
   73	expand_clause(X, [], Y0),
   74	maplist(pred([X:-true, X] & [C, C]),  Y0, Y).
   75%
   76compile_pred_word(X-->X0, Eqs, H0, R0):-!,
   77		maplist(pred([A=P, A, P]), Eqs, As, Vs),
   78		expand_clause_slim(X-->X0, [H|R]),
   79		term_variables(H, HVs),
   80		subtractq(HVs, Vs, SVs),
   81		new_names(SVs, Eqs0, 1, 'A', As),
   82		append(Eqs0, Eqs, Eqs1),
   83		term_string(H, H0, [variable_names(Eqs1),
   84							quoted(true)]),
   85		maplist(pred(([U, [V,".\n"]] :-
   86								numbervars(U, 0, _),
   87								term_string(U, V, [ numbervars(true),
   88													quoted(true)]))),
   89				R, R0).
   90compile_pred_word(X, Eqs, H0, R0):-
   91		expand_clause_slim(X, [H|R]),
   92		term_string(H, H0, [variable_names(Eqs),
   93							quoted(true)]),
   94		maplist(pred(([U, [V,".\n"]] :-
   95								numbervars(U, 0, _),
   96								term_string(U, V, [ numbervars(true),
   97													quoted(true)]))),
   98				R, R0).
   99
  100
  101			/********************
  102			*     shell string  *
  103			********************/
 shell_string(+X:term, -Y:string) is det
Expand a shell command term X into a string that can be passed to shell/1.
  109% ?- shell_string(open("1"), X).
  110% ?- shell_string(open(1), X).
  111% ?- shell_string(open(abc), X).
  112% ?- shell_string(open(-l, -m, abc), X).
  113% ?- shell_string(open(-f(a)), X).
  114% ?- shell_string(open(-f(a)), X).
  115
  116% ?- shell_string(a, Y).
  117% ?- shell_string([[a]], Y).
  118% ?- shell_string([[a],[b]], Y).
  119% ?- shell_string([[a]+[b]], Y).
  120% ?- shell_string(f(-a + b), Y).
  121% ?- shell_string(f(-a + b, -c + d), Y).
  122% ?- shell_string(f(-1 + b, -c + d, e), Y).
  123% ?- shell_string(f(-1,  b, -c + d, e), Y).
  124% ?- shell_string(f(a + b + c + d + e), Y).
  125% ?- shell_string(f(a); g(b), Y).
  126% ?- shell_string(f(1); g(1), Y).
  127% ?- shell_string({f(a); g(b)}, Y).
  128
  129shell_infix(L / R, L, /, R).
  130shell_infix(L ; R, L, ;, R).
  131shell_infix('|'(L,R), L, '|', R).
  132shell_infix(L > R, L, >, R).
  133shell_infix(L >> R, L, >>, R).
  134shell_infix(L << R, L, <<, R).
  135shell_infix(&(L, R), L, &, R).
  136shell_infix(&&(L, R), L, &&, R).
  137%
  138qshell_string(X, Y):- shell_string(X, " > /dev/null 2>&1", Y).
  139%
  140shell_string(X, Y):- shell_string(X, "", Y).
  141%
  142shell_string([], Z, Z):-!.
  143shell_string([X], Y, Z):-!, shell_string(X, Y, Z).
  144shell_string([X,Y|Z], U, V):-!, shell_string([Y|Z], U, W),
  145	string_concat(" ", W, W0),
  146	shell_string(X, W0, V).
  147shell_string(A+B, X, Y):-!, shell_string(B, X, X0),
  148	shell_string(A, X0, Y).
  149shell_string(-A, X, Y):-!, shell_string("-" + A, X, Y).
  150shell_string(--(A), X, Y):-!, shell_string("--" + A, X, Y).
  151shell_string(A, X, Y):- shell_infix(A, L, F, R), !,
  152	shell_string(R, X, X0),
  153	string_concat(F, X0, X1),
  154	shell_string(L, X1, Y).
  155shell_string({A}, X, Y):-!, shell_string("( " + A + " )", X, Y).
  156shell_string(shell(A), X, Y):-!, shell_string({A}, X, Y).
  157shell_string(A, X, Y):- compound(A), !,
  158	A =.. B,
  159	shell_string(B, X, Y).
  160shell_string(A, X, Y):- atomic(A), string_concat(A, X, Y).
  161
  162
  163		/**********************************
  164		*     compleging optional args    *
  165		**********************************/
  166
  167% ?- completing_optional_args([a(hello)], [], R).
  168% ?- completing_optional_args([a(X):hello], [], R).
  169% ?- completing_optional_args([a(X): !(X=hello)], [], R).
  170% ?- completing_optional_args([a(X):hello], [], R).
  171% ?- completing_optional_args([a(X):hello], [a(world)], R).
 completing_optional_args(+X, +Y, -Z) is det
option Z is unified with Y completed with default option X.
  176completing_optional_args(X, Y, Z):-
  177	completing_optional_args(X, Y, Z, []).
  178
  179% ?- zdd_array:completing_optional_args([a(X)], [a(Y)], R, S).
  180% ?- zdd_array:completing_optional_args([a(world)], [a(hello)], R, S).
  181% ?- zdd_array:completing_optional_args([a(X):b], [a(Y)], R, S).
  182% ?- zdd_array:completing_optional_args([a(X):10], [a(Y)], R, S).
  183
  184completing_optional_args([], R, R, []):-!.
  185completing_optional_args([A|As], Bs, [B|R], R0):- (A = A0:_ ; A0= A), !,
  186	functor(A0, F, 1),
  187	functor(B, F, 1),
  188	( select(B, Bs, Cs); Cs = Bs ), !,
  189	unify_one(A, B),
  190	completing_optional_args(As, Cs,  R,  R0).
  191
  192% For preventing expansion brace {..} by open_dict as pac macro.
  193% ( not used )
  194:- set_prolog_flag(open_dict, false).  195unify_default({G}, _):-!, once(G).
  196unify_default(X, X).
  197:- set_prolog_flag(open_dict, true).  198
  199%
  200unify_one(A:Val, B):- !, functor(A, F, 1),
  201	functor(B, F, 1),
  202	arg(1, A, U),
  203	arg(1, B, V),
  204	(	var(V)	->	U = Val,	% unify_default(Val, U),
  205					V = U
  206	;	var(U)	->  U = V
  207	;	true
  208	).
  209unify_one(A, A):-!.
  210unify_one(_, _).
  211
  212			/************************
  213			*       Set kind        *
  214			************************/
 set(+X:term, -Y:list) is det
Evaluate a set expression X into a list Y.
  219% ?- set([a,b]-[1,2], R).
  220% ?- set(singleton(pow([1,2])), X), length(X, L).
  221
  222set(emptyset,[]):-! .
  223set(X,X):-listp(X),! .
  224set(singleton(A),[B]):-!,set(A,B) .
  225set(A+B,A1):-!,(set(A,A2),set(B,A3)),union(A2,A3,A1) .
  226set(plus(A,B),A1):-!,set(A+B,A1) .
  227set(cup(A),A1):-!,(set(A,A2),set(append(A2),A3)),sort(A3,A1) .
  228set(cap(A),A1):-!,set(A,A2),math:bigcap(A2,A1) .
  229set(++(A,B),A1):-!,(set(A,A2),set(B,A3)),math:direct_sum(A2,A3,A1) .
  230set(A*B,A1):-!,(set(A,A2),set(B,A3)),math:product(A2,A3,A1) .
  231set(A-B,A1):-!,(set(A,A2),set(B,A3)),
  232	pac_meta:pac_product(misc:set_aux,A2,A3,A1) .
  233set(\(A,B),A1):-!,(set(A,A2),set(B,A3)),subtract(A2,A3,A1) .
  234set(#(A,B),A1):-!,(set(A,A2),set(B,A3)),scramble_cons(A2,A3,A1) .
  235set(&(A,B),A1):-!,(set(A,A2),set(B,A3)),math:intersection(A2,A3,A1) .
  236set(pow(A),A1):-!,set(A,A2), math:powerset(A2,A1) .
  237set(zip(A,B),A1):-!,(set(A,A2),set(B,A3)),zip(A2,A3,A1) .
  238set(sort(A),A1):-!,set(A,A2),sort(A2,A1) .
  239set((A->B),A1):-!,(set(A,A2),set(B,A3)),math:mapset(A2,A3,A1) .
  240set(..(I,J),A1):-(I0 is I,J0 is J),!,numlist(I0,J0,A1) .
  241set(in(X,Y),A1):-!,(set(X,A2),set(Y,A3)),truth(memberchk,A2,A3,A1) .
  242set(X=Y,A1):-!,(set(X,A2),set(Y,A3)),truth(==,A2,A3,A1) .
  243set(X=<Y,A1):-!,(set(X,A2),set(Y,A3)),truth(subset,A2,A3,A1) .
  244set(X>=Y,A1):-!,set(Y=<X,A1) .
  245set(X<Y,A1):-!,(set(X,A2),set(Y,A3)),truth(math:proper_subset,A2,A3,A1) .
  246set(X>Y,A1):-set(Y<X,A1) .
  247
  248%
  249set_aux(A,B,A-B).
 insert(+M:term, +X:list, -Y:list) is det
Insert M beteen every successive elements of X, and unify Y with the result.
  255% ?- misc:insert(a, [1,2,3], R).
  256insert(M, [A|P], [A|Q]):- foldl(pred(M, [B, [M, B| U], U]), P, Q, []).
  257insert(_, [], []).
  258
  259%
  260truth(X, true) :- call(X), !.
  261truth(_, false).
  262
  263truth(X, Y, true) :- call(X, Y), !.
  264truth(_, _, false).
  265
  266truth(X, Y, Z, true) :- call(X, Y, Z), !.
  267truth(_, _, _, false).
 desugaring(+X:term, -Y:term) is det
Eliminate infix '-' and '/', and prefix '+', '-', and ufify Y with the result.
  273% ?- desugaring( -(a-b-c), Y).
  274
  275desugaring(X-Y,A1+ -1*A2):-!,desugaring(X,A1),desugaring(Y,A2).
  276desugaring(+X,A1):-!,desugaring(X,A1).
  277desugaring(-X,-1*A1):-!,desugaring(X,A1).
  278desugaring(X/Y,A1 rdiv A2):-!,desugaring(X,A1),desugaring(Y,A2).
  279desugaring(X,X).
  280
  281insert_pause(cs(item),[cs(pause),cs(item)]):-! .
  282insert_pause(X,A1):-(listp(X),maplist(insert_pause,X,Y)),!,insert_pause(Y,A1) .
  283insert_pause(X,A1):-(X=..[F|As],maplist(insert_pause,As,Bs),Z=..[F|Bs]),!,
  284		insert_pause(Z,A1).
  285
  286texadjust([cs(item)|X],A1):-texadjust(X,Y),!,texadjust([10,cs(item)|Y],A1) .
  287
  288cs(cs(N),[N]):-!.
  289cs(A,A1):-listp(A),!,maplist(cs,A,A1) .
  290cs(A,A1):-A=..[_A2|As], maplist(cs,As,A1) .
  291
  292texuncomment(comment(_A1),[]).
  293
  294try2problem(env(try,Body),A1):-try2problem(Body,A2),try2problem(env(problem,A2),A1).
  295
  296drop3zw(ddol(E),[cs(noindent),cs(skip),"3zw",env(coronamath,[dol([cs(displaystyle)," ",E])])]).
  297
  298
  299
  300% product(A, B, C):-
  301% 	foldr( pred(B, [X,P,Q] :-
  302% 		foldr(pred(X, [Y,U,[X-Y|U]]), B, P, Q)), A, [], C).
  303
  304% product_cons(A, B, C):-
  305% 	foldr( pred(B, [X,P,Q] :- foldr(pred(X, [Y,U,[[X|Y]|U]]), B, P, Q)), A, [], C).
  306
  307% ?- product_cons([1,2],[[a,b],[c,d,e]], X).
  308%@ X = [[1,a,b],[1,c,d,e],[2,a,b],[2,c,d,e]] .
  309
  310% product3(A, B, C, D):-
  311% 	foldr( pred([B,C], [X,P,Q] :-
  312% 		foldr(pred([X,C], [Y,U, V]:-
  313% 			 foldr(pred([X,Y], [Z, M, [X-Y-Z|M]]), C, U, V)),
  314% 				B, P, Q)), A, [], D).
  315
  316% product4(A, B, C, D, E):-
  317% 	foldr( pred([B,C,D],
  318% 		    [X, P, Q] :-
  319% 		foldr(pred([X,C,D],
  320% 			   [Y, U, V]:-
  321% 			 foldr(pred([X,Y,D],
  322% 				    [Z, M, N]:-
  323% 			      foldr(pred([X,Y,Z],
  324% 					 [W, R,[X-Y-Z-W|R]]), D, M, N)),
  325% 			       C, U, V)),
  326% 		      B, P, Q)),
  327% 	        A, [], E).
  328
  329matrix_paths([], [[]]).
  330matrix_paths([X|Y], Z):- matrix_paths(Y,  PY),
  331	foldr(pred(PY, [J, P, Q]:-
  332	     foldr(pred(J, [K, N, [[J|K]|N]]), PY, P, Q)),
  333	      X, [], Z).
  334
  335
  336% ?- time(repeat(10^8, choices_by_fold([[1,2],[a,b,c],[3,4]], R))).
  337%@ % 7,900,000,001 inferences, 394.599 CPU in 394.833 seconds (100% CPU, 20020346 Lips)
  338%@ true.
  339
  340% ?- time(repeat(10^8, choices([[1,2],[a,b,c],[3,4]], R))).
  341%@ % 4,300,000,001 inferences, 138.387 CPU in 138.479 seconds (100% CPU, 31072358 Lips)
  342%@ true.
by [compile, pac, region] of emacs-jockey.pl
choices_by_fold(X, Y):- reverse(X, X0), foldl(pred([A,B,C] :- foldr( pred(B, [L,P,Q] :- foldr(pred(L, [M,U,[[L|M]|U]]), B, P, Q)), A, [], C)), X0, [[]], Y).
  357% ?- length(L, 10), maplist(misc:random_choice([[a,b],[c,d,e]]), L), maplist(writeln, L).
  358
  359random_choice([L|R], [A|Q]):- length(L, N), I is random(N),
  360			      nth0(I, L, A),
  361			      random_choice(R, Q).
  362random_choice([], []).
 list(+X:term, -Y:list) is det
Expand a list term X into a list Y.
  368% ?- list([1,2]\[1,2,3,4], R).
  369% ?- list([a,b]^2, R).
  370% ?- list(^^([a,b], 2), R).
  371% ?- list([a,b]^2+[c,d]^3+[e,f]^4, R), length(R, L).
  372% ?- list([a,b]^0+[c,d]^1+[e,f]^2, R), length(R, L).
  373% ?- list([a,b]^^3, R), length(R, L).
  374
  375list(A+B,A1):-!, list(A,A2),
  376	list(B,A3),
  377	append(A2,A3,A1).
  378list(\(A,B),Z):-!, list(A,X),list(B,Y), append(X,Z,Y) .
  379list(A/B,Z):-!, list(A,X),list(B,Y), append(Z,Y,X) .
  380list(E^L,A1):-N is L,!,list(E,A2),times(N,A2,A1) .
  381list(^^(E,L),C):-N is L,!,list(E,A),math:nlist(A,N,C) .
  382list(X,X):-listp(X),! .
  383list(+A,A1):-!,list(A,A2), append(A2,A1) .
  384list(flat(A),A1):-list(A,A2),flatten(A2,A1) .
 string(+X:term, -Y:string) is det
Expand a string term X into a string Y.
  389% ?- string("ab"+"cd"+"ef", X).
  390% ?- string("abcd"/"cd", X).
  391% ?- string("ab"\"abcd", X).
  392% ?- string(("ab"\"abcd")^3, X).
  393% ?- string(("ab"\"abcd")^3, X).
  394% ?- val(string((+) @ (list@ (+(["ab", "cd"], ["ef", "gf"])))), Y).
  395% ?- string(reverse("abcd"), X).
  396% ?- string(reverse(reverse("uvw") + reverse("ab" + "12")), X).
  397
  398string(A+B,A1):-!, string(A,A2),
  399	string(B,A3),
  400	string_concat(A2,A3,A1).
  401string(\(A,B),Z):-!, string(A,X),
  402	string(B,Y),
  403	string_concat(X,Z,Y).
  404string(A/B,Z):-!, string(A,X),
  405	string(B,Y),
  406	string_concat(Z,Y,X).
  407string(E^L,A1):-N is L,!,string(E,A2),
  408	string_times(N,A2,A1) .
  409string(reverse(X),B):-!, string(X,A1),
  410	string_codes(A1,A2),
  411	reverse(A2,A),
  412	string_codes(B,A).
  413string(+A,A1):-!, string(A,A2),
  414	list(A2,A3),
  415	string_list_concat(A3,A1).
  416string(X,X):-(string(X);atom(X)),!.
  417
  418
  419% split by variable length filler.
  420split_by_filler(X) --> (skip_filler; []), token_and_split(X).
  421
  422%
  423token_and_split([]) --> elisp:end_of_list.
  424token_and_split([A|X]) --> wl("[^\s\t\r\n]+", A, []),  split_by_filler(X).
  425
  426skip_filler --> wl("[\s\t\r\n]+").
  427
  428% ?- listing(token_and_split).
  429% ?- listing(skip_filler).
  430% ?- listing('nt#6').
  431% ?- listing('nt#5').
  432% ?- skip_filler(`   abc`, X).
  433
  434% ?- trace, string_chars("ab", L), split_by_filler(X, L, Y).
  435% ?- trace, string_chars("    ", L), split_by_filler(X, L, Y).
  436% ?- trace, string_chars(" ab  c\n \t   ", L), split_by_filler(X, L, Y).
  437% ?- trace, string_chars(" ab  c\nd\t ef   ", L), split_by_filler(X, L, Y).
  438
  439% Apply set operation on directories as a set of files.
  440
  441:- meta_predicate directory_files(2,?,?).  442directory_files(E, Ds, L):-
  443	maplist(pred([D, D0]:-expand_file_name(D, [D0])), Ds, Es),
  444	maplist(directory_files, Es, Ls),
  445	call(E, Ls, L).
  446
  447:- meta_predicate map_directory_files(1, ?).  448map_directory_files(F, D):- directory_files(D, Fs),
  449	working_directory(D0, D),
  450	maplist(ignore(F), Fs),
  451	working_directory(_, D0).
  452
  453ignore(F, X):- ignore(call(F, X)).
  454
  455% ?- directory_remove_ymhms('/Volumes/sparrow/raw-scan-master').
  456% ?- directory_remove_ymhms('/Volumes/shark/searchable-master').
  457directory_remove_ymhms(D):- expand_file_name(D, [D0]),
  458	map_directory_files(pred(([X]:-
  459					atom_codes(X, X0),
  460					parse_time_me(".pdf", X0, Y0),
  461					atom_codes(Y,Y0),
  462					rename_file(X, Y) )),
  463					D0).
  464
  465% :- listing(parse_time).
  466% ?-  misc:parse_time(`pdf`, `2007年12月21日21時35分18秒.pdf`, P), atom_codes(Y, P).
  467
  468parse_time(Ext) -->
  469	w(*(char(digit)), Year),	"å¹´",
  470	w(*(char(digit)), Month),	"月",
  471	w(*(char(digit)), Day),		"日",
  472	w(*(char(digit)), Hour),	"時",
  473	w(*(char(digit)), Minute),	"分",
  474	w(*(char(digit)), Second),	"秒",
  475	".",
  476	w(*(.), Ext),
  477	current([]),
  478	{ append([Year, Month, Day, Hour, Minute, Second, `.`,  Ext], Y) },
  479	peek(Y).
  480
  481% ?- dir_minus('~/Desktop', '~/Desktop', Z).
  482% ?- dir_minus('~', '~/Desktop', Z).
  483% ?- dir_minus('~', '~', Z).
  484dir_minus(X,Y,Z):- directory_files(fun([[A,B]]-> (set::(A\B))), [X, Y], Z).
  485dir_plus(X,Y,Z):- directory_files(fun([[A,B]]-> (set::(A+B))), [X, Y], Z).
  486
  487%
  488rename_directory_suffix(Suffix0, Suffix, Dir):-
  489	expand_file_name(Dir, [Dir0]),
  490	map_directory_files(
  491 	 pred([Suffix0,Suffix], [X]:- (	atom_concat(X0, Suffix0, X),
  492					atom_concat(X0, Suffix, Y),
  493					rename_file(X, Y)
  494				)),
  495	Dir0).
  496
  497:- meta_predicate collect_subterm(1,?,?).  498
  499collect_subterm(F, X, Y):- collect_subterm(X, Y0, [], F), sort(Y0, Y).
  500
  501%
  502collect_subterm(X, [X|V], V, F):- call(F, X), !.
  503collect_subterm(X, V, W, F):- compound(X), !,
  504	X=..[_|As],
  505	foldr(	pred(F, [A, P, Q] :- collect_subterm(A, P, Q, F), As, V, W)).
  506collect_subterm(_, V, V, _).
  507
  508% :- dynamic calls/2.
  509% % from swi library.
  510% assert_call_graph :-
  511%         retractall(calls(_, _)),
  512%         prolog_walk_code([ trace_reference(_),
  513%                            on_trace(assert_edge),
  514%                            source(false)
  515%                          ]),
  516%         predicate_property(calls(_,_), number_of_clauses(N)),
  517%         format('Got ~D edges~n', [N]).
  518
  519% assert_edge(Callee, Caller, _Where) :-
  520%         calls(Caller, Callee), !.
  521% assert_edge(Callee, Caller, _Where) :-
  522%         assertz(calls(Caller, Callee)).
  523
  524%
  525predicate_arity(F, L):-
  526	setof(P/N,
  527		A^X^(	predicate_property(A:X, file(F)),
  528			functor(X, P, N)
  529		  ),
  530	      L),
  531	insert(", ", L, L0),
  532	smash(["[", L0, "]"]).
  533
  534%
  535predicate_arity_for_export(F,  L):-
  536	writeln('start ...'),
  537	assert_call_graph,
  538	writeln('call graph done'),
  539	find_exportables_from_calls(F, L).
  540
  541% ?- qcompile(zdd(zdd)), module(zdd).
  542
  543
  544% ?- find_exportables_from_calls('/Users/cantor/local/lib/pacpl7/engine.pl', Expo), insert(",\n", Expo, E), maplist(write, E).
  545
  546find_exportables_from_calls(Loc,  Exp):-
  547	predicate_arity(Loc,  L0),
  548	setof(F/N, P^X^(
  549			member(F/N, L0),
  550			functor(P, F, N),
  551			once(calls(X,  user:P)),
  552			\+ predicate_property(X, file(Loc))
  553		       ),
  554	      Exp),
  555	insert(",\n", Exp, E),
  556	maplist(write, E).
  557
  558
  559% ?- calls(X, user:assocq(_,_,_)), predicate_property(X, file(A)).
  560% ?- misc:residue(([a,b,c,d,e]-[a,b]-[c]), R).
  561
  562residue(X-Y,V):-!, residue(X,A),
  563	residue(Y,U),
  564	append(U,V,A).
  565residue(X,X).
  566
  567% ?-  parse_utf8(`My name is 向井 国昭.`, R), smash(R).
  568parse_utf8 --> sed(kanji(A), =(A)),
  569	maplist(pred(([X, Y] :- listp(X), string_codes(Y, X))
  570	       &
  571	       ([X, Y] :- char_code(Y, X)))).
  572
  573kanji(A)  --> w(char(utf8b), A, B), wl(*char(utf8c), B).
  574
  575% ?- misc:cgi_bin_name_edit.
  576%@ true.
  577
  578% For test.
  579% cgi_bin_name_edit :- cgi_bin_name_edit(
  580%      		"/Users/cantor/Desktop/http_request.js",
  581% 		"/Users/cantor/Desktop/http_request1.js").
  582% for test.
  583% cgi_bin_name_edit :- cgi_bin_name_edit(
  584% 	 	"/Users/cantor/local/cgi-bin/http_request.js",
  585% 		"/Users/cantor/Desktop/http_request.js").
  586
  587% cgi_bin_name_edit(In_js_name, Out_js_name) :-  getenv(cgi_bin, U),
  588% 	atomics_to_string([U, /], V),
  589% 	term_string(V, V0),
  590% 	atomics_to_string([V0, ";"], V1),
  591% 	string_codes(V1, V2),
  592% 	setup_call_cleanup(
  593% 	 (	open(In_js_name, read, In),
  594% 		open(Out_js_name, write, Out) ),
  595% 		repeat_line(V2, In, Out),
  596% 	(	close(In),
  597% 		close(Out))).
  598
  599% cgi_bin_name_edit(V, A, B):-
  600% 	head_sed(sed([V],
  601% 		 (wl("[\s\t]*var[\s\t]+CGIBIN[\s\t]*=[\s\t]*", X), wl(".*")),
  602% 		 (X + V)), A, B).
  603%
  604repeat_line(V, In, Out):- read_line_to_codes(In, A),
  605	A \== end_of_file,
  606	cgi_bin_name_edit(V, A, B),
  607	maplist(put_code(Out), B),
  608	put_code(Out, 0'\n),			%%%% '
  609	!,
  610	repeat_line(V, In, Out).
  611repeat_line(_,_,_).
  612
  613
  614% ?- expand_sgn_brace(sgn([a,b]), X).
  615% ?- expand_sgn_brace((sgn([a,b]), sgn([c,d])), X).
  616expand_sgn_brace(sgn([A,A0|B]),(A1;A2)):-!,
  617	expand_sgn_brace(sgn([A]),A1),
  618	expand_sgn_brace(sgn([A0|B]),A2).
  619expand_sgn_brace(sgn([A]),A1):-!,expand_sgn_brace(A,A1).
  620expand_sgn_brace((A,B),(A1,A2)):-!,expand_sgn_brace(A,A1),
  621	expand_sgn_brace(B,A2).
  622expand_sgn_brace((A;B),(A1;A2)):-!,expand_sgn_brace(A,A1),
  623	expand_sgn_brace(B,A2).
  624expand_sgn_brace(\+A,\+A1):-!,expand_sgn_brace(A,A1).
  625expand_sgn_brace(A/N,A0/N):-!,expand_sgn_brace(A,A0).
  626expand_sgn_brace(X,A1):-is_list(X),!,
  627	maplist(expand_sgn_brace,X,A1).
  628expand_sgn_brace(X,X).
  629
  630% Samples defining functions on a sort of expressions.
  631
  632% ?- listing(list_plus).
  633% ?- misc:list_plus([a,b,c]+[d,e,f]+[g,h,i], R).
  634
  635list_concat(X+Y,A1):-list_concat(X,A2),
  636	list_cocnat(Y,A3),
  637	append(A2,A3,A1) .
  638list_concat(X,X).
  639
  640
  641% ?- listing(my_add).
  642% ?- misc:my_add(1+2+3+4+5, R).
  643my_add(X+Y,A1):- my_add(X,A2),
  644	my_add(Y,A3),
  645	plus(A2,A3,A1).
  646my_add(X,X).
  647
  648% ?- misc:string_rev(rev("abc"), R).
  649%@ R = "cba" .
  650% ?- write_canonical([rev/1-misc:string_reverse]).
  651%@ [:(-(/(rev,1),misc),string_reverse)]
  652
  653% list_plus		:= [(+)/2-append].
  654% list_rev		:= [rev/1-reverse].
  655% list_plus_rev	:= (list_plus + list_rev).
  656% list_plus_only	:= (list_plus_rev \ list_rev).
  657
  658% % string sort.
  659% % ?- misc:string_plus_rev(rev(rev("abc")+rev("def")), R).
  660% %@ R = "defabc" .
  661
  662% string_plus		:= [(+)/2- string_concat].
  663% string_rev		:= [rev/1- (misc:pred(([X, Y]:-
  664% 								string_codes(X, X0),
  665% 								reverse(X0, Y0),
  666% 								string_codes(Y, Y0))))].
  667% string_plus_rev	:= (string_plus + string_rev).
  668% string_plus_rev_meet := (string_plus * string_rev).
  669% string_plus_only	:= (string_plus_rev \ string_rev).
  670
  671% empty_sgn := [].
  672
  673% Example uses of @
  674% uuu(A,B) --> A@B.
  675% vvv(A,B) --> #(A)@B.
  676% www(A, B) --> fun([X,Y,Z]->(X@Y@Z))@A@B.
  677%?- misc:www(append, [a,b], [c,d], R).
  678%@ R = [a, b, c, d].
  679% ?- call(fun([F,X]-> F@X), append([a,b]), [c,d], R).
  680%@ R = [a, b, c, d].
  681
  682% DISCOURSE by @brebs
  683
  684% ?- split_list_at_nth1(N, [a,b,c], [X|T], End).
  685% ?- split_list_at_nth1(N, [a,b,c], St, [a,b,c|T]).
  686% ?- trace, split_list_at_nth1(N, [a,b], Start, End).
  687split_list_at_nth1(Nth1, Long, Start, End) :-
  688    (   nonvar(Nth1) -> must_be(nonneg, Nth1), Once = true
  689    ;   is_list(Long), once(is_list(Start) ; is_list(End)) -> Once = true
  690    ;   is_list(End), is_list(Start) -> Once = true
  691    ;   Once = false
  692    ),
  693    split_list_at_nth1_(Long, 0, Nth1, Once, Start, End).
  694
  695split_list_at_nth1_(L, N, N, Once, [], L) :-
  696    (Once == true -> ! ; true).
  697split_list_at_nth1_([H|T], N, Nth1, Once, [H|Upto], End) :-
  698    N1 is N + 1,
  699    split_list_at_nth1_(T, N1, Nth1, Once, Upto, End)