Common #
Internal helper lemmas for NN.Runtime.Autograd.IRExec.Correctness.
These lemmas relate the typed runtime context (TorchLean.TensorPack) to the untyped IR
value table (Array Spec.SomeTensor) and provide small building-block correctness steps that are
reused across the per-op proofs.
The lemmas are grouped as follows:
packedTensorsOfContext*lemmas: relate the typed context produced byForwardData.evalto an untypedArray (Spec.SomeTensor α)(this is what the IR evaluator uses).denoteAllState*lemmas: package the IR forward evaluator (ForwardGraph.denoteAll) in the form expected by IR-style semantic equivalence proofs.
These lemmas are infrastructure: they should not encode op-specific logic. Per-op correctness files (Matmul/Pooling/LayerNorm/MSELoss) should depend on this module and not re-prove these bridges.
Main definitions #
throw_bind_ne_ok: eliminates impossible success branches afterthrow.NoRawLog: side condition for theorem statements that do not carry the positivity precondition required by raw reallog.noRawLog_of_forall_mem: dischargeNoRawLogfrom a node-array fact, so a concrete graph can close it withdecide.packedTensorsOfContext_*: typed-context to IR-array bridge lemmas.evalAt_matmul_leading_ok,evalAt_axisReduction_ok:evalAtin well-typed success cases.denoteAllState_*helpers: semantic equivalence bridges between lowered state and IR denotation tables.
Implementation notes #
- This module is shared infrastructure: predictable proof contracts matter more than clever proof tricks.
- Many lemmas here are proof-irrelevance/indexing bridges; these are repetitive but they remove a lot of friction from op-specific proofs.
- Collecting these utilities in one place gives op-specific correctness modules shared rewrite and indexing lemmas instead of repeated local proof scripts.
- These files can build slowly because they connect two representations at once: typed
TorchLean.TensorPackcontexts on the forward-graph side and dynamically shapedSpec.SomeTensorarrays on the IR side. Most of the cost is not arithmetic; it is Lean checking that shape casts, array indices, and proof-irrelevant casts line up exactly. - When the same proof pattern appears in multiple operator files, prefer a named lemma with a clear
contract over another local
simpscript.
Tags #
correctness, infrastructure, tensorpack, dval, bridge-lemmas
The lowering and semantic evaluators agree on a successfully decoded unary parent.
The lowering and semantic evaluators agree on successfully decoded binary parents.
Shared side conditions #
These predicates describe the exact fragment covered by a theorem. Keeping them in Common lets
the per-op lemmas, the semantic equivalence proof, and the chapter index refer to the same public
contract without import cycles.
Core semantic equivalence side condition: the IR graph contains no raw .log nodes.
The scientific raw-log domain is positive inputs. The IR denotation reports Except.error for
nonpositive values, while the pure lowered closure applies Tensor.logSpec to every input. The
end-to-end semantic-equivalence theorem therefore excludes every .log node. Protecting its input
with a positive clamp or a softplus-based construction can avoid the domain failure, but does not
discharge this syntactic predicate; that graph needs a separate domain-aware argument.
Instances For
Discharge NoRawLog from a statement about the node array.
NoRawLog quantifies over node ids through Graph.getNode, which is the right shape for the
recursive lowering proof but an annoying shape for a caller holding a concrete graph. Every id that
getNode accepts reads an element of g.nodes, so a fact about the array is enough, and for a
literal graph the hypothesis is closed by decide:
theorem myGraphNoRawLog : NoRawLog myGraph :=
noRawLog_of_forall_mem (by decide)
We added this because the alternative was for every user of
denoteAll_eq_of_lowerToForwardGraph to redo the same getNode case analysis inline.
If a do-chain begins with throw, it cannot produce an .ok result.
This lemma is used throughout the lowered-correctness proofs to close impossible branches where lowering would have thrown an error message.
packedTensorsOfContext ignores type-level casts of the underlying TorchLean.TensorPack.
ForwardData.eval introduces a definitional cast when extending contexts; this lemma lets us erase
it before reasoning about the corresponding Array of Spec.SomeTensors.
packedTensorsOfContext for a snoc’d context corresponds to Array.push of the appended
tensor.
Optional lookup in packedTensorsOfContext agrees with indexing the underlying typed context.
This is the main bridge between the typed runtime context and the untyped IR value table.
Optional lookup in packedTensorsOfContext by a typed Idx agrees with getIdx on the
underlying TorchLean.TensorPack.
This packages packedTensorsOfContext_getElem? into the repository’s Idx wrapper.
Graph.expectShape succeeds on a Spec.SomeTensor built with the same shape.
Graph.expectShape transports a shape-erased tensor when its stored shape equals the requested
one.
NN.IR.Graph.evalAt for a .matmul node whose parents share the leading shape
Shape.ofList leadingRev.reverse and end in the matrix axes [rows, inner] and [inner, cols].
The leading shape is spelled through its reversed dimension list because that is how both the IR
evaluator and lowerMatmul recover it from the parent shapes. The lemma records the exact
NN.IR.Graph.matmulLeading term produced by the evaluator for any leading shape (plain matrices,
one batch axis, or several batch axes).
The two axis reductions supported by lowered IR semantic equivalence.
- sum : AxisReductionKind
- mean : AxisReductionKind
Instances For
Convert a lowered axis-reduction case to its IR operation kind.
Instances For
Typed denotation of a lowered axis-reduction case.
Instances For
NN.IR.Graph.evalAt for either axis-reduction node in a well-typed success case.
This helper records the exact Tensor.reduceSum term produced by the IR evaluator once:
- the parent has the expected shape
s, - the axis validity check succeeds, and
- the node's declared
outShapematchesshapeAfterSum s axis.
The final cast to n.outShape comes from the evalAt "shape-tag normalization" step.
evalAt_axisReduction_ok specialized to summation.
NN.IR.Graph.evalAt for a .reduceMean axis node, specialized to a well-typed success case.
This is the mean analogue of evalAt_reduceSum_ok.
Repackage a lowered State as an ForwardGraph so we can call its evaluator helpers.
Instances For
Evaluate the lowered prefix state and convert its typed runtime context into an IR-style table.
Instances For
denoteAllState commutes with extending the SSA graph by one node (ForwardData.snoc).
This is the key step for proving that the lowering pass’s prefix-building loop stays in semantic equivalence with the IR denotation table.
Build a typed runtime index (Idx) for a numeric IR parent id.
The forward executor's context is typed by a list of shapes [inShape] ++ ss. mkIdx checks that:
idis in bounds, and- the context shape at that position matches the expected shape
s.
Lookup in denoteAllState agrees with getIdx when mkIdx pid s succeeds.
This is used when proving correctness of the per-node lowering pass step: we translate parent ids in the IR into typed indices into the forward-graph context.
One-step finishing lemma for the buildFrom/denoteAllFrom semantic equivalence proof.
If we know:
- the tail recursion
i+1is correct (hTail), - the IR evaluator step at
imatches the forward-graph node’sforward(hEval), and - the forward-graph table at
iis the previous table plus the pushed node value (hStep), thendenoteAllFromatireturns the final forward-graph table.