Protocol/1

How to - protocol/1

Note: This is a work in progress. When it is complete these notes will be removed.

Note: Do not reply to this topic, questions, concerns, comments, etc. are to handled in
Wiki discussion: How to - protocol/1

Note: This is just to get the topic started and hopefully others to jump in and make this useful. Even if you are brand new to Prolog, this is such a basic and fundamental concept that you can and should join in to help improve the value of this Wiki. Join the discussion at Wiki discussion: How to - protocol/1

Note: This is a wiki and if you have Trust level: Basic you can edit this by clicking on the pencil icon in the lower right. Capture
These topics also have history so they can be rolled-back if needed.

protocol/1 will copy the output that goes to the screen to a file. So if you run a trace/0 and the output goes to the screen, a copy will be sent to a file. To simplify having to write the entire path for protocol/1 I find it easier to set the current working directory using working_directory/2 and then only set the specific file with protocol/1.

Example

For this example create a file, e.g.

trace_example.pl

and add some facts and predicates to demonstrate tracing.

parent(ann,helen).
parent(helen,henry).
parent(henry,mary).

ancestor(X,Y) :- parent(X,Y).
ancestor(X,Y) :- parent(X,Z),
    ancestor(Z,Y).

Open SWI-Prolog top level and use consult/1 to load the file

consult("C:/ ... /trace_example.pl").

NB On Windows the directory separators are / not \. Change them if necessary.

Since the SWI-Prolog terminal on Windows will default to using color with tracing and that will add unneeded escape sequences to the output file set_prolog_flag/2 needs to be run to turn the color off.

?- set_prolog_flag(color_term,false).
true.

Verify that the terminal is not using color.

?- current_prolog_flag(color_term,X).
X = false.

A quick run to verify the predicate and facts work

?- ancestor(ann,henry).
true ;
false.

Now set the current working directory to where the output file will be created.

?- working_directory(_,"C:/Users/Eric/Documents/Prolog").

and verify that the change occurred

?- working_directory(CWD,CWD).
CWD = 'c:/users/eric/documents/prolog/'.

Since I don’t want to press the space bar for each trace output I disable user interaction for all the debug ports using leash/1

?- leash(-all).

and since I want to see all of the output from all of the debug ports I enable them all with visible/1

?- visible(+all).

Enable the copying/capture of the screen to a file

?- protocol("./trace_output.txt").

start the tracer

?- trace.

and run a query to be traced

?- ancestor(ann,henry).

   Call: (8) ancestor(ann, henry) ? creep
   Call: (9) parent(ann, henry) ? creep
   Fail: (9) parent(ann, henry) ? creep
   Redo: (8) ancestor(ann, henry) ? creep
   Call: (9) parent(ann, _1124) ? creep
   Exit: (9) parent(ann, helen) ? creep
   Call: (9) ancestor(helen, henry) ? creep
   Call: (10) parent(helen, henry) ? creep
   Exit: (10) parent(helen, henry) ? creep
   Exit: (9) ancestor(helen, henry) ? creep
   Exit: (8) ancestor(ann, henry) ? creep
true ;
   Redo: (9) ancestor(helen, henry) ? creep
   Call: (10) parent(helen, _1124) ? creep
   Exit: (10) parent(helen, henry) ? creep
   Call: (10) ancestor(henry, henry) ? creep
   Call: (11) parent(henry, henry) ? creep
   Fail: (11) parent(henry, henry) ? creep
   Redo: (10) ancestor(henry, henry) ? creep
   Call: (11) parent(henry, _1124) ? creep
   Exit: (11) parent(henry, mary) ? creep
   Call: (11) ancestor(mary, henry) ? creep
   Call: (12) parent(mary, henry) ? creep
   Fail: (12) parent(mary, henry) ? creep
   Redo: (11) ancestor(mary, henry) ? creep
   Call: (12) parent(mary, _1124) ? creep
   Fail: (12) parent(mary, _1124) ? creep
   Fail: (11) ancestor(mary, henry) ? creep
   Fail: (10) ancestor(henry, henry) ? creep
   Fail: (9) ancestor(helen, henry) ? creep
   Fail: (8) ancestor(ann, henry) ? creep
false.

end the tracing

?- nodebug.

and end the copying of the screen to the file

?- noprotocol.

