1:- module(snippets,
    2	  [show_digraph/1, show_digraph/2,
    3	   term_to_graph/4, graph_to_dot/2,
    4	   clean_paragraph/2,
    5        al/2, ans/2, ans/3, anseq/2, asy/2, ax/2, bc/2,
    6	bcopy/2, bv/2, c/2, cl/2, clr/2, cp/2, cp_sample/2, csvcols/2,
    7	csvcols/3, d/2,
    8	dcl/3, detex/2, df/2, ds/2, e/2,
    9	e/3, e_/2, e_/3,
   10	environment/3,
   11	lin_sol/2, lip/2, lqa/2, lsample/2, ltx/2, m/2, marriage/3, mc/2,
   12	mm/2, mmm/2, msmp/3, mt/2, mtex/2, mv/2, nax/2, ndf/2, nlatitem/2,
   13	npr/2, o/2, oh/2, ol/2, open_pdf/2, pcopy/2, pdo/2, pdot/2,
   14	pf/2, pipe/3, pm/2, pp/2, pr/2, prf/2, prove_full/2, prove_monadic/2,
   15	pt/2, ptex/2, qalist/2, qar/2, query_ans_buffer_html/3,
   16	query_ans_buffer_html_/3, r/2, r_term_dot/2, r_term_dot/3,
   17	region_lines/3, s/2, s_/2, sa/2, sa_/2, sbc/2, script_size/2, seth/2,
   18	setp/2, show_set_in_tex/2,
   19	tabcols/3, tc/2, term_dot/1, term_dot/2, tex_kanji/2, tk/2, try/2,
   20	ttb/2, tth/2, ttl/2, ttm/2, tto/2, ttq/2, tts/2, ttt/2, ttx/2, ul/2,
   21	uptex/2, verb/2, x/2, xetex/2]).   22%
   23:- use_module(util(misc)).   24% :- expects_dialect(pac).
   25term_expansion --> pac:expand_pac.
   26% :- use_module(pac('expand-pac')).
   27% term_expansion --> expand_pac.
   28
   29:- use_module(pac(basic)).   30:- use_module(pac(op)).   31
   32clean_paragraph --> paragraph,
   33	maplist(phrase((split, remove([])))),
   34	remove([]).
   35
   36% ?- environment(itemize, `a\n`, R), smash(R).
   37% ?- environment(itemize, `\n\na\n\n\n`, R), smash(R).
   38environment(E) --> clean_paragraph,
   39	maplist(pred([X, ["\\item ", Y]]:- insert("\n", X, Y))),
   40	insert("\n"),
   41        peek(X, ["\\begin{", E, "}\n", X, "\n\\end{", E, "}\n"]).
   42
   43%
   44enum	-->	region, environment(enumerate), overwrite.
   45
   46eit	-->	region, environment(itemize), overwrite.
   47
   48%
   49lip --> region, paragraph, remove([]),
   50	maplist(pred([X, ["<li> ", X, "</li>"]])),
   51	insert("\n\n"),
   52	overwrite.
   53
   54li --> region, split, remove([]),
   55	maplist(pred([X, ["<li> ", X, "</li>"]])),
   56	insert("\n\n"),
   57	overwrite.
   58
   59ul --> region, peek(X, ["<ul>\n", X, "</ul>\n"]), overwrite.
   60
   61ol --> region, peek(X, ["<ol>\n", X, "</ol>\n"]), overwrite.
   62
   63% ?- trace, eval_markup_text(`@ (=).\n hello`, R).
   64
   65%  [2010/09/27]
   66ep --> region, parse_bind_context, clear.
   67ep0 --> region, parse_bind_context.
   68%  [2013/05]
   69epr --> region, eval_markup_text, clear.
   70epr0 --> region, eval_markup_text.
   71
   72%
   73sbc --> region, pred([X, X] :- save_bc(X)), clear.
   74sbc --> peek("parse fail.\n").
   75
   76bc --> region,
   77	pac([D, D]:-
   78		(	nb_getval(saved_bc, G),
   79			bind_context(([com(G, D)], []), (_, _))
   80		)
   81	),
   82	clear.
   83bc --> peek("fail.\n").
   84
   85% [2011/05/06]
   86ds -->  region, wrap_sort_def, overwrite.
   87
   88% [2010/12/05]
   89pm --> region, parse_mimetex([mimetex_name(mimetex)]).
   90
   91open_pdf --> region, mac_open("~/Cabinet/chronicle/2009/scansnap"), clear.
   92
   93
   94% dbg --> split,
   95%	remove([]),
   96%	maplist(phrase((herbrand(_), eval, herbrand_opp))),
   97%	insert(`\n`).
   98
   99c --> elisp:wdf.
  100
  101pp(X/N, L):- functor(P, X, N), source_file(P, L).
  102
  103fp(X)-->elisp:find_pred(X).
  104
  105marriage(N) --> marriage:marriage(N).
  106
  107%%
  108x --> {elisp:line_exec}.
  109
  110pdo --> {platex_buffer}.
  111
  112% math viewer
  113mv --> region, latex:math_view, clear.
  114
  115ptex --> {latex_control:latex_control(ptex, latex_control:jarticle)}.
  116uptex --> {latex_control:latex_control(uptex, latex_control:uarticle)}.
  117xetex --> {latex_control:latex_control(xetex, latex_control:xarticle)}.
  118pdot --> {latex_control:latex_control(ptex, latex_control:powerdot)}.
  119
  120%
  121pf --> region, proof_figure.
  122pt --> region, prooftree:proof_platex_region.
  123
  124%
  125cl --> elisp:mark_whole_buffer, elisp:check_length_region.
  126clr --> elisp:check_length_region.
  127
  128ltx --> {pdflatex_current_buffer_file}, clear.
 asymptote
  131asy --> {asy_current_buffer_file}, clear.
  132
  133% help(X) :- system:help(X).
  134% apr(X) :- system:apropos(X).
  135% listing :- system:listing.
  136% listing(X) :- system:listing(X).
  137
  138% ?- make_stable_marriage_problem(3, Y, Z).
  139msmp(X, Y, Z):- make_stable_marriage_problem(X, Y, Z),
  140	maplist(writeln, Y), nl,nl,
  141	maplist(writeln, Z).
  142
  143% lsample --> e(fun(prover:refute_with_support)).
  144lsample --> e(fun(fol)).
  145
  146prove_monadic --> region, herbrand, folm, smash.
  147prove_full --> region, herbrand, fol, smash.
  148
  149script_size --> region, wrap(`{\\scriptsize\n`, `}`), overwrite.
  150
  151'M' --> eit.
  152
  153tab_to_spaces --> region, listsubst([(`\t`, `    `)]), overwrite.
  154
  155bv --> region, verb, overwrite.
  156verb --> peek(X, [`\\verb|`, X, `|`]).
  157pcopy --> {copy_mirror_pdf(map_mirror)}.
  158bcopy --> {copy_mirror_buffer(map_mirror)}.
  159
  160%
  161pipe(F)--> pipe_to_obj, phrase(F), obj_to_pipe.
  162dcl(D) --> snd(obj_put(D)).
  163mtex --> pipe(mimetex).
  164hopen--> pipe(browse).
  165qalist--> pipe(question_button_list).
  166
  167%%%% create html
  168%% logic-exercise バッファにて::  e(fun(fol))  => logic-exercise.html
  169%% logic-exercise バッファにて::  eho(fun(fol))  => deldel.thml
  170query_ans_buffer_html(X) --> region, query_ans_buffer_html_(X).
  171
  172query_ans_buffer_html_(X) --> buffer_html(query_ans_html(X, ol)), clear.
  173
  174e --> query_ans_buffer_html(eval).
  175e(S) --> query_ans_buffer_html(eval(S)).
  176s --> query_ans_buffer_html(solve).
  177sa --> query_ans_buffer_html(solve_all).
  178
  179e_ --> query_ans_buffer_html_(eval).
  180e_(S) --> query_ans_buffer_html_(eval(S)).
  181s_ --> query_ans_buffer_html_(solve).
  182sa_ --> query_ans_buffer_html_(solve_all).
  183
  184%%%%
  185%   ex.  f(rubic:rubic)
  186%   f(id) ::  1 <cr> 2
  187%   eho ::  append([1,2,3], [4,5,6])
  188%   ex_infomath --> query_ans_html(infomath('deldel.html'),
  189%      eval(fun(id)), ol).
  190%
  191% f(F) --> query_ans_html(test('deldel.html'), eval(fun(F)), ol).
  192% eho    --> query_ans_html(test('deldel.html'), eval, ol).
  193% eho(S) --> query_ans_html(test('deldel.html'), eval(S), ol).
  194% solve  --> query_ans_html(test('deldel.html'), solve, ol).
  195% solve_all --> query_ans_html(test('deldel.html'), solve_all, ol).
  196
  197% f_(F) --> query_ans_html_(test('deldel.html'), eval(fun(F)), ol).
  198% eho_    --> query_ans_html_(test('deldel.html'), eval, ol).
  199% eho_(S) --> query_ans_html_(test('deldel.html'), eval(S), ol).
  200% solve_  --> query_ans_html_(test('deldel.html'), solve, ol).
  201% solve_all_ --> query_ans_html_(test('deldel.html'), solve_all, ol).
  202
  203%%%%%
  204% ttb:: [1,2]+[3,4]
  205ttb --> region, set_calc_html.
  206% ttt:: [1,2]+[3,4]
  207ttt --> region, herbrand, term_value, peek(X, [`$`, X, `$`]), overwrite.
  208% ttm:: [1,2]+[3,4]
  209ttm --> region, herbrand, term_value(set_tex), overwrite.
  210% ttl:: [1,2]+[3,4]
  211ttl --> region, query_ans_html(eval(set), ol), html_show. % [//]
  212% tto:: [1,2]+[3,4]
  213tto --> region, query_ans_html(eval(set), ol), overwrite.
  214% tth:: [1,2]+[3,4]
  215tth --> region, herbrand, set_mimetex, html_show.
  216% ttx: [1,2]+[3,4]
  217ttx --> region, herbrand, set_mimetex, overwrite.
  218% ttq: [1,2]+[3,4]
  219ttq --> region, herbrand, set_pred, overwrite.
  220% tts: [1,2]+[3,4]
  221tts --> region, herbrand, ans_button_set, overwrite.
  222% seth :: pow([1,2,3])
  223seth --> region, show_set_in_tex, html_show.
  224% setp :: pow([1,2,3])
  225setp --> region, show_set_in_tex, overwrite.
  226
  227show_set_in_tex --> split,
  228	remove([]),
  229	maplist(phrase((herbrand, set_pred, tag(li)))),
  230	tag(ol).
  231
  232hc --> region,	peek(A, [`<center>\n`, A, `<br>\n</center>\n`]), overwrite.
  233
  234% % sweep ::  x+y=1; x+2*y=5/****
  235% /**  :: er
  236% #  flatten, herbrand, matrix:solve_equations
  237% x+y=1;
  238% x-y=1
  239% [y, x]=[0, 1]  ***/
  240
  241lin_sol --> sweep.
  242sweep --> region, herbrand, matrix:solve_equations, smash.
  243
  244eq -->  region, env_equation(``),  overwrite.
  245eql --> region, env_equation(`\\label{eq:}`), smash, current(X),
  246       overwrite, { elisp:goto_char(`\\label{eq:`, X) }.
  247go --> region, herbrand(_), phrase, clear.
  248cp_sample--> {filepath(test('deldel.html'), A),
  249	 filepath(mathcgi('fpop-sample.html'), B),
  250	 sh(cp(A, B))}.
  251
  252cp --> region, herbrand, filepath,
  253	{filepath(test('deldel.html'), A) },
  254	#(B, sh(cp(A, B))).
  255
  256%%%%%%% mimetex for question and answer HTML %%%%%%
  257oh  --> { html:open_current_html }, clear.
  258
  259%%% html file
  260hs --> region,
  261	obj_init(text, [file_name(test('deldel.html'))]),
  262	browse,
  263	clear.
  264
  265mt  --> html(test('temporal.html'), id, (question(mimetex), tag(p))).
  266lim --> region, question(mimetex), peek(A, [`<li>`, A, `</li>`]), overwrite.
mm --> region, question(mimetex), overwrite.
  270mm --> region, parse_mimetex([]), overwrite.
  271mmm --> question(mimetex).
  272mc --> region,
  273	current(X),
  274	{ parse_mimetex((X, [mimetex_name(mimetexcode)]), (Y, _)) },
  275	peek(Y),
  276	overwrite.
  277
  278%%% answer part
  279ans        --> ans([]).
  280anseq      --> ans([`=`]).
  281ans(Options) --> region, mm_answer(ans, Options), overwrite.
  282
  283qar --> region,
  284	paragraph,
  285	remove([]),
  286	sed(qamimetex(mimetex, ans, tag(li), [])),
  287	tag(ul).
  288
  289m --> message.
  290o --> overwrite.
  291r --> region.
  292d --> dired.
  293
  294detex --> region, (tex:tex_parse), detex_rule, overwrite.
  295
  296tk --> {ensure_loaded('convert-dcg')}, tex_kanji.
  297tex_kanji --> region, texparse,
  298	eval([tex_kanji_rule, detex_rule, ps]),
  299	overwrite.
  300
  301corona --> tex(drop3zw).
  302
  303enclose_env(E) --> peek(X, ["\\begin{", E, "}\n", X, "\\end{", E, "}"]).
  304
  305nlatitem --> texparse, eval(texadjust), tex_codes.
  306ip       --> region, insert_pause, overwrite.
  307
  308t2p      --> texparse, eval(try2problem), tex_codes.
  309nax      --> named_env(ax).
  310ndf      --> named_env(df).
  311npr      --> named_env(prop).
  312try      --> enclose_env(try).
  313ax       --> enclose_env(ax).
  314ex       --> enclose_env(ex).
  315df       --> enclose_env(df).
  316pr       --> enclose_env(prop).
  317prf      --> enclose_env(proof).
  318en       --> enclose_env(enumerate).
  319al       --> enclose_env(align).
  320it       --> enclose_env(itemize).
  321lqa      --> qa(longans).
  322
  323js      --> region, peek(X, [`<script>`,X,`</script>`]), overwrite.
  324tc      --> region, peek(X, [`<code>`,X,`</code>`]), overwrite.
  325
  326% ?- edit(enum).
  327sol --> region, herbrand, matrix:solve_equations.
  331region_lines(X)-->region, split, remove([]), maplist(phrase(X)).
  332
  333%
  334csvcols --> csv:columns([1,6], `,`, `\n`).
  335
  336csvcols(X) --> csv:columns(X, `,`, `\n`).
  337
  338tabcols --> csv:columns([1,4], `\t`, `\n`).
  339
  340tabcols(X) --> csv:columns(X, `\t`, `\n`).
?- term_dot(f([a,b,c])). ?- term_dot(f(a, g(b1,b2,b3), c)).
?- graphviz:term2. @ true.% ?- graphviz:term2. @ true. ?- sld2.
  353%%%%%%%
  354r_term_dot --> r_term_dot(pdf).
  355r_term_dot(Toption) --> region, herbrand, current(X),
  356	{term_dot(Toption, X)},
  357	clear.
  358
  359term_dot(X):- term_dot(pdf, X).
  360%
  361term_dot(Toption, X):- use_module(graphviz),
  362          graphviz:term(X),
  363	  sh(dot( -'T'(Toption), -o('__term.'+ Toption), 'term.dot');
  364	       open('__term.'+Toption)).
  365
  366
  367		/**********************
  368		*     show digraph    *
  369		**********************/
  370
  371% ?- snippets:show_digraph(subgraph(g, graph([rankdir = "LR"]); a-[b,c];x-y;u->v)).
  372% ?- snippets:show_digraph(subgraph(g, graph([rankdir = "LR"]); {rank=same; a; u}; a-[b,c];x-y;u->v)).
  373% ?- snippets:show_digraph(subgraph(g, graph([rankdir = "LR"]); a-[b,c]; x-y; u->v)).
  374% ?- snippets:show_digraph(subgraph(g, [a(b,c),x(y)]); y->a; x->c).
  375%@ true.
  376% ?- snippets:show_digraph(subgraph(g, [a(b,c)]); subgraph(h,[x(y)]); y->a; x->c).
  377% ?- snippets:show_digraph(subgraph(cluster_g, [a(b,c)]); subgraph(cluster_h,[x(y)]); y->a; x->c).
  378% ?- snippets:show_digraph(rankdir="LR"; node([shape=oval]); a->b).
  379% ?- snippets:show_digraph(a->a->b->c->d).
  380% ?- snippets:show_digraph([x, y, a->b->c->d]).
  381% ?- snippets:show_digraph([x,y]).
  382% ?- snippets:show_digraph([x->y@[color = red]]).  %% << error
  383% ?- snippets:show_digraph(x->y@[color = red]).
  384% ?- snippets:show_digraph(x@[color = red, style=filled]).
  385% ?- snippets:show_digraph(node([shape = box; color = red]); [x, y, a->b->c->d]).
  386% ?- snippets:show_digraph([a(a)]).
  387% ?- snippets:show_digraph([a(a,b,c)]).
  388% ?- snippets:show_digraph([s(y,m), k(y,m)]; rankdir = "LR").
  389% ?- snippets:show_digraph([s(y,m), k(y,m)]; node([shape=point]); rankdir = "LR").
  390% ?- snippets:show_digraph(subgraph("clusterABC", [s(y,m), k(y,m)])).
  391% ?- snippets:show_digraph(a->b->c->d; subgraph("ABC", [s(y,m), k(y,m)])).
  392%@ true.
  393
  394show_digraph_default(
  395	[ out(pdf),
  396	  counter_name(graph_counter),
  397	  stem("dot_graph"),
  398	  directory(D)
  399	]):- getenv(home, H),
  400	     atomics_to_string([H,/,'Desktop', /, '_iMG_TMP'], D).
  401%
  402
  403%
  404show_digraph(X) :-  show_digraph_default(Opts),
  405    once(show_digraph(X, Opts)).
  406
  407%
  408show_digraph(G, Opts) :-
  409	once(term_to_graph(G, H, E, N)),
  410	once(graph_to_dot(digraph(g, H, E, N), Digraph)),
  411	new_base_name(Opts, OX),
  412	obj(get([file(U)]), OX, _),
  413	atomics_to_string([U, ".dot"], DOT),
  414	atomics_to_string([U, ".pdf"], PDF),
  415	file(DOT, write, smash(Digraph)),
  416	sh(dot(-'T'(pdf), -o(PDF), DOT)),
  417	sh(open(PDF)).
  418
  419
  420		/****************************
  421		*     Graphviz interface    *
  422		****************************/
  423
  424% [2015/04/16]
  425% ?- snippets:term_to_graph([s(m,y), k(m, y)], H, E, N).
  426% ?- snippets:term_to_graph([a(1),b(1)], H, E, N).
  427% ?- snippets:term_to_graph(a->a, H, E, N).
  428% ?- snippets:term_to_graph(a->a->b->c->d,H, E, N).
  429% ?- snippets:term_to_graph(x-[a,b,c], H, E, N).
  430% ?- snippets:term_to_graph([x-[a,b,c]], H, E, N).
  431% ?- snippets:term_to_graph(a=b; c=d, H, E, N).
  432% ?- snippets:term_to_graph(subgraph(s, a=b; c=d); u->v, H, E, N).
  433% ?- snippets:term_to_graph(a@b; c=d, H, E, N).
  434% ?- snippets:term_to_graph(subgraph(cluster1, [1-[a]]),  H, E, N).
  435
  436term_to_graph(G, H, E, N):- term_to_graph(G, H,[], E,[], N, []).
  437
  438%
  439term_to_graph(digraph(G, Body),
  440	      [digraph(G, Head, E0, N0)|H], H, E, E, N, N):-!,
  441	term_to_graph(Body, Head, [], E1, [], N1, []),
  442	sort(E1, E0),
  443	sort(N1, N0).
  444term_to_graph(subgraph(G, Body),
  445	      [subgraph(G, Head, E0, N0)|H], H, E, E, N, N):-!,
  446	term_to_graph(Body, Head, [], E1, [], N1, []),
  447	sort(E1, E0),
  448	sort(N1, N0).
  449term_to_graph(nopac({G}), H, H0, E, E0, N, N0):- !,
  450	term_to_graph(G, H, H0, E, E0, N, N0).
  451term_to_graph((G;G0), H, H0, E, E0, N, N0):- !,
  452	term_to_graph(G, H, H1, E, E1, N, N1),
  453	term_to_graph(G0, H1, H0, E1, E0, N1, N0).
  454term_to_graph((G,G0), H, H0, E, E0, N, N0):- !,
  455	term_to_graph(G, H, H1, E, E1, N, N1),
  456	term_to_graph(G0, H1, H0, E1, E0, N1, N0).
  457term_to_graph(X@A, [X@A|H], H, E, E, N, N):-!.
  458term_to_graph(X->(Y@A), [(X->Y)@A|H], H, E, E, N, N):-!.
  459term_to_graph(X->Y, H, H, E, E0, [X|N], N0):-!,
  460	flatten(->, X->Y, Ns),
  461	append(Ns, N0, N),
  462	list_to_links(Ns, E, E0).
  463term_to_graph(X-Y, H, H, E, E0, [X|N], N0):-!,
  464	term_to_arrows(Y, X, E, E0, N, N0).
  465term_to_graph(X, H, H, E, E, [X|N], N):- atomic(X), !.
  466term_to_graph(X, H, H, E, E0, N, N0):- is_list(X), !,
  467	term_to_arrows(X, E, E0, N, N0).
  468term_to_graph(X, [X|H], H, E, E, N, N).
  469
  470% ?- trace, snippets:term_to_graph(subgraph(cluster1, [a-[1]]), H, E, N).
  471%@ H = [subgraph(cluster1, [], [(a->1)], [1, a])],
  472%@ E = N, N = [].
  473
  474
  475%
  476list_to_links([A, B|R], [A->B|E], E0):-
  477	list_to_links([B|R], E, E0).
  478list_to_links([_], E, E).
  482term_to_arrows(A-B, F, [F->A|E], E0, [A|N], N0):- !,
  483	term_to_arrows(B, A, E, E0, N, N0).
  484term_to_arrows(A->B, F, [F->A|E], E0, [A|N], N0):- !,
  485	term_to_arrows(B, A, E, E0, N, N0).
  486term_to_arrows([A|As], F, E, E0, N, N0):- !,
  487	term_to_arrows(A, F, E, E1, N, N1),
  488	term_to_arrows(As, F, E1, E0, N1, N0).
  489term_to_arrows([], _, E, E, N, N):- !.
  490term_to_arrows(A, F, [F->G|E], E0, [G|N], N0):-
  491	A =..[G|As],
  492	term_to_arrows(As, G, E, E0, N, N0).
  493
  494%
  495term_to_arrows(A-B, E, E0, [A|N], N0):- !,
  496	term_to_arrows(B, A, E, E0, N, N0).
  497term_to_arrows(A->B, E, E0,[A|N], N0):- !,
  498	term_to_arrows(B, A, E, E0, N, N0).
  499term_to_arrows([X|R], E, E0, N, N0):- !,
  500	term_to_arrows(X, E, E1, N, N1),
  501	term_to_arrows(R, E1, E0, N1, N0).
  502term_to_arrows([], E, E, N, N):-!.
  503term_to_arrows(X, E, E0, [F|N], N0):-!, X =.. [F|As],
  504	term_to_arrows(As, F, E, E0, N, N0).
  505
  506%
  507graph_to_dot(digraph(G, H, E, N),
  508		      [ "digraph ", G0, " {\n", Body, "\n}\n"]):-
  509	    term_string(G, G0),
  510	    maplist(graph_to_dot, [H, N, E], Body).
  511graph_to_dot(subgraph(G, H, E, N),
  512		      [ "subgraph ", G0, " {\n", Body, " };\n"]):-
  513	    term_string(G, G0),
  514	    maplist(graph_to_dot, [H, N, E], Body).
  515graph_to_dot(X,  Y):- is_list(X), !, maplist(graph_to_dot, X, Y).
  516graph_to_dot(@(X, A), D):- !, graph_to_dot(X, A, D).
  517graph_to_dot(X, [ F0, " [", A0,  "];\n" ]):- X =.. [F, A], !,
  518	term_string(F, F0),
  519	flatten_term_string(A, A0).
  520graph_to_dot(X, [Y, ";\n"]):- term_string(X, Y).
  521
  522%
  523graph_to_dot(rank, [A|D], ["{rank=", A, "; ", D0, "};\n"]):- !,
  524	flatten_list(D, D1, [], ;),
  525	maplist(term_string, D1, D2),
  526	insert("; ", D2, D0).
  527graph_to_dot(X,  D, [ X0, " [", D0,  "];\n" ]):-
  528	term_string(X, X0),
  529	flatten_term_string(D, D0).
  530
  531% ?- snippets:flatten_list([a;b,b;c],X,[],;).
  532%@ X = [a, b, b, c].
  533
  534flatten_term_string(X, Y):- flatten_list(X, X0, [], ;),
  535	maplist(term_string, X0, X1),
  536	insert(", ", X1, Y).
  537
  538%
  539flatten_list([], A, A, _).
  540flatten_list([X;Y|Z], A, B, ;):- !,
  541	flatten_list([X], A, C, S),
  542	flatten_list([Y], C, D, S),
  543	flatten_list(Z, D, B, S).
  544flatten_list([X|R], [X|A], B, S):- flatten_list(R, A, B, S)