:- module(instrument).
:- export get_callsite_data_body / 3.
:- export set_callsite_data_body / 3.
:- export file_callsites_body / 4.
:- export module_callsites_body / 3.
:- export instrument_control_body / 3.
:- export file_result_body / 3.
:- export file_result_body / 2.
:- export module_result_body / 2.
:- export module_result_body / 1.
:- export instrument_body_check_options / 4.
:- export instrument_body / 3.
:- export erase_file_templates / 2.
:- export erase_module_templates / 1.
:- export defined_modules / 2.
:- export get_callsite_data / 2.
:- export set_callsite_data / 2.
:- export module_callsites / 2.
:- export file_callsites / 3.
:- export erase_file_templates / 1.
:- export erase_module_templates / 0.
:- export erase_all_templates / 0.
:- export instrument_control / 2.
:- export module_result / 1.
:- export module_result / 0.
:- export file_result / 2.
:- export file_result / 1.
:- export instrument / 3.
:- export instrument / 2.
:- export struct(itemplate(clause_start, clause_end, clause_fail, clause_redo, block_start, block_end, block_fail, block_redo, subgoal_start, subgoal_end, subgoal_fail, subgoal_redo, call_start, call_end, call_fail, call_redo, fact, inbetween, result, meta_args, exclude, code_weaver, asserted, module_scope, file_local, goal_expansion)).
:- tool(get_callsite_data / 2,get_callsite_data_body / 3).
:- tool(set_callsite_data / 2,set_callsite_data_body / 3).
:- tool(module_callsites / 2,module_callsites_body / 3).
:- tool(file_callsites / 3,file_callsites_body / 4).
:- tool(erase_file_templates / 1,erase_file_templates / 2).
:- tool(erase_module_templates / 0,erase_module_templates / 1).
:- tool(instrument_control / 2,instrument_control_body / 3).
:- tool(module_result / 1,module_result_body / 2).
:- tool(module_result / 0,module_result_body / 1).
:- tool(file_result / 2,file_result_body / 3).
:- tool(file_result / 1,file_result_body / 2).
:- tool(instrument / 3,instrument_body_check_options / 4).
:- tool(instrument / 2,instrument_body / 3).
:- comment(get_callsite_data_body / 3, hidden).
:- comment(set_callsite_data_body / 3, hidden).
:- comment(module_callsites_body / 3, hidden).
:- comment(file_callsites_body / 4, hidden).
:- comment(erase_file_templates / 2, hidden).
:- comment(erase_module_templates / 1, hidden).
:- comment(instrument_control_body / 3, hidden).
:- comment(module_result_body / 2, hidden).
:- comment(module_result_body / 1, hidden).
:- comment(file_result_body / 3, hidden).
:- comment(file_result_body / 2, hidden).
:- comment(instrument_body_check_options / 4, hidden).
:- comment(instrument_body / 3, hidden).
:- comment(summary, "Generic tool for code instrumentation").
:- comment(author, "Andrew Cheadle, based on ideas by Joachim Schimpf").
:- comment(date, "$Date: 2006/09/23 01:54:58 $").
:- comment(status, prototype).
:- comment(desc, html("<P>\n   The instrument library is a tool that enables predicate definitions or all\n   calls to a specific predicate to be annotated with user-defined predicates.\n   These instrumentation predicates are free to perform such actions as collect\n   program statistics or write debugging data to a stream during program\n   execution.  Additionally, the instrumentation can be inserted and removed\n   dynamically as the program executes.\n</P><P>\nThe usage is as follows:\n   <OL>\n   <LI>Load the instrument library\n   <PRE>\n   ?- lib(instrument).\n   </PRE>\n   <LI>Compile your program with the instrument compiler\n   <PRE>\n   ?- instrument:instrument(my_program, Templates).\n   </PRE>\n   <LI>Run the query for which you wish to generate instrumentation data\n   <PRE>\n   ?- my_query(X,Y,Z).\n   </PRE>\n   <LI>Generate an html file containing the results. E.g. the following\n   will create the result file instrument/my_program.html:\n   <PRE>\n   ?- instrument:results(my_program).\n   </PRE>\n   <LI>View the result file using any browser. The result file\n   contains a pretty-printed form of the source, annotated with\n   the instrumentation results.\n   </OL>\n   <P>\n   The following is an example of very basic use of the tool.\n   Consider instrumenting a simple path finding program saved in a\n   file called 'instrument_example.ecl.\n   <PRE>\n   list_member(X, [X | _Tail]).\n   list_member(X, [_ | Tail]):-\n   list_member(X, Tail).\n \n   all_edges(Graph, Source, Outgoing):-\n       findall((Source-Next),list_member((Source-Next), Graph), Outgoing).\n \n   path(_Graph, Source, Source, []).\n   path(Graph, Source, Sink, [(Source-Next) | Path]):-\n       all_edges(Graph, Source, Outgoing),\n       list_member((Source-Next), Outgoing),\n       path(Graph, Next, Sink, Path).\n \n   test(Path):-\n       path([1-2, 1-3, 2-4, 3-4, 4-5, 4-6, 5-7, 5-8, 6-7,\n             1-8, 8-9, 8-10, 9-10, 9-11, 10-11],\n             1,\n             7,\n             Path).\n   </PRE>\n   The simplest way to instrument your code is to insert predicates around\n   every call in the source. The following code demonstrates how to\n   print the CPU time before and after every predicate call:\n   <PRE>\n   get_time(Cpu):-\n       statistics(times, [Cpu, _Sys, _Real]).\n \n   time_point:-\n       get_time(T),\n       writeln(error, T).\n \n   go:-\n       File = instrument_example,\n       GlobalTemplate = itemplate{subgoal_start:time_point/0,\n                                         subgoal_end:time_point/0},\n       instrument(File, GlobalTemplate),\n       test(Path).\n   </PRE>\n   Note the same predicate <TT>time_point/0</TT> is specified before and\n   after goal calls. If we wished to instrument all calls except those\n   to <TT>list_member/2</TT>, the following call to <TT>instrument/2</TT> is\n   made:\n   <PRE>\n        instrument(File, GlobalTemplate - [list_member/2])\n   </PRE>\n   In general any number of goals may be specified in this 'exclusion list'.\n   <P> \n   The following code demonstrates alternative instrumentation\n   for this excluded predicate:\n   <PRE>\n   :-lib(instrument).\n\n   :-export time_point/0, special_point/0.\n\n   get_time(Cpu):-\n       statistics(times,[Cpu, _Sys, _Real]).        \n\n   time_point:-\n       get_time(T),\n       writeln(error, T).\n\n   special_point:-\n       writeln(error, 'start, end, redo or fail').\n\n   go:-\n       File = instrument_example,\n       GlobalTemplate = itemplate{subgoal_start:time_point/0,\n                                        subgoal_end:time_point/0},\n       SpecialTemplate = itemplate{call_start:special_point/0,\n                                         call_end:special_point/0,\n                                         call_fail:special_point/0\n                                         call_redo:special_point/0},\n       instrument(File,[GlobalTemplate - [list_member/2],\n                        (list_member/2) = SpecialTemplate]),\n       test(Path).\n   </PRE>\n   Notice how the <TT>special_point/0</TT> predicate is assigned to the\n   <TT>call_start</TT>, <TT>call_end</TT>, <TT>call_fail</TT> and \n   <TT>call_redo</TT> points in this example. This ensures that the \n   <TT>special_point</TT> predicate is called if <TT>list_member/2</TT> \n   fails, or if resatisfiable, executed at the redo.\n   <P>\n   Using arity-1 predicates (i.e. one argument predicates)\n   unique identification of the callsite can be obtained:\n   <PRE>\n   :-lib(instrument).\n\n   get_time(Cpu):-\n       statistics(times, [Cpu, _Sys, _Real]).        \n\n   time_point(CallSite):-\n       get_time(T),\n       writeln(error,['Time', T, 'at callsite', CallSite]).\n\n   go:-\n       File = instrument_example,\n       GlobalTemplate = itemplate{subgoal_start:time_point/1,\n                                        subgoal_end:time_point/1},\n       instrument(File, GlobalTemplate),\n       test(Path).\n   </PRE>\n   <P>\n   By supplying a predicate to the <TT>result</TT> field of a template \n   one can specify terms to be printed within a copy of the source code.\n   Using this feature along with the utility predicates \n   <TT>get_callsite_data/2</TT> and <TT>set_callsite_data/2</TT> \n   one can create quite varied and useful output.\n   <PRE>\n   :-lib(instrument).\n\n   get_time(Cpu):-\n       statistics(times, [Cpu, _Sys, _Real]).        \n\n   time_point(CallSite):-\n       get_time(T),\n       set_callsite_data(CallSite, T).\n\n   result(CallSite, _Type, _Module, Goal, NewGoal):-\n       get_callsite_data(CallSite, Time),\n       NewGoal='instrument:point_before'(Time, Goal).\n   go:-\n       File = instrument_example,\n       GlobalTemplate = itemplate{subgoal_start:time_point/1,\n                                        result:result/5},\n       instrument(File, GlobalTemplate),\n       test(Path),\n       file_result(File).\n   </PRE>\n   No data is printed during the running of the <TT>test(Path)</TT> call, \n   but the <TT>file_result(File)</TT> call causes the source code to be \n   emitted (color coded) with the given callsite data embedded.\n</P>")).
:- comment(struct(itemplate), [summary : " The template used to guide predicate instrumentation", fields : [clause_start : "PredSpec of maximum arity two, the atom 'inherit', or variable", clause_end : "PredSpec of maximum arity two, the atom 'inherit', or variable", clause_fail : "PredSpec of maximum arity two, the atom 'inherit', or variable", clause_redo : "PredSpec of maximum arity two, the atom 'inherit', or variable", block_start : "PredSpec of maximum arity two, the atom 'inherit', or variable", block_end : "PredSpec of maximum arity two, the atom 'inherit', or variable", block_fail : "PredSpec of maximum arity two, the atom 'inherit', or variable", block_redo : "PredSpec of maximum arity two, the atom 'inherit', or variable", subgoal_start : "PredSpec of maximum arity two, the atom 'inherit', or variable", subgoal_end : "PredSpec of maximum arity two, the atom 'inherit', or variable", subgoal_fail : "PredSpec of maximum arity two, the atom 'inherit', or variable", subgoal_redo : "PredSpec of maximum arity two, the atom 'inherit', or variable", call_start : "PredSpec of maximum arity two, the atom 'inherit', or variable", call_end : "PredSpec of maximum arity two, the atom 'inherit', or variable", call_fail : "PredSpec of maximum arity two, the atom 'inherit', or variable", call_redo : "PredSpec of maximum arity two, the atom 'inherit', or variable", fact : "PredSpec of maximum arity one, the atom 'inherit', or variable", inbetween : "PredSpec of maximum arity two, the atom 'inherit', or variable", result : "PredSpec of maximum arity five, the atom 'inherit', or variable", meta_args : "List of itemplate or variable", exclude : "List of PredSpec, the atom 'inherit', or variable", code_weaver : "PredSpec of maximum arity six, the atom 'inherit', or variable", asserted : "Specific atom, the atom 'inherit' or variable", module_scope : "Atomic module name, the atom 'inherit' or variable", file_local : "Specific atom, the atom 'inherit' or variable", goal_expansion : "Specific atom, the atom 'inherit' or variable"], see_also : [erase_all_templates / 0, get_callsite_data / 2, instrument / 2, instrument / 3, instrument_control / 2, library(instrument), module_callsites / 2, module_result / 0, set_callsite_data / 2, defined_modules / 2], desc : html("<P>\n   The <TT><B>itemplate</B></TT> structure serves as a specification that \n   determines how predicate definitions and calls to predicates are instrumented.\n   </P><P>\n   An <TT>itemplate</TT> is associated with a predicate whose definition or \n   invocations are to be instrumented. This association is specified as an \n   argument to <TT>instrument:instrument/2</TT> or <TT>instrument:instrument/3</TT> \n   and is of the form: <TT>PredSpec = itemplate{...}</TT>.\n   </P><P>\n   <TT>PredSpec</TT> is of the form <TT>Module:Functor/Arity</TT>. \n   If the module qualifier is omitted, then <TT>PredSpec</TT> is assumed to \n   be a predicate defined within the calling module context in which \n   <TT>instrument/2</TT> was invoked. The definition context for a module \n   can be wildcarded by specifying the module qualifier as the atom \n   <TT>every_module</TT> or by setting the <TT>itemplate module_scope</TT> \n   field to <TT>every_module</TT>.\n   </P><P>\n   This has two effects:\n   <OL>\n   <LI> When instrumenting predicate definitions a template can be applied \n        to a predicate regardless of the module it is defined in.\n   <LI> When instrumenting predicate calls a template can be applied to a \n        predicate regardless of whether it is module qualified or not.\n   </OL>\n   However, as a general rule of thumb, predicate specifications for \n   <TT>PredSpec</TT> and instrumentation predicates within the templates \n   should be correctly module qualified. \n   </P><P>\n   When determining whether a predicate is to be instrumented, a template is \n   sought which matches the module qualified <TT>PredSpec</TT>, first using \n   the named module (or current module if unqualified) and then using \n   <TT>every_module</TT> as the module qualifier.\n   </P><P>\n   Within the template, predicate specifications supplied to its fields \n   determine how predicate instrumentation and invocation proceeds. \n   The template specifies the following instrumentation points:\n   <DL><DT>\n   <PRE>clause_start</PRE>\n   <DD>\n   A call to the specified predicate is placed at the beginning of each \n   clause definition of the predicate the template is being applied to.\n   <DT>\n   <PRE>clause_end</PRE>\n   <DD>\n   A call to the specified predicate is placed at the end of each clause \n   definition of the predicate the template is being applied to.\n   <DT>\n   <PRE>clause_fail</PRE>\n   <DD>\n   A call to the specified predicate is placed such that failure within \n   the clause definition of the predicate the template is being applied \n   to results in its invocation.\n   <DT>\n   <PRE>clause_redo</PRE>\n   <DD>\n   A call to the specified predicate is placed such that failure and \n   re-execution (i.e. resatisfiable execution) within the clause \n   definition of the predicate the template is being applied to results \n   in its invocation.\n   <DT>\n   <PRE>block_start</PRE>\n   <DD>\n   A call to the specified predicate is placed at the beginning of each \n   conjunction (comma-sequences of subgoals) within the definition of \n   the predicate the template is being applied to.\n   <DT>\n   <PRE>block_end</PRE>\n   <DD>\n   A call to the specified predicate is placed at the end of each \n   conjunction within the definition of the predicate the template is \n   being applied to.\n   <DT>\n   <PRE>block_fail</PRE>\n   <DD>\n   A call to the specified predicate is placed such that failure of each \n   conjunction within the definition of the predicate the template is being \n   applied to results in its invocation.\n   <DT>\n   <PRE>block_redo</PRE>\n   <DD>\n   A call to the specified predicate is placed such that failure and \n   re-execution (i.e. resatisfiable execution) of each conjunction within \n   the definition of the predicate the template is being applied to results \n   in its invocation.\n   <DT>\n   <PRE>subgoal_start</PRE>\n   <DD>\n   A call to the specified predicate is placed at the beginning of each \n   subgoal within the definition of the predicate the template is being \n   applied to.\n   <DT>\n   <PRE>subgoal_end</PRE>\n   <DD>\n   A call to the specified predicate is placed at the end of each subgoal \n   within the definition of the predicate the template is being applied to.\n   <DT>\n   <PRE>subgoal_fail</PRE>\n   <DD>\n   A call to the specified predicate is placed such that failure of each \n   subgoal within the definition of the predicate the template is being \n   applied to results in its invocation.\n   <DT>\n   <PRE>subgoal_redo</PRE>\n   <DD>\n   A call to the specified predicate is placed such that failure and \n   re-execution (i.e. resatisfiable execution) of each subgoal within \n   the definition of the predicate the template is being applied to results \n   in its invocation.\n   <DT>\n   <PRE>call_start</PRE>\n   <DD>\n   A call to the specified predicate is placed at the beginning of each \n   call invocation of the predicate the template is being applied to.\n   <DT>\n   <PRE>call_end</PRE>\n   <DD>\n   A call to the specified predicate is placed at the end of each call \n   invocation of the predicate the template is being applied to.\n   <DT>\n   <PRE>call_fail</PRE>\n   <DD>\n   A call to the specified predicate is placed such that failure of a call \n   invocation of the predicate the template is being applied to results in \n   its invocation.\n   <DT>\n   <PRE>call_redo</PRE>\n   <DD>\n   A call to the specified predicate is placed such that failure and \n   re-execution (i.e. resatisfiable execution) of a call invocation of the \n   predicate the template is being applied to results in its invocation.\n   <DT>\n   <PRE>fact</PRE>\n   <DD>\n   A call to the specified predicate is placed as the clause body of the \n   fact predicate the template is being applied to. A fact is a predicate \n   definition with no defined clause body.\n   <DT>\n   <PRE>inbetween</PRE>\n   <DD>\n   A call to the specified predicate is placed at the end of each subgoal \n   of a conjunction within the definition of the predicate the template is \n   being applied to.\n   </DL>\n   </P><P>\n   The default value for the instrumentation predicates is that none are \n   defined and so no instrumentation is performed. This is equivalent to \n   setting the field values explicitly to free variables.\n   </P><P>\n   The instrumentation predicates must be defined with one of the following \n   signatures:\n   <DL><DT>\n   Arity 0\n   <DD>\n   When an arity zero instrumentation predicate is specified, it is invoked \n   with no arguments passed.\n   <DT>\n   Arity 1\n   <DD>\n   Each code instrumentation point within a module is uniquely identified \n   by its callsite identifier. The callsite identifier is a monotonically \n   increasing integer incrementing from the initial value of 0. It is the \n   callsite identifier value that is passed to an arity one instrumentation \n   predicate.\n   <DT>\n   Arity 2\n   <DD>\n   An arity two instrumentation predicate is passed the callsite identifier \n   in argument position one and an auxiliary variable in argument position \n   two. The same auxiliary variable is passed as argument two to the start, \n   end and fail instrumentation points (i.e. it is common to <TT>clause_start</TT>, \n   <TT>clause_end </TT>, <TT>clause_fail</TT> and <TT>clause_redo</TT> while a \n   different auxiliary variable is common to <TT>block_start</TT>, \n   <TT>block_end</TT>, <TT>block_fail</TT> and <TT>block_redo</TT>, etc).\n   </DL>\n   </P><P>\n   It is anticipated that the callsite identifier be used for executing \n   callsite specific code or storing data pertinent to the callsite in a \n   non-logical store keyed by callsite identifier - \n   <TT>set_callsite_data/2</TT> and <TT>get_callsite_data/2</TT> are provided \n   for exactly this purpose.\n   </P><P>\n   The auxiliary variable passed as argument two to instrumentation \n   predicates is provided for convenience for capturing 'delta' measurements \n   between the start, end and fail instrumentation points. The variable is a \n   logical variable and while the value passed to the end or fail predicate \n   is guaranteed to be the value bound by the start predicate, backtracking \n   past the start predicate results in the unbinding of the variable. If the \n   captured delta should be retained beyond backtracking then it should be \n   placed in the callsite's non-logical store using <TT>set_callsite_data/2</TT>.\n   </P><P>\n   The maximum arity of the fact and inbetween point predicates is one - \n   only the callsite identifier is passed, there is no benefit in passing an \n   auxiliary variable.\n   </P><P>\n   The result instrumentation predicate provides a mechanism for \n   pretty-printing the annotated source code with the instrumentation results \n   gathered during execution. By executing <TT>instrument:module_result/0</TT>\n   or <TT>instrument:file_result/1</TT> the predicate specified for result \n   instrumentation within the template is invoked as each of the \n   instrumentation points are encountered for pretty-printing.\n   </P><P>\n   The result instrumentation predicate must be defined with one of the \n   following signatures:\n   <DL> <DT>\n   Arity 0\n   <DD>\n   When an arity zero predicate is specified, it is invoked with no \n   arguments passed.\n   <DT>\n   Arity 1\n   <DD>\n   The callsite identifier representing the instrumentation point is \n   passed to an arity one result predicate.\n   <DT>\n   Arity 2\n   <DD>\n   The instrumentation point type is passed as argument two of an arity \n   two result predicate. The point type is the atom associated with the \n   point, for example <TT>call_start, call_end, call_fail or call_redo</TT>, \n   etc. \n   <DT>\n   Arity 3\n   <DD>\n   The module into which the file being pretty-printed was instrumented \n   and compiled is passed as argument three of an arity three result predicate.\n   <DT>\n   Arity 4\n   <DD>\n   The goal appearing in the source code around which instrumentation was \n   originally placed is passed as argument four of an arity four result \n   predicate.\n   <DT>\n   Arity 5\n   <DD>\n   The fifth argument of an arity five result predicate is a result goal \n   that can be returned to the pretty-printer to be placed in the \n   pretty-printed output in the place of the fourth argument goal. This \n   allows the goal to be annotated with commentary or instrumentation results.\n   </DL>\n   </P><P>\n   The <TT>meta_args</TT> field of the <TT>itemplate</TT> structure is \n   applicable only to templates associated with predicates that are \n   meta-predicates. When applicable, <TT>meta_args</TT> is a list of \n   <TT>itemplate</TT>. Each element in the list is a template for the \n   corresponding argument of the meta-predicate. The template defined \n   instrumentation points are applied to the code found inside the \n   meta-predicate at this argument position. For example: \n   <PRE>findall/3 = itemplate{..., meta_args:[_, ITemplateArg2, _]...}</PRE> \n   is an <TT>itemplate</TT> specification describing the instrumentation \n   of the meta-predicate <TT>findall/3</TT>. Argument one and three undergo \n   no instrumentation (denoted by free variables) and argument two is \n   instrumented according to <TT>ITemplateArg2</TT>.\n   </P><P>\n   Within the meta-predicate argument <TT>itemplate</TT> fields may be \n   specified as being <TT>inherit</TT>-ed. When such a field is specified \n   as inherited it is set to the corresponding value of the template used in \n   instrumenting the definition of the predicate in which the call to the \n   meta-predicate resides. \n   </P><P>\n   The <TT>exclude</TT> field of the <TT>itemplate</TT> contains a list of \n   predicate specifications. Any occurrence of such a predicate as a call \n   or subgoal is excluded from application of the instrumentation specified \n   by the enclosing template. The main use of exclusion is in preventing \n   instrumentation application to recursive predicates or built-ins.\n   </P><P>\n   The <TT>code_weaver</TT> field of the <TT>itemplate</TT> specifies a \n   predicate of arity six that is a compile-time callback allowing arbitrary \n   user code to be woven into the code currently undergoing compilation. The \n   weaving of user code is performed before the insertion of instrumentation \n   predicates. The arguments of the predicate are as follows:\n   <DL> <DT>\n   File\n   <DD>\n   The name of the file currently undergoing compilation.\n   <DT>\n   Code\n   <DD>\n   The block of code available for manipulation by the user specified code \n   weaving predicate.\n   <DT>\n   Type\n   <DD>\n   The ECLiPSe construct type of the 'Code' block, one of: \n   <TT>clause, head, body, fact, variable, conjunction, disjunction, \n   conditional, do, goal</TT>. The decomposition of code blocks into these \n   various constructs is for convenience to save the weaver predicate from \n   having to match out the constructs itself. It is however free to do so \n   by operating solely on the <TT>clause</TT> construct.\n   <DT>\n   WeavedCode\n   <DD>\n   The block of code that results from the weaving of the Code' block with \n   the arbitrary user code. \n   <DT>\n   Mode\n   <DD>\n   The mode that code weaving is proceeding in, either <TT>compile</TT>, \n   during compilation, or <TT>print</TT> during pretty-printing.\n   <DT>\n   Module\n   <DD>\n   The module the code is being compiled into.\n   </DL>\n   </P><P>\n   The remaining fields of the <TT>itemplate</TT> structure specify the \n   options:\n   <DL><DT>\n   <TT>asserted</TT> (default:free variable)\n   <DD><P>\n   The value of asserted may be the atoms: <TT>on</TT>, <TT>off</TT> and \n   <TT>post_compile</TT> or a free variable. When a free variable, the \n   instrumentation predicates are compiled into the code like any other \n   predicates. However, when set to one of the atomic values, the predicates \n   are compiled such that they can be inserted and removed at runtime. This \n   is done efficiently such that there is negligible overhead on execution.\n   </P><P>\n   The value <TT>on</TT> specifies that the predicates are initially inserted.\n   The value <TT>off</TT> that they are removed and <TT> post_compile</TT> \n   that they are not inserted until compilation of the whole file has \n   completed. The <TT>post_compile</TT> option is provided so that \n   instrumentation predicates inserted into predicate definitions that get \n   executed at compile-time do not get executed.\n   </P><P>\n   During execution, the instrumentation predicates can be inserted and \n   removed using <TT>instrument:instrument_control/2</TT>. \n   <P><DT>\n   <TT>module_scope</TT> (default:free variable)\n   <DD><P>\n   The possible values are an atom representing a module name, the atom \n   <TT>every_module</TT> or a free variable indicating the current module. \n   The value is used to determine the module definition context of \n   unqualified instrumentation predicates or the predicate associated with \n   the template for definition and call instrumentation:\n   <DL><DT>\n   Named module\n   <DD><P>\n   The unqualified predicate is qualified with the named module.\n   <P><DT>\n   Free variable\n   <DD><P>\n   The unqualified predicate is qualified with the calling module context \n   in which <TT>instrument/2</TT> was first invoked.\n   <P><DT>\n   <TT>every_module</TT>\n   <DD><P>\n   The unqualified predicate is qualified with the name of the current \n   compilation module.\n   <P></DL><P><DT>\n   <TT>file_local</TT> (default:<TT>off</TT>)\n   <DD><P>\n   Templates persist in a global store between successive calls to \n   <TT>instrument/2</TT> and <TT>instrument/3</TT>. If it is undesirable \n   for a template to be added to the global store (thus making it available \n   for the instrumentation of other files and modules) an <TT>itemplate</TT> \n   may be declared as being applicable to only the file currently being \n   instrumented by setting this option to <TT>on</TT>.\n   </P><P>\n   The search order for an instrumentation template is first in the file \n   local store and then in the global store.\n   <P><DT>\n   <TT>goal_expansion</TT> (default:<TT>on</TT>)\n   <DD><P>\n   Setting this to <TT>off</TT> will suppress goal expansion inlining) \n   during compilation. This may be necessary when the processed code \n   contains predicates that get executed at compile time. \n   </P></DL><P>")]).
:- comment(defined_modules / 2, [summary : "Retrieve the modules defined by a file.", args : ["File" : "Atom or string", "Modules" : "List of atoms"], amode : defined_modules(+, -), fail_if : no, resat : no, see_also : [get_callsite_data / 2, file_callsites / 3, instrument / 2, instrument / 3, library(instrument), set_callsite_data / 2, struct(itemplate), defined_modules / 2], desc : html("<P>\n   It is often necessary to know what modules a file has defined in order \n   to operate on module specific data.  This predicate can be used to return \n   the modules defined by a file which has been compiled with the instrument \n   compiler.")]).
:- comment(erase_all_templates / 0, [summary : "Erase all instrument template stores.", args : [], fail_if : no, resat : no, desc : html("<P>\n   This predicate erases all <TT>itemplate</TT> that are persisted in \n   the global and file local template stores between successive calls \n   to <TT>instrument/2</TT> and <TT>instrument/3</TT>."), see_also : [erase_module_templates / 0, erase_file_templates / 1, instrument / 2, instrument / 3, library(instrument), struct(itemplate), defined_modules / 2]]).
:- comment(erase_file_templates / 1, [summary : "Erase the file local instrument template store for a\n   specific file.", amode : erase_file_templates(+), args : ["File" : "Atom or string"], fail_if : "No instrumentation templates exist for the file in \n   the calling module context.", resat : no, desc : html("<P>\n   This predicate erases all templates associated with the named file \n   that was compiled into the the calling module context and persisted \n   by (successive) calls to <TT>instrument/2</TT> and <TT>instrument/3</TT>. \n   The predicate is a tool and the file local templates of a module other \n   than the current calling module context can be erased by invoking \n   <TT>erase_file_templates(File)@Module</TT>."), see_also : [erase_all_templates / 0, erase_module_templates / 0, instrument / 2, instrument / 3, library(instrument), struct(itemplate), defined_modules / 2]]).
:- comment(erase_module_templates / 0, [summary : "Erase all instrument template stores for a specific module.", args : [], fail_if : "No instrumentation templates exist for the calling module.", resat : no, desc : html("<P>\n   This predicate erases all templates of the calling module context, \n   that are persisted in the global and file local template stores \n   between successive calls to <TT>instrument/2</TT> and <TT>instrument/3</TT>. \n   The predicate is a tool and the templates of a module other than the \n   current calling module context can be erased by invoking \n   <TT>erase_module_templates@Module</TT>. To erase templates \n   applicable to all modules, the atom <TT>every_module</TT> may be \n   specified."), see_also : [erase_all_templates / 0, erase_file_templates / 1, instrument / 2, instrument / 3, library(instrument), struct(itemplate), defined_modules / 2]]).
:- comment(file_callsites / 3, [summary : "Retrieve start and end callsite identifiers for named file.", args : ["File" : "Atom or string", "StartId" : "Intger", "EndId" : "Integer"], amode : file_callsites(+, ?, ?), fail_if : "StartId or EndId are not the file's starting and \n    ending callsite identifiers.", resat : no, see_also : [get_callsite_data / 2, instrument / 2, instrument / 3, library(instrument), module_callsites / 2, set_callsite_data / 2, struct(itemplate), defined_modules / 2], desc : html("<P>\n   Each code instrumentation point within a file is \n   uniquely identified by its callsite identifier.\n   The callsite identifier is a monotonically increasing \n   integer incrementing from the initial value of 0 for a \n   new module. \n   <P>\n   As additional files are instrumented and \n   compiled into a module, the start identifier is \n   incremented from the end identifier of the previous file. \n   The predicate retrieves the start and end callsite \n   identifiers for the file.\n   <P>\n   The predicate is a tool and the callsite identifiers \n   of a file instrumented in a module other than the current \n   calling module context can be retrieved by invoking \n   <TT>file_callsites(File, StartId, EndId)@Module</TT>.")]).
:- comment(file_result / 1, [summary : "Pretty-print a file, including any instrumentation results", amode : file_result(+), args : ["File" : "Atom or string"], see_also : [instrument / 2, instrument / 3, file_result / 2, library(instrument), library(pretty_printer), module_result / 0, module_result / 1, struct(itemplate), defined_modules / 2], desc : html("<P>\n   This will pretty-print the specified source file in the calling \n   module context, annotated with the result of instrumentation. \n   The resulting .html file is placed in a sub-directory called \n   instrument', relative to File.\n   </P><P>\n   See <TT>file_result/2</TT> for options to modify the output.\n   </P><P>\n   The use of this predicate is only meaningful if the module has \n   previously been instrumented and compiled \n   using <TT>instrument:instrument/1,2</TT>, and the code has been \n   run in order to obtain instrumentation results.\n   </P><P>\n   See <TT>struct(itemplate)</TT> for documentation of how the \n   result instrumentation is used in the annotation and pretty-printing \n   of the code.\n   </P><P>\n   The predicate is a tool and the instrumentation results of a \n   file in an alternate module to the current calling module context \n   can be obtained invoking <TT>file_result(File)@Module</TT>.\n   <P>")]).
:- comment(file_result / 2, [summary : "Pretty-print a file, including any instrumentation results", amode : file_result(+, +), args : ["File" : "Atom or string", "OptionList" : "List of options"], see_also : [instrument / 2, instrument / 3, file_result / 1, library(instrument), library(pretty_printer), module_result / 0, module_result / 1, struct(itemplate), defined_modules / 2], desc : html("<P>\n   This will pretty-print the specified source file in the calling \n   module context, annotated with the result of instrumentation. \n   The resulting .html file is placed in a sub-directory called \n   instrument', relative to File.\n   </P><P>\n   The use of this predicate is only meaningful if the module has \n   previously been instrumented and compiled \n   using <TT>instrument:instrument/1,2</TT>, and the code has been \n   run in order to obtain instrumentation results.\n   </P><P>\n   OptionList is a list of options identical to the one accepted by \n   <TT>pretty_print/2</TT> in the library(pretty_printer), and can be \n   used to modify the output style and the location of the output file.\n   </P><P>\n   Additionally, OptionList may contain the following options:\n   <DL><DT>\n   <TT>ignore_module_templates</TT> (default:<TT>off</TT>)\n   <DD>\n   Specifying this option as <TT>on</TT> results in the \n   use of file local templates only during instrumentation. \n   Templates are not sought from the global store.\n   <P>\n   This option should only be specified if it was also specified \n   during instrumentation (i.e. when using \n   <TT>instrument:instrument/3</TT>).\n   </P><DT>\n   <TT>macro_expansion</TT> (default:<TT>off</TT>)\n   <DD>\n   This option affects only the printing of the result (html) file. \n   By default, read-macros are not expanded in this output. \n   In rare cases, where macro expansion would affect the placement of \n   instrumentation positions, it may be necessary to set \n   this option to <TT>on</TT> in order to display the instrumentation \n   at the correct positions in the code.\n   <P><DT>\n   <TT>verbose</TT> (default:<TT>off</TT>)\n   <DD>\n   If set to <TT>on</TT>, the instrument preprocessor \n   will print predicate names as they are processed (to \n   log_output). \n   If set to <TT>debug</TT>, the instrument preprocessor \n   prints each instrumented and/or woven predicate definition (to \n   log_output).\n   </DL><P>\n   See <TT>struct(itemplate)</TT> for documentation of how the \n   result instrumentation is used in the annotation and pretty-printing \n   of the code.\n   </P><P>\n   The predicate is a tool and the instrumentation results of a \n   file in an alternate module to the current calling module context \n   can be obtained invoking <TT>module_result(File, OptionList)@Module</TT>.\n   </P>")]).
:- comment(get_callsite_data / 2, [summary : "Retrieve data associated with an instrumentation callsite \n   from its non-logical store.", args : ["SiteId" : "Integer", "UserData" : "Valid Prolog term"], amode : get_callsite_data(+, ?), fail_if : "Data has not been stored for callsite identifier SiteId.", resat : no, exceptions : [4 : "SiteId is not instantiated.", 5 : "SiteId is not an integer."], see_also : [file_callsites / 3, instrument / 2, instrument / 3, library(instrument), module_callsites / 2, set_callsite_data / 2, struct(itemplate), defined_modules / 2], desc : html("<P>\n   Each code instrumentation point within a file is uniquely identified \n   by its callsite identifier. The callsite identifier is a monotonically \n   increasing integer incrementing from the initial value of 0 for a new \n   module. \n   <P>\n   The predicate retrieves the data (a valid Prolog term) that has been \n   associated with the specified instrumentation callsite within a module \n   or file.\n   <P>\n   The data is stored in a non-logical store and can be stored using \n   <TT>instrument:set_callsite_data/2</TT>.\n   <P>\n   The predicate is a tool and data for a callsite of a module other than \n   the current calling module context can be retrieved by invoking \n   <TT>get_callsite_data(SiteId, UserData)@Module</TT>.")]).
:- comment(instrument / 2, [summary : "Compile a file, inserting predicate instrumentation", args : ["File" : "Atom or string", "ITemplates" : "itemplate, List of itemplate or PredSpec"], amode : instrument(+, +), exceptions : [4 : "ITemplates is not instantiated.", 5 : "ITemplates is not of the appropriate type."], see_also : [erase_all_templates / 0, file_result / 1, file_result / 2, file_callsites / 3, get_callsite_data / 2, instrument / 3, instrument_control / 2, library(instrument), module_callsites / 2, module_result / 0, module_result / 1, set_callsite_data / 2, defined_modules / 2], desc : html("<P>\n   This is a variant of the ECLiPSe compiler that inserts user specified \n   instrumentation predicates into the compiled code. This code can then \n   be run, and the results analysed by printing them using \n   <TT>instrument:module_result/0</TT> or <TT>instrument:file_result/1</TT>.\n   <P>\n   ITemplates can be specified as:\n   <DL><DT>\n   PredSpec of arity two\n   <DD>\n   If an arity two predicate specification is supplied, then this predicate \n   is invoked in order to retrieve the template for the predicate being \n   instrumented. Argument one is the predicate specification of the \n   predicate undergoing instrumentation. Argument two is an output variable\n   that is to be returned by this predicate as the template to use. The \n   returned <TT>itemplate</TT> will be validated before instrumentation \n   proceeds.\n   <DT>\n   <TT>itemplate</TT>\n   <DD>\n   A single template passed to <TT>instrument/2</TT> or <TT>instrument/3</TT> \n   is adopted as the <B>global</B> template to be used for predicate \n   instrumentation. If a template for the predicate currently being \n   instrumented is not found in the template stores then if a global template \n   exists, it is used.\n   <DT>\n   <TT>PredSpec = itemplate</TT>\n   <DD>\n   A template specification for instrumentation of a single predicate. If \n   however, PredSpec is not actually a valid predicate specification but \n   the atom <TT>iglobal</TT>, the template is adopted as the global template \n   (see above).\n   <DT>\n   List of <TT>itemplate</TT>\n   <DD>\n   The list is of the form: \n   <PRE>[itemplate{...} | PredSpec = itemplate{...} ... \n   PredSpec = itemplate{...}]</PRE>\n   The <TT>itemplate</TT> at the head of the list is specifies the global \n   template and is optional. The remaining elements of the list are \n   <TT>itemplate</TT> specifying instrumentation for the PredSpec with which \n   they are associated.\n   </DL><P>\n   In addition to supplying the global template, an exclude list of \n   PredSpec for predicates that should not be instrumented by the global \n   template can be specified:\n   <PRE>itemplate{...} - \n   predicate/1, my_module:my_predicate/8,...]</PRE>")]).
:- comment(instrument / 3, [summary : "Compile a file, inserting predicate instrumentation", args : ["File" : "Atom or string", "ITemplates" : "itemplate, List of itemplate or PredSpec", "OptionList" : "List of Name:Value pairs"], amode : instrument(+, +, +), exceptions : [4 : "ITemplates is not instantiated.", 5 : "ITemplates is not of the appropriate type."], see_also : [erase_all_templates / 0, file_result / 1, file_result / 2, file_callsites / 3, get_callsite_data / 2, instrument / 3, instrument_control / 2, library(instrument), module_callsites / 2, module_result / 0, module_result / 1, set_callsite_data / 2, defined_modules / 2], desc : html("<P>\n   This is a variant of the ECLiPSe compiler that inserts user specified \n   instrumentation predicates into the compiled code. \n   This code can then be run, and the results analysed by printing them using \n   <TT>instrument:module_result/0</TT> or <TT>instrument:file_result/1</TT>.\n   <P>\n   ITemplates can be specified as:\n   <DL><DT>\n   PredSpec of arity two\n   <DD>\n   If an arity two predicate specification is supplied, then this predicate \n   is invoked in order to retrieve the template for the predicate being \n   instrumented. Argument one is the predicate specification of the \n   predicate undergoing instrumentation. Argument two is an output variable th\n   at is to be returned by this predicate as the template to use. The \n   returned <TT>itemplate</TT> will be validated before instrumentation \n   proceeds.\n   <DT>\n   <TT>itemplate</TT>\n   <DD>\n   A single template passed to <TT>instrument/2</TT> or <TT>instrument/3</TT> \n   is adopted as the <B>global</B> template to be used for predicate \n   instrumentation. If a template for the predicate currently being \n   instrumented is not found in the template stores then if a global template \n   exists, it is used.\n   <DT>\n   <TT>PredSpec = itemplate</TT>\n   <DD>\n   A template specification for instrumentation of a single predicate. If \n   however, PredSpec is not actually a valid predicate specification but the \n   atom <TT>iglobal</TT>, the template is adopted as the global template \n   (see above).\n   <DT>\n   List of <TT>itemplate</TT>\n   <DD>\n   The list is of the form: \n   <PRE>[itemplate{...} | PredSpec = itemplate{...} ... \n   PredSpec = itemplate{...}]</PRE>\n   The <TT>itemplate</TT> at the head of the list is specifies the global \n   template and is optional. The remaining elements of the list are \n   <TT>itemplate</TT> specifying instrumentation for the PredSpec with which \n   they are associated.\n   </DL><P>\n   In addition to supplying the global template, an exclude list of PredSpec \n   for predicates that should not be instrumented by the global template can \n   be specified: <PRE>itemplate{...} - predicate/1, \n   my_module:my_predicate/8,...]</PRE>\n   <P>\n   OptionList may contain the following options:\n   <DL><DT>\n   <TT>erase_templates</TT>\n   <DD>\n   Specifying this option results in the removal of instrumentation templates \n   in file local and/or global template stores. The 'Value' portion of the \n   option can be specified as an atom representing a specific module, the \n   atom <TT>all</TT> or the atom <TT>every_module</TT>.\n   <DT>\n   <TT>instrument_recursive</TT> (default:<TT>off</TT>)\n   <DD>\n   Specifying this option as <TT>on</TT> indicates that instrumentation \n   should be applied within recursive predicates. With it <TT>off</TT> the \n   net effect is that instrumentation is placed around the recursive \n   call-graph (unless no applicable template exists). This prevents \n   incorrect aggregation of accounting by instrumentation predicates. \n   <DT>\n   <TT>file_local_templates</TT> (default:<TT>off</TT>)\n   <DD>\n   Specifying this option as <TT>on</TT> indicates that all templates in \n   ITemplates should be stored locally to the file - they are not available \n   for use in instrumenting other files (in other modules). The \n   <TT>file_local</TT> option of the <TT>itemplate</TT> in ITemplates are \n   overridden by this option.\n   <DT>\n   <TT>ignore_module_templates</TT> (default:<TT>off</TT>)\n   <DD>\n   Specifying this option as <TT>on</TT> results in the use of file local \n   templates only during instrumentation. Templates are not sought from \n   the global store.\n   <DT>\n   <TT>verbose</TT> (default:<TT>off</TT>)\n   <DD>\n   If set to <TT>on</TT>, the instrument preprocessor will print predicate \n   names as they are processed (to log_output). If set to <TT>debug</TT>, \n   the instrument preprocessor prints each instrumented and/or woven \n   predicate definition (to log_output).\n   </DL>\n   <P>")]).
:- comment(instrument_control / 2, [summary : "Insert or remove instrumentation predicates dynamically \n   at runtime.", args : ["Mode" : "Atom", "InstrumentPredSpec" : "PredSpec"], amode : instrument_control(+, +), fail_if : "InstrumentPredSpec is not a predicate specification.", resat : no, exceptions : [68 : "PredSpec is an undefined procedure."], see_also : [instrument / 2, instrument / 3, library(instrument), struct(itemplate)], desc : html("<P>\n   If the <TT>asserted</TT> option of an <TT>itemplate</TT> \n   is set to one of <TT>on</TT>, <TT>off</TT> or \n   <TT>post_compile</TT> then the template's instrumentation \n   predicates may be inserted and removed dynamically at runtime.\n   <P>\n   When Mode is <TT>on</TT> the instrumentation predicate \n   represented is PredSpec is inserted into the code at the \n   positions specified during instrumentation. This is done \n   efficiently with negligible runtime overhead. When Mode is \n   <TT>off</TT> the instrumentation predicate is removed from \n   the instrumented code.\n   <P>\n   If PredSpec is module qualified, the instrumentation predicate \n   defined in the context of the module is inserted / removed. If \n   unqualified the predicate is assumed to be defined in the context \n   of the calling module scope.\n   <P>\n   The predicate is a tool and an unqualified instrumentation \n   predicate defined in a module other than the current \n   calling module context can be inserted / removed by invoking \n   <TT>instrument_control(Mode, InstrumentPredSpec)@Module</TT>.")]).
:- comment(module_callsites / 2, [summary : "Retrieve module start and end callsite identifiers.", args : ["StartId" : "Intger", "EndId" : "Integer"], amode : module_callsites(?, ?), fail_if : "StartId or EndId are not the module's starting and \n   ending callsite identifiers.", resat : no, see_also : [get_callsite_data / 2, file_callsites / 3, instrument / 2, instrument / 3, library(instrument), set_callsite_data / 2, struct(itemplate), defined_modules / 2], desc : html("<P>\n   Each code instrumentation point within a module is \n   uniquely identified by its callsite identifier.\n   The callsite identifier is a monotonically increasing \n   integer incrementing from the initial value of 0.\n   The predicate retrieves the start and end callsite \n   identifiers.\n   <P>\n   The predicate is a tool and the callsite identifiers \n   of a module other than the current calling module \n   context can be retrieved by invoking \n   <TT>module_callsites(StartId, EndId)@Module</TT>.")]).
:- comment(module_result / 0, [summary : "Pretty-print all files in a module, including any \n    instrumentation results", args : [], see_also : [instrument / 2, instrument / 3, file_result / 1, file_result / 2, library(instrument), library(pretty_printer), module_result / 1, struct(itemplate), defined_modules / 2], desc : html("<P>\n   This will pretty-print all source files in the calling module context, \n   annotated with the result of instrumentation.  The resulting .html \n   files are placed in a sub-directory called instrument', relative to \n   the files that were compiled into the file.\n   </P><P>\n   See <TT>module_result/1</TT> for options to modify the output.\n   </P><P>\n   The use of this predicate is only meaningful if the module has \n   previously been instrumented and compiled \n   using <TT>instrument:instrument/1,2</TT>, and the code has been \n   run in order to obtain instrumentation results.\n   </P><P>\n   See <TT>struct(itemplate)</TT> for documentation of how the \n   result instrumentation is used in the annotation and pretty-printing \n   of the code.\n   </P><P>\n   The predicate is a tool and the instrumentation results of a \n   module other than the current calling module context can be obtained \n   by invoking <TT>module_result@Module</TT>.\n   <P>")]).
:- comment(module_result / 1, [summary : "Pretty-print all files in a module, including any \n   instrumentation results", amode : module_result(+), args : ["OptionList" : "List of options"], see_also : [instrument / 2, instrument / 3, file_result / 1, file_result / 2, library(instrument), library(pretty_printer), module_result / 0, struct(itemplate), defined_modules / 2], desc : html("<P>\n   This will pretty-print all source files in the calling\n   module context, annotated with the result of instrumentation. \n   The resulting .html files are placed in a sub-directory called \n   instrument', relative to the files that were compiled into the file.\n   </P><P>\n   OptionList is a list of options identical to the one accepted by \n   <TT>pretty_print/2</TT> in the library(pretty_printer), and can be \n   used to modify the output style and the location of the output file.\n   </P><P>\n   Additionally, OptionList may contain the following options:\n   <DL><DT>\n   <TT>ignore_module_templates</TT> (default:<TT>off</TT>)\n   <DD>\n   Specifying this option as <TT>on</TT> results in the \n   use of file local templates only during instrumentation. \n   Templates are not sought from the global store.\n   <P>\n   This option should only be specified if it was also specified \n   during instrumentation (i.e. when using \n   <TT>instrument:instrument/3</TT>).\n   <DT>\n   <TT>macro_expansion</TT> (default:<TT>off</TT>)\n   <DD>\n   This option affects only the printing of the result (html) file. \n   By default, read-macros are not expanded in this output. \n   In rare cases, where macro expansion would affect the placement of \n   instrumentation positions, it may be necessary to set \n   this option to <TT>on</TT> in order to display the instrumentation \n   at the correct positions in the code.\n   <P>\n   <DT>\n   <TT>verbose</TT> (default:<TT>off</TT>)\n   <DD>\n   If set to <TT>on</TT>, the instrument preprocessor \n   will print predicate names as they are processed (to \n   log_output). \n   If set to <TT>debug</TT>, the instrument preprocessor \n   prints each instrumented and/or woven predicate definition (to \n   log_output).\n   </DL>\n   </P><P>\n   The use of this predicate is only meaningful if the module has \n   previously been instrumented and compiled \n   using <TT>instrument:instrument/1,2</TT>, and the code has been \n   run in order to obtain instrumentation results.\n   </P><P>\n   See <TT>struct(itemplate)</TT> for documentation of how the \n   result instrumentation is used in the annotation and pretty-printing \n   of the code.\n   </P><P>\n   The predicate is a tool and the instrumentation results of a \n   module other than the current calling module context can be obtained \n   by invoking <TT>module_result(OptionList)@Module</TT>.\n   <P>")]).
:- comment(set_callsite_data / 2, [summary : "Associate arbitrary data with an instrumentation callsite \n   in a non-logical store.", args : ["SiteId" : "Integer", "UserData" : "Valid Prolog term"], amode : set_callsite_data(+, ?), fail_if : no, resat : no, exceptions : [4 : "SiteId is not instantiated.", 5 : "SiteId is not an integer."], see_also : [file_callsites / 3, get_callsite_data / 2, instrument / 2, instrument / 3, library(instrument), module_callsites / 2, struct(itemplate), defined_modules / 2], desc : html("<P>\n   Each code instrumentation point within a file is \n   uniquely identified by its callsite identifier.\n   The callsite identifier is a monotonically increasing \n   integer incrementing from the initial value of 0 for a \n   new module. \n   <P>\n   The predicate associates arbitrary data (a valid Prolog term) \n   with a specified instrumentation callsite within a module or \n   file.\n   <P>\n   The data is stored in a non-logical store and can be \n   retrieved using <TT>instrument:get_callsite_data/2</TT>.\n   <P>\n   The predicate is a tool and data for a callsite \n   of a module other than the current calling module context \n   can be stored by invoking \n   <TT>set_callsite_data(SiteId, UserData)@Module</TT>.")]).
