[ Predicate Database and Compiler | Reference Manual | Alphabetic Index ]

mode +PredModes

Specifies the mode (calling pattern) for the given predicates
PredModes
Callable term with mode-indicator arguments, or a comma-separated list of such

Description

This declaration is normally used as a directive in compiled code, and informs the compiler that the arguments of the specified predicate will always have the corresponding form when the predicate is called. The compiler takes this information into account when the predicate is compiled, and generates more compact and/or faster code. Specifying the mode of a predicate that has been already compiled has no effect, unless it is recompiled. If the specified predicate does not exist, a local undefined predicate is created.

The possible argument modes are:

+
The argument is instantiated, i.e. it is not a variable.
++
The argument is ground, i.e. contains no variables.
-
The argument is not instantiated, it must be a free variable without any constraints, especially it must not occur in any other argument and it cannot be a suspending variable.
?
The mode is not known or it is neither of the above.
mode/1 is a prefix operator and accepts also comma-separated list of mode specifications in the form

   :- mode p(+), q(-), r(++, ?).
As the operator binds less than comma, the argument of mode/1 might have to be parenthesised when it is followed by other goals. Modes must be declared in a predicate's definition module. Modes are significant only for the first 15 arguments, for higher arguments the mode is always taken as ?.

NOTE: If the instantiation of a runtime predicate call violates its mode declaration, no exception is raised and its behaviour is undefined.

The declared mode information can be accessed by retrieving the predicate's 'mode' property with get_flag/3.

Modes and Determinism

Modules

This predicate is sensitive to its module context (tool predicate, see @/2).

Exceptions

(4) instantiation fault
PredModes is not ground
(5) type error
PredModes is not a callable term, or a comma list, or its arguments are not atoms.
(6) out of range
The callable term arguments are not mode indicators

Examples

Success:
    % code size:
    % no mode declarations
    [eclipse]: [append].
    /home/eclipse/src/append.pl compiled 212 bytes in 0.03 seconds

    % mode for one argument decreases the code size
    [eclipse]: mode(append(++, ?, ?)), [append].
    /home/eclipse/src/append.pl compiled 120 bytes in 0.00 seconds

    % modes for other arguments further decreases the size
    [eclipse]: mode(append(++, ++, -)), [append].
    /home/eclipse/src/append.pl compiled 92 bytes in 0.00 seconds

    % size of the trail stack
    cygnus% cat p.pl
    p(f(1), [output]) :- !.
    p(f(2), [another_one]).

    test :-
        p(f(1), X),
        statistics(trail_stack_used, T1),
        writeln(T1).
    :- test.
    cygnus% eclipse
    [eclipse]: [p].
    16
    /home/eclipse/p.pl    compiled 540 bytes in 0.02 seconds

    % With modes the code is shorter and does less trailing
    [eclipse]: mode(p(++, -)), [p].
    12
    /home/eclipse/p.pl    compiled 408 bytes in 0.02 seconds

    % bad mode declaration:
    [eclipse]: mode(p(+)), [user].
     p(a).
     user   compiled 40 bytes in 0.00 seconds

    yes.
    [eclipse]: p(X).    % call violates the mode declaration

    no (more) solution.
Error:
    mode p(X).                         (Error 4).
    mode p(+), get_flag(p/1, mode, X). (Error 5).
    % equivalent to mode((p(+), get_flag(p/1, mode, X)))

See Also

compile / 1, get_flag / 3, set_flag / 3, meta_predicate / 1