Documentation

Transfer.Combinators.ParamCoherence

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 #

  1. Cast-composition (AdaptComp/AdaptId). castViaParam P a := P.fwd.map a is the representation-change coercion. cast_trans and cast_id are the two coherence laws that make coercion chains correct; both hold by rfl because Param_trans's forward map is Q.map ∘ P.map and paramId's is id.

  2. Combinator distributes over composition (the functor law), forward-map / cast form. For each container/type-former combinator, the forward map of "compose then combine" equals "combine then compose" — the cast/forward-map version of the functor law (prod, option, list, arrow). For arrow this is contravariant in the domain.

  3. Combinator-distributes, full relational form. Proved for prod (the relation of the composite equals the composite of the relations) via funext/propext. arrow/sum/option/list relational forms are noted where they need more than the cast form.

  4. Identity laws (cast form). prod_id/arrow_id: a combinator applied to identity Params 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 #

The identity annotated relation on T: relation Eq, both maps id, full map3 in both directions. The diagonal Param. (Same data as paramEqFull; named paramId to flag its role as the unit of the composition Param_trans.)

Equations
Instances For

    The identity annotated relation at the forward/backward-map1 level — the input shape paramArrow consumes. Relation Eq, both maps id.

    Equations
    Instances For

      The identity annotated relation at the forward-map2a, backward-map0 level — the input shape paramProd/paramOption/paramList consume. Relation Eq, forward map id (its graph is Eq).

      Equations
      Instances For
        def Transfer.Param.castViaParam {A B : Type u} {n : MapClass} (P : Param MapClass.map3 n A B) (a : A) :
        B

        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
        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.

          theorem Transfer.Param.cast_id {A : Type u} (a : A) :

          AdaptId — coercion through the identity relation is the identity. Holds by rfl: paramId's forward map is id.

          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
          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.

            4. Identity laws (cast form): combinator over paramId = identity coercion #

            theorem Transfer.Param.prod_id_cast {A : Type u} (p : A × A) :

            prod_id. The product combinator applied to two identity element Params has forward map the identity on the product.

            theorem Transfer.Param.arrow_id_cast {A : Type u} (f : A → A) :

            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.

            Demos: the coherence laws close, and one combinator law #