\chapter{Hackers corner}			\label{sec:hack}

This appendix describes a number of predicates which enable the Prolog
user to inspect the Prolog environment and manipulate (or even redefine)
the debugger.  They can be used as entry points for experiments with
debugging tools for Prolog. The predicates described here should be
handled with some care as it is easy to corrupt the consistency of the
Prolog system by misusing them.

\section{Examining the Environment Stack}	\label{sec:manipstack}

\begin{description}
    \predicate[det]{prolog_current_frame}{1}{-Frame}
Unify \arg{Frame} with an integer providing a reference to the parent of
the current local stack frame.  A pointer to the current local frame
cannot be provided as the predicate succeeds deterministically and
therefore its frame is destroyed immediately after succeeding.

    \predicate[semidet]{prolog_current_choice}{1}{-Choice}
Unify \arg{Choice} with an integer provided a reference to the last
choice point.  Fails if the current environment has no choice points.
See also \index{prolog_choice_attribute/3}\predref{prolog_choice_attribute}{3}.

    \predicate{prolog_frame_attribute}{3}{+Frame, +Key, :Value}
Obtain information about the local stack frame \arg{Frame}.  \arg{Frame}
is a frame reference as obtained through \index{prolog_current_frame/1}\predref{prolog_current_frame}{1},
\index{prolog_trace_interception/4}\predref{prolog_trace_interception}{4} or this predicate.  The key values are
described below.

\begin{description}
    \termitem{alternative}{}
\arg{Value} is unified with an integer reference to the local stack
frame in which execution is resumed if the goal associated with
\arg{Frame} fails. Fails if the frame has no alternative frame.

    \termitem{has_alternatives}{}
\arg{Value} is unified with \const{true} if \arg{Frame} still is a
candidate for backtracking; \const{false} otherwise.

    \termitem{goal}{}
\arg{Value} is unified with the goal associated with \arg{Frame}. If the
definition module of the active predicate is not the calling context,
the goal is represented as \mbox{\tt \bnfmeta{module}:\bnfmeta{goal}}. Do not instantiate
variables in this goal unless you {\bf know} what you are doing!
Note that the returned term may contain references to the frame and
should be discarded before the frame terminates.%
	\footnote{The returned term is actually an illegal Prolog term
		  that may hold references from the global to the local
		  stack to preserve the variable names.}

    \termitem{parent_goal}{}
If \arg{Value} is instantiated to a callable term, find a frame
executing the predicate described by \arg{Value} and unify the arguments
of \arg{Value} to the goal arguments associated with the frame. This is
intended to check the current execution context. The user must ensure
the checked parent goal is not removed from the stack due to last-call
optimisation and be aware of the slow operation on deeply nested calls.

    \termitem{predicate_indicator}{}
Similar to \const{goal}, but only returning the
[\bnfmeta{module}:]\bnfmeta{name}/\bnfmeta{arity} term describing the term, not the actual
arguments.  It avoids creating an illegal term as \const{goal} and
is used by the library \pllib{prolog_stack}.

    \termitem{clause}{}
\arg{Value} is unified with a reference to the currently running clause.
Fails if the current goal is associated with a foreign (C) defined
predicate. See also \index{nth_clause/3}\predref{nth_clause}{3} and \index{clause_property/2}\predref{clause_property}{2}.

    \termitem{level}{}
