
mode +PredModes

   Specifies the mode (calling pattern) for the given predicates

Arguments
   PredModes           Callable term with mode-indicator arguments, or a comma-separated list of such

Type
   Predicate Database and Compiler

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
   mode(++) is det

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

Exceptions
     4 --- PredModes is not ground
     5 --- PredModes is not a callable term, or a comma list, or its arguments are not atoms.
     6 --- 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
