
tool(++PredSpecI, ++PredSpecB)

   Declares PredSpecI as a tool interface procedure and PredSpecB as its body
procedure.


Arguments
   PredSpecI           Expression of the form Atom/Integer.
   PredSpecB           Expression of the form Atom/Integer.

Type
   Modules

Description
   It defines PredSpecI as a tool interface procedure in the caller module
   and declares PredSpecB as its body procedure.  The arity of PredSpecB
   must be one higher than the arity of PredSpecI, otherwise an exception
   is raised.  This is because when PredSpecI is called, the system puts
   the name of the caller module in the additional argument and calls
   PredSpecB.

   The default visibility for the interface procedure is local.
   The body procedure gets exported implicitly.

   The tool/2 declaration can be used before the body procedure is defined.

   If PredSpecI already exists and if the system has already compiled some
   calls to it, tool/2 gives error 62 (``inconsistent procedure
   redefinition'') since the system cannot provide the caller's home module
   for calls which are already compiled.

   Therefore, the tool/2 declaration should be always textually precede the
   first call to enable to compiler to compile the call correctly.



Modes and Determinism
   tool(++, ++) is det

Modules
   This predicate is sensitive to its module context (tool predicate, see @/2).

Exceptions
     4 --- Either PredSpecI or PredSpecB is not instantiated.
     5 --- Either PredSpecI or PredSpecB is instantiated, but not to an    expression of the form Atom/Integer.
     6 --- The arity of PredSpecB is not one greater than that of    PredSpecI.
    62 --- A call to PredSpec has already been compiled before the    tool declaration (``inconsistent procedure redefinition'').

Examples
   
% A typical meta-predicate, wrong and right way:

    [eclipse 1]: [user].
	:- module(m1).
	:- export twice/1.
	twice(P):-
	    call(P),
	    call(P).
    yes.

    [eclipse 2]: [user].
     p(1).
    yes.

    [eclipse 3]: import twice/1 from m1.
    yes.

    [eclipse 4]: twice(p(X)).
    calling an undefined procedure p(X) in module m1
    yes.

    [eclipse 5]: [user].
	:- module(m1).
	:- export twice/1.
	:- tool(twice/1,twice_body/2).
	twice_body(P,M):-
	    call(P)@M,
	    call(P)@M.
    yes.

    [eclipse 6]: twice(p(X)).
    X = 1
    yes.


% define a predicate that prints its caller module:

    [eclipse]: tool(where_am_i/0, writeln/1).
    yes.

    [eclipse]: where_am_i.
    eclipse
    yes.


% Error:
     tool(L, tb/1).                   (Error 4).
     tool(ti/0, L).                   (Error 4).
     tool(ti, tb/1).                  (Error 5).
     tool(ti/0, tb).                  (Error 5).
     tool(ti/0, tb/2).                (Error 6).

     [eclipse]: [user].
      p :- ti. % call compiled before tool declaration
      user        compiled 32 bytes in 0.02 seconds
     yes.
     [eclipse]: tool(ti/0, tb/1).     (Error 62).


See Also
   tool_body / 3, @ / 2