\arg{Value} is unified with the recursion level of \arg{Frame}. The top
level frame is at level `0'.

    \termitem{parent}{}
\arg{Value} is unified with an integer reference to the parent local
stack frame of \arg{Frame}. Fails if \arg{Frame} is the top frame.

    \termitem{context_module}{}
\arg{Value} is unified with the name of the context module of the
environment.

    \termitem{top}{}
\arg{Value} is unified with \const{true} if \arg{Frame} is the top Prolog
goal from a recursive call back from the foreign language; \const{false}
otherwise.

    \termitem{hidden}{}
\arg{Value} is unified with \const{true} if the frame is hidden from the
user, either because a parent has the hide-childs attribute (all system
predicates), or the system has no trace-me attribute.

    \termitem{skipped}{}
\arg{Value} is \const{true} if this frame was skipped in the debugger.

    \termitem{pc}{}
\arg{Value} is unified with the program pointer saved on behalf of the
parent goal if the parent goal is not owned by a foreign predicate or
belongs to a compound meta-call (e.g., call((a,b))).

    \termitem{argument}{N}
\arg{Value} is unified with the \arg{N}-th slot of the frame. Argument
1 is the first argument of the goal. Arguments above the arity
refer to local variables. Fails silently if \arg{N} is out of range.
\end{description}

    \predicate{prolog_choice_attribute}{3}{+ChoicePoint, +Key, -Value}
Extract attributes of a choice point.  \arg{ChoicePoint} is a reference
to a choice point as passed to \index{prolog_trace_interception/4}\predref{prolog_trace_interception}{4} on the 3rd
argument or obtained using \index{prolog_current_choice/1}\predref{prolog_current_choice}{1}. \arg{Key} specifies
the requested information:

\begin{description}
    \termitem{parent}{}
Requests a reference to the first older choice point.
    \termitem{frame}{}
Requests a reference to the frame to which the choice point refers.
    \termitem{type}{}
Requests the type.  Defined values are \const{clause} (the goal has
alternative clauses), \const{foreign} (non-deterministic foreign
predicate), \const{jump} (clause internal choice point), \const{top}
(first dummy choice point), \const{catch} (\index{catch/3}\predref{catch}{3} to allow for undo),
\const{debug} (help the debugger), or \const{none} (has been deleted).
\end{description}

This predicate is used for the graphical debugger to show the
choice point stack.

    \predicate{deterministic}{1}{-Boolean}
Unifies its argument with \const{true} if no choice point exists that is
more recent than the entry of the clause in which it appears. There are
few realistic situations for using this predicate. It is used by the
\index{prolog/0}\predref{prolog}{0} top level to check whether Prolog should prompt the user for
alternatives. Similar results can be achieved in a more portable fashion
using \index{call_cleanup/2}\predref{call_cleanup}{2}.
\end{description}

\section{Ancestral cuts}		\label{sec:ancestral-cut}

\begin{description}
    \predicate{prolog_cut_to}{1}{+Choice}
Prunes all choice points created since \arg{Choice}. Can be used
together with \index{prolog_current_choice/1}\predref{prolog_current_choice}{1} to implement \jargon{ancestral} cuts.
This predicate is in the hackers corner because it should not be used
in normal Prolog code. It may be used to create new high level control
structures, particularly for compatibility purposes.

Note that in the current implementation, the pruned choice points and
environment frames are \emph{not} reclaimed. As a consequence, where
predicates that are deterministic due to clause indexing, normal cuts or
\verb$(if->then;else)$ and and tail recursive run in bounded local
stack space, predicates using \index{prolog_cut_to/1}\predref{prolog_cut_to}{1} will run out of stack.
\end{description}


\section{Intercepting the Tracer}		\label{sec:tracehook}

\begin{description}
    \predicate{prolog_trace_interception}{4}{+Port, +Frame, +Choice, -Action}
Dynamic predicate, normally not defined. This predicate is called from
the SWI-Prolog debugger just before it would show a port. If this
predicate succeeds, the debugger assumes that the trace action has been taken
care of and continues execution as described by \arg{Action}. Otherwise
the normal Prolog debugger actions are performed.

\arg{Port} denotes the reason to activate the tracer (`port' in the
4/5-port, but with some additions):

\begin{description}
    \termitem{call}{}
Normal entry through the call port of the 4-port debugger.

    \termitem{redo}{PC}
Normal entry through the redo port of the 4-port debugger. The
\const{redo} port signals resuming a predicate to generate alternative
solutions. If \arg{PC} is 0 (zero), clause indexing has found another
clause that will be tried next. Otherwise, \arg{PC} is the program
counter in the current clause where execution continues. This implies we
are dealing with an in-clause choice point left by, e.g., \predref{\Ssemicolon}{2}.
Note that non-determinism in foreign predicates are also handled using
an in-clause choice point.

    \termitem{unify}{}
The unify port represents the \jargon{neck} instruction, signalling the
end of the head-matching process.  This port is normally invisible.  See
\index{leash/1}\predref{leash}{1} and \index{visible/1}\predref{visible}{1}.

    \termitem{exit}{}
The exit port signals the goal is proved.  It is possible for the goal
to have alternatives. See \index{prolog_frame_attribute/3}\predref{prolog_frame_attribute}{3} to examine the
goal stack.

    \termitem{fail}{}
The fail port signals final failure of the goal.

    \termitem{exception}{Except}
