1:- module( debug_call, 
    2        [ 
    3            debug_call/2,
    4            debug_call/3,
    5            debug_call/4,
    6            debuc/1, debuc/2, debuc/3, debuc/4,
    7            debug_chain/2, debug_chain/3,
    8            debug_consec/3, debug_consec/4,
    9            debug_message/3,
   10            debug_on/1,
   11            debug_portray/2,
   12            debug_set/2,
   13            debugging_status/2,
   14            debug_topic/2,
   15            debug_topic/3,
   16            debug_call_version/2,
   17            debugging_topic/1
   18       ] ).   19
   20:- multifile(user:message_property/2).   21:- dynamic(debug_call_message_property/2).   22
   23user:message_property( Dbg, Property ) :-
   24    debug_call_message_property( Dbg, Property ).

Debugging with calls.

Debugging information focusing on avoiding running goals to produce output that is only relevant while debugging.

Includes pre-canned, often used calls that print informative messages for common debugging tasks.

See the main predicate's documenation, debug_call/4, for more details. See file examples/exo.pl for a full pallette of examples.

Examples


?- debug(ex).
?- debug_call(ex, length, list1/[x,y,z]).
% Length for list, list1: 3

?- debug_call(ex, length, [list1,list2]/[[x,y,z],[a,b,c]], prefix('Some prefix')).
% Some prefix lengths for lists, list1: 3, list2: 3

?- debug_call(ex, dims, [m1,m2]/[[a(x),a(y),a(z)],[xy(a,b),xy(c,d),xy(e,f)]]).
%  Dimensions for matrices,  (m1) nR: 3, nC: 1. (m2) nR: 3, nC: 2.

?- debug_call(ex, enum, testo/[a,b,c]).
% Starting enumeration of list: testo
% 1.a
% 2.b
% 3.c
% Ended enumeration of list: testo
true.

?- debug_call(ex, enum, testo/[a,b,c,d,e], depth(3)).
% Starting enumeration of list: testo
% 1.a
% 2.b
% 3.c
% ... + 2 other elements
% Ended enumeration of list: testo

?- debug_call(ex, info, 'My message is ~w.'/long).
% My message is long.
true.
   % message above is printed in informational colour

?- debuc(ex, wrote, loc(file,csv)).
% Could not locate wrote on file specified by: file, and extensions: csv
?- csv_write_file('file.csv', []).

?- debuc(ex, version, debug_call).
% Using debug_call_version, at version: 2:1:1 (published on: date(2025,12,6)).

?- debuc(ex, wrote, loc(file,csv)).
% Wrote on file: 'file.csv'

?- debuc(ex, task(stop), 'write on file').
At 15:44:1 on 2nd of Jul 2024 finished task: write on file.

?- debuc(ex, task(stop), 'talking ~w', [farg(point)]).
% At 13:58:50 on 6th of Dec 2025 stop task: talking point

?- assert((simple_mess(KVs,Mess,Args):- KVs =[a=A,b=B], atom_concat(A,B,Mess), Args=[])).
?- debuc(ex, simple_mess([a=1,b=2])).
% 12
true.

?- debuc(ex, stat, runtime, true).
% stat(runtime,[182,4]).
true.

?- debuc(ex, stat, runtime, [check_point(here),comment(false)]).
stat(here,runtime,[193,11]).
true.

?- debuc(ex, stat, testo, [sub(true),comment(false)]).
duh([testo-8.0K,testo/file_a-0,testo/sub_1-4.0K]).

Variable topics

This library avoids the messy way in which package(debug) deals with variable debug topics. That is, their term expansion and subsequent pattern matching mishandles goals of the form debugging/1 and debug/3 that have an unbound variable in the 1st argument. debug_calls uses dynamic =.. .

Pack info

author
- nicos angelopoulos
version
- 0.1 2016/3/5
- 0.2 2016/11/01
- 0.3 2017/3/9
- 1.1 2018/3/20
- 1.2 2019/4/22
- 1.3 2020/3/7
- 1.4 2020/9/18
- 1.5 2022/12/29
- 2.0 2025/10/7
- 2.1 2025/10/27
- 2.2 2025/12/8
- 2.3 2026/2/8
See also
- http://stoics.org.uk/~nicos/sware/debug_call/
- debug_call/4 for information on what each version added.

*/

To be done
- options_debug( Opts, Mess, Args ) only writes if Opts contains debug(true). maybe this should be part of pack(options)
- provide a way to remove lib(debug)'s expansions
 debug_call_version(-Version, -Date)
Current version and release date for the library.
?- debug_call_version( -V, -D ).
V = 2:3:0,
D = date(2026,2,8).

*/

  143debug_call_version(2:3:0, date(2026,2,8)).
  144
  145:- use_module(library(apply)).       % maplist/4,...
  146:- use_module(library(lists)).       % member/4,...
  147:- use_module(library(debug)).       % debug/1,...
  148:- use_module(library(filesex)).     % directory_member/3.
  149:- use_module(library(readutil)).    % read_line_to_codes/2.
  150:- use_module(library(process)).     % process_create/3.
  151:- use_module(library(readutil)).    % read_line_to_codes/2.
  152:- use_module(library(prolog_pack)). % pack_property/2.
  153:- use_module(library(lib)).  154
  155:- lib(source(debug_call), [homonyms(true),index(false)]).  156:- lib(stoics_lib:locate/3 ).  157:- lib(stoics_lib:en_list/2).  158:- lib(stoics_lib:message_report/3).  159:- lib(stoics_lib:datime_readable/1).  160:- lib(end(debug_call) ).
 debuc(+Topic)
 debuc(+Topic, +Goal)
 debuc(+Topic, +Goal, +Args)
 debuc(+Topic, +Goal, +Pfx, +Args)
Shorthands for debug_call/2,3,4 and debug/1.
author
- nicos angelopoulos
version
- 0:1 2020/9/9
  172debuc( Topic ) :-
  173    debug( Topic ).
  174debuc( Topic, Goal ) :-
  175    debug_call( Topic, Goal ).
  176debuc( Topic, Goal, Arg ) :-
  177    debug_call( Topic, Goal, Arg ).
  178debuc( Topic, Goal, Arg, Opts ) :-
  179    debug_call( Topic, Goal, Arg, Opts ).
 debug_call(+Topic, +Goal)
Only call debug if we are debugging Topic.

If Goal with arity +2 is available call that instead of Goal with extra arguments Mess and Args that will be passed to debug/3. If the goal (original or +2) fail, nothing is printed by debug_call and the debug_call(T,G) itself succeeds.

 ?- goal( Goal, Mess, Args ).

Examples

 ?- debug(ex)
 ?- assert((simple_mess(KVs,Mess,Args):- KVs =[a=A,b=B], atom_concat(A,B,Mess), Args=[])).
 ?- debug_call(ex, simple_mess([a=1,b=2])).
 12
