The Elementary Ringing Language (ERIL) and the FindTouches.exe Program

Introduction

Here is a grammar-driven ringing composition-proving program, available for download for free. The program can be used for proving compositions from short touches to entire peal compositions, or can be used to search for touches that satisfy your predefined search criteria.

The elementary ringing language described here is loosely based on the concepts behind MicroSiril, but adds constructs that allow options for changes or leads within a touch. It enables a basic round block to be used, and options for variations to that block to be exercised. It allows two kinds of block repetition: one that repeats the optional leads using backtracking, and one where a repeated block must reuse the leads with the options selected the first time the block was used in the proof. In short, ERIL provides features a composition searcher might use when parts of a composition are designed, but searches need to be made to join known blocks together, or to yield a composition of the desired length.

The program Findtouches.exe is a parser for reading an ERIL touch specification, and proving the set of all touches that match that specification. The program is used as described below.

  1. Install the program on your PC. Instructions for doing this are given after this introduction.
  2. First, prepare your touch description file using a text editor of your choice. The ERIL grammar rules for forming the touch specification are described later in this document.
  3. Launch a command prompt window, and change directory to the directory containing your touch description. To find touches that match your touch description, at the command prompt, type the following command:
        FindTouches -v -i touchspecfile -o touchoutputfile

Use a text editor to inspect the list of true touches in the output touch file that match your ERIL input touch specification. If your touch specification described a single touch you wanted to prove to be true, this should appear as the only touch in the output file. If the touch is false, no touches will appear in the output file.

The FindTouches command line arguments

The following table gives you more information on how to use the FindTouches command line application. It lists each of the arguments you can use, and explains what they do.

ArgumentDescription
-h or --helpLists the command line arguments as described here
-l lib-folderUpdates the method library from the CCCBR XML zip file in the folder lib-folder
-l -Updates the method library from the executable folder. Copy the CCCBR method library files there first.
-i touch-specRead the touch specification from the file named touch-spec
-o output-fileWrite any touches found to the file output-file
-vTurns on detailed touch output if present. Only summarises touches if omitted.
-j json-file.jsonOutputs touches found in machine-readable JSON format to the specified file
-d 1Debugging output for developers. Outputs the syntax tree for the touch specification
-d 2As for -d 1 but also outputs the trellis searched by the touch proof engine
-d 3As for -d 2 but also reports the shifts and reductions of the LR(1) parser

A few notes might be useful for explaining the contents of the table above. Firstly, you will probably never need to use the -d options. They are used by developers for improving the FindTouches program, or for analysing errors, should they occur.

The Central Council Method Libraries are available from the Central Council Website. The library you will need is the zipped XML libraries for all stages. If the CCCBR website maintainers move the libraries around in the web site, these links may break. In which case, search the Central Council web site for the zipped xml libraries for
all stages. They will be in there somewhere!

A copy of the library is already present in the installation of your FindTouches application. That library though will probably be several months out of date as it is a snapshot
taken when this program was last updated. It is a good idea to update your libraries as soon as you have installed this program.

To do this, download a copy of the zipped, all stages XML library, ideally using the second link above. Save or move the downloaded file to a folder you choose, then run the following command at a command prompt to update the libraries:

FindTouches -l the-folder-in-which-you-put-the-downloaded-zip-file

Note the program only wants the folder, not the full file name.

Whenever you want to prove a touch, or search for touches, your touch specification will be saved by you into a text file somewhere. You must use the -i your-touch-spec-file command line option to pick up that touch specification. There is no way to type the touch specification in while the program is running. It expects to read it from a file.

If you provide the -o where-to-put-the-results option, it will save your output touches to the specified file. If you don’t provide this option, they will appear on the screen in the command prompt window, and not be saved anywhere.

Always provide the -v option if you want to see the detailed descriptions of each touch found. If you don’t, the abbreviated synopsis will appear which is harder to use or understand.

The -j output-json-file option generates the list of output touches in a machine-readable Javascript Object Notation format. At present this is not used by FindTouches itself, but will be in the future, and could be used by programs you write to import the touch results.

