# Text predicates

Some of the names of the Arity/Prolog32 text predicates are inconsistent. This is because of history - some predicate names have been inherited from the traditional names of predicates used by the originators of the Prolog language, other predicate names are hold-overs from the 16-bit versions of Arity/Prolog which treated atoms and strings as distinct data types. In general, "string", "atom" and "text" are synonymous. Strings are denoted using single-quotes and dollar signs.

Remember that characters (denoted by a back quote) and character lists (denoted by using double-quotes) are integers and integer lists, respectively.

## Searching Text

The predicates in this section have been developed for the manipulation of atoms as strings of text. .

string_search(+SubText, +Text, -Location)

string_search(+Case, +SubText, +Text, -Location)

The string_search/3 and string_search/4 predicates search a piece of text for the occurrence of another piece of text. The string_search/3 predicate is case-sensitive. The string_search/4 predicate allows you to specify whether the search is to be case-sensitive or not. The predicates return all Location results through backtracking.

The arguments to the predicates are:

• The Case argument is an integer indicating whether or not the search should be case-sensitive. If you supply 0 as the Case argument, then the search is case-sensitive (this is the default provided by string_search/3). If you supply 1 as the Case argument, then the search is not case-sensitive.
• SubText is the atom that you are searching for, such as a key word. If you are searching for a single character in a string or atom, you can specify the ASCII code for the character. For example, to search for the character k, you can use either 100 or k or 'k' as the SubText argument.
• The Text argument is the atom that is being searched.
• The Location argument returns the starting point of the subtext. The starting point is zero-based; the first character in a string is at location 0, the second at 1, and so on. The Location is updated to the right for subsequent matches upon backtracking.

In the following example you are searching for the letter 'b' in the string 'abracadabra'. Note that the characters are always counted from zero:

?- string_search(b, 'abracadabra', X).
X = 1 ->;
X = 8 ->;
no

The following example succeeds because the search is not case-sensitive:

?- string_search(1, doe, 'John Doe', X).
X = 5 ->;
no

## Substring, length and concatenation predicates

substring(+Text, +N, +Length, -SubText)

The substring/4 predicate is used to extract a piece of text from another piece of text.

The substring predicate takes four arguments:

• The Text argument is the atom that contains the subtext.
• The N argument specifies the starting location of the subtext. The first character of a piece of text is at location 0.
• The Length argument specifies the length of the subtext, in characters.
• SubText is the variable to which the resulting subtext is returned as a string.

For example, to extract the subtext, 'cde', from the atom, 'abcdefg', you would use substring as follows:

?- substring('abcdefg', 2, 3, X).
X = 'cde'
yes

nth_char(+N, +Text, -Char)

The nth_char/3 predicate returns the ASCII code of the character at a certain offset from the beginning of a piece of text.. The first character is at offset 0.

The nth_char/3 predicate takes the following arguments:

• N is the offset.
• Text is the atom.
• Char is unified with the extracted character.

string_length(+String, -Length)

The string_length/2 predicate returns the length of a piece of text.

concat(+[Text1,Text2, ...], -Result)

concat(+Text1, +Text2, -Result)

The concat/2 and concat/3 predicates are used to concatenate text. The items for concatenation may be atoms or byte integers (ascii characters).

## Text conversion predicates

string_upper(+Text1, -Text2)

string_lower(+Text1, -Text2)

The string_upper/2 and string_lower/2 predicates are used to convert all of the alphabetic characters (a...z and A...Z) in a piece of text to their upper case or lower case equivalents.

name(?AtomOrInt, ?List)

The name/2 predicate is used to convert an atom or integer into a list of ASCII character codes and vice versa.

The predicate name/2 has rather odd behavior in overlaying atom and integer conversion and is maintained for historical reasons. You may wish to consider using list_text/2, int_text/2, float_text/3.

For example:
?- name(quiche,L).
L = [113,117,105,99,104,101]
yes

?- name(X,[114]).
X = r
yes

?- name(quiche,"quiche").
yes

list_text(?List, ?Atom)

The list_text/2 predicate converts a list of ASCII characters to an atom, or converts an atom to a list of characters.

The following examples illustrate two uses of list_text/2.

?- list_text("one",X).
X = 'one'
yes

?- list_text("the restless", 'the restless').
yes

string_term(?Atom, ?Term)

string_termq(?Atom, ?Term)

The string_term/2 and string_termq/2 predicates convert a piece of text to a Prolog term or a Prolog term to a string. They bear strong resemblance to the input and output predicates read/1, write/1 and writeq/1.

If the first argument is instantiated, both string_term/2 and string_termq/2 interpret its content using the same mechanisms as used by the read/1 predicate. The resulting term is unified with the second term. Both predicates are subject to the same syntax error handling as read/1 and syntaxerrors/2.

If the first argument is not instantiated, string_term/2 and string_termq/2 create text using the same mechanisms as write/1 and writeq/1, respectively. The resultant text is unified with the first argument.

In the following example, string_term/2 is used to convert the string 'put(7)' to a single term:

?- string_term('put(7)',X).
X = put(7)
yes

The following examples illustrate the difference between string_term/2 and string_termq/2:

?- string_term(String, a - 'b + c' - d).
String = 'a - b + c - d'
yes

?- string_termq(String, a - 'b + c' - d).
String = 'a - ''b + c'' = d'
yes

int_text(?Integer, ?Atom)

The int_text/2 predicate converts integers to an atom representing the value and vice versa. An integer can be in the range of -2,147,483,648 to 2,147,483,647.

float_text(?Float, ?Atom, ?Format)

The float_text/2 predicate converts a floating-point number to an atom according to the specified textual format, or it converts an atom to a floating-point number.

The Float and the Atom arguments should not be both instantiated because, in general, low significance bits in floating point numbers may differ. Values that appear to match may in fact be different.

If Float is instantiated to a floating-point number the Format argument can be one of the following:

general

Trailing zeros are suppressed.

fixed(N)

N gives the number of decimal places (0 - 15).

scientific(N)

Exponent scientific notation where N gives the number of decimal places. N can be from -308 to 308.

If Atom is instantiated the Format argument is ignored. The predicate returns the floating-point number for that Atom. For example:

?- float_text(X,$1.5E26$,_).
X = 1.5E26
yes

varnames(+Term)

The varnames/1 predicate replaces each variable in a Term with a special internal term that represents a printable variable name. The Arity/Prolog32 term output predicates (such as write/1) recognize this term and will only write the specified name. Each unique variable in a Term is assigned a different name, starting with A and continuing through the alphabet.

If your program needs to output any terms that may contain variables, it may be useful to use the varnames/1 predicate first, so that names are used instead of the Arity/Prolog32 representation of a variable (an underscore followed by a four digit hexadecimal number).

For example:

?- X = x(_,B,C,_,B,_), write(X), nl, varnames(X), write(X).
x(_013C,_0148,_015C,_0168,_0148,_016C)
x(A,B,C,D,B,E)
yes

Note: The varnames/1 predicate unifies the variables of the specified term so that they are no longer variables. If you want the term to continue to contain variables, you should fail after using the varnames/1 predicate so that the variables will become unbound. For example, you could use the following predicate to write a term containing variables and leave them unbound:

var_write(Term) :- varnames(Term),   write(Term), fail.
var_write(Term).

## Deprecated predicates

atom_string(?Atom, ?String)

The atom_string/2 predicate is deprecated and existed only for compatibility with older versions of Arity/Prolog.

The atom_string/2 predicate is defined as:

atom_string(S, S) :- atom(S).`