An exception is raised and still pending.  This port is activated on
each parent frame of the frame generating the exception until the
exception is caught or the user restarts normal computation using
\const{retry}.  \arg{Except} is the pending exception term.

    \termitem{break}{PC}
A \const{break} instruction is executed.  \arg{PC} is program counter.
This port is used by the graphical debugger.

    \termitem{cut_call}{PC}
A cut is encountered at \arg{PC}. This port is used by the graphical
debugger to visualise the effect of the cut.

    \termitem{cut_exit}{PC}
A cut has been executed.  See \term{cut_call}{PC} for more information.
\end{description}

\arg{Frame} is a reference to the current local stack frame, which can
be examined using \index{prolog_frame_attribute/3}\predref{prolog_frame_attribute}{3}. \arg{Choice} is a reference
to the last choice point and can be examined using
\index{prolog_choice_attribute/3}\predref{prolog_choice_attribute}{3}. \arg{Action} must be unified with a term that
specifies how execution must continue. The following actions are
defined:

\begin{description}
    \termitem{abort}{}
Abort execution.  See \index{abort/0}\predref{abort}{0}.
    \termitem{continue}{}
Continue (i.e., \jargon{creep} in the command line debugger).
    \termitem{fail}{}
Make the current goal fail.
    \termitem{ignore}{}
Step over the current goal without executing it.
    \termitem{nodebug}{}
Continue execution in normal nodebugging mode.  See \index{nodebug/0}\predref{nodebug}{0}.
    \termitem{retry}{}
Retry the current frame.
    \termitem{retry}{Frame}
Retry the given frame.  This must be a parent of the current
frame.
    \termitem{skip}{}
Skip over the current goal (i.e., \jargon{skip} in the command line debugger).
    \termitem{up}{}
Skip to the parent goal (i.e., \jargon{up} in the command line debugger).
\end{description}

Together with the predicates described in \secref{debugger}
and the other predicates of this chapter, this predicate enables the
Prolog user to define a complete new debugger in Prolog. Besides this, it
enables the Prolog programmer to monitor the execution of a program. The
example below records all goals trapped by the tracer in the database.

\begin{code}
prolog_trace_interception(Port, Frame, _PC, continue) :-
        prolog_frame_attribute(Frame, goal, Goal),
        prolog_frame_attribute(Frame, level, Level),
        recordz(trace, trace(Port, Level, Goal)).
\end{code}

\noindent
To trace the execution of `go' this way the following query should be
given:

\begin{code}
?- trace, go, notrace.
\end{code}

\noindent
    \predicate{prolog_skip_frame}{1}{-Frame}
Indicate \arg{Frame} as a skipped frame and set the `skip level' (see
\index{prolog_skip_level/2}\predref{prolog_skip_level}{2} to the recursion depth of \arg{Frame}.  The effect
of the skipped flag is that a redo on a child of this frame is handled
differently.  First, a \const{redo} trace is called for the child, where
the skip level is set to \const{redo_in_skip}.  Next, the skip level is
set to skip level of the skipped frame.

    \predicate{prolog_skip_level}{2}{-Old, +New}
Unify \arg{Old} with the old value of `skip level' and then set this
level according to \arg{New}. \arg{New} is an integer, the atom
\const{very_deep} (meaning don't skip) or the atom \const{skip_in_redo}
(see \index{prolog_skip_frame/1}\predref{prolog_skip_frame}{1}). The `skip level' is a setting of each
Prolog thread that disables the debugger on all recursion levels deeper
than the level of the variable.  See also \index{prolog_skip_frame/1}\predref{prolog_skip_frame}{1}.
\end{description}


\section{Breakpoint and watchpoint handling}
\label{sec:breakpoint}

SWI-Prolog support \jargon{breakpoints}.  Breakpoints can be manipulated
with the library \pllib{prolog_breakpoints}. Setting a breakpoint
replaces a virtual machine instruction with the \const{D_BREAK}
instruction.  If the virtual machine executes a \const{D_BREAK}, it
performs a callback to decide on the action to perform.  This section
describes this callback, called \index{prolog:break_hook/6}\qpredref{prolog}{break_hook}{6}.

\begin{description}
    \predicate[hook,semidet]{prolog:break_hook}{6}{+Clause, +PC, +FR,
						   +BFR, +Expression, -Action}
