Skip to main content

A least-fixpoint first-order-shape-relation interpreter for the lambda-calculus

Project description

co_lambda

A first-order-shape-relation interpreter for the lambda-calculus, realizing the semantics of the paper papers/co-lambda/first-order.tex, depending on fixpoints.

A lambda-term's tree is the readout of a single first-order weak-head shape relation Sh over term positions. The shape at a position is single-valued, so there is no set to aggregate. readout(node) resolves each position's head via its Sh and descends.

Because positions are interned (structurally-equal positions are one object, identity is a pointer test), a cyclic structure has finitely many positions and the least-fixpoint reading folds it into a finite rational tree where head reduction would unfold forever. So the readout terminates on every rational tree, and decides an unproductive cycle as the meaningless leaf in finite time, where head reduction diverges. Interning is the finest instance of a pluggable position congruence (see below); a coarser sound congruence folds more.

readout has two re-entry policies:

  • fold_cycles=True (default) is the least fixpoint lfp, the denotation: a guarded cycle folds into a finite rational graph (render prints it with #N back-references); the only leaves are variables and the meaningless .
  • fold_cycles=False is the finite-budget first-iteration reading T↑1: a re-entered guarded cycle is cut to the distinct guarded-cut leaf (the hole where the budget stopped on a productive cycle), kept separate from the meaningless (an unproductive cycle, a position with no shape). never appears in the least fixpoint.

The calculus is pure (Var/Lam/App): no recursion binder is needed. The Y combinator produces the structural repetition that interning folds, so:

  • Y (cons 0) (the cyclic stream r = cons 0 r) folds to a finite rational tree.
  • Ω = (λx.xx)(λx.xx) and Y (λx.x) (i.e. letrec x = x) are unproductive cycles: they read out as under both readings.

The fold/cut is taken only at closed positions, so a folded back-reference never misreads a free de Bruijn variable.

Position congruence (a second parameter)

Which positions count as "the same" when the readout folds is a parameter, a position congruence (Definition def:congruence in the paper). readout(node, congruence=...) keys the fold on congruence.key(node) instead of raw object identity. A congruence is sound when it is contained in tree equality (it never folds positions with different trees); stated over the full signature, soundness is the congruence law read coinductively, so a well-formed congruence folds without changing the denotation. _congruence.py provides four instances, from finest to coarser:

  • IdentityCongruence (the default): syntactic de Bruijn identity, key = id(node), a pointer test. The finest instance; reproduces the pure-interning readout exactly.
  • EGraphCongruence: a union-find with congruence closure over the syntactic constructors. The caller asserts sound (tree-equal) merges with merge(a, b); closure propagates them to App/Lam parents, and the readout shares the merged positions. The inductive (least-fixpoint) family: it folds whatever finitely many tree-equal pairs generate.
  • PositionEGraphCongruence: the faithful def:congruence, keyed on the demanded descent (the shape tree) rather than the syntax. It auto-folds any two positions bisimilar under Sh with no asserted merge (a redex and its reduct collapse on sight), folding exactly the rational fragment. It cannot finitize an infinitely-presented shape graph, so the Y F 0 witness below still diverges: bisimulation alone does not rescue a dead-argument cycle.
  • DeadSubtermCongruence(rules=...): equality up to dead subterms, the key being the syntax with every dead-argument slot erased to a canonical placeholder (a tree-preserving map, not a congruence closure). The dead slots are recognised by a library of sound rules; the caller enables a subset. RecursionArgumentRule folds the paper's Y F 0 witness, where a constant-headed recursion carries an index it never inspects; UnusedParameterRule erases the argument of a function that discards it. This is the one reading that folds the witness, which neither e-graph can.

No parser is provided. Build terms in Python with the HOAS DSL in _dsl.py (lam, app, build), which compiles to a first-order de Bruijn AST; _prelude.py collects example terms (combinators, Scott-encoded lists, Church numerals with Peano arithmetic).

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

co_lambda-0.6.0.post1.dev0.tar.gz (136.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

co_lambda-0.6.0.post1.dev0-py3-none-any.whl (139.7 kB view details)

Uploaded Python 3

File details

Details for the file co_lambda-0.6.0.post1.dev0.tar.gz.

File metadata

  • Download URL: co_lambda-0.6.0.post1.dev0.tar.gz
  • Upload date:
  • Size: 136.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for co_lambda-0.6.0.post1.dev0.tar.gz
Algorithm Hash digest
SHA256 0e54adc0ec351a9b87b332a123f0de8eceaaaac000beb618bf1352bc1981d759
MD5 665a0cc5beba8d886aab672a315c444b
BLAKE2b-256 7b4b6d6dadd92a99579b7ac3f00fabb9685c7bcd8557e20a75828135d4a630b2

See more details on using hashes here.

Provenance

The following attestation bundles were made for co_lambda-0.6.0.post1.dev0.tar.gz:

Publisher: ci.yml on Atry/co-lambda

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file co_lambda-0.6.0.post1.dev0-py3-none-any.whl.

File metadata

File hashes

Hashes for co_lambda-0.6.0.post1.dev0-py3-none-any.whl
Algorithm Hash digest
SHA256 6287be69fc10725893477f073161cc2087c80edff3866afbbc3ff6fadab502b8
MD5 3bcf306a4743963bfe8e770e5169210b
BLAKE2b-256 a22b234f870793065d370269fbce9fadc270a30d5b58c48f40092a03f42eb3df

See more details on using hashes here.

Provenance

The following attestation bundles were made for co_lambda-0.6.0.post1.dev0-py3-none-any.whl:

Publisher: ci.yml on Atry/co-lambda

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page