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.
% 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).