author
- nicos angelopoulos
version
- 0.2 2018/3/20
  204debug_call( Topic, Goal ) :-
  205    debugging_topic( Topic ),
  206    !,
  207    debug_call_goal( Topic, Goal ).
  208debug_call( _Topic, _Goal ).
  209
  210debug_call_goal( Topic, Moal ) :-
  211    ( Moal = Mod:Goal -> true; Goal = Moal, Mod=user ),
  212    functor( Goal, Functor, Arity ),
  213    Extra is Arity + 2,
  214    current_predicate( Mod:Functor/Extra ),
  215    !,
  216    ( call(Mod:Goal,Mess,Args) ->
  217        debug( Topic, Mess, Args )
  218        ;
  219        true
  220    ).
  221debug_call_goal( _Topic, Goal ) :-
  222    ( call(Goal) -> true; true ).
 debug_chain(+TopicCond, +TopicDep)
 debug_chain(+TopicCond, +TopicDep, -TDprior)
If already debugging TopicCond, then also start debugging TopicDep. TDprior is true if TopicDep was already debugging, else is false. Current implementation sets TDprior to true whenever Topic is not debugged, as it assumes that this value best suit independent fluctuation of TopicDep. Only in the case of debug_chain/2, TopicDep can be a list.
author
- nicos angelopoulos
version
- 0.1 2014/4/4
- 0.2 2016/11/1
See also
- debug_set/2
  238debug_chain( Topic, Then ) :-
  239    en_list( Then, Thens ),
  240    maplist( debug_chain(Topic), Thens, _Priors ).
  241
  242debug_chain( Topic, Then, Prior ) :-
  243    debugging_topic( Topic ),
  244    !,
  245    debugging_status( Then, Prior ),
  246    debug( Then ).
  247debug_chain( _Topic, _Then, true ). 
  248    % setting 3rd to true is a bit presumptious of its uses later on
 debug_message(+Topic, +Mess, +Args)
A wrap around debug/3 that calls it by constructing the term on-the-fly. So that lib(debug) does not create a record by inspecting the term (via expansion). Particularly useful in sending uninstantiated Topics.
author
- nicos angelopoulos
version
- 0.1 2016/11/1
- 0.1 2026/1/25, avoid building the term with =.. use call/4 directly

*/

  261debug_message( Topic, Mess, Args ) :-
  262    call( debug, Topic, Mess, Args ).
 debugging_topic(?Topic)
A wrap around debugging/1 that calls it by constructing the term on-the-fly. So that lib(debug) does not create a record by inspecting the term (via expansion). Particularly useful in sending uninstantiated Topics.
author
- nicos angelopoulos
version
- 0.1 2016/11/1

*/

  274debugging_topic( Topic ) :-
  275    Call =.. [debugging,Topic],
  276    call( Call ).
 debugging_status(+Topic, -Status)
Status == true iff debugging(Topic) succeeds. Else, it is false. Similar to debugging/2, but does not fail for undefined Topic.
 ?- debug( something ).
 true.
 ?- debugging_status( something, Some ).
 Some = true.
 ?- debugging_status( some_else, Else ).
 Else = false.
author
- nicos angelopoulos
version
- 0.1 2014/7/23
  293debugging_status( Topic, Status ) :-
  294    debugging_topic( Topic ),
  295    !,
  296    Status = true.
  297debugging_status( _Topic, false ).
 debug_set(+Prior, +Topic)
Reset Topic according to Prior: true sets Topic to on and false turns Topic off.
 ?- nodebug( chained ).
 true.
 ?- debug( testo ).
 Warning: testo: no matching debug topic (yet)
 true.
 ?- debug( chained, 'debugs chains 1', [] ).
 true.
 ?- debug_chain( testo, chained, Prior ).
 Prior = false.
 ?- debug( chained, 'debugs chains 2', [] ).
 % debugs chains 2
 true.
 ?- Prior = false, debug_set( Prior, chained ).
 Prior = false.
 ?- debug( chained, 'debugs chains 3', [] ).
 true
author
- nicos angelopoulos
version
- 0.1 2014/7/23
- 0.2 2016/8/22, Prior == true used to do nothing, now it turns topic on. also renmaed from debug_set/2.
See also
- debug_chain/3
  326debug_set( false, Topic ) :-
  327    nodebug( Topic ).
  328debug_set( true, Topic ) :-
  329    debug( Topic ).
 debug_topic(+Topic, +Opts, -Restore)
Start debugging Topic if options(debug(true),Opts), with Restore being instantiated to a term that can be used to restore the original debug state of Topic (see options_restore/2). If options(debug(false),Opts) then Topic is stopped from being debugged (Restore still holds the correct term for restoring debugging state for topic to precall status).
?- assert( ( on_t(I,Topic) :- (debugging(Topic) -> write(I-y(Topic)) ; write(I-n(Topic))), nl ) ).
?- T = options, debug(T), on_t(1,T), debug_topic(T,[debug(false)],R), on_t(2,T), debug_set(R,T), on_t(3,T).
1-y(options)
2-n(options)
3-y(options)
T = options,
R = true.

?- T = options, nodebug(T), on_t(1,T), debug_topic(T,[debug(true)],R), on_t(2,T), debug_set(R,T), on_t(3,T).
1-n(options)
2-y(options)
3-n(options)
T = options,
R = false.
author
- nicos angelopoulos
version
- 0.1 2016/8/22

*/

  360debug_topic( Topic, Opts, Restore ) :-
  361    memberchk( debug(Dbg), Opts ),
  362    Dbg == true,
  363    !,
  364    debug_topic_restore( Topic, Restore ),
  365    debug( Topic ).
  366debug_topic( Topic, _Opts, Restore )  :-        % becomes default under this implementation
  367    debug_topic_restore( Topic, Restore ),
  368    nodebug( Topic ).
  369
  370debug_topic_restore( Topic, Restore ) :- 
  371    debugging_topic( Topic ),
  372    !,
  373    Restore = true.
  374debug_topic_restore( _Topic, false ).
 debug_topic(+Flag, +Topic)
Start debugging Topic if Flag == true, and stop debugging if Flag == false.
 ?- debug_topic( true, example ).
author
- nicos angelopoulos
version
- 0.1 2014/12/10
- 0.2 2016/08/22, added nodebug/1 when Flag == false
See also
- options_append/4
  388debug_topic( true, Topic ) :-
  389    debug( Topic ).
  390debug_topic( false, Topic ) :-
  391    nodebug(Topic).
 debug_on(+Topic)
As debug/1, but do not print warning if topic is not known.
  397debug_on( Topic ) :-
  398    asserta( prolog_debug:debugging(Topic,true,[user_error])).
 debug_portray(+Topic, +Term)
Call portray_clause(Term) if we are debugging Topic.
author
- nicos angelopoulos
version
- 0.1
  407debug_portray( Topic, Term ) :-
  408    debugging_topic( Topic ),
  409    !,
  410    portray_clause( Term ).
  411debug_portray( _Topic, _Term ).
 debug_call(+Topic, +DebuGoal, +Arg)
 debug_call(+Topic, +DebuGoal, +Arg, +Opts)
Automates often used debug calls with emphasis on: (a) avoiding calling things that will not be reported and (b) easy tailoring of the messages.

The main novelty is the introduction of abbreviated Goals, that print bespoke messages for often used debugging information. For example the following code ejects info on the legth of the list. Not only the code for calculating the length only happens if debugging for the topic ex, is on, but the message is also tailored to reporting lengths of lists.

 ?- debug(ex).
 ?- debug_call(ex, length, math_vars/[x,y,z]).
 % Length for list, math_vars: 3

With v1.3 the debuc/n shorthand was introduced. So debuc/1,2,3,4 are shorthands for debug_call/1,2,3,4.

