Skip to content

Commit 33b5f5d

Browse files
committed
feat(pillar): add Pillars 15-17 (deferred stubs with proof obligations)
Deferred substrate-tier pillars following the lance-graph/crates/jc DEFERRED convention (Pillar 11 was deferred several months before sigker landed and activated it): - Pillar 15: Mexican-hat / DoG unimodality. Awaiting Mexican-hat resonance kernel in hpc::dragonfly. Will certify DoG kernel unimodality at κ = σ_s/σ_c ∈ [1.5, 3.0]. - Pillar 16: BTSP-gated bundling unbiasedness. Awaiting stable BTSP API in dn_tree. Will certify Doob optional-stopping unbiasedness of gated bundle. - Pillar 17: Quaternary tree balance under Zipf access. Awaiting Zipf workload simulator + DNTree inspector methods. Will certify Brent-style depth/occupancy variance bounds. Each stub exports its SEED constant, a prove_pillar_N() returning a deferred-shape PillarReport (zeros + passed=true), and a full proof-obligation docstring describing the activation plan.
1 parent 793d0b9 commit 33b5f5d

3 files changed

Lines changed: 472 additions & 0 deletions

File tree

src/hpc/pillar/btsp_unbiased.rs

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
#![allow(missing_docs)]
2+
//! Pillar-16 — BTSP-gated bundling unbiasedness certification.
3+
//! **DEFERRED** pending stable BTSP plasticity API in
4+
//! `ndarray::hpc::dn_tree`.
5+
//!
6+
//! Substrate-tier pillar: when activated, this pillar will certify that
7+
//! the BTSP-gated stochastic bundling operator used by
8+
//! `dn_tree::DNTree::update` (with `btsp_gate_prob > 0` and
9+
//! `btsp_boost > 1`) is an *unbiased* estimator of the underlying
10+
//! signal — i.e. that the gate does not introduce a systematic drift
11+
//! in the long-run mean of the bundled summary.
12+
//!
13+
//! # The unbiasedness claim
14+
//!
15+
//! Let `B_t = bundle(B_{t−1}, hv_t, lr_eff(t))` where
16+
//!
17+
//! ```text
18+
//! lr_eff(t) = lr · boost with probability p_btsp
19+
//! lr_eff(t) = lr with probability 1 − p_btsp
20+
//! ```
21+
//!
22+
//! For unbiasedness we require the BTSP-gated dynamics to converge to
23+
//! the *same* long-run mean as the gate-disabled dynamics
24+
//! (`lr_eff(t) ≡ lr` for all `t`). Equivalently, for any fixed input
25+
//! distribution `μ` of hypervectors:
26+
//!
27+
//! ```text
28+
//! lim_{T→∞} E[B_T | BTSP active] = lim_{T→∞} E[B_T | BTSP disabled]
29+
//! ```
30+
//!
31+
//! This holds if and only if the gate's expected step
32+
//! `E[lr_eff] = lr · ((1 − p_btsp) + p_btsp · boost)` produces an
33+
//! effective bundling weight that the bundling operator's fixed-point
34+
//! equation tolerates without drift — formally, that `lr_eff` enters
35+
//! linearly through Doob's optional stopping theorem on the
36+
//! martingale-decomposable component of the bundle update.
37+
//!
38+
//! # Why the substrate needs this
39+
//!
40+
//! The BTSP gate is the substrate's mechanism for *importance-weighted*
41+
//! plasticity — high-salience events get a 7× learning-rate boost
42+
//! (mimicking CaMKII amplification in biological synapses). If the gate
43+
//! is *biased*, the long-run summary drifts toward an artifact of the
44+
//! gate schedule rather than the true input distribution. The drift is
45+
//! invisible in lab conditions (Jan's 100% recall numbers at θ ∈ [1.45,
46+
//! 1.60]) because lab inputs are themselves drawn from the target
47+
//! distribution; the bias surfaces only when the input distribution
48+
//! shifts under operational load.
49+
//!
50+
//! Pillar-16 pins the unbiasedness claim to a measurable Monte-Carlo
51+
//! estimate of the long-run mean, with the gate-disabled run as the
52+
//! reference.
53+
//!
54+
//! # Probe design (deferred until BTSP API stabilises)
55+
//!
56+
//! 1. Fix bit width `BIT_WIDTH = 1024`, base learning rate `lr = 0.05`,
57+
//! gate probability `p_btsp = 0.01`, boost `boost = 7.0`.
58+
//! 2. Fix a target distribution `μ` over input hypervectors — a small
59+
//! discrete set of `K = 8` "prototype" vectors, drawn uniformly per
60+
//! step.
61+
//! 3. Run `T = 10_000` bundle steps with BTSP disabled (`p_btsp = 0`);
62+
//! record `B_T` as the reference mean `M_ref`.
63+
//! 4. Run `T` bundle steps with BTSP enabled; record `B_T` as `M_btsp`.
64+
//! 5. Repeat both runs `N_REPLICAS = 64` times with different seeds.
65+
//! 6. Verify that
66+
//! `‖ mean(M_btsp) − mean(M_ref) ‖_∞ < BIAS_TOLERANCE`
67+
//! and that the per-bit empirical bias falls within a
68+
//! `BIAS_CHI2_BUDGET` chi-squared confidence band.
69+
//!
70+
//! # Cross-verification
71+
//!
72+
//! When active, the probe will compare ndarray's `dn_tree::bundle_into`
73+
//! output against an independent re-derivation of the Bernoulli-mixture
74+
//! step (same approach as Pillar-13). The math is verifiable against a
75+
//! numpy / scipy reference implementation in `scripts/pillar_16_oracle.py`
76+
//! (to be written alongside activation).
77+
//!
78+
//! # Activation gate
79+
//!
80+
//! Active when:
81+
//! - `ndarray::hpc::dn_tree::bundle_into` (or equivalent) has a stable
82+
//! public signature accepting `(current, hv, lr, boost, rng)`.
83+
//! - `DNConfig::with_btsp` and the BTSP fire/boost semantics are
84+
//! contract-frozen (no further breaking changes).
85+
//!
86+
//! # Pass criteria (when active)
87+
//!
88+
//! - `‖ E[B_btsp] − E[B_ref] ‖_∞ < 0.05` (5% bit-bias tolerance).
89+
//! - Chi-squared test on per-bit bias: `χ² ≤ critical at α = 0.01,
90+
//! df = BIT_WIDTH − 1`.
91+
//! - `psd_rate` ≥ 0.999 (fraction of bit positions within tolerance).
92+
//! - `lognorm_concentration` = `log(1 + max bit-bias)`.
93+
//!
94+
//! # References
95+
//!
96+
//! * Bittner, K. C., Milstein, A. D., Grienberger, C., Romani, S., &
97+
//! Magee, J. C. (2017). *Behavioral time scale synaptic plasticity
98+
//! underlies CA1 place fields.* Science 357(6355). (Original BTSP
99+
//! observation in hippocampal CA1.)
100+
//! * Doob, J. L. (1953). *Stochastic Processes.* Wiley. (Optional
101+
//! stopping for the martingale decomposition that pins the
102+
//! unbiasedness criterion.)
103+
//!
104+
//! # SEED
105+
//!
106+
//! `PILLAR_16_SEED = 0x_C16_B751P_BC057` (BTSP boost, reserved).
107+
108+
use crate::hpc::pillar::prove_runner::PillarReport;
109+
110+
/// Deterministic seed for all Pillar-16 RNG streams.
111+
pub const PILLAR_16_SEED: u64 = 0x_C16B_751B_BC05;
112+
113+
/// Run the Pillar-16 deferred placeholder.
114+
///
115+
/// **Currently DEFERRED.** Replace the body when the BTSP API is
116+
/// stabilised; see the "Probe design" section in the module docs for
117+
/// the activation plan.
118+
pub fn prove_pillar_16() -> PillarReport {
119+
PillarReport {
120+
pillar_id: 16,
121+
seed: PILLAR_16_SEED,
122+
n_paths: 0,
123+
n_hops: 0,
124+
psd_rate: 0.0,
125+
lognorm_concentration: 0.0,
126+
passed: true,
127+
}
128+
}
129+
130+
// ── Tests ───────────────────────────────────────────────────────────────────
131+
132+
#[cfg(test)]
133+
mod tests {
134+
use super::*;
135+
136+
#[test]
137+
fn pillar_16_seed_matches_spec() {
138+
assert_eq!(PILLAR_16_SEED, 0x_C16B_751B_BC05);
139+
}
140+
141+
#[test]
142+
fn pillar_16_deferred_shape() {
143+
let r = prove_pillar_16();
144+
assert_eq!(r.pillar_id, 16);
145+
assert_eq!(r.seed, PILLAR_16_SEED);
146+
assert_eq!(r.n_paths, 0);
147+
assert_eq!(r.n_hops, 0);
148+
assert_eq!(r.psd_rate, 0.0);
149+
assert_eq!(r.lognorm_concentration, 0.0);
150+
assert!(r.passed);
151+
}
152+
153+
#[test]
154+
fn pillar_16_seed_anchored() {
155+
let r1 = prove_pillar_16();
156+
let r2 = prove_pillar_16();
157+
assert_eq!(r1.passed, r2.passed);
158+
assert_eq!(r1.psd_rate, r2.psd_rate);
159+
assert_eq!(r1.lognorm_concentration, r2.lognorm_concentration);
160+
}
161+
}

