From 3aa07bd31d7154d44512ed0f01feafdae3891420 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 19 Jul 2026 14:11:57 +0000 Subject: [PATCH] =?UTF-8?q?deepnsm:=20SPO->+-5->Markov->AriGraph=20pipelin?= =?UTF-8?q?e=20=E2=80=94=20the=20endgame=20fact-building=20spine?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Composes the proven organs end-to-end on committed data: SPO 2^3 role collapse -> +-5 CausalEdge window fill -> Markov/NARS reasoning fills the facts NO window stated -> AriGraph-shaped KG grounded on lemRank. The synthetic corpus never states dog->pet->animal whole. Stage 2 lands 6 direct facts from the +-5 window (dog r671 is_a pet r2968, ...). Stage 3 DEDUCES (dog is_a animal) via transitive is_a and (dog need food) via property inheritance down the is_a basin -- both c=0.73, strictly weaker than premises (NARS monotonicity). Query 'what is dog?' returns pet [direct c=0.90] + animal [reasoned c=0.73]. KILL-gated on a fact being reasoned-not-read. The qualia-sign=irony affect layer is the ONE deferred leg: framed as a signed contradiction (SPO literal vs qualia sign), stored per the committed-contradiction doctrine; triangle_bridge::qualia_distance is the hook; falsifier needs a labeled ironic corpus -> CONJECTURE, not fabricated. std-only, zero-dep, deterministic, clippy/fmt-clean. Records E-SPO-MARKOV-KG-SPINE-1 (with the operator's endgame north-star map). Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01K3RyLEbuNSHxxB3NTTrGki --- .claude/board/EPIPHANIES.md | 17 ++ crates/deepnsm/examples/spo_markov_kg.rs | 328 +++++++++++++++++++++++ 2 files changed, 345 insertions(+) create mode 100644 crates/deepnsm/examples/spo_markov_kg.rs diff --git a/.claude/board/EPIPHANIES.md b/.claude/board/EPIPHANIES.md index 3893d225..6bded67d 100644 --- a/.claude/board/EPIPHANIES.md +++ b/.claude/board/EPIPHANIES.md @@ -1,3 +1,20 @@ +## 2026-07-19 — E-SPO-MARKOV-KG-SPINE-1 — the endgame's fact-building spine, runnable: text → SPO 2³ facts → ±5 CausalEdge window fill → Markov/NARS reasoning FILLS the facts no window stated (transitive is_a + property inheritance down the is_a basin) → AriGraph-shaped KG grounded on lemRank; the qualia-sign=irony affect layer is the ONE deferred leg (named CONJECTURE, corpus-gated) + +**Status:** FINDING (built + measured, KILL-gated, clippy/fmt-clean 1.95) + the operator's endgame NORTH-STAR recorded. **Confidence:** High for the spine (the three organs compose end-to-end); the corpus is synthetic (real ngrams.info COCA windows are licensed/gitignored). Deliverable: `crates/deepnsm/examples/spo_markov_kg.rs` (std-only, zero-dep, deterministic). Operator's endgame: *"SPO 2³ represents actual facts filled by CausalEdge context from +5/-5, then reasoning fills the remaining with Markov chain context building ... reasoning about supporting basins or being sarcasm/irony (qualia -8/+8 negative are inverted or ironic) ... the stylistic and linguistic gets reasoned about and stored as knowledge graph."* + +**The endgame → substrate map (the north-star, so it stops resetting):** +| clause | substrate | status | +|---|---|---| +| SPO 2³ = facts | DeepNSM PoS FSM → role-mask collapse | ✅ E-SURFACE-FORM-COLLAPSE-1 | +| filled by CausalEdge ±5 | Markov ±5 / `temporal.rs` stream; `gridlake_spo_ngrams` lands real SPO | ✅ substrate | +| reasoning fills the rest via Markov + basins | NARS revision IS Markov (I-SUBSTRATE-MARKOV); basins = `part_of:is_a` rails | ✅ E-ARM-DISCOVERY-REASONING-BRIDGE-1 | +| qualia −8/+8 sign = irony/sarcasm | `triangle_bridge::qualia_distance` (parse-qualia vs SPO expected footprint) | ⚠️ **DEFERRED — the one open leg** | +| stored as knowledge graph | AriGraph SPO triples + CausalEdge64 | ✅ sink | + +**What this example proves (the spine, measured):** a synthetic COCA-lemma corpus where the chain `dog → pet → animal` is NEVER stated whole. Stage 2 lands 6 DIRECT facts from the ±5 window, each grounded on its lemRank gridlake address (`dog r671`, `pet r2968`, `animal r780`) with NARS truth ``. Stage 3 **DEDUCES** what no window stated: `(dog is_a animal)` via transitive is_a and `(dog need food)` via property inheritance down the is_a basin, both `` — strictly weaker than any premise (NARS monotonicity). Query `what is dog?` → `pet [direct c=0.90]` + `animal [reasoned c=0.73]`. KILL-gated on a fact being **reasoned, not read** — the gap-fill firing is the claim. + +**The deferred affect leg, framed correctly (not fabricated):** irony/sarcasm = a **signed contradiction** between the SPO literal valence and the qualia sign — and per the standing doctrine (*"opinions are committed contradictions preserved, not resolved"*), it is STORED as a signed contradiction, never smoothed. `triangle_bridge::qualia_distance` already computes the contradiction *magnitude*; the missing piece is reading a large distance WITH a sign-flip as the ironic-inversion bit and persisting `{literal SPO, qualia sign, inversion}` as one quad. Its falsifier needs a labeled ironic corpus (not committed) — so it is a **CONJECTURE with a named probe**, deliberately not measured here. Additive: example + board only, no core change. **Cross-ref:** E-SURFACE-FORM-COLLAPSE-1, E-ARM-DISCOVERY-REASONING-BRIDGE-1, E-FREQ-IS-COSINE-REPLACEMENT-1 (lemRank grounding), E-TRI-FIDELITY-SOA-SELF-REASONING-1 (the basin-reasoning cascade), I-SUBSTRATE-MARKOV (NARS=Markov), `triangle_bridge.rs` (the qualia hook), `gridlake_spo_ngrams.rs` (the licensed-corpus real-SPO path). + ## 2026-07-19 — E-TRI-FIDELITY-SOA-SELF-REASONING-1 — the graph reasons about itself: ONE 512-byte SoA node co-resides all three distance fidelities (FULL 4096² / PALETTE 6×256:256 ADC / MORTON address-only), self-audits each vs ground truth, and a route→verify RDO cascade matches brute-force NN at 97.9% fewer exact evals — the "self-optimizing space-time-aware graph" endgame, runnable on committed data **Status:** FINDING (built + measured, KILL-gated, clippy/fmt-clean on 1.95). **Confidence:** High for the co-residence + cascade mechanism; magnitude is an 8-genre floor (the 2×256:256 committed demo; production 6×256:256 sharpens it). Deliverable: `crates/deepnsm/examples/tri_fidelity_soa.rs` (std-only, zero-dep, deterministic, no RNG). Operator: *"We use 512 byte SoA so you could store all 3 versions in DeepNSM examples — 4096² / 6×256:256 / Morton-comma mipmap — and let the Graph reason about itself."* diff --git a/crates/deepnsm/examples/spo_markov_kg.rs b/crates/deepnsm/examples/spo_markov_kg.rs new file mode 100644 index 00000000..bb2e671a --- /dev/null +++ b/crates/deepnsm/examples/spo_markov_kg.rs @@ -0,0 +1,328 @@ +//! The fact-building spine: text -> SPO 2^3 facts -> +-5 CausalEdge window +//! fill -> Markov/NARS reasoning fills the remaining -> stored as a knowledge +//! graph. The affect layer (qualia sign = irony/sarcasm) is deferred; this +//! example proves the SPINE that layer sits on. +//! +//! This is the DeepNSM realization of the operator's endgame, spine-first: +//! +//! "SPO 2^3 represents actual facts that get filled by CausalEdge context +//! from +5/-5, and then reasoning fills the remaining with Markov chain +//! context building ... reasoning about supporting basins ... stored as +//! knowledge graph." +//! +//! It composes three already-recorded findings into one runnable pipeline: +//! +//! - `E-SURFACE-FORM-COLLAPSE-1` -- the SPO 2^3 role mask collapses a token +//! to a (lemma, role) fact slot (Subject/Object nominal, Predicate verbal). +//! - the Markov +-5 trajectory / `temporal.rs` stream -- the CausalEdge +//! context window that lands DIRECTLY-supported facts. +//! - `E-ARM-DISCOVERY-REASONING-BRIDGE-1` + `I-SUBSTRATE-MARKOV` (the NARS +//! revision arc IS the Markov trajectory) -- transitive deduction + +//! property inheritance down the `is_a` basin fill the facts NO window +//! ever stated. +//! +//! ## The three stages +//! +//! 1. COLLAPSE: each sentence's tokens -> (lemma, Role) via a tiny PoS FSM +//! (determiners skipped; copula/verb = Predicate; nouns = Subject before +//! the predicate, Object after). +//! 2. +-5 FILL: for each Predicate token, the Subject is the nearest noun +//! within 5 to its left and the Object the nearest noun within 5 to its +//! right -- the CausalEdge (S -predicate-> O), landed from the window. +//! Each direct fact carries a NARS truth . +//! 3. MARKOV/NARS FILL: the remaining facts are DEDUCED, not read -- +//! transitive `is_a` (dog is_a pet, pet is_a animal |- dog is_a animal) +//! and property inheritance down the `is_a` basin (dog is_a pet, pet +//! need food |- dog need food). NARS deduction truth: f = f1*f2, +//! c = c1*c2*0.9 (monotone weaker than any premise). +//! +//! The result is an AriGraph-shaped knowledge graph: nodes carry their COCA +//! `lemRank` (the frequency-centroid gridlake address from +//! `E-FREQ-IS-COSINE-REPLACEMENT-1`), edges carry NARS truth. A query reads +//! direct + deduced facts, deduced strictly weaker. +//! +//! Honest boundary: a small SYNTHETIC corpus of COCA lemmas (the real +//! ngrams.info COCA windows are licensed / gitignored -- see +//! `gridlake_spo_ngrams`). The corpus is the demonstrator; the PIPELINE (+-5 +//! fill -> NARS gap-fill -> store) is the claim, KILL-gated on a fact being +//! DEDUCED that no window stated. +//! +//! ## Run +//! +//! ```bash +//! cargo run --manifest-path crates/deepnsm/Cargo.toml --example spo_markov_kg +//! ``` + +use std::collections::HashMap; + +/// A NARS truth value: frequency (evidence ratio) and confidence. +#[derive(Clone, Copy)] +struct Truth { + f: f64, + c: f64, +} +impl Truth { + /// NARS deduction: chaining two beliefs weakens both terms. + fn deduce(self, other: Truth) -> Truth { + Truth { + f: self.f * other.f, + c: self.c * other.c * 0.9, + } + } +} + +/// The SPO role a collapsed token fills. Subject and Object are the same +/// nominal class at collapse time (`Noun`); which one a noun fills is +/// resolved by POSITION relative to the predicate at +-5 fill time (before +/// the predicate = Subject, after = Object), per the S/O nominal simplification +/// in `E-SURFACE-FORM-COLLAPSE-1`. +#[derive(Clone, Copy, PartialEq)] +enum Role { + Noun, + Predicate, + Skip, +} + +/// The 6-word predicate vocabulary of the synthetic corpus, each mapped to +/// its lemma. `is`/`is_a` is the taxonomy copula; the rest are properties. +fn predicate_lemma(tok: &str) -> Option<&'static str> { + match tok { + "is" => Some("is_a"), + "runs" | "run" => Some("run"), + "needs" | "need" => Some("need"), + "eats" | "eat" => Some("eat"), + _ => None, + } +} + +fn role_of(tok: &str) -> Role { + match tok { + "the" | "a" | "an" => Role::Skip, + _ if predicate_lemma(tok).is_some() => Role::Predicate, + _ => Role::Noun, // resolved to Subject/Object by position at fill time + } +} + +/// Load `lemma -> rank` from the committed COCA frequency table (the +/// gridlake address each SPO node lands on). +fn load_ranks(csv_path: &str) -> HashMap { + let text = std::fs::read_to_string(csv_path).unwrap_or_default(); + let mut m = HashMap::new(); + for line in text.lines().skip(1) { + let f: Vec<&str> = line.split(',').collect(); + if f.len() < 2 { + continue; + } + if let Ok(rank) = f[0].trim().parse::() { + m.entry(f[1].to_ascii_lowercase()).or_insert(rank); + } + } + m +} + +fn main() { + let csv = concat!(env!("CARGO_MANIFEST_DIR"), "/word_frequency/lemmas_5k.csv"); + let ranks = load_ranks(csv); + + // A small SYNTHETIC corpus of COCA lemmas. The chain dog -> pet -> animal + // is deliberately never stated whole; the graph must DEDUCE (dog is_a + // animal) and (dog need food). + let corpus: [&[&str]; 6] = [ + &["the", "dog", "is", "a", "pet"], + &["a", "pet", "is", "an", "animal"], + &["the", "cat", "is", "an", "animal"], // direct, for contrast + &["a", "pet", "needs", "food"], + &["the", "dog", "runs"], + &["the", "cat", "eats", "food"], + ]; + const WINDOW: usize = 5; + + // Stage 1+2: COLLAPSE + +-5 FILL. Facts keyed (subject, predicate) -> obj. + // `is_a` facts and property facts share the store; obj = "" for + // predicate-only facts (the dog runs). + let mut direct: Vec<(String, String, String, Truth)> = Vec::new(); + for sent in corpus.iter() { + // collapse tokens to (lemma, role), keeping position + let toks: Vec<(&str, Role)> = sent.iter().map(|&t| (t, role_of(t))).collect(); + for (pi, &(ptok, prole)) in toks.iter().enumerate() { + if prole != Role::Predicate { + continue; + } + let pred = predicate_lemma(ptok).unwrap(); + // Subject = nearest noun within WINDOW to the left + let subj = (0..pi) + .rev() + .filter(|&k| pi - k <= WINDOW) + .find(|&k| toks[k].1 == Role::Noun) + .map(|k| toks[k].0); + // Object = nearest noun within WINDOW to the right + let obj = ((pi + 1)..toks.len()) + .filter(|&k| k - pi <= WINDOW) + .find(|&k| toks[k].1 == Role::Noun) + .map(|k| toks[k].0); + if let Some(s) = subj { + let o = obj.unwrap_or("").to_string(); + direct.push((s.to_string(), pred.to_string(), o, Truth { f: 1.0, c: 0.9 })); + } + } + } + + // Stage 3: MARKOV/NARS FILL -- deduce facts no window stated. + // (a) transitive is_a: s is_a m, m is_a o |- s is_a o + // (b) property inheritance: s is_a m, m PRED o |- s PRED o (PRED != is_a) + let is_a: Vec<(String, String, Truth)> = direct + .iter() + .filter(|(_, p, o, _)| p == "is_a" && !o.is_empty()) + .map(|(s, _, o, t)| (s.clone(), o.clone(), *t)) + .collect(); + let stated: std::collections::HashSet<(String, String, String)> = direct + .iter() + .map(|(s, p, o, _)| (s.clone(), p.clone(), o.clone())) + .collect(); + + let mut deduced: Vec<(String, String, String, Truth)> = Vec::new(); + // (a) transitive is_a (single hop of closure; the chain here is length 2) + for (s, m, t1) in is_a.iter() { + for (m2, o, t2) in is_a.iter() { + if m == m2 && s != o { + let key = (s.clone(), "is_a".to_string(), o.clone()); + if !stated.contains(&key) && !deduced.iter().any(|(a, _, c, _)| a == s && c == o) { + deduced.push((s.clone(), "is_a".to_string(), o.clone(), t1.deduce(*t2))); + } + } + } + } + // (b) property inheritance down the is_a basin + for (s, m, t1) in is_a.iter() { + for (bs, bp, bo, t2) in direct.iter() { + if bp != "is_a" && bs == m { + let key = (s.clone(), bp.clone(), bo.clone()); + if !stated.contains(&key) + && !deduced + .iter() + .any(|(a, p, c, _)| a == s && p == bp && c == bo) + { + deduced.push((s.clone(), bp.clone(), bo.clone(), t1.deduce(*t2))); + } + } + } + } + + // Store: the AriGraph-shaped knowledge graph (adjacency + truth), nodes + // grounded on their COCA lemRank (gridlake address). + let rank_of = |w: &str| { + ranks + .get(w) + .map(|r| r.to_string()) + .unwrap_or_else(|| "?".into()) + }; + + println!("SPO -> +-5 fill -> Markov/NARS fill -> knowledge graph"); + println!( + " synthetic corpus: {} sentences, window +-{WINDOW}", + corpus.len() + ); + println!(); + println!("STAGE 2 -- DIRECT facts landed from the +-5 CausalEdge window:"); + for (s, p, o, t) in &direct { + let obj = if o.is_empty() { + "(intrans)" + } else { + o.as_str() + }; + println!( + " ({s} r{}) --{p}--> ({obj}{}) ", + rank_of(s), + if o.is_empty() { + String::new() + } else { + format!(" r{}", rank_of(o)) + }, + t.f, + t.c + ); + } + println!(); + println!("STAGE 3 -- DEDUCED facts (Markov/NARS; NO window stated these):"); + for (s, p, o, t) in &deduced { + println!( + " ({s}) --{p}--> ({o}) [reasoned]", + t.f, t.c + ); + } + println!(); + + // Query the graph: "what is a dog?" -> direct + deduced, deduced weaker. + let query = "dog"; + println!("QUERY what is '{query}'? (is_a closure, direct first)"); + let mut answers: Vec<(&String, Truth, bool)> = Vec::new(); + for (s, p, o, t) in &direct { + if s == query && p == "is_a" && !o.is_empty() { + answers.push((o, *t, false)); + } + } + for (s, p, o, t) in &deduced { + if s == query && p == "is_a" { + answers.push((o, *t, true)); + } + } + answers.sort_by(|a, b| b.1.c.partial_cmp(&a.1.c).unwrap()); + for (o, t, reasoned) in &answers { + println!( + " {query} is_a {o} {}", + t.c, + if *reasoned { + " [reasoned, not read]" + } else { + " [direct]" + } + ); + } + println!(); + + // KILL gates (regression guards). + let mut fail = Vec::new(); + if direct.is_empty() { + fail.push("no DIRECT facts landed from the +-5 window".to_string()); + } + let deduced_is_a_animal = deduced + .iter() + .any(|(s, p, o, _)| s == "dog" && p == "is_a" && o == "animal"); + if !deduced_is_a_animal { + fail.push( + "(dog is_a animal) was NOT deduced -- Markov/NARS gap-fill did not fire".to_string(), + ); + } + let inherited = deduced + .iter() + .any(|(s, p, o, _)| s == "dog" && p == "need" && o == "food"); + if !inherited { + fail.push("(dog need food) was NOT inherited down the is_a basin".to_string()); + } + // deduced strictly weaker than any direct fact (NARS monotonicity) + let min_direct_c = direct.iter().map(|(_, _, _, t)| t.c).fold(1.0f64, f64::min); + let max_deduced_c = deduced + .iter() + .map(|(_, _, _, t)| t.c) + .fold(0.0f64, f64::max); + if !deduced.is_empty() && max_deduced_c >= min_direct_c { + fail.push(format!( + "deduced confidence {max_deduced_c:.2} not < direct {min_direct_c:.2} (NARS monotonicity broken)" + )); + } + if fail.is_empty() { + println!("KILL GATES: all pass -- the +-5 window lands facts, NARS reasoning fills the"); + println!("basins no window stated, and the graph answers with direct + reasoned truth."); + } else { + println!("KILL GATES FAILED:"); + for f in &fail { + println!(" - {f}"); + } + std::process::exit(1); + } + println!(); + println!("DEFERRED (the affect layer): qualia -8/+8 sign = ironic/sarcastic inversion of"); + println!("the SPO literal valence, stored as a COMMITTED contradiction (triangle_bridge::"); + println!("qualia_distance is the hook). Gated on a labeled ironic corpus -- CONJECTURE, not"); + println!("fabricated here. See the endgame north-star on the board."); +}