Tape-node context primitives #
This module contains the low-level vectorized context operations used by the tape-node proof
library: block projections, one-hot cotangent injections, and the bridge from generic
OpSpecFDerivCorrect witnesses to NodeFDerivCorrect nodes.
Coordinate lemmas for the Euclidean identification #
Mathlib's EuclideanSpace is PiLp 2, a type synonym carrying a WithLp wrapper. The four lemmas
below are the plumbing that lets us forget the wrapper: each says that reading coordinate i of a
vector built from f gives f i, for the various shapes the wrapper takes. They are boring on
purpose, and having them as simp lemmas is what keeps the real proofs in this file readable.
And once more for EuclideanSpace.equiv, the spelling used by vecOfFun.
Inner product against a one-dimensional constant vector collapses to a single product.
Scalar tensors vectorize to Vec 1, so this is the lemma that turns the adjointness statement for a
scalar node into ordinary multiplication instead of a sum over Finset.univ.
Project a vectorized context onto the block at list position i.
CtxVec.get is the shape-indexed interface; it accepts an Idx Γ s and transports the result to
the statically known shape s.
Instances For
Adjointness of block projection and injection.
This is the vectorized counterpart of the one-hot cotangent principle used in tape soundness.
Project the block specified by idx : Idx Γ s out of a vectorized context.
Instances For
Selecting a block after vectorization agrees with selecting the original tensor.
Typed tensor selection commutes with vectorization, including its shape cast.
Inject a block into a vectorized context at idx, filling other blocks with zeros.
Instances For
Continuous linear map extracting the head block of a nonempty vectorized context.
Instances For
headCLM reads the leading block of coordinates, exactly as flattenCtx_cons lays them out.
Continuous linear map extracting the tail blocks of a nonempty vectorized context.
Instances For
tailCLM reads the trailing blocks.
The bundled getBlockCLM computes the same thing as the plain getBlock.
This is the payoff of building it recursively from headCLM and tailCLM: block selection comes
out
continuous and linear by construction, so nothing downstream has to prove it again.
get packaged as a continuous linear map.
Instances For
Nodes in this file are authored directly on the vectorized context CtxVec.
This is the most convenient authoring style for analytic proofs: forwardVec/jvpVec/vjpVec
are definitional, and the correctness obligation is an inner-product identity on Euclidean
vectors.
Convenience constructor: build a tape Node from vector-level forward/JVP/VJP plus adjointness.
The correct_inner field is exactly the local VJP/JVP law:
⟪jvp x dx, δ⟫ = ⟪dx, vjp x δ⟫.
Instances For
A node built by ofFn has the given forward map.
A node built by ofFn has the given forward-mode derivative.
A node built by ofFn has the given reverse-mode derivative. Together the three projection
lemmas mean a caller never has to unfold ofFn, only supply the soundness argument h once.
OpSpecFDerivCorrect instance for a linear layer.
This is the analytic correctness lemma behind the tape node constructors: it identifies the JVP
with the Fréchet derivative (a matrix multiplication) for linearSpec.
PyTorch analogue: the torch.nn.Linear forward map is affine, so its derivative is constant.
https://pytorch.org/docs/stable/generated/torch.nn.Linear.html