Installing the Program

Installation on Microsoft Windows

At present, there is no automated installer for FindTouches, though there may be one in the future should I get time to build a windows-based version of the application. If you want to install and use FindTouches, you’ll need to follow the steps below.

  1. First, you need to ensure you have the most recent .NET runtime on your computer. Launch a command prompt window and type the command dotnet --version. If it tells you dotnet is not found, or the version number is older than version 10.0, you’ll need to install a recent version. Microsoft gives you detailed instructions on how to do that
    here.
  2. Download the program and its components from this link for Intel x64 WIndows installations, where it is held as a zip file. For Windows on Arm64 installations, use this link. Make sure you download the version that matches your computer architecture. At the time of writing, Windows is at version 11, and runs equally well on Intel x64 or on SnapDragon ARM hardware. Make sure you choose the correct zip file to download!
  3. Unzip the file into a folder of your choice, for example your Documents folder or a sub-folder there.
  4. Unzipping the program actually creates a new sub-folder for the program and its components with the name FindTouches. If you chose to unzip to the folder C:\users\fred\My Documents” for example, the files will appear in “C:\users\fred\My Documents\FindTouches”.
  5. You might find it convenient to add this folder to your path so that you can run the command FindTouches.exe from anywhere in the filesystem, rather than having to change to the FindTouches folder first. To do this, launch a command prompt as an administrator, and run the command: setx PATH "%PATH%;your-eril-folder-path". For example, if you unzipped to the folder in the example above, use setx PATH "%PATH%;C:\users\fred\My Documents\FindTouches".
  6. Terminate your command prompt window. When you want to use FindTouches, just launch another command prompt window. Note you won’t be able to use FindTouches until after you terminated the command prompt in which you ran the setx command.
  7. The first time you run FindTouches you will need to update the method library from the collection on the Central Council web site, or at least from the slightly out of date version that is shipped with the program. To do this, launch a command prompt window and change to the directory that contains the FindTouches.exe program ( in the FindTouches folder where you unzipped it). Then run the command:
FindTouches -l .

Don’t forget to type the space and the period character at the end of the command as shown above. This is not merely punctuation! This causes the method library to be created from the CCCBR_methods.xml.zip file that is shipped with the program. If you have downloaded a more recent version of the library, make sure you copy the CCCBR_methods.xml.zip file into the same folder as FindTouches.exe first, then run the command above.

Installation on Linux platforms

At present, there is no automated package installer for FindTouches, though there may be one in the future when we build a GUI-based version of the application. If you want to use the program, you’ll need to follow these steps.

  1. First, you need to ensure you have the most recent .NET runtime on your computer. Launch a command prompt window and type the command dotnet --version. If it tells you dotnet is not found, or the version number is older than version 10.0, you’ll need to install a recent version. Microsoft gives you detailed instructions on how to do that
    here.
  2. Download the program and its components from (link yet to be provided) where it is held as a zip file. Make sure you download the version that matches your computer architecture. At the time of writing, many dialects of Linux exist, but they are usually divided into those that run on the Intel x64 architecture, or on ARM hardware. Make sure you choose the correct zip file to download!
  3. Unzip the file into a directory of your choice, for example your own home directory or a sub-directory there.
  4. Unzipping the program actually creates a new sub-directory for the program and its components with the name Eril. If you chose to unzip to the folder “/home/fred” for example, the files will appear in “/home/fred/Eril”.
  5. You might find it convenient to add this folder to your path so that you can run the command FindTouches from anywhere in the filesystem, rather than having to change to the FindTouches folder first. To do this, edit the file named ~/.bash_profile in your home directory (/home/yourname/.bash_profile) and add the following lines to the bottom of the file (This assumes you unzipped the program in your $HOME folder. Amend the path below if you put it somewhere else):
if [ -d "$HOME/FindTouches" ] ; then
  PATH="$PATH:$HOME/FindTouches"
