Aviary
A Jupyter kernel for combinatory logic (combinator calculus): SKI, BCKW, and the Smullyan aviary (Bluebird, Cardinal, Mockingbird, Phoenix, Psi, Vireo, the once- and twice-removed permuting birds, and more), evaluated under normal-order (leftmost-outermost, lazy) reduction to full normal form.
K ▲ (M M)
▲ [1 step]
M M (the classic non-terminating self-application) is not touched --
that's normal order's laziness in action.
Install
Requires Python >= 3.10.
pip install aviary-kernel
python -m aviary_kernel.install --user # or --prefix /path/to/env
Or from a checkout, for development:
python3 -m venv .venv && source .venv/bin/activate
pip install -e .
python -m aviary_kernel.install --prefix .venv
This registers a kernelspec named aviary, displayed as
"Aviary (Combinator Calculus)" in Jupyter frontends. Then:
jupyter notebook demo.ipynb # open the demo
jupyter console --kernel aviary # or drop into a REPL
(--user installs into your per-user Jupyter kernel directory;
--prefix .venv installs into the active virtualenv instead, which is
handy for local development without touching your global Jupyter
config.)
Usage
A cell is a sequence of lines; each non-empty line is one statement: a
magic (%name ...), a definition (Name := expr or
Name v1 v2 -> expr), or an expression. # starts a comment.
Expressions
Application is left-associative and implicit -- S K K means
((S K) K). Parentheses group; S K (K I) differs from S (K (K I)).
Any built-in bird, or arbitrary Unicode atom (▲, 🟢, foo_bar), can
appear free:
B ▲ 🟢 (K ◆ ●)
▲ (🟢 ◆) [2 steps]
Names like Q1/Q₁, W'/W′/W¹, and E^/Ê are the same bird
under Unicode normalization (subscript digits, primes, superscript one)
and explicit ASCII aliases; %ascii on/off picks which script output
uses.
Definitions
🟢 x y z -> x (z y) # rule (a new combinator of arity 3)
Theta := U U # alias (already preloaded, for reference)
Rules can be recursive (the name may appear in its own body -- that's
how you'd hand-roll a sage bird); recursive definitions reduce fine but
can't be basis-expanded to a finite S/K/I term (%ski raises an error
explaining why, and suggests routing through Y/Θ instead). Redefining
a built-in is an error; redefining a user definition replaces it.
%undef Name removes a user definition; %defs lists them all.
Magics
| Magic | Effect |
|---|---|
%trace expr |
step-by-step reduction trace |
%whnf expr |
reduce to weak head normal form only |
%ski expr / %sk expr |
basis-expand to S/K/I (or strict S/K); does not reduce |
%fuel N |
set the step budget for the session (bare form prints it) |
%size N |
set the term-size guard (bare form prints it) |
%birds |
table of the whole registry |
%whatis X |
one bird/definition's name(s), arity, rule, λ-form, and S/K/I form |
%defs |
list user definitions |
%undef X |
remove a user definition |
%ascii on|off |
toggle Q1 vs Q₁-style output |
Reduction is fuel-bounded (10 000 steps and 100 000 atoms by default);
running out is a warning, not an error -- you get the partial term
back and can raise the budget with %fuel/%size and try again:
M M
M M [10000 steps]
⚠ no normal form after 10000 steps (fuel exhausted); term size 3
Examples
Every non-recursive bird's SKI form comes from Curry's bracket-abstraction algorithm applied to its rule, on demand:
%ski Q₁
S (S (K S) (S (K K) (S (K S) K))) (K (S (K (S I)) K))
%trace shows normal order at work, including descent into stuck
arguments once the head sticks:
%trace Φ B C K x y
0 Φ B C K x y
Φ 1 B (C x) (K x) y
B 2 C x (K x y)
K 3 C x x
Package layout
aviary_kernel/
terms.py Term model (Atom | App), pretty-printer
parser.py lexer + parser -> Term
birds.py the bird registry (verified against two independent sources; see below)
reduce.py normal-order reducer: iterative, fuel/size/interrupt-checked
abstraction.py bracket abstraction -> S/K/I (and S/K)
magics.py %-command dispatch
kernel.py AviaryKernel(ipykernel.kernelbase.Kernel)
install.py `python -m aviary_kernel.install` writes the kernelspec
kernelspec/ kernel.json
tests/ pytest suite (parser, birds, reduce, abstraction, kernel end-to-end)
demo.ipynb living documentation / acceptance demo
SPEC.md the full design spec
Development
pip install -e '.[test]'
pytest # full suite
python -m aviary_kernel.install --prefix .venv # register the kernel into this venv
Metadata
Release files for aviary-kernel 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| aviary_kernel-0.1.0.tar.gz | 38.4 kB | Without provenance | Details for aviary_kernel-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| aviary_kernel-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for aviary_kernel-0.1.0-py3-none-any.whl |
Total release size: 65.0 kB
Release files / aviary_kernel-0.1.0.tar.gz
| Download URL | aviary_kernel-0.1.0.tar.gz |
|---|---|
| Size | 38.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
496f70782069b3f6a3a1d2842ceade0d2464f74e1787b4d71840303efd849493
|
|
BLAKE2b-256 checksum How to use checksums |
16f8735729cf8bf1bd877610a84556abb66885ff77dfa820e129d7d95c802a11
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.7
|
Release files / aviary_kernel-0.1.0-py3-none-any.whl
| Download URL | aviary_kernel-0.1.0-py3-none-any.whl |
|---|---|
| Size | 26.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b6b969ac1d6da68379b92e352c99f4ef52532c5bdd8f9daa89eb65a994b97b2f
|
|
BLAKE2b-256 checksum How to use checksums |
59642dbc21188fd309787d97e6ac0c24d41d9dc0552d830e424b37a16f663e9b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.7
|
Security for aviary-kernel 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.