\emph{Experimental}
This hook is called if the virtual machine executes a \const{D_BREAK},
set using \index{set_breakpoint/4}\predref{set_breakpoint}{4}. \arg{Clause} and \arg{PC} identify the
breakpoint. \arg{FR} and \arg{BFR} provide the environment frame and
current choicepoint.  \arg{Expression} identifies the action that is
interrupted, and is one of the following:

    \begin{description}
	\termitem{call}{Goal}
    The instruction will call \arg{Goal}.  This is generated for nearly
    all instructions. Note that \arg{Goal} is semantically
    equivalent to the compiled body term, but might differ
    syntactically. This is notably the case when arithmetic expressions
    are compiled in optimized mode (see \prologflag{optimise}).  In
    particular, the arguments of arithmetic expressions have already
    been evaluated.  Thus, \arg{A} is 3*\arg{B}, where \arg{B} equals
    3 results in a term \exam{call(A is 9)} if the clause was compiled
    with optimization enabled.

        \termitem{\Scut}{}
    The instruction will call the cut. Because the semantics of
    metacalling the cut differs from executing the cut in its
    original context we do not wrap the cut in \functor{call}{1}.

	\termitem{\Sneck}{}
    The breakpoint is on the \jargon{neck} instruction, i.e., after
    performing the head unifications.

	\termitem{exit}{}
    The breakpoint is on the \jargon{exit} instruction, i.e., at the
    end of the clause. Note that the exit instruction may not be reached
    due to last-call optimisation.

	\termitem{unify_exit}{}
    The breakpoint is on the completion of an in-lined unification while
    the system is not in debug mode.  If the system is in debug mode,
    inlined unification is returned as call(Var=Term).\footnote{This
    hack will disappear if we find a good solution for applying D_BREAK
    to inlined unification.  Only option might be to place the break on
    both the unification start and end instructions.}
    \end{description}

If \index{prolog:break_hook/6}\qpredref{prolog}{break_hook}{6} succeeds, it must unify \arg{Action} with a value
that describes how execution must continue. Possible values for
\arg{Action} are:

    \begin{description}
	\termitem{continue}{}
    Just continue as if no breakpoint was present.

	\termitem{debug}{}
    Continue in \jargon{debug mode}.  See \index{debug/0}\predref{debug}{0}.

	\termitem{trace}{}
    Continue in \jargon{trace mode}.  See \index{trace/0}\predref{trace}{0}.

	\termitem{call}{Goal}
    Execute \arg{Goal} instead of the goal that would be executed.
    \arg{Goal} is executed as \index{call/1}\predref{call}{1}, preserving (non-)determinism
    and exceptions.
    \end{description}

If this hook throws an exception, the exception is propagated normally.
If this hook is not defined or fails, the default action is executed.
This implies that, if the thread is in debug mode, the tracer will be
enabled (\const{trace}) and otherwise the breakpoint is ignored
(\const{continue}).

This hook allows for injecting various debugging scenarios into the
executable without recompiling. The hook can access variables of the
calling context using the frame inspection predicates. Here are some
examples.

    \begin{itemize}
	\item Create \jargon{conditional} breakpoints by imposing
	conditions before deciding the return \const{trace}.
	\item Watch variables at a specific point in the execution.
	Note that binding of these variables can be monitored
	using \jargon{attributed variables}, see \secref{attvar}.
	\item Dynamically add \jargon{assertions} on variables
	using \index{assertion/1}\predref{assertion}{1}.
	\item Wrap the \arg{Goal} into a meta-call that traces
	progress of the \arg{Goal}.
    \end{itemize}
\end{description}


\section{Adding context to errors: prolog_exception_hook}
\label{sec:excepthook}

The hook \index{prolog_exception_hook/4}\predref{prolog_exception_hook}{4} has been introduced in SWI-Prolog 5.6.5
to provide dedicated exception handling facilities for application
frameworks, for example non-interactive server applications that
wish to provide extensive context for exceptions for offline debugging.

\begin{description}
    \predicate{prolog_exception_hook}{4}{+ExceptionIn, -ExceptionOut,
					 +Frame, +CatcherFrame}
This hook predicate, if defined in the module \const{user}, is between
raising an exception and handling it. It is intended to allow a program
adding additional context to an exception to simplify diagnosing the
problem. \arg{ExceptionIn} is the exception term as raised by \index{throw/1}\predref{throw}{1} or
one of the built-in predicates. The output argument \arg{ExceptionOut}
describes the exception that is actually raised. \arg{Frame} is the
innermost frame. See \index{prolog_frame_attribute/3}\predref{prolog_frame_attribute}{3} and the library
\pllib{prolog_stack} for getting information from this.
\arg{CatcherFrame} is a reference to the frame calling the matching
\index{catch/3}\predref{catch}{3}, \const{none} if the exception is not caught or \const{'C'}
if the exception is caught in C calling Prolog using the flag
\const{PL_Q_CATCH_EXCEPTION}.

