Reason — chain of thought, deterministic, MoT split
A chain of thought, deterministic, at picojoule grain. A small cascade walks each query through five tiers (arithmetic → named-fact lookup → HDC-style shape match → cited composition → model-class). Each tier is split into a reasoning expert (classify the form) and a generation expert (produce the answer); generation only runs when reasoning matches. Indented rows on the trace are generation hops; left-aligned rows are reasoning hops. Every sub-hop carries its own joule receipt. The exhibit rotates through eight canonical queries that exercise every resolution outcome including the model-class refusal.
view the kernel that wrote this receipt crates/mathground-view/src/cascade.rs
//! A tiny cognitive cascade for the math domain, split mixture-of-
//! transformers-style into per-tier reasoning + generation experts.
//!
//! Demonstrates the same SHAPE that a reasoning VLA emits — a chain of
//! decisions, each tagged with what was tried, what matched, and what it
//! cost — except every hop is deterministic. Each tier is now split into
//! two sub-experts:
//!
//! • Reasoning expert — does this query fit this tier's grammar?
//! (Decides the *form*; cheap; classifies.)
//! • Generation expert — given a recognised form, produce the answer.
//! (Only runs when the reasoning expert matched.)
//!
//! The visible trace expands to one hop per sub-expert that fired. A
//! resolved tier contributes TWO hops (reasoning ✓ → generation ✓); an
//! unmatched tier contributes ONE (reasoning ✗ — no generation needed).
//! Same architectural shape as Cosmos 3's mixture-of-transformers — one
//! reasoning transformer + one expert generation transformer — at zero
//! GPU cost.
//!
//! Tiers (ladder, checked in order; first matching tier resolves):
//!
//! L0-closed — arithmetic / symbolic evaluation.
//! L0-retrieved — exact citation lookup in a fixed table.
//! L0-identifiable — HDC-style shape match against a small atom pool.
//! L1 — citation-backed composition.
//! L2 — model-generated. Reasoning matches (recognises the
//! query as model-class); generation refuses and reports
//! the would-cost — substrate honesty.
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum CascadeTier {
L0Closed,
L0Retrieved,
L0Identifiable,
L1,
L2,
}
impl CascadeTier {
pub fn label(self) -> &'static str {
match self {
CascadeTier::L0Closed => "L0-closed",
CascadeTier::L0Retrieved => "L0-retrieved",
CascadeTier::L0Identifiable => "L0-identifiable",
CascadeTier::L1 => "L1",
CascadeTier::L2 => "L2",
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum SubExpert {
Reasoning,
Generation,
}
impl SubExpert {
pub fn label(self) -> &'static str {
match self {
SubExpert::Reasoning => "reasoning",
SubExpert::Generation => "generation",
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CascadeHop {
pub tier: CascadeTier,
pub expert: SubExpert,
/// Short, human-readable description of what this expert did.
pub action: String,
pub matched: bool,
pub bit_ops: u64,
pub wall_ns_per_op: f64,
/// Set only on the generation hop when generation succeeded.
pub answer: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CascadeTrace {
pub query: String,
pub hops: Vec<CascadeHop>,
pub resolved_at: Option<CascadeTier>,
pub final_answer: Option<String>,
pub total_bit_ops: u64,
}
/// Probe of a single tier — what its reasoning expert decided, what (if
/// anything) its generation expert produced, and the cost of each.
struct TierProbe {
reasoning_matched: bool,
reasoning_action: &'static str,
reasoning_cost: u64,
generation_action: Option<&'static str>,
generation_answer: Option<String>,
generation_cost: u64,
}
// ── L0-closed: arithmetic and basic algebra ───────────────────────────
enum ClosedForm {
BinaryArithmetic,
Factorial,
}
fn probe_l0_closed(query: &str) -> TierProbe {
let q = query.trim();
let parts: Vec<&str> = q.split_whitespace().collect();
let reason_cost = 64u64;
let mut form: Option<ClosedForm> = None;
if parts.len() == 3
&& matches!(parts[1], "+" | "-" | "*" | "/")
&& parts[0].parse::<f64>().is_ok()
&& parts[2].parse::<f64>().is_ok()
{
form = Some(ClosedForm::BinaryArithmetic);
} else if let Some(stripped) = q.strip_suffix('!') {
if let Ok(n) = stripped.trim().parse::<u32>() {
if n <= 12 {
form = Some(ClosedForm::Factorial);
}
}
}
if form.is_none() {
return TierProbe {
reasoning_matched: false,
reasoning_action: "classify as arithmetic / factorial",
reasoning_cost: reason_cost,
generation_action: None,
generation_answer: None,
generation_cost: 0,
};
}
let (answer, action, cost) = match form.unwrap() {
ClosedForm::BinaryArithmetic => {
let a = parts[0].parse::<f64>().unwrap();
let b = parts[2].parse::<f64>().unwrap();
let answer = match parts[1] {
"+" => Some(format!("{}", a + b)),
"-" => Some(format!("{}", a - b)),
"*" => Some(format!("{}", a * b)),
"/" if b != 0.0 => Some(format!("{}", a / b)),
_ => None,
};
(answer, "evaluate arithmetic expression", 32)
}
ClosedForm::Factorial => {
let n: u32 = q.strip_suffix('!').unwrap().trim().parse().unwrap();
let f: u64 = (1..=n as u64).product();
(Some(format!("{f}")), "evaluate factorial", (n as u64) * 32)
}
};
TierProbe {
reasoning_matched: true,
reasoning_action: "classify as arithmetic / factorial",
reasoning_cost: reason_cost,
generation_action: Some(action),
generation_answer: answer,
generation_cost: cost,
}
}
// ── L0-retrieved: named constants and theorems ────────────────────────
const RETRIEVED: &[(&str, &str)] = &[
("pi", "π ≈ 3.141592653589793"),
("e", "e ≈ 2.718281828459045"),
("phi", "φ ≈ 1.618033988749895 (golden ratio)"),
("c", "c = 299 792 458 m/s (speed of light, exact)"),
("h", "h ≈ 6.62607015×10⁻³⁴ J·s (Planck, exact since 2019)"),
("kt ln 2 at 300 k", "kT·ln 2 ≈ 2.870×10⁻²¹ J (Landauer floor)"),
("pythagorean theorem", "a² + b² = c² (for a right triangle, c = hypotenuse)"),
("eulers identity", "e^(iπ) + 1 = 0"),
("eulers formula", "e^(iθ) = cos θ + i sin θ"),
("schwarz inequality", "|⟨u, v⟩| ≤ ‖u‖·‖v‖"),
("law of cosines", "c² = a² + b² − 2 a b cos C"),
("planck-einstein", "E = h ν"),
("entropy of binary distribution", "H(p) = −p log₂ p − (1−p) log₂(1−p)"),
];
fn probe_l0_retrieved(query: &str) -> TierProbe {
let q = query.trim().to_lowercase();
let reason_cost = (RETRIEVED.len() as u64) * 50;
// Reasoning expert: is the query EXACTLY a known key?
let hit = RETRIEVED.iter().find(|(k, _)| q == *k);
if let Some((_, value)) = hit {
TierProbe {
reasoning_matched: true,
reasoning_action: "match against named-fact table",
reasoning_cost: reason_cost,
generation_action: Some("emit cited value"),
generation_answer: Some((*value).to_string()),
generation_cost: 32,
}
} else {
TierProbe {
reasoning_matched: false,
reasoning_action: "match against named-fact table",
reasoning_cost: reason_cost,
generation_action: None,
generation_answer: None,
generation_cost: 0,
}
}
}
// ── L0-identifiable: HDC-style margin-gated shape match ───────────────
const IDENTIFIABLE: &[(&str, &str)] = &[
("area of a unit circle", "π r² with r = 1 → π"),
("circumference of a unit circle", "2π r with r = 1 → 2π"),
("area of an equilateral triangle, side 1", "(√3 / 4) · s² with s = 1 → ≈ 0.433"),
("volume of a unit sphere", "(4/3) π r³ with r = 1 → ≈ 4.189"),
("rms of a sine wave amplitude a", "a / √2"),
];
fn probe_l0_identifiable(query: &str) -> TierProbe {
let q = query.trim().to_lowercase();
let q_tokens: std::collections::HashSet<&str> =
q.split_whitespace().filter(|t| t.len() > 1).collect();
let mut scores: Vec<(f64, &str, &str)> = Vec::with_capacity(IDENTIFIABLE.len());
for (key, value) in IDENTIFIABLE {
let k_tokens: std::collections::HashSet<&str> =
key.split_whitespace().filter(|t| t.len() > 1).collect();
let inter: usize = q_tokens.intersection(&k_tokens).count();
let union: usize = q_tokens.union(&k_tokens).count();
let sim = if union == 0 { 0.0 } else { inter as f64 / union as f64 };
scores.push((sim, key, value));
}
scores.sort_by(|a, b| b.0.partial_cmp(&a.0).unwrap_or(std::cmp::Ordering::Equal));
let reason_cost = (IDENTIFIABLE.len() as u64) * 200;
let top = scores.first().copied();
let second_sim = scores.get(1).map(|t| t.0).unwrap_or(0.0);
if let Some((sim, _key, value)) = top {
if sim >= 0.5 && (sim - second_sim) >= 0.15 {
return TierProbe {
reasoning_matched: true,
reasoning_action: "shape-match against atom pool (margin-gated)",
reasoning_cost: reason_cost,
generation_action: Some("emit matched-atom value"),
generation_answer: Some(value.to_string()),
generation_cost: 32,
};
}
}
TierProbe {
reasoning_matched: false,
reasoning_action: "shape-match against atom pool (margin-gated)",
reasoning_cost: reason_cost,
generation_action: None,
generation_answer: None,
generation_cost: 0,
}
}
// ── L1: cited composition ─────────────────────────────────────────────
fn probe_l1(query: &str) -> TierProbe {
let q = query.trim().to_lowercase();
let reason_cost = 200u64;
if let Some(rest) = q.strip_prefix("compose ") {
let parts: Vec<&str> = rest.split(" times ").collect();
if parts.len() == 2 {
let l_probe = probe_l0_retrieved(parts[0]);
let r_probe = probe_l0_retrieved(parts[1]);
if let (Some(lv), Some(rv)) = (l_probe.generation_answer, r_probe.generation_answer) {
let answer = format!("compose({}, {}) — both cited from L0-retrieved", lv, rv);
return TierProbe {
reasoning_matched: true,
reasoning_action: "recognise `compose X times Y` form",
reasoning_cost: reason_cost,
generation_action: Some("retrieve both cites and compose"),
generation_answer: Some(answer),
generation_cost: 400,
};
}
}
}
TierProbe {
reasoning_matched: false,
reasoning_action: "recognise `compose X times Y` form",
reasoning_cost: reason_cost,
generation_action: None,
generation_answer: None,
generation_cost: 0,
}
}
// ── L2: model-generated (we don't ship one) ───────────────────────────
fn probe_l2(_query: &str) -> TierProbe {
// Reasoning expert: anything that reached this tier is by definition a
// would-need-a-model query — reasoning always matches. The generation
// expert refuses and reports the would-cost (~10⁹ bit-ops for a small
// local model's single short generation).
TierProbe {
reasoning_matched: true,
reasoning_action: "classify as model-class (escapes lower tiers)",
reasoning_cost: 64,
generation_action: Some("refuse: substrate does not ship a model"),
generation_answer: None,
generation_cost: 1_000_000_000,
}
}
// ── Walker ────────────────────────────────────────────────────────────
pub struct TimeFn {
pub now_ns: fn() -> f64,
}
fn record_probe(
tier: CascadeTier,
probe: TierProbe,
hops: &mut Vec<CascadeHop>,
total_bit_ops: &mut u64,
time: &TimeFn,
) -> (bool, Option<String>) {
// Reasoning hop — always recorded.
let t_r = (time.now_ns)();
let dt_r = ((time.now_ns)() - t_r).max(0.0);
let wall_ns_per_op = if probe.reasoning_cost > 0 {
dt_r / probe.reasoning_cost as f64
} else {
dt_r
};
*total_bit_ops = total_bit_ops.saturating_add(probe.reasoning_cost);
hops.push(CascadeHop {
tier,
expert: SubExpert::Reasoning,
action: probe.reasoning_action.into(),
matched: probe.reasoning_matched,
bit_ops: probe.reasoning_cost,
wall_ns_per_op,
answer: None,
});
if !probe.reasoning_matched {
return (false, None);
}
// Generation hop — only when reasoning matched.
let t_g = (time.now_ns)();
let dt_g = ((time.now_ns)() - t_g).max(0.0);
let gen_wall = if probe.generation_cost > 0 {
dt_g / probe.generation_cost as f64
} else {
dt_g
};
*total_bit_ops = total_bit_ops.saturating_add(probe.generation_cost);
let answer = probe.generation_answer.clone();
hops.push(CascadeHop {
tier,
expert: SubExpert::Generation,
action: probe
.generation_action
.map(|s| s.to_string())
.unwrap_or_default(),
matched: answer.is_some(),
bit_ops: probe.generation_cost,
wall_ns_per_op: gen_wall,
answer: answer.clone(),
});
(answer.is_some(), answer)
}
/// Walk the cascade for `query`. Each tier first runs its reasoning expert,
/// then (if reasoning matched) its generation expert. A tier "resolves" the
/// query only when generation also produces an answer; otherwise the cascade
/// continues with the next tier. L2's generation always refuses → no
/// resolution.
pub fn walk(query: &str, time: &TimeFn) -> CascadeTrace {
let mut hops = Vec::new();
let mut total_bit_ops: u64 = 0;
let mut resolved_at: Option<CascadeTier> = None;
let mut final_answer: Option<String> = None;
let probes: [(CascadeTier, fn(&str) -> TierProbe); 5] = [
(CascadeTier::L0Closed, probe_l0_closed),
(CascadeTier::L0Retrieved, probe_l0_retrieved),
(CascadeTier::L0Identifiable, probe_l0_identifiable),
(CascadeTier::L1, probe_l1),
(CascadeTier::L2, probe_l2),
];
for (tier, probe_fn) in probes {
let probe = probe_fn(query);
let (gen_ok, ans) = record_probe(tier, probe, &mut hops, &mut total_bit_ops, time);
if gen_ok {
resolved_at = Some(tier);
final_answer = ans;
break;
}
}
CascadeTrace {
query: query.into(),
hops,
resolved_at,
final_answer,
total_bit_ops,
}
}
#[cfg(test)]
mod tests {
use super::*;
fn now() -> f64 {
use std::sync::atomic::{AtomicU64, Ordering};
static CLOCK: AtomicU64 = AtomicU64::new(0);
CLOCK.fetch_add(100, Ordering::Relaxed) as f64
}
fn time() -> TimeFn {
TimeFn { now_ns: now }
}
#[test]
fn l0_closed_match_emits_reasoning_then_generation() {
let t = walk("2 + 2", &time());
assert_eq!(t.resolved_at, Some(CascadeTier::L0Closed));
assert_eq!(t.final_answer.as_deref(), Some("4"));
assert_eq!(t.hops.len(), 2);
assert_eq!(t.hops[0].tier, CascadeTier::L0Closed);
assert_eq!(t.hops[0].expert, SubExpert::Reasoning);
assert!(t.hops[0].matched);
assert_eq!(t.hops[1].tier, CascadeTier::L0Closed);
assert_eq!(t.hops[1].expert, SubExpert::Generation);
assert!(t.hops[1].matched);
assert_eq!(t.hops[1].answer.as_deref(), Some("4"));
}
#[test]
fn unmatched_tier_emits_reasoning_only() {
// "pi" doesn't match L0-closed; reasoning at L0-closed records a
// single hop with matched=false.
let t = walk("pi", &time());
let l0_closed_hops: Vec<&CascadeHop> = t.hops.iter().filter(|h| h.tier == CascadeTier::L0Closed).collect();
assert_eq!(l0_closed_hops.len(), 1);
assert_eq!(l0_closed_hops[0].expert, SubExpert::Reasoning);
assert!(!l0_closed_hops[0].matched);
// Resolution on L0-retrieved → reasoning + generation = 2 hops there.
let l0_retrieved_hops: Vec<&CascadeHop> = t
.hops
.iter()
.filter(|h| h.tier == CascadeTier::L0Retrieved)
.collect();
assert_eq!(l0_retrieved_hops.len(), 2);
assert_eq!(t.resolved_at, Some(CascadeTier::L0Retrieved));
}
#[test]
fn factorial_resolves_at_l0_closed() {
let t = walk("6!", &time());
assert_eq!(t.resolved_at, Some(CascadeTier::L0Closed));
assert_eq!(t.final_answer.as_deref(), Some("720"));
assert_eq!(t.hops.len(), 2);
}
#[test]
fn l0_identifiable_resolves_unit_circle() {
let t = walk("circumference of a unit circle", &time());
assert_eq!(t.resolved_at, Some(CascadeTier::L0Identifiable));
assert!(t.final_answer.unwrap().contains("2π"));
}
#[test]
fn l2_reasoning_matches_but_generation_refuses() {
let t = walk("what is the meaning of life?", &time());
assert_eq!(t.resolved_at, None);
// L2 reasoning hop matches (recognises the query as model-class),
// L2 generation hop is recorded as not-matched (refused).
let l2_hops: Vec<&CascadeHop> = t.hops.iter().filter(|h| h.tier == CascadeTier::L2).collect();
assert_eq!(l2_hops.len(), 2);
assert_eq!(l2_hops[0].expert, SubExpert::Reasoning);
assert!(l2_hops[0].matched);
assert_eq!(l2_hops[1].expert, SubExpert::Generation);
assert!(!l2_hops[1].matched);
assert_eq!(l2_hops[1].bit_ops, 1_000_000_000);
}
#[test]
fn replay_is_deterministic_across_tier_split() {
let a = walk("pythagorean theorem", &time());
let b = walk("pythagorean theorem", &time());
assert_eq!(a.resolved_at, b.resolved_at);
assert_eq!(a.final_answer, b.final_answer);
assert_eq!(a.total_bit_ops, b.total_bit_ops);
assert_eq!(a.hops.len(), b.hops.len());
for (ha, hb) in a.hops.iter().zip(b.hops.iter()) {
assert_eq!(ha.tier, hb.tier);
assert_eq!(ha.expert, hb.expert);
assert_eq!(ha.matched, hb.matched);
assert_eq!(ha.bit_ops, hb.bit_ops);
assert_eq!(ha.answer, hb.answer);
}
}
#[test]
fn compose_resolves_at_l1_with_two_l0_retrieved_cites() {
let t = walk("compose pi times e", &time());
assert_eq!(t.resolved_at, Some(CascadeTier::L1));
let l1_hops: Vec<&CascadeHop> = t.hops.iter().filter(|h| h.tier == CascadeTier::L1).collect();
assert_eq!(l1_hops.len(), 2);
assert!(l1_hops[1].answer.as_ref().unwrap().contains("compose("));
}
}
This is the exact Rust file compiled into the WASM module the page just loaded. Every line that runs on your device is here. The receipt is a function of this code, not a bespoke benchmark.
About this exhibit
The cascade is the substrate's primary primitive. A small ladder of tiers — closed-form, retrieved, identifiable, cited, model-class — is walked for every query. Every tier is split into a reasoning sub-expert (classify the form) and a generation sub-expert (produce the answer in that form). Generation only fires when reasoning matches.
The visible trace IS the chain of thought. Each hop is a deterministic function; the whole trace is replayable from the query alone; no model weights are involved. Every hop carries its own picojoule receipt.
At /exhibits you can see the eight kernels (FFT, Lorenz, heat, etc.) that L0-closed evaluators would dispatch to inside a richer cascade. This exhibit shows the routing logic above them.