ERIL Composition Finder and Prover

Introduction

Here is a grammar-driven composition search engine and proof engine, available for free download. This page and the links off it describe how to write composition specifications for ERIL, so that you can search for touches, quarter-peals or even peals. If you already have a composition, you can write an explicit specification for that composition and this program will prove it for you. It will even summarise any music the composition contains.

The simple ringing language as used in MicroSiril and other peal provers has been in use for many years. It gives an ‘identifier = expansion’ based syntax that expands to raw place notation for input to a peal prover program. Thus the prover need have no concept of method structure, or of the concept of leads, blocks, and calls. This is an ideal ringing language for proving a fixed composition, butit doesn’t lend itself readily to back-tracking composition searches. In particular it cannot be used to specify a constrained back-tracking search. For example, if we wanted to search for peals based on certain fixed block patterns with optional calling positions or choices of spliced method, we could not specify the layout of the fixed parts of the touch in a way that would allow a back-tracking program to perform this constrained search.

The elementary ringing language described here is based on some of the concepts of MicroSiril, but adds new 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 as set the previous 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 get the desired length.

In this version of ERIL, the application is made available as a command line program only. You will need to install it, then launch a Windows command prompt with the current directory set to the folder where ERIL was installed, or with the folder containing eril.exe included in the command prompt’s PATH.

The program ​eril.exe is a program that reads an ERIL touch specification from a file, then proves the set of all touches that match that specification. As usual with all freeware, no warranties are given for its performance, though it has been thoroughly tested to ensure it doesn not return false touches. The program is used in the following way:

  • First, prepare your touch description file using a text editor of your choice, like notepad or notepad++. The ERIL grammar rules needed to construct the touch description are explained later in this page.
  • Launch a command prompt window, and navigate to the folder where your touch description file lives.
  • Run the eril.exe program: eril touchDescriptionFilePath outputTouchFilePath
  • Use a text editor again to inspect the list of true touches in the output touch file that match the ERIL touch specification.

Installing ERIL

To install ERIL on your Windows PC, download the file eril.zip from this location.

Create a new folder somewhere in your filesystem, where you want the ERIL program to live. For example, create a folder C:\MyPrograms\Eril.

Unzip/extract the contents of the eril.zip file into that folder.

You now need to set the environment variables for the Windows command prompt in order to make the ERIL program callable from any folder you are working in. To do this, launch a command prompt as administrator as follows:

  1. Click on the windows button and type ‘cmd‘. One of the top items that appears in the search results should be Command Prompt.
  2. Right-click on Command Prompt and select Run as Administrator from the pop-up menu that appears. An old fashioned command line window should appear.
  3. In the new window, type the following command, then hit the return key:
  setx path "%PATH%;C:\MyPrograms\Eril\"

This should arrange that all future command prompt windows are able to run the ERIL program. There is a recent but not up to date copy of the MicroSiril method library, as maintained by Julian Morgan, in the file methods.dat. To construct a more recent one, the batch file mkmeth.bat produces the methods file from a more recent set of MicroSiril method files which you can download from the CCCBR web site.

Proving/finding a simple touch

Let’s assume you have installed ERIL as described above, and you created your ERIL composition description file in a folder C:\MyTouches with the name coolstedmanscript.txt.

Launch a command prompt window by tapping the Windows key, then typing cmd followed by the return key. Once the command prompt window appears, at the command prompt type the command CD C:\MyTouches followed by the return key, This will change the current folder you are working in to be the same folder as the one with your touch script.

To run ERIL, type the command eril.exe coolstedmanscript.txt foundtouches.txt followed by the return key. This will read your touch script from the file coolstedmanscript.txt, and will use it to find any touches that match the touch script, placing the true touches found into the output file foundtouches.txt.

Warning! If you’ve used a script with too many optional paths in it, this could take a considerable if not near infinite time. For example a script that searches for all true touches of stedman triples mayhave to try every possible combination of sequences of plain, bobbed and singled sixes for a whole peal length! It is a good idea to choose a single touch you want to prove, or author a script with not too many optional paths in it.

