The midstring/N family has four members:

The principal routine for taking apart an atom is midstring/6.

is true when

Either ABC or both B and AC should be instantiated. Apart from this restriction, midstring/6 is a genuine relation, and all the other arguments can be solved for.

How can you be expected to remember all these arguments? The arguments fall into two groups: three text objects and three integers. The three integers form a little picture of what you want.

                 |   LenA    |     LenB    |  LenC   |
         ABC=     a a a a a a B B B B B B B c c c c c

So the order of the three integer arguments is the same as the order of the substrings whose lengths they are. Note that none of these arguments is a "position" in any string: all three of them are to be understood as lengths of strings.

The order of the text arguments was chosen to extend the order used by substring/5 (see lib-txp-sub-substring). Generally, you are more likely to know ABC than B or AC, and you are more likely to know B than AC. For example, a common use of the midstring/[3,4,5,6] family is to ask "if B is deleted from ABC, what results?", which can be done by asking

     | ?- midstring(this_is_abc, is, AC, _, _, _).
     AC = th_is_abc ;
     AC = this__abc ;

Earlier in this section we saw midstring/4 used to append two strings. Now we can see how that works:

     | ?- midstring(BC, B, C, 0).

is true when BC can be broken into three parts, A, B, and C, such that 0 is the length of A, the lengths of B and C are unconstrained, and C is the concatenation of A and C.

Another way to see this is that

     | ?- midstring (ABC, B, AC, N).

is true when ABC is obtained by inserting B just after the Nth character of AC.

Some other examples using the midstring/N family:

It would not be useful to try to memorize these examples. Instead, remember the picture:

     ABC,  B,  AC,  LenA,  LenB,  LenC

Note that midstring/[3,4,5,6] has been carefully designed so that you can extract and insert from either the left or the right with equal facility, and so that successive calls to extract related fragments will require a minimum of arithmetic. For example, suppose we want to break a text ABCD into four pieces, where the lengths of B and D are known. We think about the picture

             ABCD = '' (ABC) D
             ABC  = A (B) C
             AC   = A (C) ''

and then write

     four_parts(ABCD, A, B, C, D, LenB, LenD) :-
             /* this is an example */
             midstring(ABCD, ABC, D, 0, _, LenD),
             midstring(ABC, B, AC, LenA, LenB),
             midstring(AC, C, A, LenA, _, 0).