The hook is run in `nodebug' mode. If it succeeds, \arg{ExceptionOut} is
considered the current exception. If it fails, \arg{ExceptionIn} is used
for further processing. The hook is \emph{never} called recursively.
The hook is \emph{not} allowed to modify \arg{ExceptionOut} in such
a way that it no longer unifies with the catching frame.

Typically, \index{prolog_exception_hook/4}\predref{prolog_exception_hook}{4} is used to fill the second argument
of \term{error}{Formal, Context} exceptions. \arg{Formal} is
defined by the ISO standard, while SWI-Prolog defines \arg{Context}
as a term \term{context}{Location, Message}.  \arg{Location} is bound
to a term \bnfmeta{name}/\bnfmeta{arity} by the kernel.  This hook can be used to add
more information on the calling context, such as a full stack trace.

Applications that use exceptions as part of normal processing must
do a quick test of the environment before starting expensive gathering
information on the state of the program.

The hook can call \index{trace/0}\predref{trace}{0} to enter trace mode immediately. For example,
imagine an application performing an unwanted division by zero while all
other errors are expected and handled.  We can force the debugger using
the hook definition below.  Run the program in debug mode (see \index{debug/0}\predref{debug}{0})
to preserve as much as possible of the error context.

\begin{code}
user:prolog_exception_hook(
         error(evaluation_error(zero_divisor), _),
         _, _, _) :-
        trace, fail.
\end{code}

\noindent
\end{description}


\section{Hooks using the exception predicate}	\label{sec:exception3}

This section describes the predicate \index{exception/3}\predref{exception}{3}, which can be defined
by the user in the module \module{user} as a multifile predicate. Unlike
the name suggests, this is actually a \jargon{hook} predicate that has
no relation to Prolog exceptions as defined by the ISO predicates
\index{catch/3}\predref{catch}{3} and \index{throw/1}\predref{throw}{1}.

The predicate \index{exception/3}\predref{exception}{3} is called by the kernel on a couple of events,
allowing the user to `fix' errors just-in-time. The mechanism allows for
\jargon{lazy} creation of objects such as predicates.

\begin{description}
    \predicate{exception}{3}{+Exception, +Context, -Action}