?- Mtx = [h(a,b,c),r(1,2,3),r(4,5,6),r(7,8,9)],
   debuc(ex, dims, mtx/Mtx).

Dimensions for matrix, mtx: nR: 4, nC: 3.

The predicate can work as a replacement to debug/3. That is, if Goal does not match any of the forms below, it will be interpreted as a message.

?- debuc(ex, 'A simple message in a ~a.', [bottle] ).
A simple message in a bottle.

The predicate can be used to call arbitrary Goal and then print a message after it has successfull completed (see below).
When Goal is a known abbreviation from those shown below, the Arg usually qualifies the output generated.

As of v2 the last two arguments of the /4 version of the predicate were switched from Pfx and Arg to Arg and Opts. Opts pass arbitary things to Goal, each abbreviation Goal can demand different options. All debuc Goals can take prefix(Pfx) which corresponds to Pfx in the old /4 version, and pred(Fnc,Ar) or pred(Pid).

 ?- debuc(ex, enum, list_x/[x1,x1,x3], [pred(integral,2),prefix('At')] ).
 % At predicate: integral/2 starting enumeration of list: list_x
 % 1.x1
 % 2.x1
 % 3.x3
 % At predicate: integral/2 ended enumeration of list: list_x

The predicate is relaxed about Opts. It can be a single term, which will be cast into a list.

 ?- debuc(ex, pwd, my_run, pred(bio_db,3) ).

 Predicate: bio_db/3 pwd at, my_run, is: '/home/nicos/pl/packs/private/debug_call/'

Goal in:

