Documentation

CatCryptCore.Deep.RawCode

Raw Code: Free Monad for Computations #

This file defines the deep embedding of CatCrypt computations as a free monad.

Main definitions #

Location model #

Nominal Structure #

Location validity is tracked by the ValidCode inductive predicate (see Package.lean), not by a syntactic locs function on RawCode.

Implementation notes #

This is a free monad, meaning it represents computation syntax trees without any semantic interpretation. The monad instance allows using do-notation for building computations, but the monad laws are not necessarily satisfied at the syntactic level (they hold after quotienting by observational equivalence).

We use Core.Location directly to enable axiom-free interpretation to the shallow embedding (SPComp). This unifies the heap model between the deep and shallow embeddings.

References #

inductive CatCrypt.Deep.RawCode :
Type u → Type (u + 1)

Raw code: syntax tree for probabilistic stateful computations.

This is a free monad representing:

  • Pure computations (ret)
  • Sequencing (bind)
  • Probabilistic choice (sample)
  • State access (get/put)
  • Failure (fail)

The type parameter α is the return type of the computation.

Note: We use Core.Location directly to enable axiom-free interpretation to the shallow embedding. Location types are at Type 0 (universe level 0), so get returns ULift.{u} ℓ.ty to lift to universe u.

Instances For
    @[match_pattern]
    def CatCrypt.Deep.RawCode.pure {α : Type u} (a : α) :

    Pure return: lift a value into a computation

    Equations
    Instances For
      @[match_pattern]
      def CatCrypt.Deep.RawCode.seq {α β : Type u} (c : RawCode α) (k : αRawCode β) :

      Monadic bind: sequence two computations

      Equations
      Instances For
        @[implicit_reducible]

        Monad instance for RawCode.

        Note: This instance is not lawful at the syntactic level! The monad laws hold only after quotienting by observational equivalence. This instance is provided to enable do-notation.

        Equations
        • One or more equations did not get rendered due to their size.
        @[implicit_reducible]

        Applicative functor instance (derived from Monad)

        Equations
        • One or more equations did not get rendered due to their size.
        def CatCrypt.Deep.RawCode.inductionOn {α : Type u} {motive : {α : Type u} → RawCode αProp} (c : RawCode α) (ret : ∀ {α : Type u} (a : α), motive (ret a)) (bind : ∀ {α β : Type u} (c : RawCode α) (k : αRawCode β), motive c(∀ (a : α), motive (k a))motive (c.bind k)) (sample : ∀ (T : Type u) [inst : Fintype T] [inst_1 : Nonempty T], motive (sample T)) (get : ∀ ( : Core.Location), motive (get )) (put : ∀ ( : Core.Location) (v : .ty), motive (put v)) (fail : ∀ {α : Type u}, motive fail) (oracleCall : ∀ (op : ) (dom codom : Type u) (x : dom), motive (oracleCall op dom codom x)) (embed : ∀ {α : Type u} (c : Core.SPComp α), motive (embed c)) :
        motive c

        Structural induction principle for RawCode.

        This provides a convenient way to prove properties by structural induction, handling all constructors of the free monad.

        Equations
        • =
        Instances For

          Helper: sample from a non-empty fintype (with explicit instance arguments)

          Equations
          Instances For
            @[inline]

            Helper: failing computation

            Equations
            Instances For

              Oracle Call Substitution #

              substOracle replaces oracle calls in code with concrete implementations. This is the key operation for package linking: after constructing code with oracleCall placeholders, linking substitutes the linked package's implementations.

              def CatCrypt.Deep.RawCode.substOracle {α : Type u} (c : RawCode α) (env : (dom codom : Type u) → domRawCode codom) :

              Substitute all oracle calls in code with concrete implementations.

              Given an environment env that maps operation identifiers and types to RawCode implementations, this function recursively replaces every oracleCall op dom codom x with env op dom codom x.

              This is the core of DeepPackage.link: the linked package's implementations become the oracle environment.

              Equations
              Instances For
                theorem CatCrypt.Deep.RawCode.substOracle_id {α : Type u} (c : RawCode α) :
                (c.substOracle fun (op : ) (dom codom : Type u) (x : dom) => oracleCall op dom codom x) = c

                Substituting with the identity oracle environment (oracleCall) is a no-op.

                substOracle c (fun op dom codom x => .oracleCall op dom codom x) = c

                This is proved by structural induction on the code tree.

                theorem CatCrypt.Deep.RawCode.substOracle_comp {α : Type u} (c : RawCode α) (env₁ env₂ : (dom codom : Type u) → domRawCode codom) :
                (c.substOracle env₁).substOracle env₂ = c.substOracle fun (op : ) (dom codom : Type u) (x : dom) => (env₁ op dom codom x).substOracle env₂

                Double substitution can be composed into a single substitution.

                (c.substOracle env₁).substOracle env₂ = c.substOracle (fun op dom codom x => (env₁ op dom codom x).substOracle env₂)

                This is the key lemma for proving associativity of DeepPackage.link.

                @[simp]
                theorem CatCrypt.Deep.RawCode.substOracle_fail {α : Type u} (env : (dom codom : Type u) → domRawCode codom) :

                Substituting into fail gives fail.

                @[simp]
                theorem CatCrypt.Deep.RawCode.substOracle_ret {α : Type u} (a : α) (env : (dom codom : Type u) → domRawCode codom) :
                (ret a).substOracle env = ret a

                Substituting into ret gives ret.

                A predicate asserting that a RawCode tree contains no oracleCall nodes.

                Code satisfying NoOracleCall is self-contained: it does not depend on any oracle environment. This is a key property for reduction packages, where non-delegated operations are handled by code that never calls imports.

                All code produced by G_core_package_construction satisfies this predicate, since it has imports := ∅.

                Instances For
                  theorem CatCrypt.Deep.RawCode.substOracle_eq_self {α : Type u} {c : RawCode α} (h : c.NoOracleCall) (env : (dom codom : Type u) → domRawCode codom) :
                  c.substOracle env = c

                  substOracle is a no-op on code without oracle calls.

                  This is the foundational lemma for reduction package proofs: when the reduction delegates an operation to G_core's impl (which has no oracle calls), the linking substitution doesn't change the code.

                  Location Registry #

                  A location registry maps atoms to Core.Locations. This enables nominal reasoning about code while maintaining compatibility with the evaluation that uses Core.Location (with nat ids).

                  The registry ensures:

                  1. Each atom maps to a unique Core.Location id
                  2. The mapping is consistent (same atom always gives same id)
                  3. Types are preserved

                  A location registry maps atoms to Core.Location ids. This bridges the nominal (atom-based) and evaluation (nat-based) models.

                  Instances For

                    Default registry: atoms map directly to their underlying nat value

                    Equations
                    Instances For
                      theorem CatCrypt.Deep.LocRegistry.atomToId_ne (reg : LocRegistry) (a₁ a₂ : Nominal.Atom) (h : a₁ a₂) :
                      reg.atomToId a₁ reg.atomToId a₂

                      Two atoms with different values map to different ids