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

### 8.19 Atomic term processing

- atom_length/2
- atom_concat/3
- sub_atom/5
- char_code/2
- lower_upper/2
- atom_chars/2, atom_codes/2
- number_atom/2, number_chars/2, number_codes/2
- name/2
- new_atom/2, new_atom/1
- current_atom/1
- atom_property/2

These built-in predicates enable atomic terms to be processed as a sequence of characters and character codes. Facilities exist to split and join atoms, to convert a single character to and from the corresponding character code, and to convert a number to and from a list of characters and character codes.

#### 8.19.1 atom_length/2

Templates

  atom_length(+atom, ?integer)

Description

atom_length(Atom, Length) succeeds if Length unifies with the number of characters of the name of Atom.

Errors

Atom is a variable |  | instantiation_error
Atom is neither a variable nor an atom |  | type_error(atom, Atom)
Length is neither a variable nor an integer |  | type_error(integer, Length)
Length is an integer < 0 |  | domain_error(not_less_than_zero, Length)

Portability

ISO predicate.

#### 8.19.2 atom_concat/3

Templates

  atom_concat(+atom, +atom, ?atom)
  atom_concat(?atom, ?atom, +atom)

Description

atom_concat(Atom1, Atom2, Atom12) succeeds if the name of Atom12 is the concatenation of the name of Atom1 with the name of Atom1. This predicate is re-executable on backtracking (e.g. if Atom12 is instantiated and both Atom1 and Atom2 are variables).

Errors

Atom1 and Atom12 are variables |  | instantiation_error
Atom2 and Atom12 are variables |  | instantiation_error
Atom1 is neither a variable nor an atom |  | type_error(atom, Atom1)
Atom2 is neither a variable nor an atom |  | type_error(atom, Atom2)
Atom12 is neither a variable nor an atom |  | type_error(atom, Atom12)

Portability

ISO predicate.

#### 8.19.3 sub_atom/5

Templates

  sub_atom(+atom, ?integer, ?integer, ?integer, ?atom)

Description

sub_atom(Atom, Before, Length, After, SubAtom) succeeds if atom Atom can be split into three atoms, AtomL, SubAtom and AtomR such that Before is the number of characters of the name of AtomL, Length is the number of characters of the name of SubAtom and After is the number of characters of the name of AtomR. This predicate is re-executable on backtracking.

Errors

Atom is a variable |  | instantiation_error
Atom is neither a variable nor an atom |  | type_error(atom, Atom)
SubAtom is neither a variable nor an atom |  | type_error(atom, SubAtom)
Before is neither a variable nor an integer |  | type_error(integer, Before)
Length is neither a variable nor an integer |  | type_error(integer, Length)
After is neither a variable nor an integer |  | type_error(integer, After)
Before is an integer < 0 |  | domain_error(not_less_than_zero, Before)
Length is an integer < 0 |  | domain_error(not_less_than_zero, Length)
After is an integer < 0 |  | domain_error(not_less_than_zero, After)

Portability

ISO predicate.

#### 8.19.4 char_code/2

Templates

  char_code(+character, ?character_code)
  char_code(-character, +character_code)

Description

char_code(Char, Code) succeeds if the character code for the one-char atom Char is Code.

Errors

Char and Code are variables |  | instantiation_error
Char is neither a variable nor a one-char atom |  | type_error(character, Char)
Code is neither a variable nor an integer |  | type_error(integer, Code)
Code is an integer but not a character code |  | representation_error(character_code)

Portability

ISO predicate.

#### 8.19.5 lower_upper/2

Templates

  lower_upper(+character, ?character)
  lower_upper(-character, +character)

Description

lower_upper(Char1, Char2) succeeds if Char1 and Char2 are one-char atoms and if Char2 is the upper conversion of Char1. If Char1 (resp. Char2) is a character that is not a lower (resp. upper) letter then Char2 is equal to Char1.

Errors

Char1 and Char2 are variables |  | instantiation_error
Char1 is neither a variable nor a one-char atom |  | type_error(character, Char1)
Char2 is neither a variable nor a one-char atom |  | type_error(character, Char2)

Portability

GNU Prolog predicate.

#### 8.19.6 atom_chars/2, atom_codes/2

Templates

  atom_chars(+atom, ?character_list)
  atom_chars(-atom, +character_list)
  atom_codes(+atom, ?character_code_list)
  atom_codes(-atom, +character_code_list)

Description

atom_chars(Atom, Chars) succeeds if Chars is the list of one-char atoms whose names are the successive characters of the name of Atom.

atom_codes(Atom, Codes) is similar to atom_chars/2 but deals with a list of character codes.

Errors

Atom is a variable and Chars (or Codes) is a partial list or a list with an element which is a variable |  | instantiation_error
Atom is neither a variable nor an atom |  | type_error(atom, Atom)
Chars is neither a list nor a partial list |  | type_error(list, Chars)
Codes is neither a list nor a partial list |  | type_error(list, Codes)
An element E of the list Chars is neither a variable nor a one-char atom |  | type_error(character, E)
An element E of the list Codes is neither a variable nor an integer |  | type_error(integer, E)
An element E of the list Codes is an integer but not a character code |  | representation_error(character_code)

Portability

ISO predicates. The ISO reference only causes a type_error(list, Chars) if Atom is a variable and Chars is neither a list nor a partial list. GNU Prolog always checks if Chars is a list. Similarly for Codes. The type_error(integer, E) when an element E of the Codes is not an integer is a GNU Prolog extension. This seems to be an omission in the ISO reference since this error is detected for many other built-in predicates accepting a character code (e.g. char_code/2, put_code/2).

