## 4.21 Character properties

SWI-Prolog offers two comprehensive predicates for classifying characters and character-codes. These predicates are defined as built-in predicates to exploit the C-character classification's handling of locale (handling of local character-sets). These predicates are fast, logical and deterministic if applicable.

In addition, there is the library `library(ctype)` providing compatibility with some other Prolog systems. The predicates of this library are defined in terms of code_type/2.

char_type(?Char, ?Type)
  Tests or generates alternative Types or Chars. The character-types are inspired by the standard C `<ctype.h>` primitives.
  alnum
    Char is a letter (upper- or lowercase) or digit.
  alpha
    Char is a letter (upper- or lowercase).
  csym
    Char is a letter (upper- or lowercase), digit or the underscore (`_`). These are valid C- and Prolog symbol characters.
  csymf
    Char is a letter (upper- or lowercase) or the underscore (`_`). These are valid first characters for C- and Prolog symbols
  ascii
    Char is a 7-bits ASCII character (0..127).
  white
    Char is a space or tab. E.i. white space inside a line.
  cntrl
    Char is an ASCII control-character (0..31).
  digit
    Char is a digit.
  digit(Weigth)
    Char is a digit with value Weigth. I.e. `char_type(X, digit(6)` yields X = `'6'`. Useful for parsing numbers.
  xdigit(Weigth)
    Char is a hexa-decimal digit with value Weigth. I.e. `char_type(a, xdigit(X)` yields X = `'10'`. Useful for parsing numbers.
  graph
    Char produces a visible mark on a page when printed. Note that the space is not included!
  lower
    Char is a lower-case letter.
  lower(Upper)
    Char is a lower-case version of Upper. Only true if Char is lowercase and Upper uppercase.
  to_lower(Upper)
    Char is a lower-case version of Upper. For non-letters, or letter without case, Char and Lower are the same. See also upcase_atom/2 and downcase_atom/2.
  upper
    Char is an upper-case letter.
  upper(Lower)
    Char is an upper-case version of Lower. Only true if Char is uppercase and Lower lowercase.
  to_upper(Lower)
    Char is an upper-case version of Lower. For non-letters, or letter without case, Char and Lower are the same. See also upcase_atom/2 and downcase_atom/2.
  punct
    Char is a punctuation character. This is a `graph` character that is not a letter or digit.
  space
    Char is some form of layout character (tab, vertical-tab, newline, etc.).
  end_of_file
    Char is -1.
  end_of_line
    Char ends a line (ASCII: 10..13).
  newline
    Char is a the newline character (10).
  period
    Char counts as the end of a sentence (.,!,?).
  quote
    Char is a quote-character (`"`, `'`, ```).
  paren(Close)
    Char is an open-parenthesis and Close is the corresponding close-parenthesis.
code_type(?Code, ?Type)
  As char_type/2, but uses character-codes rather than one-character atoms. Please note that both predicates are as flexible as possible. They handle either representation if the argument is instantiated and only will instantiate with an integer code or one-character atom depending of the version used. See also the Prolog flag double_quotes, atom_chars/2 and atom_codes/2.

### 4.21.1 Case conversion

There is nothing in the Prolog standard for converting case in textual data. The SWI-Prolog predicates code_type/2 and char_type/2 can be used to test and convert individual characters. We have started some additional support:

downcase_atom(+AnyCase, -LowerCase)
  Converts the characters of AnyCase into lowercase as char_type/2 does (i.e. based on the defined locale if Prolog provides locale support on the hosting platform) and unifies the lowercase atom with LowerCase.
upcase_atom(+AnyCase, -UpperCase)
  Converts, similar to downcase_atom/2, an atom to upper-case.

### 4.21.2 White space normalization

normalize_space(-Out, +In)
  Normalize white space in In. All leading and trailing white space is removed. All non-empty sequences for Unicode white space characters are replaces by a single space (`\u0020`) character. Out uses the same conventions as with_output_to/2 and format/3.

### 4.21.3 Language specific comparison

This section deals with predicates for language specific string comparison operations.

collation_key(+Atom, -Key)
  Create a Key from Atom for locale specific comparison. The key is defined such that if the key of atom A precedes the key of atom B in the standard order of terms, A is alphabetically smaller than B using the sort order of the current locale.

  The predicate collation_key/2 is used by locale_sort/2 from library(sort). Please examine the implementation of locale_sort/2 as an example of using this call.

  The Key is an implementation defined and generally unreadable string. On systems that do not support locale-handling, Key is simply unified with Atom.

locale_sort(+List, -Sorted)
  Sort a list of atoms using the current locale. List is a list of atoms or string objects (see section 4.22). Sorted is unified with a list containing all atoms of List, sorted to the rules of the current locale. See also collation_key/2 and setlocale/3.