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