Atomic term processing

6.19 | Atomic term processing

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.

6.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.

6.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.

6.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.

6.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.

6.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.

6.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)`
`Atom` is a variable and an element `E` of the list `Chars` is neither a variable nor a one-char atom |  | `type_error(character, E)`
`Atom` is a variable and an element `E` of the list `Codes` is neither a variable nor an integer |  | `type_error(integer, E)`
`Atom` is a variable and 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`).

6.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 character codes.
`number_codes(Number, Codes)` is similar to `number_atom/2` but deals with a list of characters.
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)`
`Number` is a variable and `Chars` is neither a list nor a partial list |  | `type_error(list, Chars)`
`Number` is a variable and `Codes` is neither a list nor a partial list |  | `type_error(list, Codes)`
`Number` is a variable and an element `E` of the list `Chars` is neither a variable nor a one-char atom |  | `type_error(character, E)`
`Number` is a variable and an element `E` of the list `Codes` is neither a variable nor an integer |  | `type_error(integer, E)`
`Number` is a variable and 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 6.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`).

6.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 6.19.6) or number_chars/2 (section 6.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.

6.19.9 | `atom_hash/2`

Templates

  `atom_hash(+atom, ?integer)
  atom_hash(?atom, +integer)`

Description
`atom_hash(Atom, Hash)` succeeds if `Hash` is the internal key associated to `Atom` (an existing atom). The internal key of an atom is a unique integer ³ 0 and < to the `max_atom` Prolog flag (section 6.22.1).
Errors

`Atom` and `Hash` are both variables |  | `instantiation_error`
`Atom` is neither a variable nor an atom |  | `type_error(atom, Atom)`
`Hash` is neither a variable nor an integer |  | `type_error(integer, Hash)`
`Hash` is an integer < 0 |  | `domain_error(not_less_than_zero, Hash)`

Portability
GNU Prolog predicate.

6.19.10 | `new_atom/3`, `new_atom/2`, `new_atom/1`

Templates

  `new_atom(+atom, +integer, -atom)
  new_atom(+atom, -atom)
  new_atom(-atom)`

Description
`new_atom(Prefix, Hash, Atom)` unifies `Atom` with a new atom whose name begins with the characters of the name of `Prefix` and whose internal key is `Hash` (section 6.19.9). 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), `0`-`9` (digit), `#`, `$`, `&`, `_`, `@`.
`new_atom/2` is similar to `new_atom/3`, but the atom generated can have any (free) internal key.
`new_atom/1` is similar to `new_atom(atom_, Atom)`, i.e. the generated atom begins with `atom_`.
Errors

`Prefix` is a variable |  | `instantiation_error`
`Hash` is a variable |  | `instantiation_error`
`Prefix` is neither a variable nor an atom |  | `type_error(atom, Prefix)`
`Hash` is neither a variable nor an integer |  | `type_error(integer, Hash)`
`Hash` is an integer < 0 |  | `domain_error(not_less_than_zero, Hash)`
`Atom` is not a variable |  | `type_error(variable, Atom)`

Portability
GNU Prolog predicate.

6.19.11 | `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.

6.19.12 | `atom_property/2`

Templates

  `atom_property(?atom, ?atom_property)`

Description
`atom_property(Atom, Property)` succeeds if `current_atom(Atom)` succeeds (section 6.19.11) 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 internal key of the atom (section 6.19.9).
- `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,2000 Daniel Diaz
Verbatim copying and distribution of this entire article is permitted in any medium, provided this notice is preserved.
More about the copyright