There are two approaches to concatenation. One is to provide a concatenation function that takes some number of text objects and yields their concatenation. The other is to provide a concatenation relation.

Quintus Prolog provides a built-in concatenation relation for lists, namely append/3. This concatenation relation can perforce be applied to lists of character codes.

     | ?- ensure_loaded(library(printchars)).
     | ?- append("app", "end", X).
     X = "append"
     | ?- append(X, "end", "intend").
     X = "int"
     | ?- append(_, [C|_], "to be written"),
     |    put(C), fail.
     to be written

library(strings) contains a concatenation relation for text objects. This relation was inherited from the DEC-10 Prolog library. The original code was written to support gensym/2 (described in lib-txp-ato) and then generalized.

concat(?Text1, +Constant2, ?Text3)
is true when Text1 and Text3 are the same kind of text object, Constant2 is any sort of constant, and
          name(Text1, Name1),
          name(Constant2, Name2),
          name(Text3, Name3),
          append(Name1, Name2, Name3)

is true. It can be used to solve for Text1 given the other two arguments or to solve for Text3 given the other two arguments, but unlike append/3 it cannot be used to solve for Constant2.

This definition is retained for backwards compatibility with the DEC-10 Prolog and C-Prolog libraries, and with earlier versions of the Quintus library. concat/3 may be removed from future versions of the Quintus library.

There is a proper concatenation relation that is exactly analogous to append/3:

string_append(?A, ?Z, ?AZ)
is true when A, Z, and AZ are all atoms, and
     name(A, NameA),
     name(Z, NameZ),
     name(AZ, NameAZ)
     append(NameA, NameZ, NameAZ)

is true. It can be used to solve for any one of its arguments given the other two.

As a point of interest, string_append/3 could have been defined using midstring/4, which is defined below.

     append_strings(A, Z, AZ) :-
             midstring(AZ, A, Z, 0).


     | ?- concat(app, end, X).
     X = append
     | ?- string_append(app, end, X).
     X = append
     | ?- concat(X, end, append).
     X = app
     | ?- string_append(X, end, append).
     X = app
     | ?- concat(app, X, append).  % SURPRISE!
     | ?- string_append(app, X, append).
     X = end
     | ?- concat(app, 137, X).
     X = app137
     | ?- string_append(app, 137, X).
     | ?- concat(X, Y, ab).  % SURPRISE!
     | ?- string_append(X, Y, ab).
     X = '', Y = ab ;
     X = a, Y = b ;
     X = ab, Y = '' ;