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.5.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.5.0.post1.dev0-py3-none-any.whl (139.7 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: co_lambda-0.5.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.5.0.post1.dev0.tar.gz
Algorithm Hash digest
SHA256 ef9173d72c3a2222cabeb77c2033b4ee7efba420dea97490598d614e1a553fb5
MD5 5cc815f866b5430e8e3514808cb7f5d6
BLAKE2b-256 78c5157cf1205779f5bee1f38650b8a1bc89d152b48f8806222736ce8a8f16c3

See more details on using hashes here.

Provenance

The following attestation bundles were made for co_lambda-0.5.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.5.0.post1.dev0-py3-none-any.whl.

File metadata

File hashes

Hashes for co_lambda-0.5.0.post1.dev0-py3-none-any.whl
Algorithm Hash digest
SHA256 7067b92984fb771c8751e03810424ff673be03469e2e298ddba0eb69d35853ea
MD5 e877dfcab987c93f18a8bc2679013b24
BLAKE2b-256 95e839109113fae42667843da647939c2753b234e6830c12b1130b061fe16be4

See more details on using hashes here.

Provenance

The following attestation bundles were made for co_lambda-0.5.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