Now open the file C:\Users\Eric\Documents\Prolog\trace_output.txt

true.  
  
10 ?- trace.  
  
  
true.  
  
[trace] 10 ?- ancestor(ann,henry).  
  
  
   Call: (8) ancestor(ann, henry)  
   Unify: (8) ancestor(ann, henry)  
   Call: (9) parent(ann, henry)  
   Fail: (9) parent(ann, henry)  
   Redo: (8) ancestor(ann, henry)  
   Unify: (8) ancestor(ann, henry)  
   Call: (9) parent(ann, _6466)  
   Unify: (9) parent(ann, helen)  
   Exit: (9) parent(ann, helen)  
   Call: (9) ancestor(helen, henry)  
   Unify: (9) ancestor(helen, henry)  
   Call: (10) parent(helen, henry)  
   Unify: (10) parent(helen, henry)  
   Exit: (10) parent(helen, henry)  
   Exit: (9) ancestor(helen, henry)  
   Exit: (8) ancestor(ann, henry)  
true  ;  
   Redo: (9) ancestor(helen, henry)  
   Unify: (9) ancestor(helen, henry)  
   Call: (10) parent(helen, _6466)  
   Unify: (10) parent(helen, henry)  
   Exit: (10) parent(helen, henry)  
   Call: (10) ancestor(henry, henry)  
   Unify: (10) ancestor(henry, henry)  
   Call: (11) parent(henry, henry)  
   Fail: (11) parent(henry, henry)  
   Redo: (10) ancestor(henry, henry)  
   Unify: (10) ancestor(henry, henry)  
   Call: (11) parent(henry, _6466)  
   Unify: (11) parent(henry, mary)  
   Exit: (11) parent(henry, mary)  
   Call: (11) ancestor(mary, henry)  
   Unify: (11) ancestor(mary, henry)  
   Call: (12) parent(mary, henry)  
   Fail: (12) parent(mary, henry)  
   Redo: (11) ancestor(mary, henry)  
   Unify: (11) ancestor(mary, henry)  
   Call: (12) parent(mary, _6466)  
   Fail: (12) parent(mary, _6466)  
   Fail: (11) ancestor(mary, henry)  
   Fail: (10) ancestor(henry, henry)  
   Fail: (9) ancestor(helen, henry)  
   Fail: (8) ancestor(ann, henry)  
false.  
  
[trace] 11 ?-  nodebug.  
  
  
true.  
  
12 ?- noprotocol.  

Here is an example of using the above functions to create a basic predicate that toggles logging on and off with a single command.

% ----->>>>> toggle_trace_logging/0

% This predicate turns trace logging OFF it is currently ON, and ON if it 
% 	is OFF.  Note, when logging is turned ON, any existing file with the 
%	log file name we use is OVERWRITTEN.  This can be changed by using 
%	protcola/1 (append) instead of protocol/1.  Also, this code always
%     writes to a file named `prolog-trace.plg` in the current working
%     directory.

	turn_off_trace_logging :-
		noprotocol,
		% Undo the changes we made to support and format trace output to 
		%	a file.
		leash(+all),
		% Show all output from the debug ports.
		visible(-all),
		set_prolog_flag(color_term, true),
		% Turn OFF tracing.
		notrace,
		write('Trace logging is now OFF.'), nl, !.

	turn_on_trace_logging :-
		% Establish the log file name while turning tracing ON.
		protocola('./prolog-trace.plg'),
		% Turn off color output so we don't get color characters in the 
		%	logging file.
		set_prolog_flag(color_term, false),
		% Turn off space bar confirmation for each output since we 
		%	are outputting to a file.
		leash(-all),
		% Show all output from the debug ports.
		visible(+all),
		% Turn ON tracing.
		notrace,
		write('Trace logging is now ON.'), nl, !.

toggle_trace_logging :- 
	% Is trace logging currently on?
	protocolling(_),
	% Yes.  Turn it off.
	write('Turning OFF trace logging.'), nl,
	turn_off_trace_logging,
	!.

toggle_trace_logging :-
	% Tracing is assumed to be OFF now.  Turn it on.
	write('Turning ON trace logging.'), nl,
	turn_on_trace_logging,
	!.
1 Like

A post was merged into an existing topic: Wiki discussion: How to - protocol/1