[ Modules | Reference Manual | Alphabetic Index ]

# tool(++PredSpecI, ++PredSpecB)

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

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

## Description

It defines PredSpecI as a tool interface procedure in the context 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 context 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 context 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) instantiation fault
  Either PredSpecI or PredSpecB is not instantiated.
(5) type error
  Either PredSpecI or PredSpecB is instantiated, but not to an expression of the form Atom/Integer.
(6) out of range
  The arity of PredSpecB is not one greater than that of PredSpecI.
(62) inconsistent procedure redefinition
  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's context 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