The arrow (app / function) parametricity rule #
A Lean port of Trocq's std/Param_arrow.v (https://github.com/rocq-community/trocq):
the combinators that build a Param annotated relation on a function space
(A → B) from Param relations on the domain A and codomain B.
This is the function rule of the parametricity translation: it tells the
engine how to relate f : A → B and f' : A' → B'.
The funext advantage #
Coq's std variant gates the map2b/map3 arrow combinators on a
`{Funext} instance, because their R_in_map field needs functional
extensionality to prove map f = f' from a pointwise relation. Lean has
funext as a theorem, so those gates are unnecessary: map0 through map3
(and map4, free by proof irrelevance on Prop-valued R) hold with no
extra axioms.
Accessor dictionary (Coq → Lean) #
At the input levels where the field exists:
map PB→PB.fwd.map(PB fwd ≥map1)comap PA→PA.bwd.map(PA bwd ≥map1)map_in_R PB→PB.fwd.map_in_R(PB fwd ≥map2a)R_in_map PB→PB.fwd.R_in_map(PB fwd ≥map2b)comap_in_R PA→PA.bwd.map_in_R(PA bwd ≥map2a)R_in_comap PA→PA.bwd.R_in_map(PA bwd ≥map2b)
Recall PA.bwd : MapHas n (symRel PA.R), and symRel PA.R a' a = PA.R a a',
so PA.bwd.map : A' → A, PA.bwd.map_in_R : ∀ a' a, PA.bwd.map a' = a → PA.R a a',
and PA.bwd.R_in_map : ∀ a' a, PA.R a a' → PA.bwd.map a' = a.
Trocq R_arrow: two functions are related when they send PA-related
inputs to PB-related outputs. Coq accesses only the R field, so the
level parameters stay fully polymorphic (the function relation does not
depend on how much structure each component carries).
Equations
- Transfer.Param.R_arrow PA PB f f' = ∀ (a : A) (a' : A'), PA.R a a' → PB.R (f a) (f' a')
Instances For
map0 — no structure #
Trocq Map0_arrow.
Equations
- Transfer.Param.Map0_arrow PA PB = { }
Instances For
map1 — the forward map PB.map ∘ f ∘ PA.comap #
Trocq Map1_arrow: the function map sends f : A → B to
fun a' => PB.fwd.map (f (PA.bwd.map a')). Needs PA backward-map1
(to get comap) and PB forward-map1 (to get map).
Equations
Instances For
map2a — map plus graph-inclusion map_in_R #
Trocq Map2a_arrow. The function map is the same PB.map ∘ f ∘ PA.comap;
map_in_R says: if that map sends f to f', then f and f' are
R_arrow-related. Needs PA backward-map2b (R_in_comap) and
PB forward-map2a (map_in_R).
Equations
Instances For
map2b — map plus relation-inclusion R_in_map (via funext) #
Trocq Map2b_arrow. R_in_map says: if f, f' are R_arrow-related,
then the function map sends f to f'. The Coq std variant gates this
on `{Funext}; in Lean funext is a theorem, so it is axiom-free.
Needs PA backward-map2a (comap_in_R) and PB forward-map2b
(R_in_map).
Equations
Instances For
map3 — both inclusions (via funext) #
Trocq Map3_arrow: the full graph relation, combining Map2a_arrow's
map_in_R and Map2b_arrow's R_in_map. Needs both inclusions on each
component: PA backward-map3, PB forward-map3. Axiom-free in Lean
(the R_in_map half uses funext).
Equations
Instances For
map4 — map3 plus the (free, proof-irrelevant) coherence #
Trocq Map4_arrow. Over Prop-valued R the coherence R_in_mapK is
automatic by proof irrelevance, so the univalent level is constructible
without univalence. Needs PA backward-map3, PB forward-map3.
Equations
Instances For
The Param-level arrow combinator #
Assembling forward and backward structure into a Param on the function space.
The forward-map1, backward-map1 output needs only a forward and a backward
map on each component, i.e. PA PB : Param .map1 .map1.
- The forward map is
Map1_arrow'sPB.map ∘ · ∘ PA.comap. - The backward map is the symmetric
PA.map ∘ · ∘ PB.comap—Map1_arrowrun on the directions ofPA.symm,PB.symm. SinceMap1Has(and hence thebwdfieldMapHas .map1 (symRel (R_arrow PA PB))) records only a function, it is built inline and no relation-coercion is needed.
paramArrow: from PA PB : Param .map1 .map1, an annotated relation
Param .map1 .map1 (A → B) (A' → B') whose relation is R_arrow PA PB,
forward map PB.map ∘ · ∘ PA.comap, backward map PA.map ∘ · ∘ PB.comap.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Demo: the arrow combinators compose on a concrete pair #
The identity (equality) relation on a type, packaged at the levels each arrow
rule consumes (Param .map0 .map3 as domain, Param .map3 .map0 as codomain,
Param .map1 .map1 for paramArrow), feeds two copies through the arrow
combinators; the resulting function relation is the pointwise lift of
equality.
The diagonal as a domain input for the arrow rules: forward-map0,
backward-map3.
Equations
Instances For
The diagonal as a codomain input for the arrow rules: forward-map3,
backward-map0.
Equations
Instances For
The diagonal at the forward-map1, backward-map1 level (the input shape
paramArrow consumes).