A predicate is implemented by what is called the supervisor code. That can be regarded a preamble and depends on how the predicate is defined. If it is foreign, this uses one of the i_fcall* instructions which creates the arguments for the C function and calls it. If is a normal predicate it depends on things such as being thread-local, dynamic or static and in the latter case on the indexing opportunities. The supervisor is created on the first call (actually, the initial supervisor is S_VIRGIN
, which analyses the predicate and replaces itself by the real supervisor on the first call. reloading the predicate resets the supervisor to S_VIRGIN
).
Unification is a very special case. The VM defines many unification instructions and the predicate is hardly ever called. It is there to support meta calling it (e.g, maplist(=(x), LIst)
) and such that you can reason about programs using reflexive predicates such as predicate_property/2. Being foreign, =/2 only has a supervisor and no clauses.