##### `midstring/[3,4,5,6]`

The `midstring/N` family has four members:

• `midstring(`ABC`, `B`, `AC`, `LenA`, `LenB`, `LenC`)`
• `midstring(`ABC`, `B`, `AC`, `LenA`, `LenB`)`
• `midstring(`ABC`, `B`, `AC`, `LenA`)`
• `midstring(`ABC`, `B`, `AC`)`

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

`midstring/6`
is true when
• ABC, B, and AC are all atoms.
• ABC can be broken into three pieces A, B, and C,
• AC is the concatenation of A and C,
• LenA is the length of A,
• LenB is the length of B, and
• LenC is the length of C.

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 ;

no
```

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:

• To delete 7 characters from `I"m going, Tom`, retaining the first 4 characters:
```          | ?- midstring('I''m going, Tom', _, Answer, 4, 7).

```

To search for the text `ab` in `abracadabra`:

```          | ?- midstring(abracadabra, ab, _, Offset).

Offset = 0 ;
Offset = 7 ;
no
```

• To divide Whole into Front and Back, where the length of Front is known:
```          | ?- midstring(Whole, Front, Back, 0, FrontLength).
```
• To divide Whole into Front and Back, where the length of Back is known:
```          | ?- midstring(Whole, Front, Back, 0, _, BackLength).
```
• To insert Part into Fringes at a given Offset from the left, yielding Whole:
```          | ?- midstring(Whole, Part, Fringes, Offset).
```
• To insert Part into Fringes at a given Offset from the right, yielding Whole:
```          | ?- midstring(Whole, Part, Fringes, _, _, Offset).
```
• To delete Drop characters from Whole, starting at a given Offset from the left, yielding Short:
```          | ?- midstring(Whole, _, Short, Offset, Drop).
```
• To delete Drop characters from Whole, starting at a given Offset from the right, yielding Short:
```          | ?- midstring(Whole, _, Short, _, Drop, Offset).
```
• To determine the Length of Text:
```          | ?- midstring(Text, Text, '', 0, Length, 0).
```

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).
```