fi
  1. Log out and log in again. This causes your session to rerun the commands in .bash_profile when you launch a command prompt window. From that point on you will be able to run FindTouches regardless of where you are working in the folder hierarchy.
  2. The first time you run FindTouches you will need to update the method library from the collection on the Central Council web site, or at least from the slightly out of date version that is shipped with the program. To do this, launch a command prompt window and change to the directory that contains the FindTouches program ( in the FindTouches folder where you unzipped it). Then run the command:
FindTouches -l .

Don’t forget to type the space and the period character at the end of the command as shown above. This is not merely punctuation! This causes the method library to be created from the CCCBR_methods.xml.zip file that is shipped with the program. If you have downloaded a more recent version of the library, make sure you copy the CCCBR_methods.xml.zip file into the same folder as the FindTouches program first, then run the command above.

Writing Eril touch specifications

In this section we shall explain the syntax used to create touch specifications that FindTouches can understand.

Top level structure of an Eril specification

A touch description is broken into three parts. First, the header line states the number of bells the touch is rung on, where to find the method library, etc. At the moment, this
header only specifies the number of bells as a number followed by a semi-colon. This version of Eril supports any number of bells in the range 4 to 16.

Second is a sequence of substitution or macro substitution statements. These are described below, but they provide a description of how to expand the touch description into a sequence of place notations. Basically each substitution allows you to describe a more complicated sequence of leads or place notations using a single word. Most of the touch description is laid down in this second section.

Lastly comes the touch specification itself. This is the component that is actually proven. Most touch specifications use the substitutions and macros that were defined in the second section, to enable the actual touch specification to be written down succinctly.

White space and comments

White space characters like spaces, tabs and even new lines are used to make ERIL more readable. White space is used to separate other items in the touch specification, but has no meaning of its own. Hence white space should not appear within place notation sequences, for example.

Comments are placed after forward-slash characters ‘/’ and continue to the end of the line on which they appear. A comment allows you to put remarks or reminders into your touch specification that will be ignored by the Eril programs, but that are helpful to you as the author.

Place notation tokens

Any change that takes you from one row to the next in a touch can have adjacent bells swapping places, or bells lying still in the same place from one row to the next. To specify where the places are to be made, and hence which pairs are to swap places, we need to describe The places to be made between adjacent changes.

For example, in a method on eight bells, the place notation 1458 means that the bell at the lead, the bells in 4ths and 5ths, and the bell at the back will lie still, while bells in 2-3 and 6-7 will swap places.

On 16 bells, the maximum change width supported by Eril, the places are represented by the numbers and letters 1234567890ETABCD representing first place up to sixteenths respectively. Note that only capital letters are used for places inside changes.

On even numbers of bells, it is possible to have a change where nobody lies still, and every odd-placed bell swaps places with the even-placed that was following it. This ‘cross change’ is represented by one of the characters x, X, or -, but the hyphen character is the one in most widespread use.

Methods are not made up of single changes, but are described using a sequence of changes representing a single lead of the method. For this reason, place notation is always written as a sequence of change values with no intervening spaces. For example, one lead of Plain Bob Minor has the place notation -16-16-16-16-16-12. As you can see, every other change is a cross-change, interspersed with lead-and-lie places until the treble gets back to the lead, at which point a bell makes seconds place over the treble.

Not every method has alternate changes always being a cross-change. Many methods may have changes with places next door to each other. In this case we separate the adjacent changes with a period character. Hence the place notation for a lead of Reverse Canterbury Minor would be 34.16-16-16-16-16.34.12.

Blocks or sequences

Adjacent blocks of place notation can be fused into one longer sequence by connecting them with a + character. For example, we might represent a touch of Plain, Little, Plain Bob as follows:

-16-16-16-16-16-12 + -16-14-16-12 + -16-16-16-16-16-12

Method library

Writing out the place notation for every method in your touch is a waste of effort, and likely to suffer from mistakes. Eril supports the Central Council method libraries, and can import the CCCBR XML versions of their method library so that your copy of Eril always has the most recent lists of all methods and their place notations.

