1/* Part of SWI-Prolog 2 3 Author: Jan Wielemaker 4 E-mail: J.Wielemaker@vu.nl 5 WWW: http://www.swi-prolog.org 6 Copyright (c) 2001-2016, University of Amsterdam 7 VU University Amsterdam 8 All rights reserved. 9 10 Redistribution and use in source and binary forms, with or without 11 modification, are permitted provided that the following conditions 12 are met: 13 14 1. Redistributions of source code must retain the above copyright 15 notice, this list of conditions and the following disclaimer. 16 17 2. Redistributions in binary form must reproduce the above copyright 18 notice, this list of conditions and the following disclaimer in 19 the documentation and/or other materials provided with the 20 distribution. 21 22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 25 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 26 COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 27 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 28 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 30 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 32 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 POSSIBILITY OF SUCH DAMAGE. 34*/ 35 36:- module(prolog_listing, 37 [ listing/0, 38 listing/1, 39 portray_clause/1, % +Clause 40 portray_clause/2, % +Stream, +Clause 41 portray_clause/3 % +Stream, +Clause, +Options 42 ]). 43:- use_module(library(lists)). 44:- use_module(library(settings)). 45:- use_module(library(option)). 46:- use_module(library(error)). 47:- set_prolog_flag(generate_debug_info, false). 48 49:- module_transparent 50 listing/0. 51:- meta_predicate 52 listing( ), 53 portray_clause( , , ). 54 55:- predicate_options(portray_clause/3, 3, [pass_to(system:write_term/3, 3)]). 56 57:- multifile 58 prolog:locate_clauses/2. % +Spec, -ClauseRefList
88:- setting(listing:body_indentation, nonneg, 8, 89 'Indentation used goals in the body'). 90:- setting(listing:tab_distance, nonneg, 8, 91 'Distance between tab-stops. 0 uses only spaces'). 92:- setting(listing:cut_on_same_line, boolean, true, 93 'Place cuts (!) on the same line'). 94:- setting(listing:line_width, nonneg, 78, 95 'Width of a line. 0 is infinite').
mymodule
, use:
?- mymodule:listing.
108listing :- 109 context_module(Context), 110 list_module(Context). 111 112list_module(Module) :- 113 ( current_predicate(_, Module:Pred), 114 \+ predicate_property(Module:Pred, imported_from(_)), 115 strip_module(Pred, _Module, Head), 116 functor(Head, Name, _Arity), 117 ( ( predicate_property(Pred, built_in) 118 ; sub_atom(Name, 0, _, _, $) 119 ) 120 -> current_prolog_flag(access_level, system) 121 ; true 122 ), 123 nl, 124 list_predicate(Module:Head, Module), 125 fail 126 ; true 127 ).
?- listing(append([], _, _)). lists:append([], A, A).
148listing(M:Spec) :- 149 var(Spec), 150 !, 151 list_module(M). 152listing(M:List) :- 153 is_list(List), 154 !, 155 forall(member(Spec, List), 156 listing(M:Spec)). 157listing(X) :- 158 ( prolog:locate_clauses(X, ClauseRefs) 159 -> list_clauserefs(ClauseRefs) 160 ; '$find_predicate'(X, Preds), 161 list_predicates(Preds, X) 162 ). 163 164list_clauserefs([]) :- !. 165list_clauserefs([H|T]) :- 166 !, 167 list_clauserefs(H), 168 list_clauserefs(T). 169list_clauserefs(Ref) :- 170 clause(Head, Body, Ref), 171 portray_clause((Head :- Body)).
175list_predicates(PIs, Context:X) :- 176 member(PI, PIs), 177 pi_to_head(PI, Pred), 178 unify_args(Pred, X), 179 list_define(Pred, DefPred), 180 list_predicate(DefPred, Context), 181 nl, 182 fail. 183list_predicates(_, _). 184 185list_define(Head, LoadModule:Head) :- 186 compound(Head), 187 Head \= (_:_), 188 functor(Head, Name, Arity), 189 '$find_library'(_, Name, Arity, LoadModule, Library), 190 !, 191 use_module(Library, []). 192list_define(M:Pred, DefM:Pred) :- 193 '$define_predicate'(M:Pred), 194 ( predicate_property(M:Pred, imported_from(DefM)) 195 -> true 196 ; DefM = M 197 ). 198 199pi_to_head(PI, _) :- 200 var(PI), 201 !, 202 instantiation_error(PI). 203pi_to_head(M:PI, M:Head) :- 204 !, 205 pi_to_head(PI, Head). 206pi_to_head(Name/Arity, Head) :- 207 functor(Head, Name, Arity). 208 209 210% Unify the arguments of the specification with the given term, 211% so we can partially instantate the head. 212 213unify_args(_, _/_) :- !. % Name/arity spec 214unify_args(X, X) :- !. 215unify_args(_:X, X) :- !. 216unify_args(_, _). 217 218list_predicate(Pred, Context) :- 219 predicate_property(Pred, undefined), 220 !, 221 decl_term(Pred, Context, Decl), 222 format('% Undefined: ~q~n', [Decl]). 223list_predicate(Pred, Context) :- 224 predicate_property(Pred, foreign), 225 !, 226 decl_term(Pred, Context, Decl), 227 format('% Foreign: ~q~n', [Decl]). 228list_predicate(Pred, Context) :- 229 notify_changed(Pred, Context), 230 list_declarations(Pred, Context), 231 list_clauses(Pred, Context). 232 233decl_term(Pred, Context, Decl) :- 234 strip_module(Pred, Module, Head), 235 functor(Head, Name, Arity), 236 ( hide_module(Module, Context, Head) 237 -> Decl = Name/Arity 238 ; Decl = Module:Name/Arity 239 ). 240 241 242decl(thread_local, thread_local). 243decl(dynamic, dynamic). 244decl(volatile, volatile). 245decl(multifile, multifile). 246decl(public, public). 247 248declaration(Pred, Source, Decl) :- 249 decl(Prop, Declname), 250 predicate_property(Pred, Prop), 251 decl_term(Pred, Source, Funct), 252 Decl =.. [ Declname, Funct ]. 253declaration(Pred, Source, Decl) :- 254 predicate_property(Pred, meta_predicate(Head)), 255 strip_module(Pred, Module, _), 256 ( (Module == system; Source == Module) 257 -> Decl = meta_predicate(Head) 258 ; Decl = meta_predicate(Module:Head) 259 ), 260 ( meta_implies_transparent(Head) 261 -> ! % hide transparent 262 ; true 263 ). 264declaration(Pred, Source, Decl) :- 265 predicate_property(Pred, transparent), 266 decl_term(Pred, Source, PI), 267 Decl = module_transparent(PI).
274meta_implies_transparent(Head):- 275 compound(Head), 276 arg(_, Head, Arg), 277 implies_transparent(Arg), 278 !. 279 280implies_transparent(Arg) :- 281 integer(Arg), 282 !. 283implies_transparent(:). 284implies_transparent(//). 285implies_transparent(^). 286 287 288list_declarations(Pred, Source) :- 289 findall(Decl, declaration(Pred, Source, Decl), Decls), 290 ( Decls == [] 291 -> true 292 ; write_declarations(Decls, Source), 293 format('~n', []) 294 ). 295 296 297write_declarations([], _) :- !. 298write_declarations([H|T], Module) :- 299 format(':- ~q.~n', [H]), 300 write_declarations(T, Module). 301 302list_clauses(Pred, Source) :- 303 strip_module(Pred, Module, Head), 304 ( clause(Pred, Body), 305 write_module(Module, Source, Head), 306 portray_clause((Head:-Body)), 307 fail 308 ; true 309 ). 310 311write_module(Module, Context, Head) :- 312 hide_module(Module, Context, Head), 313 !. 314write_module(Module, _, _) :- 315 format('~q:', [Module]). 316 317hide_module(system, Module, Head) :- 318 predicate_property(Module:Head, imported_from(M)), 319 predicate_property(system:Head, imported_from(M)), 320 !. 321hide_module(Module, Module, _) :- !. 322 323notify_changed(Pred, Context) :- 324 strip_module(Pred, user, Head), 325 predicate_property(Head, built_in), 326 \+ predicate_property(Head, (dynamic)), 327 !, 328 decl_term(Pred, Context, Decl), 329 format('% NOTE: system definition has been overruled for ~q~n', 330 [Decl]). 331notify_changed(_, _).
If Options is provided, the option-list is passed to write_term/3 that does the final writing of arguments.
347% The prolog_list_goal/1 hook is a dubious as it may lead to 348% confusion if the heads relates to other bodies. For now it is 349% only used for XPCE methods and works just nice. 350% 351% Not really ... It may confuse the source-level debugger. 352 353%portray_clause(Head :- _Body) :- 354% user:prolog_list_goal(Head), !. 355portray_clause(Term) :- 356 current_output(Out), 357 portray_clause(Out, Term). 358 359portray_clause(Stream, Term) :- 360 must_be(stream, Stream), 361 portray_clause(Stream, Term, []). 362 363portray_clause(Stream, Term, M:Options) :- 364 must_be(list, Options), 365 meta_options(is_meta, M:Options, QOptions), 366 \+ \+ ( copy_term_nat(Term, Copy), 367 numbervars(Copy, 0, _, 368 [ singletons(true) 369 ]), 370 do_portray_clause(Stream, Copy, QOptions) 371 ). 372 373is_meta(portray_goal). 374 375do_portray_clause(Out, Var, Options) :- 376 var(Var), 377 !, 378 pprint(Out, Var, 1200, Options). 379do_portray_clause(Out, (Head :- true), Options) :- 380 !, 381 pprint(Out, Head, 1200, Options), 382 full_stop(Out). 383do_portray_clause(Out, Term, Options) :- 384 clause_term(Term, Head, Neck, Body), 385 !, 386 inc_indent(0, 1, Indent), 387 infix_op(Neck, RightPri, LeftPri), 388 pprint(Out, Head, LeftPri, Options), 389 format(Out, ' ~w', [Neck]), 390 ( nonvar(Body), 391 Body = Module:LocalBody, 392 \+ primitive(LocalBody) 393 -> nlindent(Out, Indent), 394 format(Out, '~q', [Module]), 395 '$put_token'(Out, :), 396 nlindent(Out, Indent), 397 write(Out, '( '), 398 inc_indent(Indent, 1, BodyIndent), 399 portray_body(LocalBody, BodyIndent, noindent, 1200, Out, Options), 400 nlindent(Out, Indent), 401 write(Out, ')') 402 ; setting(listing:body_indentation, BodyIndent), 403 portray_body(Body, BodyIndent, indent, RightPri, Out, Options) 404 ), 405 full_stop(Out). 406do_portray_clause(Out, (:-use_module(File, Imports)), Options) :- 407 length(Imports, Len), 408 Len > 3, 409 !, 410 format(Out, ':- use_module(~q,', [File]), 411 portray_list(Imports, 14, Out, Options), 412 write(Out, ').\n'). 413do_portray_clause(Out, (:-module(Module, Exports)), Options) :- 414 !, 415 format(Out, ':- module(~q,', [Module]), 416 portray_list(Exports, 10, Out, Options), 417 write(Out, ').\n'). 418do_portray_clause(Out, (:-Directive), Options) :- 419 !, 420 write(Out, ':- '), 421 portray_body(Directive, 3, noindent, 1199, Out, Options), 422 full_stop(Out). 423do_portray_clause(Out, Fact, Options) :- 424 portray_body(Fact, 0, noindent, 1200, Out, Options), 425 full_stop(Out). 426 427clause_term((Head:-Body), Head, :-, Body). 428clause_term((Head-->Body), Head, -->, Body). 429 430full_stop(Out) :- 431 '$put_token'(Out, '.'), 432 nl(Out).
440portray_body(Var, _, _, Pri, Out, Options) :- 441 var(Var), 442 !, 443 pprint(Out, Var, Pri, Options). 444portray_body(!, _, _, _, Out, _) :- 445 setting(listing:cut_on_same_line, true), 446 !, 447 write(Out, ' !'). 448portray_body((!, Clause), Indent, _, Pri, Out, Options) :- 449 setting(listing:cut_on_same_line, true), 450 \+ term_needs_braces((_,_), Pri), 451 !, 452 write(Out, ' !,'), 453 portray_body(Clause, Indent, indent, 1000, Out, Options). 454portray_body(Term, Indent, indent, Pri, Out, Options) :- 455 !, 456 nlindent(Out, Indent), 457 portray_body(Term, Indent, noindent, Pri, Out, Options). 458portray_body(Or, Indent, _, _, Out, Options) :- 459 or_layout(Or), 460 !, 461 write(Out, '( '), 462 portray_or(Or, Indent, 1200, Out, Options), 463 nlindent(Out, Indent), 464 write(Out, ')'). 465portray_body(Term, Indent, _, Pri, Out, Options) :- 466 term_needs_braces(Term, Pri), 467 !, 468 write(Out, '( '), 469 ArgIndent is Indent + 2, 470 portray_body(Term, ArgIndent, noindent, 1200, Out, Options), 471 nlindent(Out, Indent), 472 write(Out, ')'). 473portray_body((A,B), Indent, _, _Pri, Out, Options) :- 474 !, 475 infix_op(',', LeftPri, RightPri), 476 portray_body(A, Indent, noindent, LeftPri, Out, Options), 477 write(Out, ','), 478 portray_body(B, Indent, indent, RightPri, Out, Options). 479portray_body(\+(Goal), Indent, _, _Pri, Out, Options) :- 480 !, 481 write(Out, \+), write(Out, ' '), 482 prefix_op(\+, ArgPri), 483 ArgIndent is Indent+3, 484 portray_body(Goal, ArgIndent, noindent, ArgPri, Out, Options). 485portray_body(Call, _, _, _, Out, Options) :- % requires knowledge on the module! 486 m_callable(Call), 487 option(module(M), Options, user), 488 predicate_property(M:Call, meta_predicate(Meta)), 489 !, 490 portray_meta(Out, Call, Meta, Options). 491portray_body(Clause, _, _, Pri, Out, Options) :- 492 pprint(Out, Clause, Pri, Options). 493 494m_callable(Term) :- 495 strip_module(Term, _, Plain), 496 callable(Plain), 497 Plain \= (_:_). 498 499term_needs_braces(Term, Pri) :- 500 callable(Term), 501 functor(Term, Name, _Arity), 502 current_op(OpPri, _Type, Name), 503 OpPri > Pri, 504 !.
508portray_or(Term, Indent, Pri, Out, Options) :- 509 term_needs_braces(Term, Pri), 510 !, 511 inc_indent(Indent, 1, NewIndent), 512 write(Out, '( '), 513 portray_or(Term, NewIndent, Out, Options), 514 nlindent(Out, NewIndent), 515 write(Out, ')'). 516portray_or(Term, Indent, _Pri, Out, Options) :- 517 or_layout(Term), 518 !, 519 portray_or(Term, Indent, Out, Options). 520portray_or(Term, Indent, Pri, Out, Options) :- 521 inc_indent(Indent, 1, NestIndent), 522 portray_body(Term, NestIndent, noindent, Pri, Out, Options). 523 524 525portray_or((If -> Then ; Else), Indent, Out, Options) :- 526 !, 527 inc_indent(Indent, 1, NestIndent), 528 infix_op((->), LeftPri, RightPri), 529 portray_body(If, NestIndent, noindent, LeftPri, Out, Options), 530 nlindent(Out, Indent), 531 write(Out, '-> '), 532 portray_body(Then, NestIndent, noindent, RightPri, Out, Options), 533 nlindent(Out, Indent), 534 write(Out, '; '), 535 infix_op(;, _LeftPri, RightPri2), 536 portray_or(Else, Indent, RightPri2, Out, Options). 537portray_or((If *-> Then ; Else), Indent, Out, Options) :- 538 !, 539 inc_indent(Indent, 1, NestIndent), 540 infix_op((*->), LeftPri, RightPri), 541 portray_body(If, NestIndent, noindent, LeftPri, Out, Options), 542 nlindent(Out, Indent), 543 write(Out, '*-> '), 544 portray_body(Then, NestIndent, noindent, RightPri, Out, Options), 545 nlindent(Out, Indent), 546 write(Out, '; '), 547 infix_op(;, _LeftPri, RightPri2), 548 portray_or(Else, Indent, RightPri2, Out, Options). 549portray_or((If -> Then), Indent, Out, Options) :- 550 !, 551 inc_indent(Indent, 1, NestIndent), 552 infix_op((->), LeftPri, RightPri), 553 portray_body(If, NestIndent, noindent, LeftPri, Out, Options), 554 nlindent(Out, Indent), 555 write(Out, '-> '), 556 portray_or(Then, Indent, RightPri, Out, Options). 557portray_or((If *-> Then), Indent, Out, Options) :- 558 !, 559 inc_indent(Indent, 1, NestIndent), 560 infix_op((->), LeftPri, RightPri), 561 portray_body(If, NestIndent, noindent, LeftPri, Out, Options), 562 nlindent(Out, Indent), 563 write(Out, '*-> '), 564 portray_or(Then, Indent, RightPri, Out, Options). 565portray_or((A;B), Indent, Out, Options) :- 566 !, 567 inc_indent(Indent, 1, NestIndent), 568 infix_op(;, LeftPri, RightPri), 569 portray_body(A, NestIndent, noindent, LeftPri, Out, Options), 570 nlindent(Out, Indent), 571 write(Out, '; '), 572 portray_or(B, Indent, RightPri, Out, Options). 573portray_or((A|B), Indent, Out, Options) :- 574 !, 575 inc_indent(Indent, 1, NestIndent), 576 infix_op('|', LeftPri, RightPri), 577 portray_body(A, NestIndent, noindent, LeftPri, Out, Options), 578 nlindent(Out, Indent), 579 write(Out, '| '), 580 portray_or(B, Indent, RightPri, Out, Options).
588infix_op(Op, Left, Right) :- 589 current_op(Pri, Assoc, Op), 590 infix_assoc(Assoc, LeftMin, RightMin), 591 !, 592 Left is Pri - LeftMin, 593 Right is Pri - RightMin. 594 595infix_assoc(xfx, 1, 1). 596infix_assoc(xfy, 1, 0). 597infix_assoc(yfx, 0, 1). 598 599prefix_op(Op, ArgPri) :- 600 current_op(Pri, Assoc, Op), 601 pre_assoc(Assoc, ArgMin), 602 !, 603 ArgPri is Pri - ArgMin. 604 605pre_assoc(fx, 1). 606pre_assoc(fy, 0). 607 608postfix_op(Op, ArgPri) :- 609 current_op(Pri, Assoc, Op), 610 post_assoc(Assoc, ArgMin), 611 !, 612 ArgPri is Pri - ArgMin. 613 614post_assoc(xf, 1). 615post_assoc(yf, 0).
624or_layout(Var) :- 625 var(Var), !, fail. 626or_layout((_;_)). 627or_layout((_->_)). 628or_layout((_*->_)). 629 630primitive(G) :- 631 or_layout(G), !, fail. 632primitive((_,_)) :- !, fail. 633primitive(_).
642portray_meta(Out, Call, Meta, Options) :- 643 contains_non_primitive_meta_arg(Call, Meta), 644 !, 645 Call =.. [Name|Args], 646 Meta =.. [_|Decls], 647 format(Out, '~q(', [Name]), 648 line_position(Out, Indent), 649 portray_meta_args(Decls, Args, Indent, Out, Options), 650 format(Out, ')', []). 651portray_meta(Out, Call, _, Options) :- 652 pprint(Out, Call, 999, Options). 653 654contains_non_primitive_meta_arg(Call, Decl) :- 655 arg(I, Call, CA), 656 arg(I, Decl, DA), 657 integer(DA), 658 \+ primitive(CA), 659 !. 660 661portray_meta_args([], [], _, _, _). 662portray_meta_args([D|DT], [A|AT], Indent, Out, Options) :- 663 portray_meta_arg(D, A, Out, Options), 664 ( DT == [] 665 -> true 666 ; format(Out, ',', []), 667 nlindent(Out, Indent), 668 portray_meta_args(DT, AT, Indent, Out, Options) 669 ). 670 671portray_meta_arg(I, A, Out, Options) :- 672 integer(I), 673 !, 674 line_position(Out, Indent), 675 portray_body(A, Indent, noindent, 999, Out, Options). 676portray_meta_arg(_, A, Out, Options) :- 677 pprint(Out, A, 999, Options).
[ element1, [ element1 element2, OR | tail ] ]
687portray_list([], _, Out, _) :- 688 !, 689 write(Out, []). 690portray_list(List, Indent, Out, Options) :- 691 nlindent(Out, Indent), 692 write(Out, '[ '), 693 EIndent is Indent + 2, 694 portray_list_elements(List, EIndent, Out, Options), 695 nlindent(Out, Indent), 696 write(Out, ']'). 697 698portray_list_elements([H|T], EIndent, Out, Options) :- 699 pprint(Out, H, 999, Options), 700 ( T == [] 701 -> true 702 ; nonvar(T), T = [_|_] 703 -> write(Out, ','), 704 nlindent(Out, EIndent), 705 portray_list_elements(T, EIndent, Out, Options) 706 ; Indent is EIndent - 2, 707 nlindent(Out, Indent), 708 write(Out, '| '), 709 pprint(Out, T, 999, Options) 710 ).
724pprint(Out, Term, _, Options) :- 725 nonvar(Term), 726 Term = {}(Arg), 727 line_position(Out, Indent), 728 ArgIndent is Indent + 2, 729 format(Out, '{ ', []), 730 portray_body(Arg, ArgIndent, noident, 1000, Out, Options), 731 nlindent(Out, Indent), 732 format(Out, '}', []). 733pprint(Out, Term, Pri, Options) :- 734 ( compound(Term) 735 -> compound_name_arity(Term, _, Arity), 736 Arity > 0 737 ; is_dict(Term) 738 ), 739 \+ nowrap_term(Term), 740 setting(listing:line_width, Width), 741 Width > 0, 742 ( write_length(Term, Len, [max_length(Width)|Options]) 743 -> true 744 ; Len = Width 745 ), 746 line_position(Out, Indent), 747 Indent + Len > Width, 748 Len > Width/4, % ad-hoc rule for deeply nested goals 749 !, 750 pprint_wrapped(Out, Term, Pri, Options). 751pprint(Out, Term, Pri, Options) :- 752 listing_write_options(Pri, WrtOptions, Options), 753 write_term(Out, Term, WrtOptions). 754 755nowrap_term('$VAR'(_)) :- !. 756nowrap_term(_{}) :- !. % empty dict 757nowrap_term(Term) :- 758 functor(Term, Name, Arity), 759 current_op(_, _, Name), 760 ( Arity == 2 761 -> infix_op(Name, _, _) 762 ; Arity == 1 763 -> ( prefix_op(Name, _) 764 -> true 765 ; postfix_op(Name, _) 766 ) 767 ). 768 769 770pprint_wrapped(Out, Term, _, Options) :- 771 Term = [_|_], 772 !, 773 line_position(Out, Indent), 774 portray_list(Term, Indent, Out, Options). 775pprint_wrapped(Out, Dict, _, Options) :- 776 is_dict(Dict), 777 !, 778 dict_pairs(Dict, Tag, Pairs), 779 pprint(Out, Tag, 1200, Options), 780 format(Out, '{ ', []), 781 line_position(Out, Indent), 782 pprint_nv(Pairs, Indent, Out, Options), 783 nlindent(Out, Indent-2), 784 format(Out, '}', []). 785pprint_wrapped(Out, Term, _, Options) :- 786 Term =.. [Name|Args], 787 format(Out, '~q(', Name), 788 line_position(Out, Indent), 789 pprint_args(Args, Indent, Out, Options), 790 format(Out, ')', []). 791 792pprint_args([], _, _, _). 793pprint_args([H|T], Indent, Out, Options) :- 794 pprint(Out, H, 999, Options), 795 ( T == [] 796 -> true 797 ; format(Out, ',', []), 798 nlindent(Out, Indent), 799 pprint_args(T, Indent, Out, Options) 800 ). 801 802 803pprint_nv([], _, _, _). 804pprint_nv([Name-Value|T], Indent, Out, Options) :- 805 pprint(Out, Name, 999, Options), 806 format(Out, ':', []), 807 pprint(Out, Value, 999, Options), 808 ( T == [] 809 -> true 810 ; format(Out, ',', []), 811 nlindent(Out, Indent), 812 pprint_nv(T, Indent, Out, Options) 813 ).
821listing_write_options(Pri,
822 [ quoted(true),
823 numbervars(true),
824 priority(Pri),
825 spacing(next_argument)
826 | Options
827 ],
828 Options).
836nlindent(Out, N) :- 837 nl(Out), 838 setting(listing:tab_distance, D), 839 ( D =:= 0 840 -> tab(Out, N) 841 ; Tab is N // D, 842 Space is N mod D, 843 put_tabs(Out, Tab), 844 tab(Out, Space) 845 ). 846 847put_tabs(Out, N) :- 848 N > 0, 849 !, 850 put(Out, 0'\t), 851 NN is N - 1, 852 put_tabs(Out, NN). 853put_tabs(_, _).
860inc_indent(Indent0, Inc, Indent) :- 861 Indent is Indent0 + Inc*4. 862 863:- multifile 864 sandbox:safe_meta/2. 865 866sandbox:safe_meta(listing(What), []) :- 867 not_qualified(What). 868 869not_qualified(Var) :- 870 var(Var), 871 !. 872not_qualified(_:_) :- !, fail. 873not_qualified(_)
List programs and pretty print clauses
This module implements listing code from the internal representation in a human readable format.
Layout can be customized using
library(settings)
. The effective settings can be listed using list_settings/1 as illustrated below. Settings can be changed using set_setting/2.