Documentation

LeanMlir.Proofs.Certificates.SmoothingCP

The exact Clopper–Pearson tie for randomized smoothing #

smoothing_mc_certified (SmoothingMC.lean) qualifies the reported radius with Hoeffding's 1 − exp(−2Nt²) — a crude bound. Cohen–Rosenfeld–Kolter's CERTIFY actually deploys the EXACT binomial lower confidence limit (Clopper–Pearson, proportion_confint one-sided). This file closes that last arithmetic gap:

All results are propext / Classical.choice / Quot.sound-clean.

noncomputable def Proofs.binomTail (N k : ) (q : ) :

Upper tail of the Binomial(N, q) distribution: P(X ≥ k) as a real polynomial in q — exactly what the driver evaluates.

Equations
Instances For
    noncomputable def Proofs.cpLower (α : ) (N k : ) :

    The Clopper–Pearson lower confidence bound at level α for k successes in N trials: the smallest success probability whose upper tail at k still exceeds α.

    Equations
    Instances For
      theorem Proofs.binomTail_le_of_lt_cpLower {α p : } (hp : p Set.Icc 0 1) {N k : } (h : p < cpLower α N k) :
      binomTail N k p α

      The CP key inequality: if the true p lies strictly below the CP lower bound, its tail is at most α (contrapositive of sInf ≤).

      noncomputable def Proofs.hitCount {E : Type u_1} (A : Set E) (N : ) (ω : Fin NE) :

      The number of samples landing in A, as a Fin N-indexed indicator sum (Set.indicator: no decidability needed).

      Equations
      Instances For
        theorem Proofs.hitCount_mono {E : Type u_1} {A B : Set E} (hAB : AB) (N : ) (ω : Fin NE) :
        hitCount A N ω hitCount B N ω

        The count is monotone in the target set.

        theorem Proofs.hitCount_le {E : Type u_1} (A : Set E) (N : ) (ω : Fin NE) :
        hitCount A N ω N
        theorem Proofs.measurable_hitCount {E : Type u_1} [MeasurableSpace E] {A : Set E} (hA : MeasurableSet A) (N : ) :
        theorem Proofs.hitCount_insertNth_zero {E : Type u_1} (A : Set E) (N : ) (x : E) (τ : Fin NE) :
        hitCount A (N + 1) (Fin.insertNth 0 x τ) = A.indicator 1 x + hitCount A N τ

        Prepending a sample to the tuple adds its indicator to the count.

        theorem Proofs.pi_hitCount_eq_binomial {E : Type u_1} [MeasurableSpace E] (ν : MeasureTheory.Measure E) [MeasureTheory.IsProbabilityMeasure ν] {A : Set E} (hA : MeasurableSet A) (N j : ) :
        (MeasureTheory.Measure.pi fun (x : Fin N) => ν) {ω : Fin NE | hitCount A N ω = j} = (N.choose j) * ν A ^ j * ν A ^ (N - j)

        The count of successes over the product measure is binomial (point law, ℝ≥0∞ form): P(hitCount = j) = C(N,j)·ν(A)^j·ν(Aᶜ)^(N−j). Induction on N through the coordinate-0 product split, Fubini on the first sample, and Pascal's rule.

        theorem Proofs.pi_hitCount_real_eq_binomial {E : Type u_1} [MeasurableSpace E] (ν : MeasureTheory.Measure E) [MeasureTheory.IsProbabilityMeasure ν] {A : Set E} (hA : MeasurableSet A) (N j : ) :
        (MeasureTheory.Measure.pi fun (x : Fin N) => ν).real {ω : Fin NE | hitCount A N ω = j} = (N.choose j) * ν.real A ^ j * (1 - ν.real A) ^ (N - j)

        The point law in real form.

        theorem Proofs.pi_hitCount_tail_real {E : Type u_1} [MeasurableSpace E] (ν : MeasureTheory.Measure E) [MeasureTheory.IsProbabilityMeasure ν] {A : Set E} (hA : MeasurableSet A) (N k : ) :
        (MeasureTheory.Measure.pi fun (x : Fin N) => ν).real {ω : Fin NE | k hitCount A N ω} = binomTail N k (ν.real A)

        The upper-tail law: P(hitCount ≥ k) over the product measure is exactly the binomTail polynomial the CP bound is defined from.

        theorem Proofs.cp_coverage {E : Type u_1} [MeasurableSpace E] (ν : MeasureTheory.Measure E) [MeasureTheory.IsProbabilityMeasure ν] {A : Set E} (hA : MeasurableSet A) (N : ) {α : } ( : 0 α) :
        1 - α (MeasureTheory.Measure.pi fun (x : Fin N) => ν).real {ω : Fin NE | cpLower α N (hitCount A N ω) ν.real A}

        Clopper–Pearson coverage. With probability at least 1 − α over the N iid samples, the CP lower bound computed from the observed count is a genuine lower bound for the true probability ν(A). No tail-monotonicity in the parameter is needed: the minimal-counterexample count k₀ has p < cpLower α N k₀, so its tail at p is ≤ α by the sInf defining property, and every count below k₀ certifies by minimality.

        The binomial tail is monotone in the success probability — by COUPLING, not calculus: instantiate the tail law at the uniform measure on [0,1] with the nested sets [0,q] ⊆ [0,p], and the tail events nest pointwise.

        theorem Proofs.binomTail_one {N k : } (hk : k N) :
        binomTail N k 1 = 1

        At q = 1 the tail is exactly 1 (only the j = N term survives).

        theorem Proofs.le_cpLower_of_tail_le {α q₀ : } ( : α < 1) {N k : } (hk : k N) (hq₀ : q₀ Set.Icc 0 1) (h : binomTail N k q₀ α) :
        q₀ cpLower α N k

        The solved-form CP bound: one in-kernel tail check binomTail N k q₀ ≤ α certifies q₀ as a lower bound for cpLower — the form the driver's reported q₀ can be verified in.

        theorem Proofs.smoothing_cp_certified {n k : } {σ : } ( : 0 < σ) {C : EuclideanSpace (Fin (n + 1))Fin k} (hC : Measurable C) (hp : ∀ (c : Fin k) (x : EuclideanSpace (Fin (n + 1))), (z : EuclideanSpace (Fin (n + 1))), if C (x + σ z) = c then 1 else 0 ProbabilityTheory.stdGaussian (EuclideanSpace (Fin (n + 1))) Set.Ioo 0 1) (x : EuclideanSpace (Fin (n + 1))) (y : Fin k) (N : ) {α : } ( : 0 α) :
        1 - α (MeasureTheory.Measure.pi fun (x : Fin N) => ProbabilityTheory.stdGaussian (EuclideanSpace (Fin (n + 1)))).real {ω : Fin NEuclideanSpace (Fin (n + 1)) | ∀ (δ : EuclideanSpace (Fin (n + 1))), δ < σ * stdNormalQuantile (cpLower α N (∑ i : Fin N, if C (x + σ ω i) = y then 1 else 0))∀ (j : Fin k), j y (z : EuclideanSpace (Fin (n + 1))), if C (x + δ + σ z) = j then 1 else 0 ProbabilityTheory.stdGaussian (EuclideanSpace (Fin (n + 1))) < (z : EuclideanSpace (Fin (n + 1))), if C (x + δ + σ z) = y then 1 else 0 ProbabilityTheory.stdGaussian (EuclideanSpace (Fin (n + 1)))}

        The Clopper–Pearson smoothing certificate. Sample N iid standard Gaussians; report the radius σ·Φ⁻¹(cpLower α N k) from the exact binomial lower confidence limit at the observed class count k. With probability ≥ 1 − α over the samples, the reported radius is GENUINELY certified: every ‖δ‖ < σ·Φ⁻¹(cpLower α N k) keeps y the strict argmax of the smoothed classifier. Same guarantee shape as smoothing_mc_certified, but the confidence bound is now the arithmetic Cohen's CERTIFY actually deploys.

        theorem Proofs.smoothing_cp_certified_solved {n k : } {σ : } ( : 0 < σ) {C : EuclideanSpace (Fin (n + 1))Fin k} (hC : Measurable C) (hp : ∀ (c : Fin k) (x : EuclideanSpace (Fin (n + 1))), (z : EuclideanSpace (Fin (n + 1))), if C (x + σ z) = c then 1 else 0 ProbabilityTheory.stdGaussian (EuclideanSpace (Fin (n + 1))) Set.Ioo 0 1) (x : EuclideanSpace (Fin (n + 1))) (y : Fin k) {N k₀ : } (hk₀ : k₀ N) {α q₀ : } ( : 0 α) (hα1 : α < 1) (hq₀ : q₀ Set.Ioo 0 1) (htail : binomTail N k₀ q₀ α) :
        1 - α (MeasureTheory.Measure.pi fun (x : Fin N) => ProbabilityTheory.stdGaussian (EuclideanSpace (Fin (n + 1)))).real {ω : Fin NEuclideanSpace (Fin (n + 1)) | (∑ i : Fin N, if C (x + σ ω i) = y then 1 else 0) = k₀∀ (δ : EuclideanSpace (Fin (n + 1))), δ < σ * stdNormalQuantile q₀∀ (j : Fin k), j y (z : EuclideanSpace (Fin (n + 1))), if C (x + δ + σ z) = j then 1 else 0 ProbabilityTheory.stdGaussian (EuclideanSpace (Fin (n + 1))) < (z : EuclideanSpace (Fin (n + 1))), if C (x + δ + σ z) = y then 1 else 0 ProbabilityTheory.stdGaussian (EuclideanSpace (Fin (n + 1)))}

        The driver tie, solved form. For the OBSERVED count k₀ and the driver's reported CP lower bound q₀ (rationalized down), ONE in-kernel tail check binomTail N k₀ q₀ ≤ α certifies: with probability ≥ 1 − α over the samples, IF the count comes out k₀ THEN the radius σ·Φ⁻¹(q₀) is genuinely certified. This is the per-image scorecard theorem shape: instantiate at the driver's (N, k₀, α, q₀) and the hypothesis is pure kernel rational arithmetic.

        Summing the tail term by term with norm_num prices out at driver scale (N = 10112, hundreds of terms, Nat.choose far from the diagonal). The ListDot recipe applies instead: a kernel-computable ℕ numerator + a once-proven bridge, so each per-image scorecard hypothesis is ONE decide +kernel bignum inequality (~0.1 s even for thousands of terms — kernel Nat.pow/mul are GMP-accelerated).

        def Proofs.binomTailNum (N k a d : ) :

        Kernel-computable tail numerator: Σ_{i=0}^{N-k} C(N,i)·a^(N-i)·(d-a)^i (i = N - j, so the binomial coefficient rides the SMALL side, and descFactorial/factorial computes it free of the exponential Pascal recursion — Nat.choose_eq_descFactorial_div_factorial makes the truncated division exact).

        Equations
        Instances For
          theorem Proofs.binomTailNum_eq {N k : } (hk : k N) (a d : ) :
          binomTailNum N k a d = jFinset.Icc k N, N.choose j * a ^ j * (d - a) ^ (N - j)

          The kernel numerator is the tail's numerator over Icc k N (reflect the range, Nat.choose_symm).

          theorem Proofs.binomTail_eq_kernel {N k : } (hk : k N) {a d : } (ha : a d) (hd : 0 < d) :
          binomTail N k (a / d) = (binomTailNum N k a d) / d ^ N

          The real tail at a rational a/d equals the kernel numerator over d^N.

          theorem Proofs.binomTail_le_of_kernel_check {N k a d A : } (hk : k N) (ha : a d) (hd : 0 < d) (hA : 0 < A) (hcheck : A * binomTailNum N k a d d ^ N) :
          binomTail N k (a / d) 1 / A

          One kernel bignum inequality certifies a tail bound: the per-image scorecard hypothesis at q₀ = a/d, α = 1/A, discharged by decide +kernel.