call(Goal)
Call Goal before printing debugging message debug(Topic, Mess, MArgS). Goal is called in deterministic context. Goal is called with extra arguments +Arg, -Mess and -MArgS.
call(Goal, Opts)
As above, but Opts are passed as an extra, last argument in the call.
dims
Prints the dimensions of matrix, see mtx_dims/3.
duh
Short for shell command 'du -h -s' which is disc usage, summarized and in human readable form. Arg should be the directory to report the size of. Can take options check_point() and comment()- as does stat. The latter allows for reporting without '%' so terms can be read in by read/1 or consulted. In addition, option sub() can be used the subdirectories of
end
Translates to finishing ~Arg or finishing ~Topic if Arg==true.
enum
Print members of lists and arguments of terms, where each item is printed on single line and prefixed by an index number Knows: depth(Depth) (restricts items to print).
goal
Anything that does n't match any of the above is retrived as call(Goal)
info
Print using informational machinery (usually different/green colour, to debug's blue) term should Mess/Args in the debug/3 version
input
Reports reading from a file. Arg should be file specification suitable for locate/3. Either loc(File,Exts) or simply File in which case Exts = ''. As of v2.0 the default is to print the basename, use path(abs) in Opts if the full path to the file is needed.
length
Prints the lenghts of a bunch of lists. Args should be ListNames/Lists. uses non list ListNames if debuging the length of a single list, in which case message in the singular is used.
list
Writes contents of list with header and footer. Arg should be of the form Hdr/Ftr/List, else Hdr/List unfolds to Hdr/Hdr/List and List is translated to unknown/unknown/List. Knows: depth(Depth) (restricts items to list).
ns_sel
First argument of Arg is the item selected from second arg which is expected to be a list. The selected argument can be named on the massage via sel_name(Lnm) in Opts.
odir
Output directory (Arg should exist and be a directory)
option
Option selected from options for predicate. Possible options: pred(Fnc,Ar) or pred(Pid), the caller predicate, all(OrigOpts), shows all options, internal(true), shows also '$' starting options.
options
Options used on call to a predicate. Possible options: pred(Func,Ar), pred(Pid), the caller predicate, internal(true), shows also '$' starting options.
pwd
Message about current dir Location (=Arg), (if Arg==false, location is not shown)- see examples.
read
Alias for input.
session
Print info on all loaded code, packs are shown with versions both from packs and info from <Pred>_version/2,3 if available (as per stoics.org.uk packs).
start
Translates to starting ~Arg or starting ~Topic if Arg==true.
stat
Arg should be a key that can be used as the 1st arg for statistics/1, the debuc Goal reports the statistic. Can take options check_point() and comment(). The latter allows for reporting without '%' so terms can be read in by read/1 or consulted.
task(Wch)
Time of start/stop (Wch) of a task. Other values for Wch are allowed but printed as they come. Arg can be a term (as of Version 1.5). Arg can include formatting tidles, and associated arguments should be passed via farg() option.
term
Report the input term. The term can be named via option term_name(Tnm).
var
Reports variable name (arg(1)) and its current instantiation (arg(2))
version
Reports version of software currently using:
  • predicate name of <Arg>_version/2,3 or <Arg>/2 (1st arg Version, 2nd arg release date),
  • Arg should be a term of arity 3 (Sw/Vers/Date) or arity 2 (Sw/Vrs/Date).
wrote
Reports the writting of output on a file. Arg should be file specification suitable for locate/3. Either loc(File,Exts) or simply File in which case Exts = ''. As of v2.0 the default is to print the basename, use path(abs) in Opts if the full path to the file is needed.

As of v2.1 almosst all debuc Goals work with options prefix(Pfx) and pred(Ar,Fn) (also synonymed to pred(Pid)).

v2.2 introduced ability to pass formatting patterns and arguments via farg() option.

See file examples/exo.pl for a test suit including at least one example from each debuc Goal.

Opts supported by all debugoals

prefix(Pfx)
prefixes the message
pred(F, A)
(also pred(F/A)) adds predicate caller identfication to message
farg(Farg)
pass formating argument when Arg contains '~' formatting terms that expecdt an argument [task(start),task(stop)]

Opts for specific debugoals

check_point(Point)
adds check point info to message [stat]
comment(Comm)
when Comm==false print message through format without '%' (portray_message) machineary [stat- print readable terms]
depth(Depth)
limits output times [enum,list]
 ?- debug(ex).
 
 ?- debuc( ex, (length([a,b,c],L),write(len(L)),nl) ).
 len(3)
 L = 3.

 ?- debug_call(ex, length, list1/[x,y,z]).
 % Length for list, list1: 3
  
 ?- debug_call(ex, length, [list1,list2]/[[x,y,z],[a,b,c]] prefix('some prefix')).
 % some prefix lengths for lists, list1: 3, list2: 3
 
 ?- debuc(ex, wrote, loc(file,csv)).
 % Could not locate wrote on file specified by: file, and extensions: csv

 ?- csv_write_file( 'file.csv', []).
 ?- debuc(ex, wrote, loc(file,csv)).
 % Wrote on file: 'file.csv'

 ?- debuc(ex, wrote, loc(file,csv), path(abs)).
 % Wrote on file: '/home/nicos/pl/lib/src/trace/file.csv'

 ?- debuc(ex, task(stop), 'write on file').
 % At 15:44:1 on 2nd of Jul 2014 finished task: write on file.
    
 ?- debuc( ex, pwd, here ).
 % Pwd at, here, is: '/home/nicos/.local/share/swi-prolog/pack/Downloads/bio_db_repo-publish/bio_db_repo-20.09.14/data/hs/maps/hgnc/'
 true.
 
 ?- debuc( ex, pwd, false ).
 % Pwd: '/home/nicos/.local/share/swi-prolog/pack/Downloads/bio_db_repo-publish/bio_db_repo-20.09.14/data/hs/maps/hgnc/'
 true.
 
 ?-  Etcs = [suv-17.09.26.txg,suv-17.09.21.txg], Etc = suv-17.09.26.txg,
     debuc(suv, ns_sel, c(Etc,Etcs, sel_name('suv file') ).
 Continuing with: suv-17.09.26.txg as the: suv file. From list: [suv-17.09.26.txg,suv-17.09.21.txg]

 ?- assert( (list_avg_mess(List,Mess,Args) :- length(List,Len), sum_list(List,Sum), Avg is Sum / Len, Mess = 'Avg: ~w', Args = Avg) ).
 ?- debuc( ex, call(list_avg_mess), [1,2,3] ).
 Avg: 2

 ?- debuc( ex, call(list_avg_mess), [1,2,3], prefix('By call') ).
 By call avg: 2

 ?- debuc( ex, call(list_avg_mess), [1,2,3], [pred(p1,2),prefix('By call')] ).
 By call predicate: p1/2 avg: 2

 ?- debuc(ex, stat, runtime, true).
 stat(runtime,[182,4]).
 true.
 
 ?- debuc(ex, stat, runtime, [check_point(here),comment(false)]).   % note this does not have a precedding percentage char
 stat(here,runtime,[193,11]).
 

At some point around SWI-Prolog 8, behaviour of debug/3 changed in being more strict about messages with no arguments. As of version 1.2 debug_call/3 can act as a replacement of debug/3 but with the old behaviour.

 ?- debug(ex, 'Messaging...', true).
 Messaging...
 [[ EXCEPTION while printing message 'Messaging...'
       with arguments user:true:
       raised: format('too many arguments')
    ]]
 
 true.
 
 ?- debuc(ex, 'Messaging...', true).
 % Messaging...
 true.
author
- nicos angelopoulos
version
- 0.1 2014/03/27
- 0.2 2014/04/24 added wrote
- 0.3 2014/07/2 added task
- 0.4 2014/09/22 renamed from debug_call/3
- 0.5 2014/??/?? added ns_sel
- 1.1 2018/03/20 prefer +2 arity in debug_call/2
- 1.2 2020/03/07 now can be used as a replacement for debug/3 (but with old 3rd arg behaviour, allowing eg 'true').
- 1.3 2020/09/14 added debuc Goal info and enum, debuc/2,3,4
- 2.0 2025/10/07 changed last two arguments, new option goal recogniser, pred/1, internal/1 & all/1
- 2.1 2025/10/27 pid(F,A) & prefix() universal; call() fixed; doc; enum terms fix; ns_sel simplify
- 2.2 2025/12/08 farg() option; depth() option in list and enum; debuc Goals: version, session.
- 2.3 debuGoal stat; opts comment(t/f), check_point(), duh (opts as stat + sub(D))
See also
- file examples/exo.pl
- debuc/3 shorthand for debug_call/3
  650debug_call( Topic, Goal, Arg ) :-
  651    debug_call( Topic, Goal, Arg, [] ).
  652
  653debug_call( Topic, Goal, Arg, OptsPrv ) :-
  654    debugging_topic( Topic ),
  655    !,
  656    en_list( OptsPrv, Opts ),
  657    debugging_call( Topic, Goal, Arg, Opts ).
  658debug_call( _Topic, _Goal, _Arg, _Opts ).
  659
  660debugging_call( Topic, call(Goal), Arg, Opts) :-
  661    !,
  662    call( Goal, Arg, Gess, Grgs ),
  663    !,
  664    debug_call_message_opts( Gess, Grgs, Mess, Args, Opts ),
  665    debug_message( Topic, Mess, Args ).
  666debugging_call( Topic, call_opts(Goal), Arg, Opts ) :-
  667    !,
  668    call( Goal, Arg, Gess, Grgs, Opts ),
  669    debug_call_message_opts( Gess, Grgs, Mess, Args, Opts ),
  670    debug_message( Topic, Mess, Args ).
  671debugging_call( Topic, Goal, Arg, Opts ) :- 
  672    debug_call_topic( Goal, Arg, Opts, Topic ),
  673    !.
  674debugging_call( Topic, Goal, Mess, Args ) :-
  675    compound( Goal ),
  676    call( Goal ),
  677    !,
  678    debug_message( Topic, Mess, Args ).
  679% 20.03.07: this makes debug_call/3 a replacement for debug/3...
  680debugging_call( Topic, Mess, ArgsPrv, _DbgCallArgs ) :-
  681    % as of SWI-Prolog 8.?.? there is an error thrown when true is used instead of [] as 3rd arg of debug/3
  682    atomic( Mess ),
  683    !,
  684    ( ArgsPrv == true -> Args = []; en_list(ArgsPrv,Args) ),
  685    debug( Topic, Mess, Args ).
  686debugging_call( Topic, Goal, Mess, Args ) :-
  687    Called = debug_call(Topic,Goal,Mess,Args),
  688    message_report( 'failure ignored on: ~w', Called, warning ).
 debug_consec(+Topic, +Mess, +Args)
 debug_consec(+Topic, +Clrs, +Mess, +Args)
Alternate the colours of printing messages on Topic, from those in Clrs. When missing these are [blue,magenta]. As of v0.2 Clrs can be a single colour.
 ?- debug( dbg ).
 ?- debug_consec( dbg, 'what:~w', when ).
 % what: when            <- in blue

 ?- debug_consec( dbg, 'what:~w', when ).
 % what: when            <- in magenta

 ?- debug_consec( dbg, [blue,green], 'what:~w', when ).
 % what: when            <- in blue

 ?- debug_consec( dbg, [blue,green], 'what:~w', when ).
 % what: when            <- in green

Version 0.2

 ?- debug_consec( dbg, magenta, 'what:~w', when ).
 % what: when            <- in magenta
author
- nicos angelopoulos
version
- 0.2 2019/12/29
- 0.1 2014/7/24
  722debug_consec( Topic, Mess, Args ) :-
  723    Clrs = [blue,magenta],
  724    debug_consec( Topic, Clrs, Mess, Args ).
  725
  726debug_consec( Topic, ClrS, Mess, Args ) :-
  727    debugging_topic( Topic ),
  728    !,
  729    ( is_list(ClrS) -> Clrs = ClrS; Clrs = [ClrS] ),
  730    debug_consec_topic( Topic, Clrs, Mess, Args ).
  731debug_consec( _Topic, _Clrs, _Mess, _Args ).
  732
  733debug_consec_topic( Topic, Clrs, Mess, Args ) :-
  734    with_output_to( atom(Topicat), write_term(Topic,[]) ),
  735    ( nb_current(Topicat,Value) -> true; Value = 1 ),
  736    ( nth1(Value, Clrs, Clr) -> true; Clrs = [Clr|_] ),
  737    debug_consec_color( Topic, Clr, Mess, Args ),
  738    length( Clrs, Len ),
  739    ( Value < Len -> Next is Value + 1; Next is 1 ),
  740    nb_setval( Topicat, Next ).
  741
  742debug_consec_color( Topic, Clr, Mess, Args ) :-
  743    user:message_property( debug(_), color(Attrs) ),
  744    !,
  745    retractall( debug_call_message_property(debug(_),color(_)) ),
  746    assert( debug_call_message_property(debug(_),color(fg(Clr))) ),
  747    debug_message( Topic, Mess, Args ),
  748    retractall( debug_call_message_property(debug(_),color(_)) ),
  749    assert( debug_call_message_property(debug(_),color(Attrs)) ).
  750debug_consec_color( Topic, Clr, Mess, Args ) :-
  751    assert( debug_call_message_property(debug(_),color(fg(Clr))) ),
  752    debug_message( Topic, Mess, Args ),
  753    retractall( debug_call_message_property(debug(_),color(_)) ).
  754
  755debug_call_topic( info, Arg, Bogs, _Topic ) :-
  756     ( (\+ var(Arg),Arg = Mess/Args) ->
  757          true
  758          ;
  759          % fixme: not sure what to do here ?
  760          Mess = Arg,
  761          Args = []
  762     ),
  763     debug_call_message_opts( Mess, Args, Prefixed, Prgs, Bogs ),
  764	phrase('$messages':translate_message(debug(Prefixed,Prgs)), Lines),
  765	print_message_lines(current_output, kind(informational), Lines).
  766debug_call_topic( dims, NamesPrv/MtxsPrv, Bogs, Topic ) :-
  767    ( is_list(NamesPrv) -> Names=NamesPrv, MtxsPrv=Mtxs, With = 'Dimensions for matrices, '
  768                           ; [NamesPrv] = Names, [MtxsPrv]=Mtxs, With = 'Dimensions for matrix, ' 
  769    ),
  770    maplist( debug_mtx_dims, Mtxs, NRows, NCols ),
  771    findall( PartM, (member(_,Names),PartM='~w: nR: ~d, nC: ~d.'), MParts ),
  772    atomic_list_concat( MParts, '', Right ),
  773    findall( [Name,NRow,NCol], (nth1(N,Names,Name),nth1(N,NRows,NRow),nth1(N,NCols,NCol)), NNest ),
  774    flatten( NNest, Vargs ),
  775    atom_concat( With, Right, Vess ),
  776    debug_call_message_opts( Vess, Vargs, Message, Args, Bogs ),
  777    debug_message( Topic, Message, Args ).
  778debug_call_topic( enum, InArg, Bogs, Topic ) :-
  779    ground( InArg ),
  780    ( InArg = Left/Term -> true; Left = unnamed, Term = InArg ),
  781    ( is_list(Term) ->
  782        length( Term, Len ),
  783        number_codes( Len, LenCs ),
  784        length( LenCs, SpcLen ),
  785        debug_call_topic_list_delim( Left, Topic, 'Starting enumeration of list: ~w', Bogs ),
  786        ( memberchk(depth(Depth), Bogs) -> true; Depth = inf ),
  787        debug_call_topic_enum( Term, 1, Depth, SpcLen, Topic ),
  788        debug_call_topic_list_delim( Left, Topic, 'Ended enumeration of list: ~w', Bogs )
  789        ;
  790        Term =.. [Func|Args],
  791        length( Args, Len ),
  792        number_codes( Len, LenCs ),
  793        length( LenCs, SpcLen ),
  794        atomic_list_concat( ['Starting enumeration of term: ~w (func: ',Func,')'], StrMess ),
  795        debug_call_topic_list_delim( Left, Topic, StrMess, Bogs ),
  796        ( memberchk(depth(Depth), Bogs) -> true; Depth = inf ),
  797        debug_call_topic_enum( Args, 1, Depth, SpcLen, Topic ),
  798        atomic_list_concat( ['Ended enumeration of term: ~w (func: ',Func,')'], EndMess ),
  799        debug_call_topic_list_delim( Left, Topic, EndMess, Bogs )
  800    ).
  801debug_call_topic( length, NamesPrv/ListsPrv, Bogs, Topic ) :-
  802    ( is_list(NamesPrv) -> Names=NamesPrv, ListsPrv=Lists, With = 'Lengths for lists, '
  803                           ; [NamesPrv] = Names, [ListsPrv]=Lists, With = 'Length for list, ' 
  804    ),
  805    maplist( length, Lists, Lengths ),
  806    findall( ['~w: ~w',', '], member(_,Lengths), WsNest ),
  807    flatten( WsNest, WsL ),
  808    once( append(WsLComma,[_],WsL) ),
  809    append( WsLComma, ['.'], WsLDot ),
  810    atomic_list_concat( WsLDot, '', Right ),
  811    findall( [Name,Length], (nth1(N,Names,Name),nth1(N,Lengths,Length)), NLNest ),
  812    flatten( NLNest, NLs ),
  813    atom_concat( With, Right, Vess ),
  814    debug_call_message_opts( Vess, NLs, Message, Args, Bogs ),
  815    debug_message( Topic, Message, Args ). % do the messaging
  816debug_call_topic( list, InArg, Bogs, Topic ) :-
  817    ground( InArg ),
  818    ( InArg = Left/List -> 
  819        ( Left = Hdr/Ftr -> true ; Hdr = Left, Ftr = Left )
  820        ;
  821        List = InArg, Hdr = unamed, Ftr = unamed
  822    ),
  823    debug_call_topic_list_delim( Hdr, Topic, 'Starting listing of list: ~w', Bogs),
  824    ( memberchk(depth(Depth),Bogs) -> 
  825          length( Clean, Depth ),
  826          ( append(Clean,[H|T],List) ->
  827                    maplist( debug_message(Topic,'~w'), Clean ),
  828                    length( [H|T], Xen ),
  829                    ( Xen =:= 1 -> 
  830                         Mess = '... + ~d other element'
  831                         ;
  832                         Mess = '... + ~d other elements'
  833                    ),
  834                    debug_message( Topic, Mess, Xen )
  835                    ;
  836                    maplist( debug_message(Topic,'~w'), List )
  837          )
  838          ;
  839          maplist( debug_message(Topic,'~w'), List )
  840    ),
  841    debug_call_topic_list_delim( Ftr, Topic, 'Ended listing of list: ~w', Bogs ).
  842debug_call_topic( odir, Odir, Bogs, Topic ) :-
  843    ( exists_directory(Odir) ->
  844        Mess = 'Output in directory: ~w'
  845        ;
  846        Mess = 'Output (claimed) in (non-existing) directory: ~w'
  847    ),
  848    debug_call_message_opts( Mess, [Odir], Message, Args, Bogs ),
  849    debug_message( Topic, Message, Args ).
  850debug_call_topic( option, Opt, Bogs, Topic ) :-
  851    Ness = 'Option selected: ~w',
  852    ( (memberchk(all(OrgOpts),Bogs),is_list(OrgOpts)) ->
  853               ( memberchk(internal(true),Bogs) ->
  854                    RdcOpts = OrgOpts
  855                    ;
  856                    findall( R, (member(R,OrgOpts),functor(R,F,_),\+(atom_concat('$',_,F))), RdcOpts )
  857               ),
  858               atom_concat( Ness, ' from options: ~w', Mess ),
  859               Mrgs = [Opt,RdcOpts]
  860               ;
  861               atom_concat( Ness, '.', Mess ),
  862               [Opt] = Mrgs
  863    ),
  864    debug_call_message_opts( Mess, Mrgs, Message, Args, Bogs ),
  865    debug_message( Topic, Message, Args ).
  866debug_call_topic( options, RepOpts, Bogs, Topic ) :-
  867    Ness = 'Options: ~w',
  868    ( memberchk(internal(true),Bogs) -> 
  869               RepOpts = RdcOpts
  870               ;
  871               findall( R, (member(R,RepOpts),functor(R,F,_),\+(atom_concat('$',_,F))), RdcOpts )
  872    ),
  873    debug_call_message_opts( Ness, [RdcOpts], Message, Args, Bogs ),
  874    debug( Topic,  Message, Args ).
  875debug_call_topic( duh, Dir, Bogs, Topic ) :-
  876    debug_call_duh_dir( Dir, PaPair ),
  877    ( memberchk(sub(true), Bogs ) ->
  878          findall( Os, directory_member(Dir, Os, []), Oses ),
  879          maplist( debug_call_duh_dir, Oses, SubPairs ),
  880          Pairs = [PaPair|SubPairs] 
  881          ; 
  882          Pairs = [PaPair]
  883    ),
  884    ( memberchk(check_point(Point),Bogs) ->
  885          Rec = duh(Point,Pairs)
  886          ;
  887          Rec = duh(Pairs)
  888    ),
  889    debuc_call_topic_term( Rec, Topic, Bogs ).
  890debug_call_topic( stat, Key, Bogs, Topic ) :-
  891    statistics( Key, Stat ),
  892    ( memberchk(check_point(Point),Bogs) ->
  893          Rec = stat(Point,Key,Stat)
  894          ;
  895          Rec = stat(Key,Stat)
  896    ),
  897    debuc_call_topic_term( Rec, Topic, Bogs ).
  898debug_call_topic( term, Derm, Bogs, Topic ) :-
  899    ( memberchk(term_name(Tnm),Bogs) -> 
  900          Mess = 'Reporting term (~w): ~w',
  901          Mrgs = [Tnm,Derm]
  902          ; 
  903          Mess = 'Reporting term: ~w',
  904          Mrgs = [Derm]
  905    ),
  906    debug_call_message_opts( Mess, Mrgs, Message, Args, Bogs ),
  907    debug_message( Topic, Message, Args ).
  908debug_call_topic( var, DbgTerm, Bogs, Topic ) :-
  909    arg( 1, DbgTerm, Var ),
  910    arg( 2, DbgTerm, Val ),
  911    Mess = 'Variable: ~a, value: ~w',
  912    debug_call_message_opts( Mess, [Var,Val], Message, Args, Bogs ),
  913    debug_message( Topic, Message, Args ).
  914debug_call_topic( session, _Derm, Bogs, Topic ) :-
  915     ( memberchk(in_module(Mod), Bogs) -> true; Mod = user),
  916     current_prolog_flag( version_data, Swi ),  % Swi = swi(9, 3, 34, []).
  917     Swi  = swi(Mj,Mn,Fx,Inc),
  918     ( Inc == [] -> 
  919          atomic_list_concat( [Mj,Mn,Fx], ':', Vers )
  920          ;
  921          atomic_list_concat( [Mj,Mn,Fx,Inc], ':',Vers )
  922     ),
  923     debug_message( Topic, 'Session Info', [] ),
  924     ( current_prolog_flag(version_git, Git) -> % Git = '9.3.34-41-g8cf975236'.
  925          atomic_list_concat( ['Interpreter is SWI-Prolog ',Vers,', [Git: ',Git,'].'], Mess )
  926          ;
  927          atomic_list_concat( ['Interpreter is SWI-Prolog ',Vers,'.'], Mess )
  928     ),
  929     debug_call_message_opts( Mess, [], Message, Args, Bogs ),
  930     debug_message( Topic, Message, Args ),
  931     % find where alias pack points to
  932     once( (file_search_path(pack,PackPath),atomic(PackPath)) ),
  933     debug_call_topic_session_predicate_file_prefixed( PackPath, Mod, pack, Lacks ),
  934     findall( APack-ItsVers, (member(APack,Lacks),pack_property(APack,version(ItsVers))), PVs ),
  935     findall( Stoic-VersInfo, (  Mod:predicate_property(P,file(_)),
  936                                 functor(P,Fun,Ari),
  937                                 atom_concat(Stoic,'_version',Fun),
  938                                 ( Mod:predicate_property(P,imported_from(Stoic)) ->
  939                                    true
  940                                    ;
  941                                    Mod:predicate_property(P,exported)
  942                                 ),
  943                                 ( Ari =:= 3 -> 
  944                                        G =.. [Fun,Ser,Sdt,_],
  945                                        call(Mod:G)
  946                                        ;  % defaulty 2
  947                                        Ari =:= 2,
  948                                        G =.. [Fun,Ser,Sdt],
  949                                        call(Mod:G)
  950                                  ),
  951                                  VersInfo = (Ser @< Sdt)
  952                              ),
  953                                 SVs ),
  954     ( SVs == [] ->
  955          true
  956          ;
  957          ( SVs == [_] ->
  958               debug_message( Topic, 'Pack with predicated version info.', [] )
  959               ;
  960               debug_message( Topic, 'Packs with predicated version info.', [] )
  961          ),
  962          debug_call_topic_versions_predicated( SVs, PVs, Topic, RemPVs )
  963     ),
  964     ( RemPVs = [] -> 
  965          true
  966          ;
  967          ( RemPVs = [_] ->
  968               debug_message( Topic, 'Pack with version from pack file only.', [] )
  969               ;
  970               debug_message( Topic, 'Packs with version from pack file only.', [] )
  971          ),
  972          findall( _, (member(P-V,RemPVs),debug_message(Topic,'~w-~w',[P,V])), _ )
  973     ),
  974     once( (file_search_path(swi,SwiPath),atomic(SwiPath)) ),
  975     debug_call_topic_session_predicate_file_prefixed( SwiPath, Mod, boot, Boots ),
  976     debug_message( Topic, 'System boot files loaded.', [] ),
  977     findall( _, (member(Boot,Boots),debug_message(Topic,'~w',[Boot])), _ ),
  978     directory_file_path( SwiPath, library, LibPath ),
  979     debug_call_topic_session_predicate_file_prefixed( LibPath, Mod, rel, Libs ),
  980     ( Libs = [] ->
  981          debug_message( Topic, 'No system libraries found loaded.', [] )
  982          ;
  983          ( Libs =[_] ->
  984               debug_message( Topic, 'System library loaded.', [] )
  985               ;
  986               debug_message( Topic, 'System libraries loaded.', [] )
  987          ),
  988          findall( _, (member(Lib,Libs),debug_message(Topic,'~w',[Lib])), _ )
  989     ),
  990     findall( AppF, (   Mod:predicate_property(_,file(AppF)),
  991                        ( atom_concat(PackPath,PackPsfx,AppF) ->
  992                                            % fixme: check PackTop below, against loaded ?
  993                                   catch( atomic_list_concat([_Empty,_PackTop,TopSub|_],'/',PackPsfx),_,fail),
  994                                   \+ memberchk(TopSub,[prolog,src])
  995                                   ;
  996                                   true
  997                        ),
  998                        \+atom_concat(SwiPath,_,AppF)
  999                    ),
 1000                         AppFsL ),
 1001     sort( AppFsL, AppFs ),
 1002     ( AppFs = [] ->
 1003          debug_message( Topic, 'There where no application files loaded.', [] )
 1004          ;
 1005          ( AppFs = [_] ->
 1006               debug_message( Topic, 'There is one application file loaded.', [] )
 1007               ;
 1008               debug_message( Topic, 'Application files loaded.', [] )
 1009          ),
 1010          findall( AnAF, (member(AnAF,AppFs),debug_message(Topic,'~w',[AnAF])), _ )
 1011     ),
 1012     debug_message( Topic, 'Session Info End', [] ).
 1013debug_call_topic( version, Derm, Bogs, Topic ) :-
 1014     ( atomic(Derm) -> 
 1015          atom_concat( Derm, '_version', Verm ),
 1016          ( current_predicate(Verm/2) ->
 1017               Goal =.. [Verm,V,D],
 1018               once(Goal)
 1019               ;
 1020               ( current_predicate(Verm/3) ->
 1021                    Goal =.. [Verm,V,D,_],
 1022                    once(Goal)
 1023                    ;
 1024                    ( pack_property(Derm,version(V)) ->
 1025                         D = no_date
 1026                         ;
 1027                         ( current_predicate(Derm/2) -> 
 1028                              Goal =.. [Derm,V,D],
 1029                              once(Goal)
 1030                              ;
 1031                              V = no_vers, D = no_date
 1032                         )
 1033                    )
 1034               )
 1035          ),
 1036          Mrgs = [Derm,V,D]
 1037          ;
 1038          ( functor(Derm,_,2) ->
 1039               arg( 1, Derm, Sw ),
 1040               arg( 2, Derm, V ),
 1041               Mrgs = [Sw,V,no_date]
 1042               ;
 1043               ( functor(Derm,_,3) ->
 1044                    arg( 1, Derm, Sw ),
 1045                    arg( 2, Derm, V ),
 1046                    arg( 3, Derm, D ),
 1047                    Mrgs = [Sw,V,D]
 1048                    ;
 1049                    Mrgs = [Derm,no_vers,no_date]
 1050               )
 1051          )
 1052     ),
 1053     ( D == no_date ->
 1054          (   V == no_vers ->
 1055               Mess = 'Using ~w (no version or publication date available).',
 1056               Mrgs = [A|_],
 1057               Crgs = [A]
 1058               ;
 1059               Mess = 'Using ~w, at version: ~w.',
 1060               Mrgs = [A,B|_],
 1061               Crgs = [A,B]
 1062          )
 1063          ;
 1064          Mess = 'Using ~w, at version: ~w (published on: ~w).',
 1065          Mrgs = Crgs
 1066     ),
 1067     debug_call_message_opts( Mess, Crgs, Message, Args, Bogs ),
 1068     debug_message( Topic, Message, Args ).
 1069debug_call_topic( wrote, ForLoc, Bogs, Topic ) :-
 1070    ( ForLoc = loc(Spec,Ext) -> true; Spec=ForLoc, Ext = '' ),
 1071    catch( locate(Spec,Ext,Loc), Excp, true ),
 1072    MessW = 'Wrote on file: ~p',
 1073    debug_call_location_exception_message( Excp, write, Loc, MessW, Mess, Bogs, Mrgs ),
 1074    debug_call_message_opts( Mess, Mrgs, Message, Args, Bogs ),
 1075    debug_message( Topic, Message, Args ).
 1076debug_call_topic( read, ForLoc, Bogs, Topic ) :-
 1077     debug_call_topic( input, ForLoc, Bogs, Topic ).
 1078debug_call_topic( input, ForLoc, Bogs, Topic ) :-
 1079    ( ForLoc = loc(Spec,Ext) -> true; Spec=ForLoc, Ext = '' ),
 1080    catch( locate(Spec,Ext,Loc), Excp, true ),
 1081    MessW = 'Input from file: ~p',
 1082    debug_call_location_exception_message( Excp, input, Loc, MessW, Mess, Bogs, Mrgs ),
 1083    debug_call_message_opts( Mess, Mrgs, Message, Args, Bogs ),
 1084    debug_message( Topic, Message, Args ).
 1085debug_call_topic( task(Whc), TaskPrv, Bogs, Topic ) :-
 1086    datime_readable( Readable ),
 1087    debug_call_topic_time_which_readable( Whc, Whcable ),
 1088    ( compound(TaskPrv) -> term_to_atom( TaskPrv, Task ); TaskPrv = Task ),
 1089    atomic_list_concat( [Readable,' ',Whcable,' task: ',Task,'.'], '', Mess ),
 1090    debug_call_message_opts( Mess, [], Message, Args, Bogs ),
 1091    debug_message( Topic, Message, Args ).
 1092debug_call_topic( start, Arg, Bogs, Topic ) :-
 1093    Mess = 'Starting: ~w',
 1094    ( Arg == true -> Rep = Topic; Rep = Arg ),
 1095    debug_call_message_opts( Mess, [Rep], Message, Args, Bogs ),
 1096    debug_message( Topic, Message, Args ).
 1097debug_call_topic( end, Arg, Bogs, Topic ) :-
 1098    Mess = 'Finished: ~w',
 1099    ( Arg == true -> Rep = Topic; Rep = Arg ),
 1100    debug_call_message_opts( Mess, [Rep], Message, Args, Bogs ),
 1101    debug_message( Topic, Message, Args ).
 1102debug_call_topic( pwd, Stage, Bogs, Topic ) :-
 1103    working_directory( Pwd, Pwd ),
 1104    ( Stage == false -> 
 1105        Mess = 'Pwd: ~p', Mrgs = [Pwd]
 1106        ;
 1107        Mess = 'Pwd at, ~w, is: ~p', Mrgs = [Stage,Pwd]
 1108    ),
 1109    debug_call_message_opts( Mess, Mrgs, Message, Args, Bogs ),
 1110    debug_message( Topic, Message, Args ).
 1111debug_call_topic( ns_sel, Term, Bogs, Topic ) :-
 1112    arg( 1, Term, Fst ),
 1113    arg( 2, Term, Sec ),
 1114    ( memberchk(sel_name(Trd),Bogs) ->
 1115          Mess = 'Continuing with: ~w as the: ~w. From list: ~w',
 1116          MArgs= [Fst,Trd,Sec]
 1117          ;
 1118          Mess = 'Continuing with: ~w from list: ~w',
 1119          MArgs= [Fst,Sec]
 1120    ),
 1121    debug_call_message_opts( Mess, MArgs, Message, Args, Bogs ),
 1122    debug_message( Topic, Message, Args ).
 1123
 1124debug_call_topic_session_predicate_file_prefixed( Path, Mod, Iface, Lacks ) :-
 1125     findall( APack, ( Mod:predicate_property(_Pead, file(File)), 
 1126                             atom_concat(Path, Psfx, File), 
 1127                             ( Iface == pack -> 
 1128                                   atomic_list_concat(['',APack|_], '/', Psfx)
 1129                                   ;
 1130                                   ( atom_concat('/',APack,Psfx) -> 
 1131                                        ( Iface == boot ->
 1132                                             \+ atom_concat( library, _, APack )
 1133                                             ;
 1134                                             true
 1135                                        )
 1136                                        ;
 1137                                        Psfx = APack
 1138                                   )
 1139                             )
 1140                           ),
 1141                              AllPacks ),
 1142     sort( AllPacks, Lacks ).
 1143
 1144debug_call_topic_versions_predicated( [], PVs, _Topic, RemPVs ) :-
 1145     PVs = RemPVs.
 1146debug_call_topic_versions_predicated( [Pack-SVers|T], PVs, Topic, RemPVs ) :-
 1147     ( select(Pack-InfoVer,PVs,NxtPVs) ->
 1148          debug_message( Topic, '~w-~w (Pack file version: ~w)', [Pack,SVers,InfoVer] )
 1149          ;
 1150          debug_message( Topic, '~w-~w', [Pack,SVers] ),
 1151          PVs = NxtPVs
 1152     ),
 1153     debug_call_topic_versions_predicated( T, NxtPVs, Topic, RemPVs ).
 1154
 1155debuc_call_topic_term( Rec, Topic, Bogs ) :-
 1156    ( memberchk(comment(false),Bogs) ->
 1157          format( '~q.\n', [Rec] )
 1158          ;
 1159          debug_call_message_opts( '~w.', [Rec], Message, Args, Bogs ),
 1160          debug_message( Topic, Message, Args )
 1161     ).
 1162
 1163debug_call_topic_enum( [], _I, _Depth, _Len, _Topic ).
 1164debug_call_topic_enum( [H|T], I, Depth, Len, Topic ) :-
 1165    ( I > Depth -> 
 1166          Rem = [],
 1167          length( [H|T], HTen ),
 1168          ( HTen =:= 1 -> 
 1169               Mess = '... + ~d other element'
 1170               ;
 1171               Mess = '... + ~d other elements'
 1172          ),
 1173          debug_message( Topic, Mess, HTen )
 1174          ;
 1175          T = Rem,
 1176          number_codes( I, ICs ),
 1177          length( ICs, ICsLen ),
 1178          PadLen is Len - ICsLen,
 1179          findall( ' ', between(1,PadLen,_), Spcs ),
 1180          atomic_list_concat( Spcs, '', Pad ),
 1181          atomic_list_concat( [Pad,'~d.~w'], '', Mess ),
 1182          debug_message( Topic, Mess, [I,H] )
 1183    ),
 1184    J is I + 1,
 1185    debug_call_topic_enum( Rem, J, Depth, Len, Topic ).
 1186
 1187debug_call_topic_list_delim( ListName, Topic, Std, Bogs ) :-
 1188     debug_call_message_opts( Std, [ListName], Mess, Args, Bogs ), 
 1189     debug_message( Topic, Mess, Args ).
 1190
 1191debug_call_topic_time_which_readable( Wch, Wchable ) :-
 1192    debug_call_topic_time_which_readable_known( Wch, Wchable ),
 1193    !.
 1194debug_call_topic_time_which_readable( Wch, Wch ).
 1195
 1196debug_call_topic_time_which_readable_known( start, starting ).
 1197debug_call_topic_time_which_readable_known( finish, finished ).
 1198
 1199debug_call_location_exception_message( Var, _Dir, Loc, MessI, MessO, Opts, Args ) :-
 1200    var(Var),
 1201    !,
 1202    MessI = MessO,
 1203    ( memberchk(path(abs),Opts) ->
 1204               Args = [Loc]
 1205               ;
 1206               file_base_name( Loc, Arg ),
 1207               Args = [Arg]
 1208    ).
 1209debug_call_location_exception_message( locate(cannot_locate(Spec,Ext)), Dir, _Loc, _MessI, Mess, _Opts, Args ) :-
 1210    atomic_list_concat( ['Could not locate',Dir,'file specified by: ~w, and extensions: ~w'], ' ', Mess ),
 1211    Args = [Spec,Ext].
 1212debug_call_location_exception_message( Error, _Dir, _Loc, _MessI, _Mess, _Opts, _Args ) :-
 1213    % fixme:
 1214    throw( debug_call_caught(Error) ).
 1215
 1216debug_mtx_dims( [], 0, 0 ) :-
 1217    !.
 1218debug_mtx_dims( Rows, NRows, NCols ) :-
 1219    length( Rows, NRows ),
 1220    Rows = [Hdr|_],
 1221    ( is_list(Hdr) -> length(Hdr,NCols); functor(Hdr,_,NCols) ).
 1222
 1223debug_message_prefixed( [], Standard, Standard ) :- !.
 1224debug_message_prefixed( '', Standard, Standard ) :- !.
 1225debug_message_prefixed( prefix(Pfx), Standard, Prefixed ) :-
 1226     !,
 1227     debug_message_prefixed( [prefix(Pfx)], Standard, Prefixed ).
 1228debug_message_prefixed( [H|T], Standard, Prefixed ) :-
 1229    memberchk( prefix(Pfx), [H|T] ),
 1230    !,
 1231    debug_message_prefixed_atom( Pfx, Standard, Prefixed ).
 1232debug_message_prefixed( _, Standard, Standard ).
 1233
 1234debug_call_message_opts( Std, Srgs, Mess, Args, Opts ) :-
 1235     debug_call_pred_in_opts_mess( Std, Srgs, Pess, Args, Opts ),
 1236     debug_message_prefixed( Opts, Pess, Mess ).
 1237
 1238debug_call_pred_in_opts_mess( Std, Opt, Prefixed, Prgs, Bogs ) :-
 1239     en_list( Opt, Opts ),
 1240     ( debug_call_pred_in_opts(Pid, Bogs)  ->
 1241          Pfx = 'Predicate: ~w',
 1242          debug_message_prefixed_atom( Pfx, Std, Prefixed ),
 1243          PrgsPrv = [Pid|Opts]
 1244          ;
 1245          Prefixed = Std,
 1246          PrgsPrv = Opts
 1247     ),
 1248     debug_call_pred_in_opts_mess_format_args( PrgsPrv, Prgs, Bogs ).
 1249
 1250debug_call_pred_in_opts( Pid, Opts ) :-
 1251    memberchk( pred(Fun,Ar), Opts ),
 1252    !,
 1253    Fun/Ar = Pid.
 1254debug_call_pred_in_opts( Pid, Opts ) :-
 1255    memberchk( pred(Pid), Opts ).
 1256
 1257debug_call_pred_in_opts_mess_format_args( PrgsPrv, Prgs, Bogs ) :-
 1258     findall( Farg, member(farg(Farg),Bogs), Fargs ),
 1259     append( PrgsPrv, Fargs, Prgs ).
 1260
 1261debug_message_prefixed_atom( Pfx, Standard, Prefixed ) :-
 1262    sub_atom( Standard, 0, 1, Aft, Fst ),
 1263    downcase_atom( Fst, Low ),
 1264    sub_atom( Standard, 1, Aft, 0, Right ),
 1265    atomic_list_concat( [Pfx,' ',Low,Right], Prefixed ).
 1266
 1267debug_call_duh_dir( Dir, Pair ) :-
 1268    setup_call_cleanup(
 1269            process_create(path(du), ['-h','-s',Dir],
 1270                           [ stdout(pipe(Out))
 1271                           ]),
 1272            read_line_to_codes( Out, LineCs ),
 1273            close(Out)),
 1274    atom_codes( Line, LineCs ),
 1275    atomic_list_concat( [Size,Item], '\t', Line ),
 1276    Pair = Item-Size