#ai #bellringing #artificial-intelligence


Fast and idiomatic primitives for Change Ringing

26 releases

0.12.0 Sep 9, 2023
0.11.5 Jan 4, 2023
0.11.0 Oct 21, 2022
0.10.0 Jul 31, 2022
0.3.0-alpha.1 Jul 15, 2021

#100 in Value formatting

Download history 31/week @ 2023-06-01 8/week @ 2023-06-08 51/week @ 2023-06-15 44/week @ 2023-06-22 25/week @ 2023-06-29 54/week @ 2023-07-06 25/week @ 2023-07-13 28/week @ 2023-07-20 15/week @ 2023-07-27 9/week @ 2023-08-03 14/week @ 2023-08-10 32/week @ 2023-08-17 31/week @ 2023-08-24 73/week @ 2023-08-31 77/week @ 2023-09-07 17/week @ 2023-09-14

198 downloads per month
Used in 2 crates

MIT license



BellFrame is a standard library for change ringing.

In other words, BellFrame aims to provide high-quality idiomatic implementations of basic things required for change ringing (e.g. borrowed/owned Row types, place notation parsing, method classification, access to the CC method library, etc.). These can then be shared between projects to speed up development and reduce bugs.

The two fundamental goals of BellFrame are reliability and performance, in that order. Reliability means that BellFrame's behaviour is always well defined and never causes Undefined Behaviour, even for pathological inputs. Performance means, specifically, that BellFrame's code should never be the limiting factor in a project. However, reliability is more important than unbeatable performance; I'm not going write complex optimised code until I at least know that an operation is a bottleneck. It's just so much easier to maintain simple code.


Core Data-types:

  • Truth, Parity, Stroke: Type-safe versions of bool, using the type system to prevent them from being mixed up.
  • Stage, Bell: Type-safe representations, again for avoiding common errors like calling the treble 1 (useful for humans) or 0 (for indexing into arrays).
  • Row, RowBuf: Borrowed and owned rows (respectively). Conceptually, Row is like [Bell] and RowBuf is like Vec<Bell>, except they are both guaranteed to contain valid permutations.


  • Method, Call: Method processing, and classification code. The classification algorithm is 100% compliant with the Framework (in implementing it, I discovered bugs in the CompLib's classifier, which have now been fixed).
  • MethodLib: Access to method libraries, with MethodLib::cc_lib() loading an up-to-date copy of the Central Council's library. Searching the library is also supported, and also returns suggested method names for unsuccessful searches.

Block Manipulation:

  • SameStageVec, Block: Ways of storing sequences of Rows in a single contiguous chunk of memory (thus allowing huge cache-efficiency and optimisation potential). SameStageVec is simply a sequence of Rows with the same Stage; Block allows its Rows to be given annotations of any type.

Other Useful Types:

  • Mask: Like a RowBuf, except that bells can be missing (denoted by x). For example, 1xxx5678 is a Mask, where 2,3,4 can go in any order.
  • Pattern: Default way of representing music patterns - like a Mask, except that * matches any number of bells. For example, *x7x8x* is a Pattern.


~166K SLoC