Term processing
Author: Daniel Diaz
Keywords: GNU Prolog, manual, Prolog, compiler, constraints, finite domains

### 8.4 Term processing

- functor/3
- arg/3
- (=..)/2 - univ
- copy_term/2
- term_variables/2, term_variables/3
- subsumes_term/2
- acyclic_term/1
- term_hash/4, term_hash/2
- setarg/4, setarg/3

#### 8.4.1 functor/3

Templates

  functor(+nonvar, ?atomic, ?integer)
  functor(-nonvar, +atomic, +integer)

Description

functor(Term, Name, Arity) succeeds if the principal functor of Term is Name and its arity is Arity. This predicate can be used in two ways:

- Term is not a variable: extract the name (an atom or a number if Term is a number) and the arity of Term (if Term is atomic Arity = 0).
- Term is a variable: unify Term with a general term whose principal functor is given by Name and arity is given by Arity.

Errors

Term and Name are both variables |  | instantiation_error
Term and Arity are both variables |  | instantiation_error
Term is a variable and Name is neither a variable nor an atomic term |  | type_error(atomic, Name)
Term is a variable and Arity is neither a variable nor an integer |  | type_error(integer, Arity)
Term is a variable, Name is a constant but not an atom and Arity is an integer > 0 |  | type_error(atom, Name)
Term is a variable and Arity is an integer > max_arity flag (section 8.22.1) |  | representation_error(max_arity)
Term is a variable and Arity is an integer < 0 |  | domain_error(not_less_than_zero, Arity)

Portability

ISO predicate.

#### 8.4.2 arg/3

Templates

  arg(+integer, +compound_term, ?term)

Description

arg(N, Term, Arg) succeeds if the Nth argument of Term is Arg.

Errors

N is a variable |  | instantiation_error
Term is a variable |  | instantiation_error
N is neither a variable nor an integer |  | type_error(integer, N)
Term is neither a variable nor a compound term |  | type_error(compound, Term)
N is an integer < 0 |  | domain_error(not_less_than_zero, N)

Portability

ISO predicate.

#### 8.4.3 (=..)/2 - univ

Templates

  =..(+nonvar, ?list)
  =..(-nonvar, +list)

Description

Term =.. List succeeds if List is a list whose head is the atom corresponding to the principal functor of Term and whose tail is a list of the arguments of Term.

=.. is a predefined infix operator (section 8.14.10).

Errors

Term is a variable and List is a partial list |  | instantiation_error
List is neither a partial list nor a list |  | type_error(list, List)
Term is a variable and List is a list whose head is a variable |  | instantiation_error
List is a list whose head H is neither an atom nor a variable and whose tail is not the empty list |  | type_error(atom, H)
List is a list whose head H is a compound term and whose tail is the empty list |  | type_error(atomic, H)
Term is a variable and List is the empty list |  | domain_error(non_empty_list, [])
Term is a variable and the tail of List has a length > max_arity flag (section 8.22.1) |  | representation_error(max_arity)

Portability

ISO predicate.

#### 8.4.4 copy_term/2

Templates

  copy_term(?term, ?term)

Description

copy_term(Term1, Term2) succeeds if Term2 unifies with a term T which is a renamed copy of Term1.

Errors

None.

Portability

ISO predicate.

#### 8.4.5 term_variables/2, term_variables/3

Templates

  term_variables(?term, ?list)
  term_variables(?term, ?list, ?list)

Description

term_variables(Term, List) succeeds if List unifies with a list of variables (including FD variables), each sharing with a unique variable of Term. The variables in List are ordered in order of appearance traversing Term depth-first and left-to-right.

term_variables(Term, List, Tail) is a difference-list version of the above predicate, i.e. Tail is the tail of the variable-list List.

Errors

in term_variables/2 List is neither a partial list nor a list |  | type_error(list, List)

Portability

term_variables/2 is an ISO Predicate. term_variables/3 is a GNU Prolog predicate.

#### 8.4.6 subsumes_term/2

Templates

  subsumes_term(?term, ?term)

Description

subsumes_term(General, Specific) succeeds if General can be made equivalent to Specific by binding variables in General leaving Specific unaffected. The current implementation performs the unification (with occurs check) and ensures that the variable set of Specific is not changed by the unification (which is then undone). Note that this predicate fails in the presence of FD variables in Specific.

Errors

None.

Portability

ISO predicate.

#### 8.4.7 acyclic_term/1

Templates

  acyclic_term(?term)

Description

acyclic_term(Term) succeeds if Term does not contain a cyclic (sub-)term. In this case, Term may be processed safely. If acyclic_term(Term) fails, Term contains a cycle and processing Term is not safe, because GNU Prolog does not support the unification of cyclic terms but permits their creation. Cycles can be safely undone by failing over their creation. The use of acyclic_term/1 shall thus be reserved to protect critical predicates against cyclic terms.

Errors

None.

Portability

ISO predicate.

#### 8.4.8 term_hash/4, term_hash/2

Templates

  term_hash(?term, +integer, +integer, ?integer)
  term_hash(?term, ?integer)

Description

term_hash(Term, Depth, Range, Hash) succeeds if Hash is the hash code of Term. If Term is not ground (see ground/1 (section 8.1.1)), the predicate simply succeeds (Hash is not unified). Depth is the depth limit to scan Term (starting from 1 for the top-level term). With Depth = 0 nothing is hashed, with 1 only atomic terms and the main functors/arity are hashed,... With Depth = -1 the full term is considered.

The hash code is as follows: 0 ≤ Hash < Range. If Range = 0 then Hash is not restricted (currently it is < 268435456).

term_hash(Term, Hash) is equivalent to term_hash(Term, -1, 0, Hash).

NB: the computed hash code is independent of any runtime context (i.e. it is constant across different executions). It is also independent on the underlying machine.

These predicates are useful to implement hash tables or argument indexing.

Errors

Depth is a variable |  | instantiation_error
Depth is neither a variable nor an integer |  | type_error(integer, Depth)
Range is a variable |  | instantiation_error
Range is neither a variable nor an integer |  | type_error(integer, Range)
Range is an integer < 0 |  | domain_error(not_less_than_zero, Range)
Hash is neither a variable nor an integer |  | type_error(integer, Hash)

Portability

GNU Prolog predicate.

#### 8.4.9 setarg/4, setarg/3

Templates

  setarg(+integer, +compound_term, +term, +boolean)
  setarg(+integer, +compound_term, +term)

Description

setarg(N, Term, NewValue, Undo) replaces destructively the Nth argument of Term with NewValue. This assignment is undone on backtracking if Undo = true. This should only used if there is no further use of the old value of the replaced argument. If Undo = false then NewValue must be either an atom or an integer.

setarg(N, Term, NewValue) is equivalent to setarg(N, Term, NewValue, true).

Errors

N is a variable |  | instantiation_error
N is neither a variable nor an integer |  | type_error(integer, N)
N is an integer < 0 |  | domain_error(not_less_than_zero, N)
Term is a variable |  | instantiation_error
Term is neither a variable nor a compound term |  | type_error(compound, Term)
NewValue is neither an atom nor an integer and Undo = false |  | type_error(atomic, NewValue)
Undo is a variable |  | instantiation_error
Undo is neither a variable nor a boolean |  | type_error(boolean, Undo)

Portability

GNU Prolog predicate.

Copyright (C) 1999-2021 Daniel Diaz Verbatim copying and distribution of this entire article is permitted in any medium, provided this notice is preserved. More about the copyright