Documentation

Transfer.Base.LevelRefusal

The univalence-free refusal guard #

The crux of the Trocq port is to compute, per subterm, the minimal (m,n) relation level a goal needs, and — when that level is the equivalence top (level equiv, where an equivalence is used as an equality) — refuse and report rather than import univalence (UA), which would enlarge the TCB and is in any case false for the (non-surjective) byte encodings.

That full per-subterm level inference is a separate, larger engine (Coq-Elpi → Lean MetaM). This module provides the tractable, decidable guard it relies on. The primary form of the cap lives on the Trocq lattice: the guard refuses exactly the map4 universe witness (permittedMapClass / classifyMapClass — map0–map3 is the univalence-free fragment, wider than the 3-point view). The 3-point classification (permitted / classify) is the view of that lattice guard through RelLevel.toMapClass (permitted_toMapClass / classify_toMapClass), so refusing equiv is the derived form of refusing map4. This guard makes the discipline enforceable and distinguishes this cap from full Coq-Trocq.

The discipline #

The permitted (m,n) slice on the lattice is map0–map3; in the 3-point view: map (transfers = forward), embedding (+ injective, transfers = both ways), and the refused equiv (image map4, needs UA). The crypto encodings (point/Fp¹²/word serializations) are embeddings, not bijections, so a goal that would need equiv is one this layer declines.

Primary. The univalence-free slice of the Trocq lattice: a MapClass is permitted iff it is not the map4 universe witness. map0–map3 are univalence-free (the fragment wider than the 3-point view — map2a, map2b and map3 are all permitted); only map4 needs UA.

Equations
Instances For

    The univalence-free slice in the 3-point view: the lattice guard through toMapClass. map and embedding are univalence-free; equiv (image map4) needs UA.

    Equations
    Instances For

      The 3-point guard is the view of the lattice guard (definitional).

      theorem Transfer.LevelRefusal.permitted_eq_old (lvl : RelLevel) :
      permitted lvl = match lvl with | RelLevel.equiv => false | x => true

      Old = new: the derived guard agrees with the original 3-point table (refuse exactly equiv).

      The lattice cap refuses exactly the map4 universe witness.

      The outcome of classifying the level a (sub)goal needs: either a permitted univalence-free transfer at lvl, or a refusal carrying a report of why (which subterm forced the equivalence level). The full engine feeds classify the level it infers per subterm; this module supplies classify and the report, not the inference.

      Instances For
        Equations
        • One or more equations did not get rendered due to their size.
        Instances For

          Primary. Classify a needed lattice level: refuse exactly the map4 universe witness, reporting it; every univalence-free level is permitted at its 3-point view.

          Equations
          Instances For

            Classify a needed level: the lattice classifier through toMapClass — refuses exactly the equivalence top (image map4), reporting it.

            Equations
            Instances For

              The 3-point classifier is the view of the lattice classifier (definitional).

              The lattice classifier refuses exactly the map4 universe witness.

              The wider-than-3-point fragment is permitted at the lattice level: a two-sided graph relation (map3) classifies as an embedding-view transfer, not a refusal.

              The guard is correct and decidable #

              map is permitted (forward equation transfer needs no UA).

              embedding is permitted (both-ways equation transfer via injectivity — the level at which the crypto encodings, and the Num ↪ ℕ transfer, live).

              equiv is refused with a report — the univalence-free cap.

              classify permits a level iff permitted says so — the guard and the classifier agree, by cases on the three levels.

              A minimal-level inferencer over a goal-shape model #

              The classifier above takes the needed level as given and only classifies it. This inferencer computes the level from a small, hand-rolled goal-shape AST and feeds the inferred level to classify, so classify is reached with equiv when the shape forces it rather than when a level is supplied.

              This is a minimal model. It walks a GoalShape — a small model of the cases the level discipline turns on — not a real Expr. The full engine traverses a Lean Expr, threads RelatedAt annotations through binders, and is a larger MetaM port (no Lean precedent). The contribution here is the direction of dataflow: level ← shape, then refuse-or-permit.

              The modeling decisions #

              A tiny goal-shape AST: the cases the minimal-level inferencer reasons about. A model of the level discipline rather than a real Expr (the full engine walks Expr; this drives the dataflow level ← shape).

              • leafEq (carrierLevel : RelLevel) (surjective : Bool) : GoalShape

                An equation at a leaf whose carrier encoding has level carrierLevel; surjective records whether that encoding is onto (so the backward direction is free) — false is the crypto case (injective, not onto).

              • forallFwd (dom : GoalShape) : GoalShape

                A ∀ transferred in the forward (map) direction: adds no strength.

              • forallBwd (dom : GoalShape) : GoalShape

                A ∀ needing the backward direction over dom: needs at least embedding, and forces equiv when dom is a non-surjective leaf.

              • compose (a b : GoalShape) : GoalShape

                A composite: level is the meet (weakest) of the parts.

              Instances For
                Equations
                • One or more equations did not get rendered due to their size.
                Instances For

                  The maximum (stronger) of two levels — dual to RelLevel.meet; a backward ∀ needs at least embedding, so it takes the max with embedding.

                  Equations
                  Instances For

                    Whether a shape's domain is a leaf that is an embedding but not surjective — the configuration whose reverse direction needs a bijection, hence forces equiv under a backward ∀.

                    Equations
                    Instances For

                      Infer the minimal level a shape needs. The level is computed, then handed to classify. See the section docstring above for the modeling decisions behind each clause.

                      Equations
                      Instances For

                        The end-to-end guard: infer the level the shape needs, then refuse or permit it. classify is called on a computed level.

                        Equations
                        Instances For

                          The inferencer is exercised end-to-end #

                          A plain embedding equation (e.g. a Num ↪ ℕ leaf) infers embedding and is permitted.

                          A forward ∀ over an embedding leaf still infers embedding and is permitted — the forward direction adds no strength.

                          A backward ∀ over a surjective embedding leaf is still permitted at embedding — the reverse direction is available because the leaf is onto.

                          The central refusal. A backward ∀ over a non-surjective embedding leaf (the crypto encoding case) infers equiv, so the end-to-end guard refuses — the engine declines exactly when a subterm forces the equivalence level.

                          The inferred level for that refused shape is exactly equiv — pinning down why it was refused.

                          A composite drops to the weaker level: composing a map leaf with an embedding leaf infers map (the meet), and is permitted at map.

                          A composite that contains a refusing part still composes down: meeting an equiv-forcing backward-∀ with a map leaf yields map — the composite is permitted because its weakest part carries no UA need. So meet can rescue a transfer, and refusal is level-driven (it occurs only when the inferred level — after all meets — is equiv).

                          What this module is not #

                          The inferencer above is a minimal model over a hand-rolled GoalShape; the level it computes is faithful to the discipline (forward adds nothing; backward over a non-surjective embedding forces equiv; composites meet), but the full engine walks a real Expr, threads RelatedAt levels through actual binders, and infers the least level that makes the whole transfer go through. That level-annotated parametricity translation is the heart of the Trocq paper and a larger MetaM port (no Lean precedent). The RelatedAt kernel carries the level; the transfer tactic traverses binders; the minimal-level solver over Expr is not implemented here. The contribution here is the dataflow direction: the level is computed and fed to classify rather than supplied.