A method from a method library may be loaded using a fully qualified method name in double quotes. This token expands to be the method’s place notation for a single lead of the method. The method name consists of two space-separated strings. Example:

"Cambridge Surprise"

expands to become the place notation for one lead of Cambridge. Note that the number of bells is given at the top of the touch specification already, so we don’t need to stipulate the “Minor” or “Royal” on the end.

Now we can also see why the + operator is useful, as we can use it to create a sequence of leads making up a touch. For example, a complete touch specification for a two-lead touch of spliced minor might be:

6;  / States how many bells this touch is rung on
"Cambridge Surprise" + "Little Bob";  / Note the necessary terminating semi-colon!

Note that methods in the CCCBR method collection are grouped into categories, usually based on the repetitive shape of the treble’s blue line. Examples of these are: Plain, TrebleBob, TreblePlace, Surprise, Delight, OddHunt, Principle, Alliance, SlowCourse among others. It might be worth your while exploring the method collection to find what
exotic categories are supported if you are planning to search for interesting touches!

When identifying method collection methods, you will need to include the method category when selecting a method. This is true for every category except plain methods where the treble plain hunts between the front and the back of the change. Note that for plain methods usually words like “Bob”, “Place” or “Slow Course” are embedded as part of the name of the method, implying the method category anyway.

Options in touch specifications

Sometimes you may be searching for touches rather than just proving a single touch composition. In this case, you need to include places in your touch where there are several different options to be tried. For example, maybe you want to search for all touces of length 120 of Plain Bob Minor, or all true five lead courses of surprise major drawn from the standard eight surprise major family.

To do this, you can insert into your touch specification segments where two or more different methods or blocks of place notation might be tried. When you do this, Eril will try each and every combination of your options, and returns descriptions of every matching touch it finds that is true.

A choice of place notation or of method may be denoted by the vertical bar symbol |. This means that in a backtracking search program such as Eril, each of the options may be tried in turn as part of the proving process. The example below shows you two ways of describing a lead in a touch that can either be Plain Bob Minor or Single Canterbury Bob Minor:

-16-16-16-16-16-12 | 34.16-16-16-16-16.34.12
"Plain Bob" | "Single Canterbury Bob"

Note that the + operator used to catenate two blocks of place notation, or two leads of methods has a lower precedence than the option operator |. In the example below, only the changes around the lead end vary, while the body of the lead that precedes the two alternative lead ends is the same. The example below yields either a lead of Little Bob Minor, or a lead of Crayford Little Court:

-16-14-16- + 12|16

Repetition of blocks

To indicate repetition of a block of changes or leads, an asterisk followed by the repetition value is used. The repetition value may be a decimal number, or a range enclosed in square brackets. If a single value, only that number of repetitions of the block will be tried. If a range is used, each possible number of repetitions is tried in turn to see what touches can be produced. Examples:

"Plain Bob" * 5;     / Expands to five consecutive leads of Bob Minor if on 6 bells
"Plain Bob" * [1-4]; / Expands to four different options, with 1 to 4 leads respectively

Note that the repeat operator * only applies to the token that precedes it, being very high precedence. Hence if you wish to use repetition of catenated or optional blocks, surround them with round brackets:

8;
("Cambridge Surprise" + -18-14-18- + 12|14|1234)*[2-6];

In the touch description above, we are using eight bell methods. Each block consists of a lead of Cambridge Surprise followed by a lead of Little Bob ending with no call, a bob or a single. All combinations of this sequence repeated between two to six times are tried, and will identify the seven touches with various combinations of bobs and singles at the end of each block.

Interestingly, because the lowest repeat figure is two, the two lead touch with no bob or single at the end is not reported, as it is too short (not repeated at least two times).

Substitution statements

Sometimes we would like to have an abbreviation for a complex block of leads, options, etc. A substitution statement provides this simplification. We choose a name or ‘identifier’ that has not been used already elsewhere in the touch specification, and we assign some block of Eril script to it. Whenever that identifier is subsequently seen in the touch specification, it will be expanded into the complex block it was defined as. Here is an example:

6;  / This is a touch on six bells
HalfLeadOfKent = 34-34.16-12-16-12-;
LeadOfKent = HalfLeadOfKent + 16-12-16-12-16.34-34.16;
LeadOfKent * 5; / Will check the plain course of Kent to see if it is true

The touch above defines HalfLeadOfKent as a substitute for the place notation to the right of the equals symbol. LeadOfKent defines a substitute for the expansion of HalfLeadOfKent concatenated with the extra placenotation in its expansion. Lastly the actual touch specification to be proved is the LeadOfKent * 5 on the last line. After expansion it is equivalent to:

(34-34.16-12-16-12- + 16-12-16-12-16.34-34.16) * 5;

Reversal statements

Most methods or principles that we ring are made up using a sequence of repeating blocks of place notation, usually known as leads. Furthermore, the vast majority of methods have leads where the second half of the lead’s place notation is the miror image of the first half.

If we were using Eril to explore new candidate methods that were not in the methods library, it would be useful to have a simple way of expressing this mirror imaging of blocks of place notation. We can do this by using the reversal operator ~ (the tilde character). When applied to a block of place notation, the reversal operator turns the place notation sequentially back to front. Hence the notation: ~-16-14- is converted into the places -14-16-.

Looking at the use of this to represent a lead of a typical method:

6;
HalfLeadOfKent = 34-34.16-12-16-12-;
LeadOfKent = HalfLeadOfKent + 16 + ~HalfLeadOfKent + 16;
LeadOfKent * 5;

The above touch specification is a simplified version of the previous Kent Treble Bob example that demonstrated substitutions.

Macro substitution statements

Substitution statements can also be provided with macro parameters. This allows a substitution to apply its overall substitution, then apply substitutions for each
of the parameters provided too. Consider the following example to explain this:

6;
method(body, halfLead, leadEnd) = body + halfLead + ~body + leadEnd;
plainBody = -16-36-;
stClements = method(plainBody, 36, 12);
collegeBob = method(plainBody, 36, 16);
collegeBob * 2 + stClements;

This touch specification shows how methods form families based on differences in just their lead end and half lead changes, but where the body part of the method is fixed. More importantly for our purposes here, you can see that the substitution is expanded first, then the parameters are also expanded where they occur. Thus the expansion of stClements becomes:

-16-36- + 36 + ~-16-36- + 12

Macros are one of the most powerful tools when creating simple descriptions of otherwise complicated touch specifications.

Implementing Bobs and Singles with replacement blocks

If someone asks us what the calls are for a method we are learning, we usually want to give a brief answer, such as bobs are made in fourths place at the lead end, and singles are made in thirds and fourths also at the lead end. In Eril we have a similar abbreviation that we can use to describe how the existing place notation in a block or lead has some of its places replaced by alternative places to implement a call. These additional bits of Eril syntax are known as replacement blocks.

We could also use replacement blocks to explain how one method differs very slightly from another, because the replacement blocks don’t have to be at a lead end, they could be at any offset within a lead.

To describe a replacement block, we have to obviously state its place notation. However, we also need to state how far into a lead the replacement block is applied. Here are some examples of replacement blocks:

3.123 << 1   / Starting at offset 1 change back from the lead-end to lead-head
                           / change at the end of a lead, apply two consecutive replacements
                          / to the last two changes.
567.1.7 >> 1 / The first three changes of the lead (after the lead-head row)
                         / are replaced by the three consecutive places shown
14                  / The very last change of the lead, that joins the lead-end to
                        / the next lead-head is replaced by places in 14. Can also
                       / write this as 14 << 0 if you want.

The rules for the above constructs are that the offset value after the end-specifier << or >> is the offset from either end of the lead to the first place to be made in the call. Its only use is as one of the two arguments to the & operator. The two end specifiers (<< and >>) are each higher precedence than the & operator, which in turn has higher precedence than |.

The grammar rules for Eril require that the thing to the left of the << or >> must be a place notation block or a substitution/definition name that expands to a block of
place notation. The thing to the right of the << or >> must be a positive decimal number or zero that lies within one lead of the item to the left of the & operator (discussed immediately below).