When the command prompt reappears, you can inspect the contents of foundtouches.txt for your new touches.

The program can also take input from the command line and display output in the command prompt window if you just leave out the first or both arguments. Also placing the flags -d and/or -v before the input touch description file’s name turn on debugging output or verbose touch reporting output respectively. Note that you will only wish to use -d when providing a bug report for eril back to the ERIL developers, which hopefully will not occur too often!

Syntax of ERIL composition description files

A touch description is broken into three parts. First, the top line of the script specifies the number of bells the touch is rung on. It consists of a number between 4 and 16 followed by a semi-colon.

Second is a sequence of substitution or macro substitution statements. This is the biggest part of the touch description and can cover many lines of text input. The grammar rules for writing these is given in the sections below, and provide a description of how to expand the touch description into a sequence of place notations.

Lastly come one or more touch specifications themselves. These are the components that are actually proven, one at a time. Note that touch specifications may be interspersed with substitutions and macros, but the macros and substitutions that precede the touch specifications must satisfy all the needs of the touch specifications at the point they appear.

White space and comments

The use of white space characters to make ERIL more readable is possible. White space is not treated as significant. However, white space should not appear within place notation tokens.

Comments begin with a forward slash ‘/’ and continue to the end of the line on which they begin.

Place notation tokens

Places are made up from 1234567890ETABCD as increasing valued ordered sets, e.g. 12 or 10 or 367T. Note that omission of a digit/letter at the beginning or end of the set implies the extreme position: On ten bells, 45 means 1450. Placeless (cross-) changes consist of the token ‘ ‘, or ‘ X‘ (upper case only). The junction between two place notation tokens is denoted by a period ‘.‘, but this may be omitted where the junction between two place notations is between a change with places made and a cross-change. Note also that the place letters for elevenths place through sixteenth are accepted in upper case only. Lower case letters are all available for other identifiers.

Block tokens and sequences

A sequence of place notation tokens may be treated as a unit by linking them with plus ‘+’ symbols. For example: 34-34.16 + -12-16-12-. This is seldom useful on its own as the plus operator has lower precedence than any other operator in Eril. To alter precedence levels, place the sequence in parentheses to make a block token. Block tokens are used where the block needs to be treated as a single entity.

Option tokens

A choice of place notation or of block may be denoted by the vertical bar symbol ‘| ‘. This means that in a backtracking program, each of the options may be tried in turn as part of the proving process. Note that this operator has higher precedence than the plus operator, as demonstrated in the example below of an option of a lead starting with Kent or Oxford places:

  34-34 | -34- + 16-12-16-12-

Substitution statements

A new token can be defined that becomes an alias for a sequence of one or more other tokens. This is used to simplify ERIL touch descriptions. The syntax for this is: identifier = token-sequence ; Note that the semi-colon at the end of the sequence marks the end of the substitution statement. Use of semi-colons in this way allows long token sequences to spill across multiple lines. The identifier defined in a substitution may subsequently be used in other statements, including other substitution definitions. Note that the plus symbol between the substituted token and a block of place notation must be present as below. Here is an example:

  HalfLeadOfKent = 34-34.16-12-16-12-;
  LeadOfKent = HalfLeadOfKent + 16-12-16-12-16.34-34.16;

Reversal statements

Many (most) methods and principles have place notation symmetry about the middle of a block of changes. A shorthand way of representing a block that is the reverse of another block of place notation is to use the reversal operator ‘~. Note this is not the same as the reversal operator of the MicroSiril method libraries, where the last place (at the half lead) is not repeated in the reversal, and the whole expansion includes the forward as well as the reversed sequence or places. Instead, ERIL just provides the reversal of another block via the reversal operator. Example:

  HalfLeadOfKent = 34-34.16-12-16-12-;
  LeadOfKent = HalfLeadOfKent + 16 + ~HalfLeadOfKent + 16;