src/hpc/pillar/mexican_hat.rs

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
#![allow(missing_docs)]
2+
//! Pillar-15 — Mexican-hat / Difference-of-Gaussians unimodality
3+
//! certification. **DEFERRED** pending Mexican-hat resonance kernel
4+
//! landing in `ndarray::hpc`.
5+
//!
6+
//! Substrate-tier pillar: when activated, this pillar will certify that
7+
//! the Difference-of-Gaussians (DoG) center-surround resonance kernel
8+
//! consumed by the dragonfly-tier cognitive shader has exactly one local
9+
//! maximum at the origin and exactly one annular minimum at the surround
10+
//! radius, across the full parameter band the production stack uses.
11+
//!
12+
//! # The unimodality claim
13+
//!
14+
//! For two centered isotropic Gaussians with standard deviations
15+
//! `σ_c < σ_s`, the Difference-of-Gaussians is
16+
//!
17+
//! ```text
18+
//! DoG(r ; σ_c, σ_s) = G(r ; σ_c) − G(r ; σ_s)
19+
//! ```
20+
//!
21+
//! Differentiating with respect to `r` and setting to zero gives the
22+
//! single positive root `r_min(σ_c, σ_s)`. For DoG to behave as a
23+
//! center-surround kernel — peak at origin, negative annulus, decay to
24+
//! zero — we need:
25+
//!
26+
//! 1. `DoG(0) > 0` (positive at center)
27+
//! 2. `DoG'(r) < 0` for `0 < r < r_min` (monotone decrease from peak)
28+
//! 3. `DoG'(r) > 0` for `r > r_min` (monotone increase from annulus to zero)
29+
//! 4. Exactly one root in `(0, ∞)` for the equation `DoG(r) = 0`
30+
//!
31+
//! These hold for any `σ_c < σ_s`, but the *measurable* sharpness of the
32+
//! center-surround structure depends on the ratio `κ = σ_s / σ_c`. The
33+
//! production stack uses `κ ∈ [1.5, 3.0]`; values outside this band
34+
//! produce either too-broad surrounds (resonance bleeds into neighbors,
35+
//! cascade misfires) or too-sharp surrounds (numerical instability at
36+
//! the inflection point).
37+
//!
38+
//! # Why the substrate needs this
39+
//!
40+
//! The dragonfly Mexican-hat resonance is the center-surround operator
41+
//! that implements lateral inhibition in the cognitive shader. Bad
42+
//! parameter choices (κ outside the band, or accidental introduction
43+
//! of a kernel that's a sum-of-Gaussians rather than a difference)
44+
//! produce *bimodal* or *saddle* responses that look like resonance
45+
//! but bias activation toward the wrong neighborhoods. The failure
46+
//! mode is silent: the cascade still produces top-K results, just
47+
//! systematically biased.
48+
//!
49+
//! # Probe design (deferred until kernel lands)
50+
//!
51+
//! When the Mexican-hat / DoG kernel lands in `ndarray::hpc::dragonfly`
52+
//! (or wherever it ultimately lives), Pillar-15 will:
53+
//!
54+
//! 1. Sweep `κ = σ_s / σ_c ∈ {1.1, 1.3, 1.5, 1.8, 2.0, 2.5, 3.0, 4.0}`.
55+
//! 2. For each κ, evaluate the DoG kernel on a 1D radial grid of
56+
//! `N_RADIAL = 4096` samples covering `r ∈ [0, 6 σ_s]`.
57+
//! 3. Numerically locate all critical points (sign changes in `DoG'`)
58+
//! via finite differences with `h = r_max / N_RADIAL`.
59+
//! 4. Verify:
60+
//! - Exactly one positive critical point (the annular minimum).
61+
//! - `DoG(0) > 0` and is the global maximum on the grid.
62+
//! - `DoG(r) → 0` as `r → r_max` within `1e-6 · DoG(0)`.
63+
//! - For `κ ∈ [1.5, 3.0]`, the second-derivative ratio at the
64+
//! inflection point is within the production-band budget.
65+
//!
66+
//! # Activation gate
67+
//!
68+
//! Active when:
69+
//! - `ndarray::hpc::dragonfly::mexican_hat` (or canonical location) is
70+
//! exposed as a public function `dog_eval(r: f32, sigma_c: f32, sigma_s: f32) -> f32`.
71+
//! - This module's `prove_pillar_15` body is updated to call it; the
72+
//! current `DEFERRED` placeholder must be replaced with the real probe.
73+
//!
74+
//! # Pass criteria (when active)
75+
//!
76+
//! - All seven critical-point checks pass for every κ in the sweep.
77+
//! - `psd_rate ≥ 1.0` (every κ-sample contributes a binary pass/fail;
78+
//! any failure tanks the rate).
79+
//! - `lognorm_concentration` = `log(1 + max kappa-band deviation)`.
80+
//!
81+
//! # References
82+
//!
83+
//! * Marr, D., & Hildreth, E. (1980). *Theory of edge detection.*
84+
//! Proc. R. Soc. Lond. B 207(1167). (The original DoG / Marr-Hildreth
85+
//! operator, source of the Mexican-hat name.)
86+
//! * Lindeberg, T. (1994). *Scale-Space Theory in Computer Vision.*
87+
//! Kluwer. (Scale-space justification for the σ_s / σ_c ratio band.)
88+
//!
89+
//! # SEED
90+
//!
91+
//! `PILLAR_15_SEED = 0x_C15_DAD51_DEFE` (Mexican-hat unimodality, reserved).
92+
93+
use crate::hpc::pillar::prove_runner::PillarReport;
94+
95+
/// Deterministic seed for all Pillar-15 RNG streams.
96+
pub const PILLAR_15_SEED: u64 = 0x_C15D_AD51_DEFE;
97+
98+
/// Run the Pillar-15 deferred placeholder.
99+
///
100+
/// **Currently DEFERRED.** Returns a `PillarReport` with all-zero
101+
/// numeric fields and `passed = true`, signalling "no probe ran".
102+
/// Replace the body when the Mexican-hat kernel lands; see the
103+
/// "Probe design" section in the module docs for the activation plan.
104+
///
105+
/// # Returns
106+
///
107+
/// A deferred-shape `PillarReport`:
108+
/// - `n_paths = 0`, `n_hops = 0` (no probe executed)
109+
/// - `psd_rate = 0.0`, `lognorm_concentration = 0.0`
110+
/// - `passed = true` (the deferral itself is not a failure)
111+
pub fn prove_pillar_15() -> PillarReport {
112+
PillarReport {
113+
pillar_id: 15,
114+
seed: PILLAR_15_SEED,
115+
n_paths: 0,
116+
n_hops: 0,
117+
psd_rate: 0.0,
118+
lognorm_concentration: 0.0,
119+
passed: true,
120+
}
121+
}
122+
123+
// ── Tests ───────────────────────────────────────────────────────────────────
124+
125+
#[cfg(test)]
126+
mod tests {
127+
use super::*;
128+
129+
#[test]
130+
fn pillar_15_seed_matches_spec() {
131+
assert_eq!(PILLAR_15_SEED, 0x_C15D_AD51_DEFE);
132+
}
133+
134+
#[test]
135+
fn pillar_15_deferred_shape() {
136+
// DEFERRED probe must return a recognisable deferred-shape report:
137+
// zeros everywhere except pillar_id and seed, passed = true.
138+
let r = prove_pillar_15();
139+
assert_eq!(r.pillar_id, 15);
140+
assert_eq!(r.seed, PILLAR_15_SEED);
141+
assert_eq!(r.n_paths, 0);
142+
assert_eq!(r.n_hops, 0);
143+
assert_eq!(r.psd_rate, 0.0);
144+
assert_eq!(r.lognorm_concentration, 0.0);
145+
assert!(r.passed, "deferred pillar should not be marked failed");
146+
}
147+
148+
#[test]
149+
fn pillar_15_seed_anchored() {
150+
let r1 = prove_pillar_15();
151+
let r2 = prove_pillar_15();
152+
assert_eq!(r1.passed, r2.passed);
153+
assert_eq!(r1.psd_rate, r2.psd_rate);
154+
assert_eq!(r1.lognorm_concentration, r2.lognorm_concentration);
155+
}
156+
}

0 commit comments

Comments
 (0)