To represent a replacement of some of the places in a method with new ones, use the & operator as follows. Note that the thing to the left of the & operator can be a library method, a ‘~’ expression, a block of place notation, or even another & expression. It cannot be multi-block expressions like ‘|’ or ‘+’ expressions. Here are some examples:

7;                                     / Touch is a touch of Triples
p = "Grandsire";     / Lookup Grandsire Triples from the plain
                                         / methods collection
b = p & 3.1 << 1;     / The place notation for a bobbed lead of
                                         / Grandsire using a substitution
s = p & 3.123 << 1;  / Similarly a lead ending with a single
choice = (p|b|s);    / What each lead may contain
choice * [3-10];     / Finds all 83 touches of length 42 to 140 changes

Note one more important feature. If a replacement block is specified for which the number of changes spills over the end of the lead it is modifying, the replacement also carries on into the next lead of changes. Thus variations like April Day where the call spills into the next lead across a lead end are catered for, as in the example below.
Note though that there is no way of having the call at the end of a touch automatically wrap back to the first change of the touch.

5;
Plain = "PlainBob";                       / Most plain methods have 'Bob' 
                                                                  / in their name in the method library
Bob = Plain & 3.123.3 << 1;    / Will alter one change into lead
                                                                 / beyond the call
Opt = Bob | Plain;
Part = Opt * 3 + Plain;               / Can't have calls at the last
                                                                / lead in this kind of extent
Part * 3;                                             / Finds all four April Day 120s

Value blocks

Let’s imagine we want to write a substitution for a lead that can either be Kent TB Minor, or Oxford TB Minor. As we know, these only differ from each other in the 34 places that are made at each end of the lead. We might be tempted to describe a lead that can optionally be either method as follows:

Places = 34-34 | -34-;  / One set of Kent places or one set of Oxford
LeadBody = 16-12-16-12-16-12-16-12-16;
KentOrOxford = Places + LeadBody + Places + 16;

Unfortunately, this doesn’t work. The options at the beginning and end of the lead are completely independent on each other. This KentOrOxford substitution also matches leads with Kent places at one end and Oxford at the other. What we really want is something that says “If we use Kent places at the start of a lead, use them also at the end” and likewise for Oxford places. This is what Value Blocks are for.

Value blocks surround an Eril expression with square brackets and include a block name. When the block name gets reused later in the touch specification it matches the option choice that was made earlier in the touch. Hence we could rewrite the Kent and Oxford example above as follows:

6;
Places = 34-34 | -34-;  / One set of Kent places or one set of Oxford
LeadBody = 16-12-16-12-16-12-16-12-16;
KentOrOxford = [Choice=Places] + LeadBody + Choice + 16;
KentOrOxford*5;

This now correctly matches either leads of Kent or leads of Oxford. It’s as if Choice takes a snapshot of which of the two options were made earlier in the lead, and that choice is repeated where it appears later in the lead.

Actually in the touch above, because the name Choice is used for each lead of the five leads, this finds just the plain course of either Kent or Oxford. To mix up leads of Kent or Oxford within the five leads, we need to express the touch slightly differently, as follows:

6;
LeadBody = 16-12-16-12-16-12-16-12-16;
Kent = [Places=34-34] + LeadBody + Places + 16;
Oxford = [Places=-34-] + LeadBody + Places + 16;
(Kent|Oxford)*5;

One final syntactic abbreviation for value blocks should be mentioned. If the value is to reused only within the confines of a repetition block, the name and the equals sign can be left out. The following example matches either a whole course of Kent or a whole course of Oxford. There is no change of method within the two touches (plain courses) that Eril finds when proving this touch specification:

8;  / Major
k = "Kent Treble Bob";
o = "Oxford Treble Bob";
lead = k | o;
[lead]*7; / A whole course of either Kent or Oxford

Pattern filters