Macro statements

Substitution statements can also be furnished with macro parameters. This allows a standard block to be customised where it occurs in a touch. Example:

  method(body, halfLead, leadEnd) = body + halfLead + ~body + leadEnd;
  plainBody = -16-16-;
  PlainBob = method( plainBody, 16, 12 );
  ReverseBob = method( plainBody, 56, 16 );
  DoubleBob = method( plainBody, 56, 12 );

Note that recursion in macros, as well as in ordinary substitutions is not permitted. Recursion is where you use the same macro or definition name in the expression to the right of the ‘=’ as appears at the left. Such definitions would expand to have inifinite length, which makes them unprovable.

Method statements

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 a lead of Cambridge found from a method library

Note that methods in a method collection are assumed to have the names and categories as used in the MicroSiril method collections. These are: Plain, TrebleBob, TreblePlace, Surprise, Delight, OddHunt, Principle, Alliance, SlowCourse. The word ‘Plain’ may be omitted in the method name, as this is assumed to be the default if nothing else is specified. If a prior method has been selected from the method collection, its method type becomes the new default for later methods.

Here is an example of a complete touch script that searches for certain true courses of Kent and Oxford TB Major where the first and fourth leads can be Kent or Oxford in any combination:

  8; / The 1st line specifies the number of bells
  K = "Kent TrebleBob"; / These 2 lines are substitution statements
  O = "Oxford"; / Still treble bob as current default type
  / The actual touch specification to be proven:
  K|O + O + O + K|O + O + O + K;

Repetition

To indicate repetition of a block, an asterisk followed by the repetition value is used. The repetition value may be a decimal number, or a range enclosed in square brackets. (Note though that the asterisk and repetition value must follow the block to be repeated, and cannot precede it.)

Example finding all course made from plain leads of four standard surprise major methods:

  8;
  R = "Rutland Surprise";
  CNY = "Cambridge" | "Lincolnshire" | "Yorkshire";
  ShortCourse = (CNY*4+R)|(CNY*3+R+CNY)|(CNY*2+R+CNY*2)|(CNY+R+CNY*3)|(R+CNY*4); / 5-lead courses of up to four spliced
  (R|CNY)*[3-7]; / Finds all true bobless courses of four spliced

Pattern filters

A common requirement is to specify that at a particular point in a touch the lead should end with a certain change pattern. For example, in major, we might be looking for all courses that end with the tenors at Home, or a sequence of plain leads followed by a bob at Wrong. These pattern filters are implemented using the arrow “->” operator as follows:

  (p|b|s)*[1-7]->"*78"; / Matches all courses that end with tenors at home
  p*[0-6]+b->"*7.8."|"*8.7"; / Makes next call a bob at wrong or middle

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 ‘.’

Note that 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 for example.

Replacement blocks

A common requirement is to specify that a method is like another, except for some place changes. This is particularly true if trying to describe a call in a method, where certain rows of place notation get replaced with other rows. Two constructs exist for permitting this. First a construct for representing a block of changes where some of the place notations are not described:

  3.123 << 1 / Last two places of a lead will be 3 and 123.
  / The other places are unspecified, as is the length.

  567.1.7 << 1 / First 3 changes of a lead have the specified
  / place notation. The length of the block is undefined.

  14 << 0 / Last place of a lead will be 14 as in a normal bob.

What do these tokens actually mean? The expression to the left of the shift symbol (‘<<’ or ‘>>’) is a block of place notation that is destined to replace some of the place notation in the plain lead of a method. The number to the right of the shift symbol tells us where in the plain lead the first place of the replacement block will be applied. If the number has the value ‘0’, then as with most methods this replaces the lead head change. If the number has the value ‘1’, then this would be the first change after the lead head, assuming the shift operator is a right shift (‘>>’). If the number is preceded by a left shift (‘<<‘) then the number represents how many places back into the lead before the lead head change the replacement will be applied. Hence for example, the Eril expression: “grandsire” & 3.123 << 1 represents a lead of Grandsire where the penultimate and last change of the lead are replaced with the place notation 3 and 123, thereby forming a traditional Grandsire single.

