Documentation

LeanMlir.Proofs.Nets.Small.LinearFold

The MNIST-linear train step, proof-tied to the certified SGD step #

MainMnistLinearVerified trains on verified_mlir/linear_train_step.mlir, which is written by Proofs.StableHLO.linTrainStepText (the #eval writer at the end of StableHLO.Basic). This file certifies that renderer for a single example x: the emitted weight output denotes W − lr·∂(crossEntropy ∘ dense)/∂W (Mathlib-fderiv-derived) and the bias output denotes b − lr·(certified ∂dense/∂b · (softmax − onehot)). The committed module batch-contracts over B examples, which this file does not state.

(Namespace/name lengths are kept short on purpose: tests/AuditAxioms.lean's three-axiom closure check greps #print axioms output per line, which Lean wraps past ~120 cols — long qualified names would split the benign triple across lines and false-fail the check. Keep future per-chapter capstone names short.)

What is closed here (kernel, [propext, Classical.choice, Quot.sound]) #

The committed-bytes tie (verified_mlir/linear_train_step.mlir == linTrainStepText(…)) is enforced in CI (regenerate + git diff, the "Verified-render drift guard" step in proofs.yml), not here.

Scope (the boundary shared with the forward SHlo den) #

Forward eval — end-to-end tied #

theorem Proofs.LinFold.poc_fwd_is_render {m n : ℕ} (W : Mat m n) (b : Vec n) (x : Vec m) (B : ℕ) :
∃ (argSig : String), StableHLO.linearFwdModuleV B m n W b x = StableHLO.renderModule "linear_fwd" argSig B n (StableHLO.fwdGraph W b x)

The committed linear_fwd.mlir generator linearFwdModuleV is renderModule applied to the proven fwdGraph — the emitted bytes are literally the print of the graph fwdGraph_faithful is about.

The tail fold (closed) — the emitted tail ops are pretty(provenNode) #

StableHLO.linTrainStepText (what generates verified_mlir/linear_train_step.mlir) renders the whole module as pretty of SHlo nodes, fully tied: each of SHlo.weightSgd / SHlo.biasSgd consumes the proven lossCotGraph node DIRECTLY (not a .operand %dy <placeholder> name-pin), so the forward = the proven fwdGraph (nested inside lossCotGraph) and den(output) = certified is one composed theorem below — no trusted SSA-name linkage between the cotangent and the SGD ops. The shared cotangent is rendered once per output (2×); iree CSEs the duplicate. (lr/W,b,x values are skel-erased, so the render is value-independent — the placeholders linTrainStepText passes print the same text as the live graph here.)

theorem Proofs.LinFold.poc_weightSgd_den_eq {m n : ℕ} (W : Mat m n) (b : Vec n) (x : Vec m) (lrStr : String) (lr : ℝ) (label : Fin n) :
StableHLO.den (StableHLO.SHlo.weightSgd "%x" "%W0" lrStr x W lr (StableHLO.lossCotGraph W b x (oneHot n label))) = StableHLO.linWeightDen W b x lr label

The emitted weightSgd op — consuming the proven lossCotGraph node DIRECTLY (the fully-tied render) — denotes linWeightDen (the certified sgdW step).

theorem Proofs.LinFold.poc_biasSgd_den_eq {m n : ℕ} (W : Mat m n) (b : Vec n) (x : Vec m) (lrStr : String) (lr : ℝ) (label : Fin n) :
StableHLO.den (StableHLO.SHlo.biasSgd "%b0" lrStr b lr (StableHLO.lossCotGraph W b x (oneHot n label))) = StableHLO.linBiasDen W b x lr label

The emitted biasSgd op — consuming the proven lossCotGraph node DIRECTLY — denotes linBiasDen (the certified bias step).

theorem Proofs.LinFold.poc_train_step_tail_certified {m n : ℕ} (W : Mat m n) (b : Vec n) (x : Vec m) (lrStr : String) (lr : ℝ) (label : Fin n) :
(∀ (i : Fin m) (j : Fin n), StableHLO.den (StableHLO.SHlo.weightSgd "%x" "%W0" lrStr x W lr (StableHLO.lossCotGraph W b x (oneHot n label))) (finProdFinEquiv (i, j)) = W i j - lr * pdiv (fun (v : Vec (m * n)) (x_1 : Fin 1) => crossEntropy n (dense (Mat.unflatten v) b x) label) W.flatten (finProdFinEquiv (i, j)) 0) ∧ ∀ (j : Fin n), StableHLO.den (StableHLO.SHlo.biasSgd "%b0" lrStr b lr (StableHLO.lossCotGraph W b x (oneHot n label))) j = b j - lr * ∑ i : Fin n, pdiv (fun (b' : Vec n) => dense W b' x) b j i * (softmax n (mnistLinear W b x) i - oneHot n label i)

Tail fold. For one example x, the two emitted tail ops weightSgd/biasSgd — the actual SHlo nodes linTrainStepText prints — denote, respectively, W − lr·∂(crossEntropy ∘ dense)/∂W and b − lr·(certified ∂dense/∂b · (softmax − onehot)).