[ 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

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