substring/[4,5]

Very often you are not interested in the third argument that midstring/[3,4,5,6] return. This argument is not returned or constructed by substring/[4,5]. In fact, substring/[4,5] were designed first, and midstring/[3,4,5,6] were developed from it to provide string insertion and deletion.

are true when

The ABC argument must be instantiated. The B argument may be instantiated (this provides a string search facility) but need not be. This is the reason for the argument order: arguments that are strict inputs should precede other arguments, and substring/5 has precisely one strict input.

The point of substring/5 is to let you work from the right-hand end of the text as easily as from the left-hand end. But the fact that Prolog is based on relations rather than functions means that this one operation can replace both substring and string search operations.

Thus to determine where a occurs in abracadabra,

     | ?- substring(abracadabra, a, Offset, _).
     
     Offset = 0 ;
     Offset = 3 ;
     Offset = 5 ;
     Offset = 7 ;
     Offset = 10 ;
     no
     

This is the preferred way of searching for a substring in Quintus Prolog. Note that if you use substring/5 to search for a substring, you can then extract the preceding or following characters thus:

     | ?- substring(Text, Pattern, L_Before, L_Pattern, L_After),
     |    substring(Text, Before, 0, L_Before, _),
     |    substring(Text, After, _, L_After, 0).
     

Again, this is not guesswork, but is arrived at by thinking about the picture

     Text = Before (Pattern) After
          = '' (Before) Pattern After
          = Before Pattern (After) ''
     

There are two other predicates in this family:

     index(Pattern, String, Offset) :-
             substring(String, Pattern, Offset, _).
     
     string_search(Pattern, String, Offset) :-
             substring(String, Pattern, Offset, _).
     

index/3 is retained for compatibility with earlier releases of library(strings). It will be withdrawn in a future release. If you have code that uses index/3, you should replace calls to index/3 by calls to string_search/3, which is an exact synonym for it.