1:- module(casing, [
    2    casing/3]).

Utilities for letter case

*/

 casing(?Codes, ?Lower, ?CasePattern)
True if a word, given as a code-list Codes, obeys CasePattern, which is one of allcaps, capitalized, and lower, and Lower is the downcased version of Codes. Useful for "factoring out" the casedness information of a string. Extensions to arbitrary case patterns are conceivable but not currently implemented.
   14casing(Codes, Lower, CasePattern) :-
   15  var(Codes),
   16  !,
   17  synthesize_case(Codes, Lower, CasePattern).
   18casing(Codes, Lower, CasePattern) :-
   19  analyze_case(Codes, Lower, CasePattern).
   20
   21analyze_case(Codes, Lower, allcaps) :-
   22  upcase_codes(Codes, Codes),
   23  !,
   24  downcase_codes(Codes, Lower).
   25analyze_case(Codes, Lower, capitalized) :-
   26  Codes = [Code|_],
   27  upcase_codes([Code], [Code]),
   28  !,
   29  downcase_codes(Codes, Lower).
   30analyze_case(Codes, Codes, lower) :-
   31  downcase_codes(Codes, Codes).
   32
   33synthesize_case(Codes, Lower, allcaps) :-
   34  !,
   35  upcase_codes(Lower, Codes).
   36synthesize_case([Code|Codes], [Low|Codes], capitalized) :-
   37  !,
   38  upcase_codes([Low], [Code]).
   39synthesize_case(Codes, Codes, lower).
 upcase_codes(+AnyCaseCodes, -UpperCaseCodes) is det
   42upcase_codes(AnyCaseCodes, UpperCaseCodes) :-
   43  atom_codes(AnyCaseAtom, AnyCaseCodes),
   44  upcase_atom(AnyCaseAtom, UpperCaseAtom),
   45  atom_codes(UpperCaseAtom, UpperCaseCodes).
 downcase_codes(+AnyCaseCodes, -LowerCaseCodes) is det
   48downcase_codes(AnyCaseCodes, LowerCaseCodes) :-
   49  atom_codes(AnyCaseAtom, AnyCaseCodes),
   50  downcase_atom(AnyCaseAtom, LowerCaseAtom),
   51  atom_codes(LowerCaseAtom, LowerCaseCodes)