| 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 |