Many predicates can sensibly be called in different ways, e.g. with a specific argument as input or as output. The header of the documentation of a predicate consists of one or more templates, each representing a specific way of calling the predicate.
A template can contain information about types, argument instantiation patterns, determinism and more. The syntax is informally described below:
|<template>||::=||<head>['//'] 'is' <determinism>|
|<head>||::=||<functor>'('<argspec> ',' <argspec>')'|
|<instantiation>||::=||'++' | '+' | '-' | '--' | '?' | ':' | '@' | '!'|
The determinism values originate from Mercury. Their meaning
is explained in the table below. Informally,
det is used
for deterministic transformations (e.g. arithmetic),
multi for generators.
failure indicator is rarely used. It mostly appears in
hooks or the recovery goal of catch/3.
|Succeeds exactly once without a choice point|
|Fails or Succeeds exactly once without a choice-point|
|No constraints on the number of times the predicate succeeds and whether or not it leaves choice-points on the last success.|
The meanings of the instantiation patterns for individual arguments are:
|++||Argument is ground at call-time, i.e., the argument does not contain a variable anywhere.|
|+||Argument is fully instantiated at call-time, to a term
that satisfies the type. This is not necessarily ground, e.g.,
|-||Argument is an output argument. It may be
unbound at call-time, or it may be bound to a term. In the latter case,
the predicate behaves as if the argument was unbound, and then unified
with that term after the goal succeeds. For example, the goal |
|--||Argument is unbound at call-time. Typically used by predicates that create `something' and return a handle to the created object, such as open/3 which creates a stream.|
|?||Argument is bound to a partial term of the indicated type at call-time. Note that a variable is a partial term for any type.|
|:||Argument is a meta-argument. Implies |
|@||Argument will not be further instantiated than it is at call-time. Typically used for type tests.|
|!||Argument contains a mutable structure that may be modified using setarg/3 or nb_setarg/3.|
Users should be aware that calling a predicate with arguments instantiated in a way other than specified by one of the templates may result in errors or unexpected behavior.
Developers should ensure that predicates are steadfast with respect to output arguments (marked - in the template). This means that instantiation of output arguments at call-time does not change the semantics of the goal (it may be used for optimization, though). If this steadfast behavior cannot be guaranteed, -- should be used instead.
In the current version, argument types are represented by an arbitrary term without formal semantics. In future versions we may adopt a formal type system that allows for runtime verification and static type analysis Hermenegildo, 2000, Mycroft & O'Keefe, 1984, Jeffery et al., 2000
%! length(+List:list, -Length:int) is det. %! length(?List:list, -Length:int) is nondet. %! length(?List:list, +Length:int) is det. % % True if List is a list of length Length. % % @compat iso