TorchLean API

NN.MLTheory.CROWN.Proofs.GraphRunibpEndToEnd

End-to-end IBP soundness (graph dialect, over ) #

NN.MLTheory.CROWN.Proofs.GraphCertSoundness proves:

If a per-node IBP certificate is locally consistent (CertLocalOK) and the value semantics is locally consistent (SemLocalOK), then each certified box encloses the corresponding value.

This file supplies a concrete, total evaluator and a concrete, total IBP propagation and proves they satisfy the local-consistency predicates under the TopoSorted assumption (parents have smaller ids). Combining these results yields an end-to-end theorem.

The final section connects the proof-side pass runIBP? to the engine's executable runIBP (runIBP_eq_runIBP?) and derives the end-to-end theorem for the engine (runIBP_encloses_evalGraphRec).

Array helper lemmas (getElem! after setIfInBounds) #

Total evaluators (Nat-recursive, prefix semantics) #

We define fold-by-id evaluators using Nat.rec rather than List.foldl to keep proofs small and stable. The resulting arrays coincide with the intended “evaluate in node-id order” semantics.

Evaluate the first n nodes of g in id order, leaving the rest none.

Instances For

    Evaluate all nodes of g in id order, returning the final value array.

    Instances For

      Prefix evaluator for the safe IBP checker step (certStepNode?).

      Instances For

        Run the safe IBP checker step across the full graph, producing a per-node certificate array.

        Instances For

          Prefix size facts.

          Prefix stability: later writes do not change earlier entries.

          Congruence of the step functions under TopoSorted #

          If two arrays agree on all parent ids of node id, then the step function at id evaluates to the same result.

          Local consistency of the total evaluators #

          Under topological order, the certificate produced by runIBP? satisfies CertLocalOK.

          End-to-end theorem #

          theorem NN.MLTheory.CROWN.Graph.CertSoundness.runIBP?_encloses_evalGraphRec (g : Graph) (ps : ParamStore ) (inputs : Std.HashMap Val) (htopo : TopoSorted g) (hsupp : Supported g) (hinputs : InputsEnclosed g ps inputs) (id : ) :
          id < g.nodes.sizematch (runIBP? g ps)[id]!, (evalGraphRec g ps inputs)[id]! with | some B, some v => EnclosesBox B v | x, x_1 => True

          The engine pass runIBP #

          runIBP (in NN.MLTheory.CROWN.Graph.Engine.IBP) is the executable pass that checkers call. It differs from the proof-side runIBP? above in the following ways.

          The first three differences are inessential. We identify the two passes on the op set where the per-node steps coincide (EngineCore), under the hypothesis that the proof-side pass produced a box at every node (IBPCovers), which rules out the get! default path. The engine's behaviour is not changed.

          Node kinds on which propagateIBPNode and certStepNode? compute the same box.

          Instances For

            Every node of a certificate array carries a box.

            Instances For

              The engine-core op set is contained in the op set of the IBP soundness theorem.

              Prefix of the engine's fold, by recursion on the number of processed nodes.

              Instances For

                runIBP is the engine prefix recursion when the semantic guard accepts the graph.

                runIBP is all none when the semantic guard rejects the graph.

                The engine's runIBP computes exactly the proof-side runIBP? on engine-core graphs, provided the semantic guard accepts the graph and the proof-side pass produced a box at every node.

                Coverage is needed because propagateIBPNode reads parents with get!: at a node whose parent box is missing, the engine would compute from a default box while certStepNode? returns none.

                theorem NN.MLTheory.CROWN.Graph.CertSoundness.runIBP_encloses_evalGraphRec (g : Graph) (ps : ParamStore ) (inputs : Std.HashMap Val) (htopo : TopoSorted g) (hcore : EngineCore g) (hcov : IBPCovers g (runIBP? g ps)) (hinputs : InputsEnclosed g ps inputs) (id : ) :
                id < g.nodes.size∀ (B : FlatBox ) (v : Val), (g.runIBP ps)[id]! = some B(evalGraphRec g ps inputs)[id]! = some vEnclosesBox B v

                End-to-end soundness of the engine's IBP pass: every box computed by runIBP encloses the value computed by the total evaluator evalGraphRec at the same node.

                The statement quantifies over node ids at which the engine produced a box B and the evaluator a value v, so it cannot hold through a missing entry. The semantic guard needs no hypothesis: if crownGraphSemanticsSupported rejects the graph, runIBP produces no boxes and there is nothing to prove. Coverage of the proof-side pass is needed for the reason given at runIBP_eq_runIBP?.