There is no shorthand for leaving out the shift distance number. The replacement block’s only use is after the ‘&’ operator (discussed bleow). The two shift 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 represents one. The thing to the right of the ‘<<‘ or ‘>>’ must be a positive decimal number (not a definition or macro for one), that lies within one lead length of the item to the left of the ‘&’ operator (discussed immediately below). NOTE: Earlier versions of Eril used a shift number one less for right shifts, where ‘>>0’ was equivalent to the first change into a lead, while ‘<<0’ was the lead head. This was changed to the current form as it was not logical.

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 another ‘&’ expression. It cannot be multi-block expressions like ‘|’ or ‘+’ expressions:

  7;                   / Touch is a touch of Triples
  p = "Grandsire";     / Lookup Grandsire Triples from the plain
                       / methods collection
  Bob = 3.1 << 1;      / Place notation alterations to use for a bob
  Single = 3.123 << 1; / Place notation alterations to use for a
                       / Grandsire single
  b = p & Bob;         / The place notation for a bobbed lead of
                       / Grandsire
  s = p & Single;      / Likewise for a lead ending with a single
  choice = (p|b|s);    / What each lead may contain
  choice * [3-10];     / All touches from 42 to 140 changes

Note one important feature. If a replacement block is specified for which the number of changes spills over the end of the block, the replacement should also carry on into the next block of changes. Thus variations like April Day (really Reverse St. Bartholomew!) where the call spills into the next lead across a lead end can be readily accommodated, as in the example below. Eril can do this for you. (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 spill one change into lead
                                / beyond 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 the April Day 120s

Value blocks

In proving, if an option block occurs several times over, all the options are retried at each point they occur. What a value block does is to allow us to give a name to the latest seleted value of an option block already part of the earlier changes in a touch, and to reuse the same values for the options later in the touch. The syntax uses square braces and an optional identifier:

  KentOrOxford = [block1 34-34|-34-] + 16-12-16-12-16-12-16-12-16 + block1 + 16;

Note that when used with the repetition operator ‘*’ there is no need to give the value block a name. For example, to represent a whole course of plain leads of Kent or Oxford spliced, use: KentOrOxford*5;. To represent a whole course of either Kent or Oxford (same method every lead), use: [KentOrOxford]*5.

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

Some examples of touch descriptions

To show the expressiveness of this as a touch description language, here are some simple examples. The first example is a standard 720 of Plain Bob Minor. Notice how the macro substitutes an entire plain lead of the method with a copy of the plain lead of the method in this format, thereby still having the desired effect:

  6;
  pb = "PlainBob";
  p = 12<<0;
  b = 14<<0;
  s = 1234<<0;
  course(wrong, home) = pb & wrong + pb*3 + pb & home;
  part(lastCall) = course(b, b) + course(b, lastCall);
  halfExtent = part(p) + part(p) + part(s);
  halfExtent*2;

Second example: A search for all touches of Plain Bob Minor that are made of bobs or singles at Wrong and Home, and Singles at Before, and that have between six and twelve calls:

  6;
  p = "PlainBob";
  b = p&14<<0;
  s = p&1234<<0;
  plains = p*[0-4];
  call(whichCall, music) = plains + whichCall->music;
  wrong(bobOrSingle) = call(bobOrSingle, "*6.");
  sbefore = call(s, "16*");
  home(bobOrSingle) = call(bobOrSingle, "*6");
  (wrong(b|s)|sbefore|home(b|s))*[6-12]+plains;

Footnotes

The ERIL parser generates a 2.5 Mb file the first time it is run. If you leave the file alone, each successive time ERIL is started it will initialise much faster. If you delete it, it will take several extra seconds recreating it next time you run the program. What this file contains is a table for every Major change and which change to go to next for a given place notation. It is used internally to prove touches on fewer than 9 bells at lightning speed!