The coherence-law suite (functor laws) #
The combinators in ParamTrans/ParamArrow/ParamData build annotated
relations; this file proves the coherence laws that govern how they compose.
These are the Lean realizations of the laws of AdapTT (Adjedj, Lennon-Bertrand,
Benjamin, Maillard, AdapTT: Functoriality for Dependent Type Casts, POPL 2026):
the cast-adapter identity AdaptId and composition AdaptComp, plus the
functoriality of each type former over those adapters. AdapTT secures them
definitionally via a bespoke cast calculus. In Lean the cast-form laws
(cast_id/cast_trans) hold by rfl for free — the composite's forward map is
already function composition, so composition through nested type formers is
automatic and the "stuck adapter" gap Trocq's stuck.v documents does not arise;
they need not be cited, but they certify the functor laws hold, and are used
explicitly where a coercion chain is built by hand (e.g. a transport along a chain
of intermediate representations). The relational-form law (prod_trans_rel) is the one proved
propositionally (funext/propext). The dependent type formers extend the
non-dependent →/×/List/Option laws here: paramForall (Π,
ParamForall.lean) and paramSigma (Σ, ParamSigma.lean, sigma_cast_eq =
Adapt Σ = Σ Adapt) carry the same functoriality into the dependent world.
Contents #
Cast-composition (
AdaptComp/AdaptId).castViaParam P a := P.fwd.map ais the representation-change coercion.cast_transandcast_idare the two coherence laws that make coercion chains correct; both hold byrflbecauseParam_trans's forward map isQ.map ∘ P.mapandparamId's isid.Combinator distributes over composition (the functor law), forward-map /
castform. For each container/type-former combinator, the forward map of "compose then combine" equals "combine then compose" — thecast/forward-map version of the functor law (prod,option,list,arrow). Forarrowthis is contravariant in the domain.Combinator-distributes, full relational form. Proved for
prod(the relation of the composite equals the composite of the relations) viafunext/propext.arrow/sum/option/listrelational forms are noted where they need more than the cast form.Identity laws (
castform).prod_id/arrow_id: a combinator applied to identityParams acts as the identity coercion.
All laws are univalence-free: they live entirely in the map1–map3 forward
fragment, exactly the fragment ParamHierarchy's module docstring marks as
axiom-free in Lean (funext is a theorem; only the map4 universe relation
needs univalence).
1. Cast-composition: AdapTT AdaptId / AdaptComp #
Representation-change coercion induced by a Param: its forward map. The
forward level is map3 (the level paramId and Param_trans_map3
produce); the backward level stays polymorphic.
Equations
- Transfer.Param.castViaParam P a = P.fwd.map a
Instances For
AdaptComp — coercion through a composite relation is the composition of
the two coercions. Holds by rfl: Param_trans_map3's forward map is
Q.fwd.map ∘ P.fwd.map. This is the law that makes a coercion
chain (abstract → bytes → field) correct.
Composing element Params at the level the data combinators consume #
paramProd/paramOption/paramList consume Param .map2a .map0. Their
two-step composite is again a Param .map2a .map0, built from Map2a_trans's
forward record (the backward direction is map0, nothing to compose). This is
the data-rule instance of Param_trans.
Compose two element Params at the forward-map2a, backward-map0 level —
the shape the data combinators consume. Forward map is Q.map ∘ P.map.
Equations
- Transfer.Param.Param_trans_map2a_map0 P Q = { R := Transfer.Param.R_trans P Q, fwd := Transfer.Param.Map2a_trans P Q, bwd := { } }
Instances For
Its forward map is the function composition (definitional).
2. Functor law, cast / forward-map form #
For each combinator: the forward map of composing two combinator-built
Params equals the combinator applied to the composed argument-Params.
This is the AdapTT type-former functoriality (Adapt (F …) = F (Adapt …)) in
its cast form. The data combinators consume Param .map2a .map0; the arrow
combinator consumes Param .map1 .map1. The forward maps are function
compositions, so each law is rfl (or cases+rfl / simp through the
recursive lift).
Product (covariant in both arguments) #
prod_trans (cast form). The forward map of the product of two composite
element relations equals the composite of the two product forward maps:
prod_map (Q∘P) = prod_map Q ∘ prod_map P, componentwise.
Option / List (covariant) #
option_trans (cast form). Option.map (Q∘P) = Option.map Q ∘ Option.map P
on the lifted relations.
list_trans (cast form). List.map (Q∘P) = List.map Q ∘ List.map P on
the lifted relations.
Arrow (contravariant in the domain) #
paramArrow PA PB has forward map fun f a' => PB.fwd.map (f (PA.bwd.map a')).
Composing two arrows, the codomain maps compose forward (PB) while the domain
backward maps compose in the reverse order (PA) — the contravariance. The
Param_trans_map3 of the domain supplies a backward map P.bwd.map ∘ Q.bwd.map
(reversed), exactly matching the conjugation order, so the law is rfl.
arrow_trans (cast form). The forward map of the composite of two arrow
Params equals the arrow combinator applied to the composed domain/codomain
Params — with the domain composed contravariantly. Both sides send
f : A → A to the conjugation (QB∘PB) ∘ f ∘ (P_A.bwd ∘ Q_A.bwd).
3. Functor law, full relational form (product) #
prod_trans (relational form). The relation of the product of two
composite element relations equals (as a relation, via funext/propext)
the composite of the two product relations. This is the strict functor law
R_prod (Q∘P) = (R_prod Q) ∘ (R_prod P) for the product type former.
Left side: (a,b) ~ (c,d) iff ∃ m, PA.R a m ∧ QA.R m c and likewise on the
second component (two independent witnesses). Right side: one shared witness
pair (m₁,m₂). They agree because the product witness can be split/paired.
prod_id. The product combinator applied to two identity element
Params has forward map the identity on the product.
arrow_id. The arrow combinator applied to identity domain and codomain
Params has forward map the identity on the function space (up to funext):
conjugating by id on both sides is the identity.