#### 8.19.7 number_atom/2, number_chars/2, number_codes/2

Templates

  number_atom(+number, ?atom)
  number_atom(-number, +atom)
  number_chars(+number, ?character_list)
  number_chars(-number, +character_list)
  number_codes(+number, ?character_code_list)
  number_codes(-number, +character_code_list)

Description

number_atom(Number, Atom) succeeds if Atom is an atom whose name corresponds to the characters of Number.

number_chars(Number, Chars) is similar to number_atom/2 but deals with a list of characters.

number_codes(Number, Codes) is similar to number_atom/2 but deals with a list of character codes.

Errors

Number and Atom are variables |  | instantiation_error
Number is a variable and Chars (or Codes) is a partial list or a list with an element which is a variable |  | instantiation_error
Number is neither a variable nor an number |  | type_error(number, Number)
Atom is neither a variable nor an atom |  | type_error(atom, Atom)
Chars is neither a list nor a partial list |  | type_error(list, Chars)
Codes is neither a list nor a partial list |  | type_error(list, Codes)
An element E of the list Chars is neither a variable nor a one-char atom |  | type_error(character, E)
An element E of the list Codes is neither a variable nor an integer |  | type_error(integer, E)
An element E of the list Codes is an integer but not a character code |  | representation_error(character_code)
Number is a variable, Atom (or Chars or Codes) cannot be parsed as a number and the value of the syntax_error Prolog flag is error (section 8.22.1) |  | syntax_error(atom explaining the error)

Portability

number_atom/2 is a GNU Prolog predicate. number_chars/2 and number_codes/2 are ISO predicates.

GNU Prolog only raises an error about an element E of the Chars (or Codes) list when Number is a variable while the ISO reference always check this. This seems an error since the list itself is only checked if Number is a variable.

The type_error(integer, E) when an element E of the Codes is not an integer is a GNU Prolog extension. This seems to be an omission in the ISO reference since this error is detected for many other built-in predicates accepting a character code (e.g. char_code/2, put_code/2).

#### 8.19.8 name/2

Templates

  name(+atomic, ?character_code_list)
  name(-atomic, +character_code_list)

Description

name(Constant, Codes) succeeds if Codes is a list whose elements are the character codes corresponding to the successive characters of Constant (a number or an atom). However, there atoms are for which name(Constant, Codes) is true, but which will not be constructed if name/2 is called with Constant uninstantiated, e.g. the atom ’1024’. For this reason the use of name/2 is discouraged and should be limited to compatibility purposes. It is preferable to use atom_codes/2 (section 8.19.6) or number_chars/2 (section 8.19.7).

Errors

Constant is a variable and Codes is a partial list or a list with an element which is a variable |  | instantiation_error
Constant is neither a variable nor an atomic term |  | type_error(atomic, Constant)
Constant is a variable and Codes is neither a list nor a partial list |  | type_error(list, Codes)
Constant is a variable and an element E of the list Codes is neither a variable nor an integer |  | type_error(integer, E)
Constant is a variable and an element E of the list Codes is an integer but not a character code |  | representation_error(character_code)

Portability

GNU Prolog predicate.

#### 8.19.9 new_atom/2, new_atom/1

Templates

  new_atom(+atom, -atom)
  new_atom(-atom)

Description

new_atom(Prefix, Atom) unifies Atom with a new atom whose name begins with the characters of the name of Prefix. This predicate is then a symbol generator. It is guaranteed that Atom does not exist before the invocation of new_atom/3. The characters appended to Prefix to form Atom are in: A-Z (capital letter), a-z (small letter) and 0-9 (digit).

new_atom/1 is similar to new_atom(term_, Atom), i.e. the generated atom begins with term_.

Errors

Prefix is a variable |  | instantiation_error
Prefix is neither a variable nor an atom |  | type_error(atom, Prefix)
Atom is not a variable |  | uninstantiation_error(Atom)

Portability

GNU Prolog predicate.

#### 8.19.10 current_atom/1

Templates

  current_atom(?atom)

Description

current_atom(Atom) succeeds if there exists an atom that unifies with Atom. All atoms are found except those beginning with a ’$’ (system atoms). This predicate is re-executable on backtracking.

Errors

Atom is neither a variable nor an atom |  | type_error(atom, Atom)

Portability

GNU Prolog predicate.

#### 8.19.11 atom_property/2

Templates

  atom_property(?atom, ?atom_property)

Description

atom_property(Atom, Property) succeeds if current_atom(Atom) succeeds (section 8.19.10) and if Property unifies with one of the properties of the atom. This predicate is re-executable on backtracking.

Atom properties:

- length(Length): Length is the length of the name of the atom.
- hash(Hash): Hash is the hash code of the atom, see also term_hash/2 (section 8.4.8).
- prefix_op: if there is a prefix operator currently defined with this name.
- infix_op: if there is an infix operator currently defined with this name.
- postfix_op: if there is a postfix operator currently defined with this name.
- needs_quotes: if the atom must be quoted to be read later.
- needs_scan: if the atom must be scanned when output to be read later (e.g. contains special characters that must be output with a \ escape sequence).

Errors

Atom is neither a variable nor an atom |  | type_error(atom, Atom)
Property is neither a variable nor a n atom property term |  | domain_error(atom_property, Property)
Property = length(E) or hash(E) and E is neither a variable nor an integer |  | type_error(integer, E)

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