- [ISO]
**functor**(`?Term, ?Functor, ?Arity`) -
True if
`Term`is a term with functor`Functor`and arity`Arity`. If`Term`is a variable it is unified with a new term holding only variables. functor/3 silently fails on instantiation faults^{45In version 1.2 instantiation faults led to error messages. The new version can be used to do type testing without the need to catch illegal instantiations first.}If`Term`is an atom or number,`Functor`will be unified with`Term`and arity will be unified with the integer 0 (zero). - [ISO]
**arg**(`?Arg, +Term, ?Value`) -
`Term`should be instantiated to a term,`Arg`to an integer between 1 and the arity of`Term`.`Value`is unified with the`Arg`-th argument of`Term`.`Arg`may also be unbound. In this case`Value`will be unified with the successive arguments of the term. On successful unification,`Arg`is unified with the argument number. Backtracking yields alternative solutions.^{46The instantiation pattern (-, +, ?) is an extension to `standard' Prolog. Some systems provide genarg/3 that covers this pattern.}The predicate arg/3 fails silently ifor`Arg`= 0and raises the exception`Arg`>*arity*`domain_error(not_less_then_zero,`

if`Arg`).`Arg`< 0 - [ISO]
`?Term`**=..**`?List` -
`List`is a list which head is the functor of`Term`and the remaining arguments are the arguments of the term. Each of the arguments may be a variable, but not both. This predicate is called `Univ'. Examples:?- foo(hello, X) =.. List. List = [foo, hello, X] ?- Term =.. [baz, foo(1)] Term = baz(foo(1))

**numbervars**(`+Term, +Start, -End`)-
Unify the free variables of
`Term`with a term`$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. Example:?- numbervars(foo(A, B, A), 0, End). A = '$VAR'(0) B = '$VAR'(1) End = 2

See also the

`numbervars`

option to write_term/3 and numbervars/4. **numbervars**(`+Term, +Start, -End, +Options`)-
As numbervars/3,
but providing the following options:
**functor_name**(`+Atom`)-
Name of the functor to use instead of
`$VAR`

. **attvar**(`+Action`)-
What to do if an attributed variable is encountered. Options are
`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 the a`type_error`

exception.^{47This behaviour was decided after a long discussion between David Reitter, Richard O'Keefe, Bart Demoen and Tom Schrijvers.} **singletons**(`+Bool`)-
If
`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.}

**term_variables**(`+Term, -List`)-
Unify
`List`with a list of variables, each sharing with a unique variable of`Term`.^{48This predicate used to be called free_variables/2 . The name term_variables/2 is more widely used. The old predicate is still available from the library 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 = [G367, G366, G371] X = G367 Y = G366 Z = G371

**term_variables**(`+Term, -List, ?Tail`)-
Difference list version of term_variables/2.
I.e.
`Tail`is the tail of the variable-list`List`. - [ISO]
**copy_term**(`+In, -Out`) -
Create a version if
`In`with renamed (fresh) variables and unify it to`Out`. Attributed variables (see section 6.1) have their attributed copied. The implementation of copy_term/2 can deal with infinite trees (cyclic terms). As pure Prolog cannot distinguish a ground term from another ground term with exactly the same structure, ground sub-terms are*shared*between`In`and`Out`. Sharing ground terms does affect setarg/3. SWI-Prolog provides duplicate_term/2 to create a true copy of a term.

Prolog is not capable to *modify* instantiated parts of a
term. Lacking that capability makes that 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 6.3,
discussing the use of global variables.

**setarg**(`+Arg, +Term, +Value`)-
Extra-logical predicate. Assigns the
`Arg`-th argument of the compound term`Term`with the given`Value`. The assignment is undone if backtracking brings the state back into a position before the setarg/3 call. See also nb_setarg/3.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 not copying of terms.

**nb_setarg**(`+Arg, +Term, +Value`)-
Assigns the
`Arg`-th argument of the compound term`Term`with the given`Value`as setarg/3, but on backtracking the assignment is*not*reversed. If`Term`is not atomic, it is duplicated using duplicate_term/2. This predicate uses the same technique as nb_setval/2. We therefore refer to the description of nb_setval/2 for details on non-backtrackable assignment of terms. This predicate is compatible to GNU-Prolog`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.:- module_transparent succeeds_n_times/2. 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) ).

**nb_linkarg**(`+Arg, +Term, +Value`)-
As nb_setarg/3,
but like nb_linkval/2
it does
*not*duplicate`Value`. Use with extreme care and consult the documentation of nb_linkval/2 before use. **duplicate_term**(`+In, -Out`)- Version of copy_term/2 that also copies ground terms and therefore ensures destructive modification using setarg/3 does not affect the copy. See also nb_setval/2, nb_linkval/2, nb_setarg/3 and nb_linkarg/3.
- [semidet]
**same_term**(`@T1, @T2`) -
True if
`T1`and`T2`are the equivalent and will remain the equivalent, even if setarg/3 is used on either of them. This means`T1`and`T2`are the same variable, equivalent atomic data or a compound term allocated at the same address.