1 | % (c) 2009-2019 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, | |
2 | % Heinrich Heine Universitaet Duesseldorf | |
3 | % This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) | |
4 | ||
5 | :- module(tools_printing,[ | |
6 | print_term_summary/1, print_term_summary_hash/1, | |
7 | print_term_summary_wo_nl/1, | |
8 | print_functor/1, | |
9 | print_var/1, print_vars/1, | |
10 | watch/3, | |
11 | trace_unify/2, trace_print/1, trace_print/2, | |
12 | print_error/1, | |
13 | print_message_on_output/2, | |
14 | format_error/2, | |
15 | print_red/2, print_red/1, print_green/1, | |
16 | format_with_colour/4, | |
17 | start_terminal_colour/2, | |
18 | reset_terminal_colour/1, | |
19 | print_time_stamp/1, | |
20 | print_dynamic_pred/3, print_dynamic_fact/1, | |
21 | print_goal/1, | |
22 | nested_print_term/2 | |
23 | ]). | |
24 | ||
25 | ||
26 | :- use_module(module_information). | |
27 | :- module_info(group,infrastructure). | |
28 | :- module_info(description,'This module contains printing/debug helper predicates.'). | |
29 | ||
30 | :- use_module(library(terms),[term_hash/2]). | |
31 | print_term_summary_hash(T) :- print_term_summary(T), | |
32 | term_hash(T,H), %% (H=179896960 -> trace ; true), %% | |
33 | format('Hash = ~w~n',H). | |
34 | ||
35 | %:- use_module(library(terms),[term_size/2]). | |
36 | print_term_summary(T) :- print_term_summary_wo_nl(T), | |
37 | %term_size(T,Sz), format(' term_size: ~w',[Sz]), | |
38 | nl. | |
39 | ||
40 | print_term_summary_wo_nl(N) :- var(N),!,print('VARIABLE: '),print(N). | |
41 | print_term_summary_wo_nl((A,B)) :- print('('), print_term_summary_wo_nl(A), | |
42 | print(','), print_term_summary_wo_nl(B),print(')'). | |
43 | print_term_summary_wo_nl(clpfd:Call) :- !, print(clpfd:Call). | |
44 | print_term_summary_wo_nl(Module:Call) :- !, | |
45 | print(Module), print(':'),print_term_summary_wo_nl(Call). | |
46 | print_term_summary_wo_nl(bind(Var,Val)) :- !,print_arg(bind(Var,Val)). | |
47 | print_term_summary_wo_nl(N) :- functor(N,F,Arity), print(F), print('/'),print(Arity), | |
48 | N=..[F|Args], l_print_arg(Args). | |
49 | ||
50 | l_print_arg(V) :- var(V),!, print('...'). | |
51 | l_print_arg([]). | |
52 | l_print_arg([H|T]) :- print(': '), print_arg(H), l_print_arg(T). | |
53 | ||
54 | ||
55 | ||
56 | :- use_module(library(avl)). | |
57 | % USE MODULE NOT PERFORMED TO AVOID LOADING translate and all dependent modules | |
58 | %:- use_module(translate,[print_bexpr_with_limit/2, print_bstate/1]). | |
59 | ||
60 | print_arg(N) :- var(N),!,print_var(N). | |
61 | print_arg(int(N)) :- !, (var(N) -> print_var_integer(N) ; print(int(N))). | |
62 | print_arg(float(N)) :- !, print(float(N)). | |
63 | print_arg(fd(N,GS)) :- !, | |
64 | ((number(N),b_global_sets:is_b_global_constant(GS,N,Res)) -> print(Res) | |
65 | ; print('fd('),print_integer(N),format(',~w)',GS)). | |
66 | print_arg(rec(Fields)) :- !, print('rec('), print_arg(Fields),print(')'). | |
67 | print_arg(bind(Var,Val)) :- atomic(Var), !, print(Var),print('/'),print_arg(Val). | |
68 | print_arg(field(Var,Val)) :- atomic(Var), !, print('field('),print(Var),print('/'),print_arg(Val),print(')'). | |
69 | print_arg(typedvalc(Val,Type,VarID,EnumWarning,Card)) :- | |
70 | atomic(VarID), !, format('typedvalc for ~w :(',[VarID]),print_arg(Val), | |
71 | format(',~w,~w,~w) ',[Type,EnumWarning,Card]). | |
72 | print_arg(wfx(A,B,C,D)) :- !, print(wfx(A,B,C,D)). | |
73 | print_arg(Module:Call) :- atomic(Module),!, | |
74 | print(Module), print(':'),print_arg(Call). | |
75 | print_arg(A) :- atomic(A),!, print(A). | |
76 | print_arg(A) :- A=node(_,_,_,_,_),ground(A), !, print('AVLnode.size='),avl_size(A,Sz), print(Sz). | |
77 | print_arg(avl_set(A)) :- ground(A), !, | |
78 | (custom_explicit_sets:singleton_set(avl_set(A),El) -> print('AVL{'),print_arg(El),print('}') | |
79 | ; avl_size(A,Sz), | |
80 | (Sz>3 -> print('AVL.size='),print(Sz) | |
81 | ; custom_explicit_sets:expand_custom_set_to_list(avl_set(A),ESet,_,print_arg), | |
82 | print('AVL{'), l_print_arg(ESet), print('}') | |
83 | ) | |
84 | ). | |
85 | print_arg((A,B)) :- !, print('('),print_arg(A), print(','), print_arg(B), print(')'). | |
86 | print_arg(string(A)) :- !, print('string('),print_arg(A), print(')'). | |
87 | print_arg([]) :- !, print('[]'). | |
88 | print_arg([H|T]) :- T==[], !, print('['),print_arg(H),print(']'). | |
89 | print_arg([H|T]) :- nonvar(T),T=[H2|T2],T2==[], !, | |
90 | print('['),print_arg(H),print(','),print_arg(H2),print(']'). | |
91 | print_arg([H|T]) :- nonvar(H), H=bind(_,_),!, get_list_up_to([H|T],10,S,ALL), | |
92 | translate:print_bstate(S), | |
93 | (ALL=all -> true ; print(', ... ')). | |
94 | print_arg([H|T]) :- list_skeleton_size([H|T],Sz,Type), !, | |
95 | print(Type), | |
96 | ((Type=closed,ground([H|T])) -> print('&ground') ; true), | |
97 | print(' LIST.size='), print(Sz), | |
98 | (Sz<35 -> print(' ['), l_print_arg([H|T]), print(']') ; true). | |
99 | print_arg(closure(P,T,B)) :- !, print('CLOSURE '), | |
100 | (custom_explicit_sets:is_interval_closure(P,T,B,Low,Up) -> print([Low:Up]) | |
101 | ; print(P)). %, print(' | '), print(_B). | |
102 | print_arg(mnf(Call)) :- !, print('mnf('),print_term_summary_wo_nl(Call), print(')'). | |
103 | print_arg(pp_mnf(Call)) :- !, print('mnf('),print_term_summary_wo_nl(Call), print(')'). | |
104 | print_arg(pp_cll(Call)) :- !, print('mnf('),print_term_summary_wo_nl(Call), print(')'). | |
105 | print_arg(b(Expr,T,I)) :- !, | |
106 | (T==pred -> print('PRED(') ; print('BEXPR(')), | |
107 | print_functor(Expr), print(','), | |
108 | translate:print_bexpr_with_limit(b(Expr,T,I),200), print(')'). | |
109 | print_arg(span_predicate(A,B,C)) :- | |
110 | error_manager:extract_line_col(span_predicate(A,B,C),Srow,Scol,Erow,Ecol), !, | |
111 | format('span_predicate(~w:~w-~w:~w)',[Srow,Scol,Erow,Ecol]). | |
112 | print_arg(N) :- print_functor(N). | |
113 | ||
114 | :- use_module(library(clpfd),[fd_dom/2, fd_degree/2, fd_size/2]). | |
115 | print_var(V) :- fd_dom(V,D), D \= inf..sup, fd_size(V,Sz), fd_degree(V,Dg),!, | |
116 | format('INT VAR: ~w:~w [sz:~w,dg:~w] ',[V,D,Sz,Dg]). | |
117 | %print(':('),frozen(V,Goal),write_term(Goal,[max_depth(3)]),print(')'). | |
118 | print_var(V) :- print('VARIABLE: '),print(V), print_frozen_var_info(V). | |
119 | print_var_integer(X) :- print('int(?:'),fd_dom(X,Dom),print(Dom), | |
120 | %print(':('),frozen(X,Goal),print(Goal),print(')') | |
121 | print(')'). | |
122 | ||
123 | % try determine variable type from frozen info | |
124 | print_frozen_var_info(V) :- frozen(V,G), (print_frozen_var_info2(G,V) -> true ; true). | |
125 | print_frozen_var_info2((A,B),V) :- (print_frozen_var_info2(A,V) -> true ; print_frozen_var_info2(B,V)). | |
126 | print_frozen_var_info2(b_interpreter_check:imply_true(_,_,_),_) :- print(' : BOOL'). | |
127 | print_frozen_var_info2(bool_pred:blocking_force_eq(V,_,_),Var) :- Var==V, print(' : BOOL'). | |
128 | print_frozen_var_info2(kernel_equality:eq_empty_set(V,_),Var) :- Var==V, print(' : SET'). | |
129 | % TO DO: add other co-routines for boolean values,... | |
130 | ||
131 | :- use_module(library(lists),[maplist/2]). | |
132 | print_vars(V) :- maplist(tools_printing:print_var,V),nl. | |
133 | ||
134 | print_integer(I) :- (var(I) -> fd_dom(I,Dom), print('?:'),print(Dom) ; print(I)). | |
135 | ||
136 | get_list_up_to([],_,[],all). | |
137 | get_list_up_to([H|T],N,R,ALL) :- | |
138 | (N<1 -> R=[],ALL=no ; N1 is N-1, R=[H|TR], get_list_up_to(T,N1,TR,ALL)). | |
139 | ||
140 | list_skeleton_size(X,Sz,Type) :- var(X),!,Sz=0,Type=open. | |
141 | list_skeleton_size([],0,closed). | |
142 | list_skeleton_size([_|T],N,Type) :- list_skeleton_size(T,NT,Type), N is NT+1. | |
143 | ||
144 | ||
145 | print_functor(N) :- var(N),!,print('VARIABLE: '),print(N). | |
146 | print_functor(N) :- functor(N,F,Arity), print(F), print('/'),print(Arity). | |
147 | ||
148 | % --------------- | |
149 | ||
150 | :- block watch(-,?,?). | |
151 | watch([],N,Pos) :- !,print_data([],N,Pos). | |
152 | watch([H|T],N,Pos) :- !,print_data(H,N,Pos), P1 is Pos+1, watch(H,N,Pos), watch(T,N,P1). | |
153 | watch((P1,P2),N,Pos) :- print_data((P1,P2),N,Pos), watch(P2,N,Pos). | |
154 | watch(Other,N,Pos) :- print_data(Other,N,Pos). | |
155 | print_data(Data,N,Pos) :- print(N), print(' @ '), print(Pos),print(' : '), print(Data),nl. | |
156 | ||
157 | % --------------- | |
158 | ||
159 | :- use_module(library(lists),[maplist/3]). | |
160 | trace_unify(A,B) :- trace_unify_aux(A,B,0). | |
161 | trace_unify_aux(A,B,Lvl) :- (var(A);var(B)),!,indent(Lvl),print(A),print(' <-> '), print(B), | |
162 | if(A=B,true,(print(' FAILS'),nl,fail)),nl. | |
163 | trace_unify_aux(A,B,Lvl) :- functor(A,FA,FAN), functor(B,FB,FBN), | |
164 | indent(Lvl),print(FA/FAN), | |
165 | A=..[_|As], B=..[_|Bs], | |
166 | ((FA,FAN)=(FB,FBN) | |
167 | -> (As=[] -> nl ; print('('),nl,l_trace_unify(As,Bs,Lvl)) | |
168 | ; format(' FUNCTOR MISMATCH : ~w/~w <-> ~w/~w~n',[FA,FAN,FB,FBN]), | |
169 | maplist(abstract_top_level,As,AAs), AA =..[FA|AAs], | |
170 | maplist(abstract_top_level,Bs,ABs), AB =..[FB|ABs], | |
171 | indent(Lvl), | |
172 | format(' TOP: ~w <-> ~w~n',[AA,AB]), | |
173 | fail | |
174 | ). | |
175 | indent(0) :- !. | |
176 | indent(X) :- X>0, print('+-'), X1 is X-1, indent(X1). | |
177 | ||
178 | abstract_top_level(X,R) :- simple(X),!,R=X. | |
179 | abstract_top_level(X,AX) :- functor(X,F,N), functor(AX,F,N). | |
180 | ||
181 | ||
182 | l_trace_unify([],[],L) :- indent(L), print(')'),nl. | |
183 | l_trace_unify([A|TA],[B|TB],Lvl) :- L1 is Lvl+1, trace_unify_aux(A,B,L1), | |
184 | l_trace_unify(TA,TB,Lvl). | |
185 | ||
186 | % --------------- | |
187 | ||
188 | trace_print(A) :- trace_print(A,0,4). | |
189 | trace_print(A,Max) :- trace_print(A,0,Max). | |
190 | ||
191 | trace_print(A,Lvl,MaxLvl) :- Lvl >= MaxLvl,!, indent(Lvl), print(A),nl. | |
192 | trace_print(A,Lvl,_MaxLvl) :- treat_as_atomic(A),!, indent(Lvl), print(A),nl. | |
193 | trace_print([H|T],Lvl,MaxLvl) :- !, indent(Lvl), print('['),nl, | |
194 | l_trace_print([H|T],Lvl,MaxLvl), | |
195 | indent(Lvl), print(']'),nl. | |
196 | %trace_print(A,Lvl,_MaxLvl) :- functor(A,_,1), arg(1,A,AN), atomic(AN),!, indent(Lvl), print(A),nl. | |
197 | trace_print(A,Lvl,_MaxLvl) :- A=..[_|Args], maplist(atomic,Args),!, | |
198 | indent(Lvl), print(A),nl. | |
199 | trace_print(A,Lvl,MaxLvl) :- functor(A,FA,FAN), | |
200 | indent(Lvl),print(FA/FAN),print('('),nl, | |
201 | A=..[_|As], l_trace_print(As,Lvl,MaxLvl). | |
202 | ||
203 | treat_as_atomic(A) :- var(A). | |
204 | treat_as_atomic(A) :- atomic(A). | |
205 | treat_as_atomic(nodeid(pos(_,_,_,_,_,_))). | |
206 | treat_as_atomic(sharing(_,_,_,_)). | |
207 | treat_as_atomic(ID/V) :- treat_as_atomic(ID),treat_as_atomic(V). | |
208 | treat_as_atomic([H|T]) :- T==[], treat_as_atomic(H). | |
209 | ||
210 | l_trace_print([],L,_MaxLvl) :- indent(L), print(')'),nl. | |
211 | l_trace_print([A|TA],Lvl,MaxLvl) :- L1 is Lvl+1, trace_print(A,L1,MaxLvl), | |
212 | l_trace_print(TA,Lvl,MaxLvl). | |
213 | ||
214 | % ----------------------------------- | |
215 | ||
216 | % print on error stream | |
217 | print_error(Error) :- | |
218 | start_terminal_colour([red,bold],user_error), | |
219 | call_cleanup(print_no_col(user_error,Error),reset_terminal_colour(user_error)). | |
220 | %% flush_output(user_error), %%. | |
221 | print_no_col(Stream,ErrorTerm) :- | |
222 | write(Stream,'! '), | |
223 | (var(ErrorTerm) -> write(Stream,'_') | |
224 | ; write_term(Stream,ErrorTerm,[max_depth(20),numbervars(true)])), | |
225 | nl(Stream). | |
226 | ||
227 | print_message_on_output(Color,Message) :- | |
228 | start_terminal_colour(Color,user_output), | |
229 | call_cleanup(print_no_col(user_output,Message),reset_terminal_colour(user_output)). | |
230 | ||
231 | format_error(Str,Args) :- format_with_colour(user_error,[red,bold],Str,Args). | |
232 | ||
233 | format_with_colour(Stream,Colour,Str,Args) :- | |
234 | start_terminal_colour(Colour,Stream), | |
235 | call_cleanup(format(Stream,Str,Args), | |
236 | reset_terminal_colour(Stream)). | |
237 | ||
238 | :- load_files(library(system), [when(compile_time), imports([environ/2])]). | |
239 | :- if(environ(no_terminal_colors,true)). | |
240 | no_color. | |
241 | print_red(X) :- write(X). | |
242 | print_red(Stream,T) :- write(Stream,T). | |
243 | print_green(X) :- write(X). | |
244 | reset_terminal_colour(_). | |
245 | start_terminal_colour(_,_). | |
246 | :- else. | |
247 | :- use_module(library(system),[environ/2]). | |
248 | no_color :- environ('NO_COLOR',_). % see http://no-color.org | |
249 | print_red(Stream,Term) :- no_color,!, | |
250 | format(Stream,'~w',[Term]). | |
251 | print_red(Stream,Term) :- | |
252 | format(Stream,'\e[31m~w\e[0m',[Term]). | |
253 | ||
254 | print_red(Term) :- no_color,!, | |
255 | format('~w',[Term]). | |
256 | print_red(Term) :- | |
257 | format('\e[31m~w\e[0m',[Term]). | |
258 | ||
259 | print_green(Term) :- no_color,!, | |
260 | format('~w',[Term]). | |
261 | print_green(Term) :- | |
262 | format('\e[32m~w\e[0m',[Term]). | |
263 | ||
264 | reset_terminal_colour(_) :- no_color,!. | |
265 | reset_terminal_colour(Stream) :- write(Stream,'\e[0m'). | |
266 | ||
267 | % see https://misc.flogisoft.com/bash/tip_colors_and_formatting | |
268 | start_terminal_colour(_,_) :- no_color,!. | |
269 | start_terminal_colour(red,Stream) :- !, write(Stream,'\e[31m'). | |
270 | start_terminal_colour(green,Stream) :- !, write(Stream,'\e[32m'). | |
271 | start_terminal_colour(yellow,Stream) :- !, write(Stream,'\e[33m'). | |
272 | start_terminal_colour(blue,Stream) :- !, write(Stream,'\e[34m'). | |
273 | start_terminal_colour(magenta,Stream) :- !, write(Stream,'\e[35m'). | |
274 | start_terminal_colour(cyan,Stream) :- !, write(Stream,'\e[36m'). | |
275 | start_terminal_colour(light_gray,Stream) :- !, write(Stream,'\e[37m'). | |
276 | start_terminal_colour(dark_gray,Stream) :- !, write(Stream,'\e[90m'). | |
277 | start_terminal_colour(light_red,Stream) :- !, write(Stream,'\e[91m'). | |
278 | start_terminal_colour(light_green,Stream) :- !, write(Stream,'\e[92m'). | |
279 | start_terminal_colour(white,Stream) :- !, write(Stream,'\e[97m'). | |
280 | start_terminal_colour(bold,Stream) :- !, write(Stream,'\e[1m'). | |
281 | start_terminal_colour(underline,Stream) :- !, write(Stream,'\e[4m'). | |
282 | start_terminal_colour(dim,Stream) :- !, write(Stream,'\e[2m'). | |
283 | start_terminal_colour(black_background,Stream) :- !, write(Stream,'\e[49m'). | |
284 | start_terminal_colour(red_background,Stream) :- !, write(Stream,'\e[41m'). | |
285 | start_terminal_colour(green_background,Stream) :- !, write(Stream,'\e[42m'). | |
286 | start_terminal_colour(yellow_background,Stream) :- !, write(Stream,'\e[43m'). | |
287 | start_terminal_colour(white_background,Stream) :- !, write(Stream,'\e[107m'). | |
288 | start_terminal_colour(blink,Stream) :- !, write(Stream,'\e[5m'). | |
289 | start_terminal_colour(reverse,Stream) :- !, write(Stream,'\e[7m'). | |
290 | start_terminal_colour(hidden,Stream) :- !, write(Stream,'\e[8m'). | |
291 | start_terminal_colour(reset,Stream) :- !, write(Stream,'\e[0m'). | |
292 | start_terminal_colour([],_Stream) :- !. | |
293 | start_terminal_colour([H|T],Stream) :- !, start_terminal_colour(H,Stream),start_terminal_colour(T,Stream). | |
294 | start_terminal_colour(C,_Stream) :- format(user_error,'*** UNKNOWN COLOUR: ~w~n',[C]). | |
295 | :- endif. | |
296 | ||
297 | % ----------------------------------- | |
298 | ||
299 | :- use_module(library(system),[datime/1]). | |
300 | ||
301 | print_time_stamp(Stream) :- | |
302 | datime(datime(Year,Month,Day,Hour,Min,Sec)), | |
303 | (Min<10 | |
304 | -> format(Stream,'~w/~w/~w - ~wh0~w ~ws',[Day,Month,Year,Hour,Min,Sec]) | |
305 | ; format(Stream,'~w/~w/~w - ~wh~w ~ws',[Day,Month,Year,Hour,Min,Sec]) | |
306 | ). | |
307 | ||
308 | % ----------------------------------- | |
309 | ||
310 | print_dynamic_pred(InModule,Pred,N) :- nl, | |
311 | write(':- dynamic '), print(Pred), write('/'),print(N), write('.'),nl, | |
312 | functor(Call,Pred,N), | |
313 | call(InModule:Call), write_term(Call,[quoted(true)]),write('.'),nl,fail. | |
314 | print_dynamic_pred(InModule,Pred,N) :- | |
315 | functor(Call,Pred,N), | |
316 | (call(InModule:Call) -> true ; (write_with_numbervars(Call), write(' :- fail.'),nl)), | |
317 | nl. | |
318 | ||
319 | write_with_numbervars(Term) :- copy_term(Term,T), numbervars(T,0,_), | |
320 | write_term(T,[quoted(true),numbervars(true)]). | |
321 | ||
322 | print_dynamic_fact(Fact) :- | |
323 | functor(Fact,Pred,N), | |
324 | print(':- dynamic '), print(Pred), write('/'),print(N), write('.'),nl, | |
325 | write_term(Fact,[quoted(true)]),write('.'),nl. | |
326 | ||
327 | % ----------------------------------- | |
328 | ||
329 | print_goal(V) :- var(V),!, format(' ~w~n',[V]). | |
330 | print_goal([A|B]) :- !,print_goal(A), print_goal(B). | |
331 | print_goal((A,B)) :- !,print_goal(A), print_goal(B). | |
332 | print_goal(A) :- format(' ~w~n',[A]). | |
333 | ||
334 | ||
335 | % ----------------------------------- | |
336 | ||
337 | % possible applicaton: inspect size of terms transmitted to ProB2: | |
338 | % prob2_interface:get_machine_formulas(Formulas), tell('formulasnest.pl'), nested_print_term(Formulas,6),told. | |
339 | ||
340 | nested_print_term(Term,MaxNest) :- nested_print_term(0,MaxNest,Term). | |
341 | ||
342 | indentws(0) :- !. | |
343 | indentws(X) :- X>0, print(' '), X1 is X-1, indentws(X1). | |
344 | ||
345 | :- use_module(library(terms),[term_size/2]). | |
346 | nested_print_term(CurNesting,_Max,T) :- var(T),!, indent(CurNesting),write(T),nl. | |
347 | nested_print_term(CurNesting,_,T) :- atom(T), atom_length(T,Len), | |
348 | indent(CurNesting), | |
349 | (Len > 100 | |
350 | -> atom_codes(T,Codes), length(Prefix,50), append(Prefix,_,Codes), | |
351 | format('atom: len(~w): ~s...~n',[Len,Prefix]) | |
352 | ; format('~w~n',[T])). | |
353 | nested_print_term(CurNesting,_,T) :- number(T), indent(CurNesting), format('~w~n',[T]). | |
354 | nested_print_term(CurNesting,MaxNesting,T) :- CurNesting >= MaxNesting,!, | |
355 | term_size(T,Sz), functor(T,F,N), | |
356 | indentws(CurNesting), | |
357 | (Sz>25000 -> Msg='****' ; Msg=''), format('~w/~w :: sz(~w)~w~n',[F,N,Sz,Msg]). | |
358 | nested_print_term(CurNesting,MaxNesting,T) :- | |
359 | list_skeleton_size(T,Len,closed), term_size(T,Sz),!, | |
360 | indentws(CurNesting),format('[ list_len_sz(~w,~w)~n',[Len,Sz]), | |
361 | C1 is CurNesting+1, | |
362 | maplist(nested_print_term(C1,MaxNesting),T), | |
363 | indentws(CurNesting),format('] list_len(~w)~n',[Len]). | |
364 | nested_print_term(CurNesting,MaxNesting,T) :- | |
365 | term_size(T,Sz), functor(T,F,N), | |
366 | indentws(CurNesting),format('~w/~w( sz(~w)~n',[F,N,Sz]), | |
367 | T =.. [_|Args], C1 is CurNesting+1, | |
368 | maplist(nested_print_term(C1,MaxNesting),Args), | |
369 | indentws(CurNesting),format('~w/~w)~n',[F,N]). | |
370 | ||
371 |