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
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file aviary_kernel-0.1.0.tar.gz.
File metadata
- Download URL: aviary_kernel-0.1.0.tar.gz
- Upload date:
- Size: 38.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
496f70782069b3f6a3a1d2842ceade0d2464f74e1787b4d71840303efd849493
|
|
| MD5 |
2f06fa55e7bf36f107ee8b4ac61e0ac5
|
|
| BLAKE2b-256 |
16f8735729cf8bf1bd877610a84556abb66885ff77dfa820e129d7d95c802a11
|
File details
Details for the file aviary_kernel-0.1.0-py3-none-any.whl.
File metadata
- Download URL: aviary_kernel-0.1.0-py3-none-any.whl
- Upload date:
- Size: 26.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b6b969ac1d6da68379b92e352c99f4ef52532c5bdd8f9daa89eb65a994b97b2f
|
|
| MD5 |
57f49c752bbaa7aede7579f74dc307d9
|
|
| BLAKE2b-256 |
59642dbc21188fd309787d97e6ac0c24d41d9dc0552d830e424b37a16f663e9b
|