## 4.21 Analysing and Constructing Atoms

These predicates convert between Prolog constants and lists of character codes. The predicates atom_codes/2, number_codes/2 and name/2 behave the same when converting from a constant to a list of character codes. When converting the other way around, atom_codes/2 will generate an atom, number_codes/2 will generate a number or exception and name/2 will return a number if possible and an atom otherwise.

The ISO standard defines atom_chars/2 to describe the `broken-up' atom as a list of one-character atoms instead of a list of codes. Up-to version 3.2.x, SWI-Prolog's atom_chars/2 behaved, compatible to Quintus and SICStus Prolog, like atom_codes. As of 3.3.x SWI-Prolog atom_codes/2 and atom_chars/2 are compliant to the ISO standard.

To ease the pain of all variations in the Prolog community, all SWI-Prolog predicates behave as flexible as possible. This implies the `list-side' accepts either a code-list or a char-list and the `atom-side' accept all atomic types (atom, number and string).

atom_codes(?Atom, ?String)
  Convert between an atom and a list of character codes. If Atom is instantiated, if will be translated into a list of character codes and the result is unified with String. If Atom is unbound and String is a list of character codes, it will Atom will be unified with an atom constructed from this list.
atom_chars(?Atom, ?CharList)
  As atom_codes/2, but CharList is a list of one-character atoms rather than a list of character codes46Up-to version 3.2.x, atom_chars/2 behaved as the current atom_codes/2. The current definition is compliant with the ISO standard.

      ?- atom_chars(hello, X).

      X = [h, e, l, l, o]

char_code(?Atom, ?Code)
  Convert between character and character code for a single character.47This is also called atom_char/2 in older versions of SWI-Prolog as well as some other Prolog implementations. The atom_char/2 predicate is available from the library `backcomp.pl`
number_chars(?Number, ?CharList)
  Similar to atom_chars/2, but converts between a number and its representation as a list of one-character atoms. Fails with a `representation_error` if Number is unbound and CharList does not describe a number.
number_codes(?Number, ?CodeList)
  As number_chars/2, but converts to a list of character codes rather than one-character atoms. In the mode -, +, both predicates behave identically to improve handling of non-ISO source.
atom_number(?Atom, ?Number)
  Realises the popular combination of atom_codes/2 and number_codes/2 to convert between atom and number (integer or float) in one predicate, avoiding the intermediate list.
name(?AtomOrInt, ?String)
  String is a list of character codes representing the same text as Atom. Each of the arguments may be a variable, but not both. When String is bound to an character code list describing an integer and Atom is a variable Atom will be unified with the integer value described by String (e.g. ``name(N, "300"), 400 is N + 100`' succeeds).
term_to_atom(?Term, ?Atom)
  True if Atom describes a term that unifies with Term. When Atom is instantiated Atom is converted and then unified with Term. If Atom has no valid syntax, a `syntax_error` exception is raised. Otherwise Term is ``written'' on Atom using write/1.
atom_to_term(+Atom, -Term, -Bindings)
  Use Atom as input to read_term/2 using the option `variable_names` and return the read term in Term and the variable bindings in Bindings. Bindings is a list of Name = Var couples, thus providing access to the actual variable names. See also read_term/2. If Atom has no valid syntax, a `syntax_error` exception is raised.
atom_concat(?Atom1, ?Atom2, ?Atom3)
  Atom3 forms the concatenation of Atom1 and Atom2. At least two of the arguments must be instantiated to atoms, integers or floating point numbers. For ISO compliance, the instantiation-pattern -, -, + is allowed too, non-deterministically splitting the 3-th argument into two parts (as append/3 does for lists). See also string_concat/3.
concat_atom(+List, -Atom)
  List is a list of atoms, integers or floating point numbers. Succeeds if Atom can be unified with the concatenated elements of List. If List has exactly 2 elements it is equivalent to atom_concat/3, allowing for variables in the list.
concat_atom(?List, +Separator, ?Atom)
  Creates an atom just like concat_atom/2, but inserts Separator between each pair of atoms. For example:

      ?- concat_atom([gnu, gnat], ', ', A).

      A = 'gnu, gnat'

  This predicate can also be used to split atoms by instantiating Separator and Atom:

      ?- concat_atom(L, -, 'gnu-gnat').

      L = [gnu, gnat]

atom_length(+Atom, -Length)
  True if Atom is an atom of Length characters long. This predicate also works for strings (see section 4.23). If the prolog flag `iso` is not set, it also accepts integers and floats, expressing the number of characters output when given to write/1 as well as code-lists and character-lists, expressing the length of the list.bugNote that `[]` is both an atom an empty code/character list. The predicate atom_length/2 returns 2 for this atom.
atom_prefix(+Atom, +Prefix)
  True if Atom starts with the characters from Prefix. Its behaviour is equivalent to `?- sub_atom(Atom, 0, _, _, Prefix)`. Depreciated.
sub_atom(+Atom, ?Before, ?Len, ?After, ?Sub)
  ISO predicate for breaking atoms. It maintains the following relation: Sub is a sub-atom of Atom that starts at Before, has Len characters and Atom contains After characters after the match.

      ?- sub_atom(abc, 1, 1, A, S).

      A = 1, S = b

  The implementation minimises non-determinism and creation of atoms. This is a very flexible predicate that can do search, prefix- and suffix-matching, etc.