## 4.22 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-bit ASCII character (0..127).
  white
    Char is a space or tab, i.e. white space inside a line.
  cntrl
    Char is an ASCII control character (0..31).
  digit
    Char is a digit.
  digit(Weight)
    Char is a digit with value Weight. I.e. `char_type(X, digit(6)` yields X = `'6'`. Useful for parsing numbers.
  xdigit(Weight)
    Char is a hexadecimal digit with value Weight. 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 lowercase letter.
  lower(Upper)
    Char is a lowercase version of Upper. Only true if Char is lowercase and Upper uppercase.
  to_lower(Upper)
    Char is a lowercase 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 uppercase letter.
  upper(Lower)
    Char is an uppercase version of Lower. Only true if Char is uppercase and Lower lowercase.
  to_upper(Lower)
    Char is an uppercase 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 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 will instantiate only with an integer code or a one-character atom, depending of the version used. See also the Prolog flag double_quotes, atom_chars/2 and atom_codes/2.

### 4.22.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 uppercase.

### 4.22.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 replaced by a single space (`\u0020`) character. Out uses the same conventions as with_output_to/2 and format/3.

### 4.22.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.23). 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.