TorchLean API

NN.MLTheory.CROWN.Proofs.GraphAlphaCrownTransferSoundness.AlphaBeta.StepInversion

α/β-CROWN step function: case inversion #

Lemmas that read off what stepAlphaBeta computed at a node.

Away from ReLU nodes that carry a β vector, stepAlphaBeta is stepAlpha. On a ReLU node with a β vector, the step succeeds only when the unary parent has a certificate entry and an IBP box of the same output dimension, and phaseRelaxVec? accepts the phases against that box. The inversion lemma stepAlphaBeta_relu_beta_inv exposes exactly those ingredients, together with the range of the α vector actually used (explicit or default).

Safe lookups #

A successful Cert.getAff? lookup is an in-bounds array read.

getElem!_of_getVal?_eq_some is CertSoundness's lemma, opened at the top of this file. Two files in this directory carried their own copy of it, proved with by_cases where the original uses unfold and split; the statements were the same, so the copies are gone.

A successful getAlpha? lookup is an in-bounds array read.

α vector range #

theorem NN.MLTheory.CROWN.Graph.AlphaCrownTransferSoundness.getAlpha?_unit_range {alpha : Array (Option (FlatTensor ))} {id : } {αv : FlatTensor } (halpha : AlphaOK alpha) (h : Cert.getAlpha? alpha id = some αv) (i : Fin αv.n) :
0 αv.v.getScalar i αv.v.getScalar i 1

Under AlphaOK, an α vector read by getAlpha? has every entry in [0, 1].

Casting the dimension of a tensor preserves the unit-interval range of its entries.

Reduction to α-CROWN #

theorem NN.MLTheory.CROWN.Graph.AlphaCrownTransferSoundness.stepAlphaBeta_eq_stepAlpha (g : Graph) (ps : ParamStore ) (ibp : Array (Option (FlatBox ))) (alpha : Array (Option (FlatTensor ))) (beta : Array (Option (Array ))) (cert : Array (Option (FlatAffineBounds ))) (ctx : AffineCtx) (id : ) (hnb : g.nodes[id]!.kind = IR.OpKind.reluCert.getBeta? beta id = none) :
stepAlphaBeta g ps ibp alpha beta ctx cert id = stepAlpha g ps ibp alpha ctx cert id

stepAlphaBeta is stepAlpha at every node that is not a ReLU carrying a β vector.

The hypothesis is phrased as an implication so that a single lemma covers both the non-ReLU kinds and ReLU nodes with no β entry.

Inversion of the β-phase ReLU branch #

theorem NN.MLTheory.CROWN.Graph.AlphaCrownTransferSoundness.stepAlphaBeta_relu_beta_inv (g : Graph) (ps : ParamStore ) (ibp : Array (Option (FlatBox ))) (alpha : Array (Option (FlatTensor ))) (beta : Array (Option (Array ))) (cert : Array (Option (FlatAffineBounds ))) (ctx : AffineCtx) (id : ) (b : FlatAffineBounds ) (phases : Array ) (p1 : ) (halpha : AlphaOK alpha) (hk : g.nodes[id]!.kind = IR.OpKind.relu) (hbeta : Cert.getBeta? beta id = some phases) (hps : IR.unaryParent? g.nodes[id]!.parents = some p1) (hs : stepAlphaBeta g ps ibp alpha beta ctx cert id = some b) :
∃ (xin : FlatAffineBounds ) (preB : FlatBox ) (hout : xin.outDim = preB.dim) (αt : TorchLean.Tensor [preB.dim]) (relaxLo : TorchLean.Tensor (Runtime.Ops.ReLURelax ) [preB.dim]) (relaxHi : TorchLean.Tensor (Runtime.Ops.ReLURelax ) [preB.dim]), Cert.getAff? cert p1 = some xin ibp[p1]! = some preB (∀ (i : Fin preB.dim), 0 αt.getScalar i αt.getScalar i 1) Cert.phaseRelaxVec? preB.lo preB.hi αt phases = some (relaxLo, relaxHi) b = { inDim := xin.inDim, outDim := preB.dim, loAff := Runtime.Ops.ReLU.propagateAffine relaxLo (castAffineOut hout xin.loAff), hiAff := Runtime.Ops.ReLU.propagateAffine relaxHi (castAffineOut hout xin.hiAff) }

What a successful α/β step on a ReLU node with a β vector must have computed.

The parent p1 has a certificate entry xin and an IBP box preB of matching output dimension, phaseRelaxVec? accepted phases against preB for some α vector αt with entries in [0, 1] (the explicit one, cast to preB.dim, or the default one), and the produced bounds are the phase relaxations propagated through the parent's affine bounds.