Dynamic predicate, normally not defined. Called by the Prolog system on
run-time exceptions that can be repaired `just-in-time'.  The values
for \arg{Exception} are described below.  See also \index{catch/3}\predref{catch}{3} and \index{throw/1}\predref{throw}{1}.

If this hook predicate succeeds it must instantiate the \arg{Action}
argument to the atom \const{fail} to make the operation fail silently,
\const{retry} to tell Prolog to retry the operation or \const{error} to
make the system generate an exception. The action \const{retry} only
makes sense if this hook modified the environment such that the
operation can now succeed without error.

\begin{description}
    \termitem{undefined_predicate}{}
\arg{Context} is instantiated to a predicate indicator
([module]:\bnfmeta{name}/\bnfmeta{arity}). If the predicate fails, Prolog will generate
an \except{existence_error} exception. The hook is intended to implement
alternatives to the built-in autoloader, such as autoloading code from
a database.  Do \emph{not} use this hook to suppress existence errors on
predicates.  See also \prologflag{unknown} and \secref{autoload}.

    \termitem{undefined_global_variable}{}
\arg{Context} is instantiated to the name of the missing global
variable. The hook must call \index{nb_setval/2}\predref{nb_setval}{2} or \index{b_setval/2}\predref{b_setval}{2} before returning
with the action \const{retry}.
\end{description}
\end{description}


\section{Hooks for integrating libraries}	\label{sec:intlibs}

Some libraries realise an entirely new programming paradigm on top of
Prolog.  An example is XPCE which adds an object system to Prolog as
well as an extensive set of graphical primitives.  SWI-Prolog provides
several hooks to improve the integration of such libraries.  See also
\secref{listing} for editing hooks and \secref{printmsg} for hooking
into the message system.

\begin{description}
    \predicate{prolog_list_goal}{1}{:Goal}
Hook, normally not defined. This hook is called by the 'L' command of
the tracer in the module \module{user} to list the currently called
predicate. This hook may be defined to list only relevant clauses of the
indicated \arg{Goal} and/or show the actual source code in an editor.
See also \index{portray/1}\predref{portray}{1} and \index{multifile/1}\predref{multifile}{1}.

    \predicate{prolog:debug_control_hook}{1}{:Action}
Hook for the debugger control predicates that allows the creator of
more high-level programming languages to use the common front-end
predicates to control the debugger.  For example, XPCE uses these hooks
to allow for spying methods rather than predicates. \arg{Action} is one
of:

\begin{description}
    \termitem{spy}{Spec}
Hook in \index{spy/1}\predref{spy}{1}.  If the hook succeeds \index{spy/1}\predref{spy}{1} takes no further action.
    \termitem{nospy}{Spec}
Hook in \index{nospy/1}\predref{nospy}{1}.  If the hook succeeds \index{nospy/1}\predref{nospy}{1} takes no further action.
If \index{spy/1}\predref{spy}{1} is hooked, it is advised to place a complementary hook for
\index{nospy/1}\predref{nospy}{1}.
    \termitem{nospyall}{}
Hook in \index{nospyall/0}\predref{nospyall}{0}.  Should remove all spy points.  This hook is
called in a failure-driven loop.
    \termitem{debugging}{}
Hook in \index{debugging/0}\predref{debugging}{0}.  It can be used in two ways.  It can report
the status of the additional debug points controlled by the above
hooks and fail to let the system report the others, or it succeeds,
overruling the entire behaviour of \index{debugging/0}\predref{debugging}{0}.
\end{description}

    \predicate{prolog:help_hook}{1}{+Action}
Hook into \index{help/0}\predref{help}{0} and \index{help/1}\predref{help}{1}.  If the hook succeeds, the built-in actions
are not executed. For example, \exam{?- help(picture).} is caught by the
XPCE help hook to give help on the class {\em picture}.  Defined actions
are:

\begin{description}
    \termitem{help}{}
User entered plain \index{help/0}\predref{help}{0} to give default help.  The default performs
\exam{help(\index{help/1}\predref{help}{1})}, giving help on help.
    \termitem{help}{What}
Hook in \index{help/1}\predref{help}{1} on the topic \arg{What}.
    \termitem{apropos}{What}
Hook in \index{apropos/1}\predref{apropos}{1} on the topic \arg{What}.
\end{description}
\end{description}


\section{Hooks for loading files}	\label{sec:loadfilehook}

All loading of source files is achieved by \index{load_files/2}\predref{load_files}{2}.  The hook
\index{prolog_load_file/2}\predref{prolog_load_file}{2} can be used to load Prolog code from non-files
or even load entirely different information, such as foreign files.

\begin{description}
    \predicate{prolog_load_file}{2}{+Spec, +Options}
Load a single object.  If this call succeeds, \index{load_files/2}\predref{load_files}{2} assumes the
action has been taken care of. This hook is only called if \arg{Options}
does not contain the \term{stream}{Input} option. The hook must be
defined in the module \const{user}.

This can be used to load from unusual places. For example, library
\pllib{http/http_load} loads Prolog directly from an HTTP server. It can
also be used to load source in unusual forms, such as loading compressed
files without decompressing them first. There is currently no example of
that.

    \predicate{prolog:comment_hook}{3}{+Comments, +Pos, +Term}
This hook allows for processing comments encountered by the compiler. If
this hook is defined, the compiler calls \index{read_term/2}\predref{read_term}{2} with the option
\term{comments}{Comments}.  If the list of comments returned by
\index{read_term/2}\predref{read_term}{2} is not empty it calls this comment hook with the
following arguments.

\begin{itemize}
    \item \arg{Comments} is the non-empty list of comments.  Each
	  comment is a pair \arg{Position}-\arg{String}, where
	  \arg{String} is a string object (see \secref{strings})
	  that contains the comment \emph{including} delimiters.
	  Consecutive line comments are returned as a single
	  comment.
    \item \arg{Pos} is a stream-position term that describes the
	  starting position of \arg{Term}
    \item \arg{Term} is the term read.
\end{itemize}

This hook is exploited by the documentation system. See
\index{stream_position_data/3}\predref{stream_position_data}{3}. See also \index{read_term/3}\predref{read_term}{3}.
\end{description}
