instantiation_error()
if Term is unbound
and Name/Arity is insufficiently instantiated.
SWI-Prolog also supports terms with arity 0, as in a()
(see
section 5. Such terms must be
processed using
compound_name_arity/3.
The predicate functor/3
and =../2 raise a domain_error
when faced with these terms. Without this precaution, the inconsistency
demonstrated below could happen silently.83Raising
a domain error was suggested by Jeff Schultz.
?- functor(a(), N, A). N = a, A = 0. ?- functor(T, a, 0). T = a.
domain_error(not_less_than_zero, Arg)
if Arg
< 0.?- foo(hello, X) =.. List. List = [foo, hello, X] ?- Term =.. [baz, foo(1)]. Term = baz(foo(1))
SWI-Prolog also supports terms with arity 0, as in a()
(see
section 5. Such terms must be
processed using
compound_name_arguments/3.
This predicate raises a domain error as shown below. See also functor/3.
?- a() =.. L. ERROR: Domain error: `compound_non_zero_arity' expected, found `a()'
name()
. See also compound_name_arguments/3.$VAR(N)
,
where N is the number of the variable. Counting starts at
Start. End is unified with the number that should
be given to the next variable. The example below illustrates this. Note
that the toplevel prints '$VAR'(0)
as A due to
the
numbervars(true)
option used to print answers.
?- Term = foo(X,Y,Z), numbervars(Term, 0, End), write_canonical(Term), nl. foo('$VAR'(0),'$VAR'(1),'$VAR'(0)) Term = foo(A, B, A), X = A, Y = B, End = 2.
See also the numbervars
option to write_term/3
and numbervars/4.
$VAR
.skip
, which causes numbervars/3
to ignore the attributed variable, bind
which causes it to
thread it as a normal variable and assign the next '$VAR'
(N)
term to it, or (default)
error
which raises a type_error
exception.85This
behaviour was decided after a long discussion between David Reitter,
Richard O'Keefe, Bart Demoen and Tom Schrijvers.true
(default false
), numbervars/4
does singleton detection. Singleton variables are unified with '$VAR'('_')
,
causing them to be printed as _
by write_term/2
using the numbervars option. This option is exploited by portray_clause/2
and write_canonical/2.bugCurrently
this option is ignored for cyclic terms.
'$VAR'(X)
and opens the path for replacing this valid Prolog term by an internal
representation that has no textual equivalent.library(backcomp)
. The variables in List
are ordered in order of appearance traversing Term
depth-first and left-to-right. See also
term_variables/3.
For example:
?- term_variables(a(X, b(Y, X), Z), L). L = [X, Y, Z].
Prolog is not able to modify instantiated parts of a term. Lacking that capability makes the language much safer, but unfortunately there are problems that suffer severely in terms of time and/or memory usage. Always try hard to avoid the use of these primitives, but they can be a good alternative to using dynamic predicates. See also section 7.3, discussing the use of global variables.
This predicate may be used for destructive assignment to terms, using them as an extra-logical storage bin. Always try hard to avoid the use of setarg/3 as it is not supported by many Prolog systems and one has to be very careful about unexpected copying as well as unexpected noncopying of terms. A good practice to improve somewhat on this situation is to make sure that terms whose arguments are subject to setarg/3 have one unused and unshared variable in addition to the used arguments. This variable avoids unwanted sharing in, e.g., copy_term/2, and causes the term to be considered as non-ground.
setarg(A,T,V,false)
, removing
the type restriction on Value. See also nb_linkarg/3.
Below is an example for counting the number of solutions of a goal. Note
that this implementation is thread-safe, reentrant and capable of
handling exceptions. Realising these features with a traditional
implementation based on assert/retract or flag/3
is much more complicated.
:- meta_predicate succeeds_n_times(0, -). succeeds_n_times(Goal, Times) :- Counter = counter(0), ( Goal, arg(1, Counter, N0), N is N0 + 1, nb_setarg(1, Counter, N), fail ; arg(1, Counter, Times) ).