derive_param_congr — a constructor-congruence Related deriver #
The Related kernel (Transfer/Base/Related.lean) auto-composes binary-op trees
on a single carrier (composeBinOp over RelatedBinOp squares) but stops at
any structure head: it provides no constructor congruence for user inductives.
Crossing a structure boundary (e.g. a value of a single-constructor structure
that encodes to the product of its fields) therefore needs, per type, one
product-encoding enc plus one constructor-congruence Related instance — the
Param_<T> boilerplate.
This file generates that boilerplate. It is the Trocq/Elpi Param_<T> analogue
for the Related kernel: a metaprogram that, for a single-constructor structure
T, reads the constructor's field names and types and emits
- a
ParamEnc T αinstance — the product encodingenc x = (ParamEnc.enc x.f₁, …, ParamEnc.enc x.fₙ), where each field's encoding is resolved recursively throughParamEnc(so nested derived structures compose automatically), and - the constructor congruence
Related (ParamEnc.enc) (T.mk a₁ … aₙ) (a₁', …, aₙ')from the per-fieldRelated (ParamEnc.enc) aᵢ aᵢ'facts.
With both registered, instance resolution transports a structured value
compositionally — the constructor congruence on top, the base-carrier
RelatedBinOp squares underneath — with no monolithic whole-op leaf.
Surface #
derive_param_congr T— acommandelaborator (works in-file), andderiving instance ParamCongr for T/deriving ParamCongr— the registered deriving handler (live for downstream modules, sinceinitializetakes effect only after this module is imported).
Both route to the same generator, deriveParamCongrCore.
Reflective-vs-assumed boundary #
- Reflective (read off the structure): the constructor name, the field
names, the field types (hence the
aᵢbinders), the structure's parameters (the generated instances are parametric in them), and each field's encoded typeαᵢ(viaParamEnc.enc-type inference, so nested structures' encodings compose). - Assumed / out of scope (matching the structure focus of relational
parametricity derivers): single constructor only (multi-constructor inductives
and indexed/dependent families are rejected); the per-field encodings are
whatever
ParamEncresolves to (an atomic field uses the low-priorityidleaf; a nested structure uses its own derived instance — derive bottom-up); the base-carrier op squares (RelatedBinOp) are supplied, never invented — therelatedBinOpOfLeafbridge only re-uses an existingid-registered square at theParamEnc-leaf encoding.
1. The field-encoding typeclass #
Leaf-encoding Related. a transports to itself along the ParamEnc
leaf (it is id). Gives the base case of the congruence's per-coordinate
composition an RHS that is literally the input (not ParamEnc.enc a), so
composeBinOp terminates cleanly at base-carrier variables.
Marker class keying the deriving handler (deriving instance ParamCongr for T). The handler generates the ParamEnc/Related instances and ignores the
literal class.
Instances
2. The generator #
Build the anonymous tuple syntax (x₀, …, xₙ₋₁) (right-nested Prod.mk);
a singleton is returned bare.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Build the right-nested product type syntax x₀ × … × xₙ₋₁; a singleton is
returned bare.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The core generator: read single-constructor structure declName and emit its
ParamEnc product-encoding instance and its constructor-congruence Related
instance.
Equations
- One or more equations did not get rendered due to their size.
Instances For
3. Surfaces #
In-file command: derive_param_congr T.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
The registered deriving handler (deriving instance ParamCongr for T).
Single-constructor structures only; declines otherwise so another handler can
take over.
Equations
- One or more equations did not get rendered due to their size.