Sometimes we would like to check to see if a subset of the bells in a row at a particular point in the sequence of changes are in expected positions in the row. For example, if we want to find blocks of leads that end with the tenors in their home position, i.e. a course end, we could specify a pattern that expects to see the tenors in the last two positions of the row.

We might also want to not search for complete touches that come round, but to search for turning courses in Grandsire or Stedman on higher numbers of bells. In these cases, we maybe only care that we find a sequence of leads that ends with the tenors in say the tittums or handstroke-home positions.

Look at the following example:

9;
p = "grandsire";
b = p & 3.1 << 1;
s = p & 3.123 << 1;
(p|b|s)*[5-9]->"*6978";

The above touch specification is for a search in Grandsire Caters for the 76 turning courses that take us from rounds to the back four bells coursing in Tittums with fewer than nine leads.

The change patterns that follow the arrow operator either begin or end with an asterisk ‘*’, thus representing the first or last several bells of a row, and have single unspecified bells represented by a period ‘.’. Hence the pattern ->"*.7.8." matches the last row of the block to the left of the -> operator has the 7 in 6ths place, and the 8 in 8ths place if the touch is on nine bells.

Note that as you can see above, if the entire touch specification ends with a pattern filter, the eril prover searches for any block that ends with that pattern, rather than
touches that end with rounds. This is obvious if you think about it, as ending with a pattern that does not include rounds as a pattern match could never yield a true touch. In this way then, eril can be used to search for turning courses that we need to build a bigger touch such as a peal or quarter composition.

To use pattern filters in touches that must still end in rounds, the pattern filter cannot appear at the end of the touch specification. This may confuse you, as a pattern filter at the end of a macro substitution or substitution definition that itself then gets used at the end of the touch specification can cause touches to be ‘found’ that end with a pattern match instead of coming round.

Examples of touch descriptions

Find extents of plain bob minor with calls at Wrong and Home

6;
p = "Plain Bob";
b = p & 14;
s = p & 1234;
course(w, h) = w + p*3 + h;
course((p|b|s), (p|b|s)) * 12;

This touch specification finds all 19,472 extents of Plain Bob Minor that only have calls at Wrong and Home.

Alternatively, to find two-part extents of plain bob minor with bobs at Wrong and Home but with two singles, half-way and end, we come up with the standard 6 well-known extents:

6;
p = "Plain Bob";
b = p & 14;
s = p & 1234;
course(w, h) = w + p*3 + h;
[course((p|b), (p|b)) * 5 + course((p|b), s)]*2;

All touches of eight-spliced surprise major with up to eight leads

Warning! This touch search will take several days to run! On my SnapDragon ARM laptop (2025 model), it takes 3 seconds to find all the 5-lead touches, just under a minute to find all 6 lead touches, and 104 minutes to find all the 7 lead touches, of which there are over two and a half million. I was too impatient to wait for the eight-lead touches. Maybe by the time you read this, you’ll have a computer that can execute this in a reasonable time!

8;
c = "Cambridge Surprise";
n = "Lincolnshire Surprise";
y = "Yorkshire Surprise";
r = "Rutland Surprise";
b = "Bristol Surprise";
s = "Superlative Surprise";
p = "Pudsey Surprise";
l = "London Surprise";
cb = c & 14; / Adjusts last change from 12 to 14
nb = n & 14;
yb = y & 14;
rb = r & 14;
pb = p & 14;
lb = l & 14;
sb = s & 14;
bb = b & 14; / Adjusts last change from 18 to 14
cs = c & 1234; / Adjusts last change from 12 to 1234
ns = n & 1234;
ys = y & 1234;
rs = r & 1234;
ps = p & 1234;
ls = l & 1234;
ss = s & 1234;
bs = b & 1234; / Adjusts last change from 18 to 1234
plains = (c | n | y | r | p | l | s | b); / Vertical bar means 'or'
bobs = (cb | nb | yb | rb | pb | lb | sb | bb);
singles = (cs | ns | ys | rs | ps | ls | ss | bs);
(plains | bobs | singles) *[1 - 8]; / 1 - 8 leads long