1\chapter{Hackers corner}			\label{sec:hack}
2
3This appendix describes a number of predicates which enable the Prolog
4user to inspect the Prolog environment and manipulate (or even redefine)
5the debugger.  They can be used as entry points for experiments with
6debugging tools for Prolog. The predicates described here should be
7handled with some care as it is easy to corrupt the consistency of the
8Prolog system by misusing them.
9
10\section{Examining the Environment Stack}	\label{sec:manipstack}
11
12\begin{description}
13    \predicate[det]{prolog_current_frame}{1}{-Frame}
14Unify \arg{Frame} with an integer providing a reference to the parent of
15the current local stack frame.  A pointer to the current local frame
16cannot be provided as the predicate succeeds deterministically and
17therefore its frame is destroyed immediately after succeeding.
18
19    \predicate[semidet]{prolog_current_choice}{1}{-Choice}
20Unify \arg{Choice} with an integer provided a reference to the last
21choice point.  Fails if the current environment has no choice points.
22See also prolog_choice_attribute/3.
23
24    \predicate{prolog_frame_attribute}{3}{+Frame, +Key, :Value}
25Obtain information about the local stack frame \arg{Frame}.  \arg{Frame}
26is a frame reference as obtained through prolog_current_frame/1,
27prolog_trace_interception/4 or this predicate.  The key values are
28described below.
29
30\begin{description}
31    \termitem{alternative}{}
32\arg{Value} is unified with an integer reference to the local stack
33frame in which execution is resumed if the goal associated with
34\arg{Frame} fails. Fails if the frame has no alternative frame.
35
36    \termitem{has_alternatives}{}
37\arg{Value} is unified with \const{true} if \arg{Frame} still is a
38candidate for backtracking; \const{false} otherwise.
39
40    \termitem{goal}{}
41\arg{Value} is unified with the goal associated with \arg{Frame}. If the
42definition module of the active predicate is not the calling context,
43the goal is represented as \mbox{\tt <module>:<goal>}. Do not instantiate
44variables in this goal unless you {\bf know} what you are doing!
45Note that the returned term may contain references to the frame and
46should be discarded before the frame terminates.%
47	\footnote{The returned term is actually an illegal Prolog term
48		  that may hold references from the global to the local
49		  stack to preserve the variable names.}
50
51    \termitem{parent_goal}{}
52If \arg{Value} is instantiated to a callable term, find a frame
53executing the predicate described by \arg{Value} and unify the arguments
54of \arg{Value} to the goal arguments associated with the frame. This is
55intended to check the current execution context. The user must ensure
56the checked parent goal is not removed from the stack due to last-call
57optimisation and be aware of the slow operation on deeply nested calls.
58
59    \termitem{predicate_indicator}{}
60Similar to \const{goal}, but only returning the
61[<module>:]<name>/<arity> term describing the term, not the actual
62arguments.  It avoids creating an illegal term as \const{goal} and
63is used by the library \pllib{prolog_stack}.
64
65    \termitem{clause}{}
66\arg{Value} is unified with a reference to the currently running clause.
67Fails if the current goal is associated with a foreign (C) defined
68predicate. See also nth_clause/3 and clause_property/2.
69
70    \termitem{level}{}
71\arg{Value} is unified with the recursion level of \arg{Frame}. The top
72level frame is at level `0'.
73
74    \termitem{parent}{}
75\arg{Value} is unified with an integer reference to the parent local
76stack frame of \arg{Frame}. Fails if \arg{Frame} is the top frame.
77
78    \termitem{context_module}{}
79\arg{Value} is unified with the name of the context module of the
80environment.
81
82    \termitem{top}{}
83\arg{Value} is unified with \const{true} if \arg{Frame} is the top Prolog
84goal from a recursive call back from the foreign language; \const{false}
85otherwise.
86
87    \termitem{hidden}{}
88\arg{Value} is unified with \const{true} if the frame is hidden from the
89user, either because a parent has the hide-childs attribute (all system
90predicates), or the system has no trace-me attribute.
91
92    \termitem{skipped}{}
93\arg{Value} is \const{true} if this frame was skipped in the debugger.
94
95    \termitem{pc}{}
96\arg{Value} is unified with the program pointer saved on behalf of the
97parent goal if the parent goal is not owned by a foreign predicate or
98belongs to a compound meta-call (e.g., call((a,b))).
99
100    \termitem{argument}{N}
101\arg{Value} is unified with the \arg{N}-th slot of the frame. Argument
1021 is the first argument of the goal. Arguments above the arity
103refer to local variables. Fails silently if \arg{N} is out of range.
104\end{description}
105
106    \predicate{prolog_choice_attribute}{3}{+ChoicePoint, +Key, -Value}
107Extract attributes of a choice point.  \arg{ChoicePoint} is a reference
108to a choice point as passed to prolog_trace_interception/4 on the 3rd
109argument or obtained using prolog_current_choice/1. \arg{Key} specifies
110the requested information:
111
112\begin{description}
113    \termitem{parent}{}
114Requests a reference to the first older choice point.
115    \termitem{frame}{}
116Requests a reference to the frame to which the choice point refers.
117    \termitem{type}{}
118Requests the type.  Defined values are \const{clause} (the goal has
119alternative clauses), \const{foreign} (non-deterministic foreign
120predicate), \const{jump} (clause internal choice point), \const{top}
121(first dummy choice point), \const{catch} (catch/3 to allow for undo),
122\const{debug} (help the debugger), or \const{none} (has been deleted).
123\end{description}
124
125This predicate is used for the graphical debugger to show the
126choice point stack.
127
128    \predicate{deterministic}{1}{-Boolean}
129Unifies its argument with \const{true} if no choice point exists that is
130more recent than the entry of the clause in which it appears. There are
131few realistic situations for using this predicate. It is used by the
132prolog/0 top level to check whether Prolog should prompt the user for
133alternatives. Similar results can be achieved in a more portable fashion
134using call_cleanup/2.
135\end{description}
136
137\section{Ancestral cuts}		\label{sec:ancestral-cut}
138
139\begin{description}
140    \predicate{prolog_cut_to}{1}{+Choice}
141Prunes all choice points created since \arg{Choice}. Can be used
142together with prolog_current_choice/1 to implement \jargon{ancestral} cuts.
143This predicate is in the hackers corner because it should not be used
144in normal Prolog code. It may be used to create new high level control
145structures, particularly for compatibility purposes.
146
147Note that in the current implementation, the pruned choice points and
148environment frames are \emph{not} reclaimed. As a consequence, where
149predicates that are deterministic due to clause indexing, normal cuts or
150\verb$(if->then;else)$ and and tail recursive run in bounded local
151stack space, predicates using prolog_cut_to/1 will run out of stack.
152\end{description}
153
154
155\section{Intercepting the Tracer}		\label{sec:tracehook}
156
157\begin{description}
158    \predicate{prolog_trace_interception}{4}{+Port, +Frame, +Choice, -Action}
159Dynamic predicate, normally not defined. This predicate is called from
160the SWI-Prolog debugger just before it would show a port. If this
161predicate succeeds, the debugger assumes that the trace action has been taken
162care of and continues execution as described by \arg{Action}. Otherwise
163the normal Prolog debugger actions are performed.
164
165\arg{Port} denotes the reason to activate the tracer (`port' in the
1664/5-port, but with some additions):
167
168\begin{description}
169    \termitem{call}{}
170Normal entry through the call port of the 4-port debugger.
171
172    \termitem{redo}{PC}
173Normal entry through the redo port of the 4-port debugger. The
174\const{redo} port signals resuming a predicate to generate alternative
175solutions. If \arg{PC} is 0 (zero), clause indexing has found another
176clause that will be tried next. Otherwise, \arg{PC} is the program
177counter in the current clause where execution continues. This implies we
178are dealing with an in-clause choice point left by, e.g., \predref{;}{2}.
179Note that non-determinism in foreign predicates are also handled using
180an in-clause choice point.
181
182    \termitem{unify}{}
183The unify port represents the \jargon{neck} instruction, signalling the
184end of the head-matching process.  This port is normally invisible.  See
185leash/1 and visible/1.
186
187    \termitem{exit}{}
188The exit port signals the goal is proved.  It is possible for the goal
189to have alternatives. See prolog_frame_attribute/3 to examine the
190goal stack.
191
192    \termitem{fail}{}
193The fail port signals final failure of the goal.
194
195    \termitem{exception}{Except}
196An exception is raised and still pending.  This port is activated on
197each parent frame of the frame generating the exception until the
198exception is caught or the user restarts normal computation using
199\const{retry}.  \arg{Except} is the pending exception term.
200
201    \termitem{break}{PC}
202A \const{break} instruction is executed.  \arg{PC} is program counter.
203This port is used by the graphical debugger.
204
205    \termitem{cut_call}{PC}
206A cut is encountered at \arg{PC}. This port is used by the graphical
207debugger to visualise the effect of the cut.
208
209    \termitem{cut_exit}{PC}
210A cut has been executed.  See \term{cut_call}{PC} for more information.
211\end{description}
212
213\arg{Frame} is a reference to the current local stack frame, which can
214be examined using prolog_frame_attribute/3. \arg{Choice} is a reference
215to the last choice point and can be examined using
216prolog_choice_attribute/3. \arg{Action} must be unified with a term that
217specifies how execution must continue. The following actions are
218defined:
219
220\begin{description}
221    \termitem{abort}{}
222Abort execution.  See abort/0.
223    \termitem{continue}{}
224Continue (i.e., \jargon{creep} in the command line debugger).
225    \termitem{fail}{}
226Make the current goal fail.
227    \termitem{ignore}{}
228Step over the current goal without executing it.
229    \termitem{nodebug}{}
230Continue execution in normal nodebugging mode.  See nodebug/0.
231    \termitem{retry}{}
232Retry the current frame.
233    \termitem{retry}{Frame}
234Retry the given frame.  This must be a parent of the current
235frame.
236    \termitem{skip}{}
237Skip over the current goal (i.e., \jargon{skip} in the command line debugger).
238    \termitem{up}{}
239Skip to the parent goal (i.e., \jargon{up} in the command line debugger).
240\end{description}
241
242Together with the predicates described in \secref{debugger}
243and the other predicates of this chapter, this predicate enables the
244Prolog user to define a complete new debugger in Prolog. Besides this, it
245enables the Prolog programmer to monitor the execution of a program. The
246example below records all goals trapped by the tracer in the database.
247
248\begin{code}
249prolog_trace_interception(Port, Frame, _PC, continue) :-
250        prolog_frame_attribute(Frame, goal, Goal),
251        prolog_frame_attribute(Frame, level, Level),
252        recordz(trace, trace(Port, Level, Goal)).
253\end{code}
254
255To trace the execution of `go' this way the following query should be
256given:
257
258\begin{code}
259?- trace, go, notrace.
260\end{code}
261
262    \predicate{prolog_skip_frame}{1}{-Frame}
263Indicate \arg{Frame} as a skipped frame and set the `skip level' (see
264prolog_skip_level/2 to the recursion depth of \arg{Frame}.  The effect
265of the skipped flag is that a redo on a child of this frame is handled
266differently.  First, a \const{redo} trace is called for the child, where
267the skip level is set to \const{redo_in_skip}.  Next, the skip level is
268set to skip level of the skipped frame.
269
270    \predicate{prolog_skip_level}{2}{-Old, +New}
271Unify \arg{Old} with the old value of `skip level' and then set this
272level according to \arg{New}. \arg{New} is an integer, the atom
273\const{very_deep} (meaning don't skip) or the atom \const{skip_in_redo}
274(see prolog_skip_frame/1). The `skip level' is a setting of each
275Prolog thread that disables the debugger on all recursion levels deeper
276than the level of the variable.  See also prolog_skip_frame/1.
277\end{description}
278
279
280\section{Breakpoint and watchpoint handling}
281\label{sec:breakpoint}
282
283SWI-Prolog support \jargon{breakpoints}.  Breakpoints can be manipulated
284with the library \pllib{prolog_breakpoints}. Setting a breakpoint
285replaces a virtual machine instruction with the \const{D_BREAK}
286instruction.  If the virtual machine executes a \const{D_BREAK}, it
287performs a callback to decide on the action to perform.  This section
288describes this callback, called prolog:break_hook/6.
289
290\begin{description}
291    \predicate[hook,semidet]{prolog:break_hook}{6}{+Clause, +PC, +FR,
292						   +BFR, +Expression, -Action}
293\emph{Experimental}
294This hook is called if the virtual machine executes a \const{D_BREAK},
295set using set_breakpoint/4. \arg{Clause} and \arg{PC} identify the
296breakpoint. \arg{FR} and \arg{BFR} provide the environment frame and
297current choicepoint.  \arg{Expression} identifies the action that is
298interrupted, and is one of the following:
299
300    \begin{description}
301	\termitem{call}{Goal}
302    The instruction will call \arg{Goal}.  This is generated for nearly
303    all instructions. Note that \arg{Goal} is semantically
304    equivalent to the compiled body term, but might differ
305    syntactically. This is notably the case when arithmetic expressions
306    are compiled in optimized mode (see \prologflag{optimise}).  In
307    particular, the arguments of arithmetic expressions have already
308    been evaluated.  Thus, \arg{A} is 3*\arg{B}, where \arg{B} equals
309    3 results in a term \exam{call(A is 9)} if the clause was compiled
310    with optimization enabled.
311
312        \termitem{!}{}
313    The instruction will call the cut. Because the semantics of
314    metacalling the cut differs from executing the cut in its
315    original context we do not wrap the cut in \functor{call}{1}.
316
317	\termitem{:-}{}
318    The breakpoint is on the \jargon{neck} instruction, i.e., after
319    performing the head unifications.
320
321	\termitem{exit}{}
322    The breakpoint is on the \jargon{exit} instruction, i.e., at the
323    end of the clause. Note that the exit instruction may not be reached
324    due to last-call optimisation.
325
326	\termitem{unify_exit}{}
327    The breakpoint is on the completion of an in-lined unification while
328    the system is not in debug mode.  If the system is in debug mode,
329    inlined unification is returned as call(Var=Term).\footnote{This
330    hack will disappear if we find a good solution for applying D_BREAK
331    to inlined unification.  Only option might be to place the break on
332    both the unification start and end instructions.}
333    \end{description}
334
335If prolog:break_hook/6 succeeds, it must unify \arg{Action} with a value
336that describes how execution must continue. Possible values for
337\arg{Action} are:
338
339    \begin{description}
340	\termitem{continue}{}
341    Just continue as if no breakpoint was present.
342
343	\termitem{debug}{}
344    Continue in \jargon{debug mode}.  See debug/0.
345
346	\termitem{trace}{}
347    Continue in \jargon{trace mode}.  See trace/0.
348
349	\termitem{call}{Goal}
350    Execute \arg{Goal} instead of the goal that would be executed.
351    \arg{Goal} is executed as call/1, preserving (non-)determinism
352    and exceptions.
353    \end{description}
354
355If this hook throws an exception, the exception is propagated normally.
356If this hook is not defined or fails, the default action is executed.
357This implies that, if the thread is in debug mode, the tracer will be
358enabled (\const{trace}) and otherwise the breakpoint is ignored
359(\const{continue}).
360
361This hook allows for injecting various debugging scenarios into the
362executable without recompiling. The hook can access variables of the
363calling context using the frame inspection predicates. Here are some
364examples.
365
366    \begin{itemize}
367	\item Create \jargon{conditional} breakpoints by imposing
368	conditions before deciding the return \const{trace}.
369	\item Watch variables at a specific point in the execution.
370	Note that binding of these variables can be monitored
371	using \jargon{attributed variables}, see \secref{attvar}.
372	\item Dynamically add \jargon{assertions} on variables
373	using assertion/1.
374	\item Wrap the \arg{Goal} into a meta-call that traces
375	progress of the \arg{Goal}.
376    \end{itemize}
377\end{description}
378
379
380\section{Adding context to errors: prolog_exception_hook}
381\label{sec:excepthook}
382
383The hook prolog_exception_hook/4 has been introduced in SWI-Prolog 5.6.5
384to provide dedicated exception handling facilities for application
385frameworks, for example non-interactive server applications that
386wish to provide extensive context for exceptions for offline debugging.
387
388\begin{description}
389    \predicate{prolog_exception_hook}{4}{+ExceptionIn, -ExceptionOut,
390					 +Frame, +CatcherFrame}
391This hook predicate, if defined in the module \const{user}, is between
392raising an exception and handling it. It is intended to allow a program
393adding additional context to an exception to simplify diagnosing the
394problem. \arg{ExceptionIn} is the exception term as raised by throw/1 or
395one of the built-in predicates. The output argument \arg{ExceptionOut}
396describes the exception that is actually raised. \arg{Frame} is the
397innermost frame. See prolog_frame_attribute/3 and the library
398\pllib{prolog_stack} for getting information from this.
399\arg{CatcherFrame} is a reference to the frame calling the matching
400catch/3, \const{none} if the exception is not caught or \const{'C'}
401if the exception is caught in C calling Prolog using the flag
402\const{PL_Q_CATCH_EXCEPTION}.
403
404The hook is run in `nodebug' mode. If it succeeds, \arg{ExceptionOut} is
405considered the current exception. If it fails, \arg{ExceptionIn} is used
406for further processing. The hook is \emph{never} called recursively.
407The hook is \emph{not} allowed to modify \arg{ExceptionOut} in such
408a way that it no longer unifies with the catching frame.
409
410Typically, prolog_exception_hook/4 is used to fill the second argument
411of \term{error}{Formal, Context} exceptions. \arg{Formal} is
412defined by the ISO standard, while SWI-Prolog defines \arg{Context}
413as a term \term{context}{Location, Message}.  \arg{Location} is bound
414to a term <name>/<arity> by the kernel.  This hook can be used to add
415more information on the calling context, such as a full stack trace.
416
417Applications that use exceptions as part of normal processing must
418do a quick test of the environment before starting expensive gathering
419information on the state of the program.
420
421The hook can call trace/0 to enter trace mode immediately. For example,
422imagine an application performing an unwanted division by zero while all
423other errors are expected and handled.  We can force the debugger using
424the hook definition below.  Run the program in debug mode (see debug/0)
425to preserve as much as possible of the error context.
426
427\begin{code}
428user:prolog_exception_hook(
429	 error(evaluation_error(zero_divisor), _),
430	 _, _, _) :-
431	trace, fail.
432\end{code}
433\end{description}
434
435
436\section{Hooks using the exception predicate}	\label{sec:exception3}
437
438This section describes the predicate exception/3, which can be defined
439by the user in the module \module{user} as a multifile predicate. Unlike
440the name suggests, this is actually a \jargon{hook} predicate that has
441no relation to Prolog exceptions as defined by the ISO predicates
442catch/3 and throw/1.
443
444The predicate exception/3 is called by the kernel on a couple of events,
445allowing the user to `fix' errors just-in-time. The mechanism allows for
446\jargon{lazy} creation of objects such as predicates.
447
448\begin{description}
449    \predicate{exception}{3}{+Exception, +Context, -Action}
450Dynamic predicate, normally not defined. Called by the Prolog system on
451run-time exceptions that can be repaired `just-in-time'.  The values
452for \arg{Exception} are described below.  See also catch/3 and throw/1.
453
454If this hook predicate succeeds it must instantiate the \arg{Action}
455argument to the atom \const{fail} to make the operation fail silently,
456\const{retry} to tell Prolog to retry the operation or \const{error} to
457make the system generate an exception. The action \const{retry} only
458makes sense if this hook modified the environment such that the
459operation can now succeed without error.
460
461\begin{description}
462    \termitem{undefined_predicate}{}
463\arg{Context} is instantiated to a predicate indicator
464([module]:<name>/<arity>). If the predicate fails, Prolog will generate
465an \except{existence_error} exception. The hook is intended to implement
466alternatives to the built-in autoloader, such as autoloading code from
467a database.  Do \emph{not} use this hook to suppress existence errors on
468predicates.  See also \prologflag{unknown} and \secref{autoload}.
469
470    \termitem{undefined_global_variable}{}
471\arg{Context} is instantiated to the name of the missing global
472variable. The hook must call nb_setval/2 or b_setval/2 before returning
473with the action \const{retry}.
474\end{description}
475\end{description}
476
477
478\section{Prolog events}				\label{sec:prolog-event}
479
480Version 8.1.9 introduces a uniform mechanism to listen to events that
481happen in the Prolog engine. It replaces and generalises
482\nopredref{prolog_event_hook}{1}, a hook that was introduced to support
483the graphical debugger. The current implementation deals with debug,
484thread and dynamic database events. We expect this mechanism to deal
485with more hooks in the future.
486
487\begin{description}
488    \predicate{prolog_listen}{2}{+Channel, :Closure}
489\nodescription
490    \predicate{prolog_listen}{3}{+Channel, :Closure, +Options}
491Call \arg{Closure} if an event that matches \arg{Channel} happens inside
492Prolog. Possible choice points are pruned as by once/1. Possible failure
493is ignored, but exceptions are propagated into the environment. Multiple
494closures can be associated with the same channel.  Execution of the list
495of closures may be terminated by an exception. Options:
496
497    \begin{description}
498    \termitem{as}{Location}
499\arg{Location} is one of \const{first} (default) or \const{last} and
500determines whether the new handler is expected as first or last.
501    \end{description}
502
503Defined channels are described below. The \arg{Channel} argument is the
504name of the term listed below. The arguments are added as additional
505arguments to the given \arg{Closure}.
506
507    \begin{description}
508    \termitem{abort}{}
509Called by abort/0.
510
511    \termitem{erase}{DbRef}
512Called on an erased recorded database reference or clause. Note that a
513retracted clauses is not immediately removed. Clauses are reclaimed by
514garbage_collect_clauses/0, which is normally executed automatially in
515the \const{gc} thread. This specific channel is used by clause_info/5 to
516reclaim source layout of reclaimed clauses.  User applications should
517typically use the \arg{PredicateIndicator} channel.
518
519    \termitem{break}{Action, ClauseRef, PCOffset}
520Traps events related to Prolog break points. See library
521\pllib{prolog_breakpoints}
522
523    \termitem{frame_finished}{FrameRef}
524Indicates that a stack frame that has been examined using
525prolog_current_frame/1, prolog_frame_attribute/3 and friends has
526been deleted.  Used by the source level debugger to avoid that
527the stack view references non-existing frames.
528
529    \termitem{thread_exit}{Thread}
530Globally registered channel that is called by any thread just
531before the thread is terminated.
532
533    \termitem{this_thread_exit}{}
534Thread local version of the \const{thread_exit} channel that
535is also used by the \term{at_exit}{Closure} option of
536thread_create/3.
537
538    \termitem{PredicateIndicator}{Action, ClauseRef}
539Track changes to a (dynamic) predicate.  For example:
540
541\begin{code}
542:- dynamic p/1.
543:- prolog_listen(p/1, updated(p/1)).
544
545updated(Pred, Action, Context) :-
546    format('Updated ~p: ~p ~p~n', [Pred, Action, Context]).
547\end{code}
548
549\begin{code}
550?- assert(p(a)).
551Updated p/1: assertz <clause>(0x55db261709d0)
552?- retractall(p(_)).
553Updated p/1: retractall start(user:p(_12294))
554Updated p/1: retract <clause>(0x55db261719c0)
555Updated p/1: retractall end(user:p(_12294))
556\end{code}
557
558	\begin{description}
559	\termitem{asserta}{}
560	\termitem{assertz}{}
561    A new clauses has been added as first (last) for the given
562    predicate.
563	\termitem{retract}{}
564    A clause was retracted from the given predicate using either
565    retract/1, erase/1 or retractall/1.
566	\termitem{retractall}{}
567    The begining and end of retractall/1 is indicated with
568    the \arg{Action} \const{retractall}.  The context argument
569    is \term{start}{Head} or \term{end}{Head}.
570	\end{description}
571    \end{description}
572
573    \predicate{prolog_unlisten}{2}{+Channel, :Closure}
574Remove matching closures registered with prolog_listen/3.
575\end{description}
576
577
578\section{Hooks for integrating libraries}	\label{sec:intlibs}
579
580Some libraries realise an entirely new programming paradigm on top of
581Prolog.  An example is XPCE which adds an object system to Prolog as
582well as an extensive set of graphical primitives.  SWI-Prolog provides
583several hooks to improve the integration of such libraries.  See also
584\secref{listing} for editing hooks and \secref{printmsg} for hooking
585into the message system.
586
587\begin{description}
588    \predicate{prolog_list_goal}{1}{:Goal}
589Hook, normally not defined. This hook is called by the 'L' command of
590the tracer in the module \module{user} to list the currently called
591predicate. This hook may be defined to list only relevant clauses of the
592indicated \arg{Goal} and/or show the actual source code in an editor.
593See also portray/1 and multifile/1.
594
595    \predicate{prolog:debug_control_hook}{1}{:Action}
596Hook for the debugger control predicates that allows the creator of
597more high-level programming languages to use the common front-end
598predicates to control the debugger.  For example, XPCE uses these hooks
599to allow for spying methods rather than predicates. \arg{Action} is one
600of:
601
602\begin{description}
603    \termitem{spy}{Spec}
604Hook in spy/1.  If the hook succeeds spy/1 takes no further action.
605    \termitem{nospy}{Spec}
606Hook in nospy/1.  If the hook succeeds nospy/1 takes no further action.
607If spy/1 is hooked, it is advised to place a complementary hook for
608nospy/1.
609    \termitem{nospyall}{}
610Hook in nospyall/0.  Should remove all spy points.  This hook is
611called in a failure-driven loop.
612    \termitem{debugging}{}
613Hook in debugging/0.  It can be used in two ways.  It can report
614the status of the additional debug points controlled by the above
615hooks and fail to let the system report the others, or it succeeds,
616overruling the entire behaviour of debugging/0.
617\end{description}
618
619    \predicate{prolog:help_hook}{1}{+Action}
620Hook into help/0 and help/1.  If the hook succeeds, the built-in actions
621are not executed. For example, \exam{?- help(picture).} is caught by the
622XPCE help hook to give help on the class {\em picture}.  Defined actions
623are:
624
625\begin{description}
626    \termitem{help}{}
627User entered plain help/0 to give default help.  The default performs
628\exam{help(help/1)}, giving help on help.
629    \termitem{help}{What}
630Hook in help/1 on the topic \arg{What}.
631    \termitem{apropos}{What}
632Hook in apropos/1 on the topic \arg{What}.
633\end{description}
634\end{description}
635
636
637\section{Hooks for loading files}	\label{sec:loadfilehook}
638
639All loading of source files is achieved by load_files/2.  The hook
640prolog_load_file/2 can be used to load Prolog code from non-files
641or even load entirely different information, such as foreign files.
642
643\begin{description}
644    \predicate{prolog_load_file}{2}{+Spec, +Options}
645Load a single object.  If this call succeeds, load_files/2 assumes the
646action has been taken care of. This hook is only called if \arg{Options}
647does not contain the \term{stream}{Input} option. The hook must be
648defined in the module \const{user}.
649
650This can be used to load from unusual places as well as dealing with
651Prolog code that is not represented as a Prolog source text (for example
652some binary representation). For example, library \pllib{http/http_load}
653loads Prolog directly from an HTTP server. See also
654prolog:open_source_hook/3, which merely allows for changing how a
655physical file is opened.
656
657    \predicate{prolog:open_source_hook}{3}{+Path, -Stream, +Options}
658This hooks is called by the compiler to overrule the default open/3 call
659\term{open}{Path, read, Stream}. \arg{Options} provide the options as
660provided to load_files/2. If the hook succeeds compilation continues by
661loading from the returned (input) stream. This hook is particularly
662suited to support running the code to a preprocessor. See also
663prolog_load_file/2.
664
665    \predicate{prolog:comment_hook}{3}{+Comments, +Pos, +Term}
666This hook allows for processing comments encountered by the compiler. If
667this hook is defined, the compiler calls read_term/2 with the option
668\term{comments}{Comments}.  If the list of comments returned by
669read_term/2 is not empty it calls this comment hook with the
670following arguments.
671
672\begin{itemize}
673    \item \arg{Comments} is the non-empty list of comments.  Each
674	  comment is a pair \arg{Position}-\arg{String}, where
675	  \arg{String} is a string object (see \secref{strings})
676	  that contains the comment \emph{including} delimiters.
677	  Consecutive line comments are returned as a single
678	  comment.
679    \item \arg{Pos} is a stream-position term that describes the
680	  starting position of \arg{Term}
681    \item \arg{Term} is the term read.
682\end{itemize}
683
684This hook is exploited by the documentation system. See
685stream_position_data/3. See also read_term/3.
686\end{description}
687