/*
*/
% buginit/1 - optionally opens a file to which debugging
% output is directed. The argument is the file name.
% buginit/0 - optionally opens file 'bug.log' for debugging
% output.
% user_bugwrite/1 - The user can define an output predicate
% that outputs a term, and most likely follows it with
% a newline.
% bug/1 - brackets a call to a predicate with debugging
% information
% ?/1 - an operator synonym for bug/1.
% bugclose/0 - closes the debugging file, if one was open
%
% flow/1,3 - can be used to note the flow of control at a
% point in the program, for both normal code and DCG.
%
:- export
buginit/1,
buginit/0,
bug/1,
? /1,
bugclose/0,
flow/1,
flow/3.
:- import
user_bugwrite/1,
bug$file/1.
:- op(900, fy, [?, bug]).
/*
*/
buginit(FileName) :-
fopen(B, FileName, w),
assert(bug$file(B)).
buginit :-
buginit('bug.log').
/*
*/ bugclose :- retract(bug$file(B)), !, fclose(B). bugclose. /*
You can also define your own output predicate, user_bugwrite/1, which will be used for all output if it is defined.
For example, bug/1, ?/1 can be used to debug the append/3 predicate as follows:
append([A|X], Y, [A|Z]) :-
? append(X,Y,Z).
In this case the call, exit, redo, and fail ports around
the recursive call to append/3 will all be written to
either the standard output stream, the bugfile, or whereever
user_bugwrite/1 sends the output.
*/
bug(X) :-
bug$callfail(X),
call(X),
bug$exitredo(X).
? X :- bug(X).
% Try user's bugwrite first, if not see if there's a bugfile
% if not, just writeq.
bug$write(X) :-
user_bugwrite(X), !.
bug$write(X) :-
bug$file(B), !,
writeq(B, X),
nl(B).
bug$write(X) :-
writeq(X),
nl.
% bug$callfail/1 - writes a quoted term with the message
% CALL when called, and FAIL when backtracked through
% bug$exitredo/1 - writes a quoted term with the message
% EXIT when called, and REDO when backtracked through
bug$callfail(X) :-
bug$write('CALL':X).
bug$callfail(X) :-
bug$write('FAIL':X),
fail.
bug$exitredo(X) :-
bug$write('EXIT':X).
bug$exitredo(X) :-
bug$write('REDO':X),
fail.
/*
*/
flow(X):- write('>'),write(X),nl.
flow(X):- put(`<),write(X),nl,fail.
flow(X, Y, Y):- put(`>),write(X),nl. % threaded for dcg rules
flow(X, Y, Y):- put(`<),write(X),nl,fail.