diff --git a/crates/ogar-loco/src/lib.rs b/crates/ogar-loco/src/lib.rs index 69d66d2a..41dc1322 100644 --- a/crates/ogar-loco/src/lib.rs +++ b/crates/ogar-loco/src/lib.rs @@ -588,6 +588,41 @@ impl FnIndex { /// Read a call argument. `procedures_defreturn` argument access. pub const PROC_ARG: FnIndex = FnIndex(0x85); + // ── epistemic mask algebra (0x86..0x8B, minted 2026-09-01) ────────── + // + // The operator's essence-directive, verbatim in intent: primitives like + // Belnap become reusable bytecode macros here, for literally everything. + // Semantics are owned by `lance-graph-contract::epistemic_bassin` (the + // scalar oracles these calls are parity-tested against); batch SIMD + // execution is ndarray's shipped W1a-#9 `ternlog` (native VPTERNLOGQ). + // Green-certified atoms only — Hambly-Lyons is deliberately ABSENT + // while jc Pillar 11 is red (the red-pillar mint rule). + + /// Any 3-input boolean over stacked masks: pops three masks, and the + /// call's ONE VALUE BYTE **is the 8-bit truth table** (IMM bit index = + /// `(a << 2) | (b << 1) | c`) — one FnIndex covers all 256 stacked-mask + /// combinators, which is the purest `(function : value)` in the ABI. + /// Canonical tables (asked-contested 0x80, asked-silent 0x02 = the + /// missing link, …) live in `epistemic_bassin::sweep_ternlog`. + pub const TERNLOG: FnIndex = FnIndex(0x86); + /// Belnap/FDE knowledge-order join of two mask PAIRS — bitwise OR per + /// side; provably the state layer of one-hop accumulation. + pub const BELNAP_JOIN: FnIndex = FnIndex(0x87); + /// Shannon expected-information-gain readout: pops (before, after) + /// candidate counts, pushes whole bits of narrowing (u4-saturated). + /// Proprioception, never evidence. + pub const INFO_GAIN: FnIndex = FnIndex(0x88); + /// EWA tension readout: pops (log-norm growth, certificate bound), + /// pushes quarters-of-the-bound (u4; 7 = the 1.75× PASS slack). + pub const SIGMA_TENSION: FnIndex = FnIndex(0x89); + /// One-hop accumulation of a LIST of bassin pairs into the parent pair — + /// exact sums per side, one clamp; a parent expresses its DIRECT + /// children only. + pub const ACCUMULATE: FnIndex = FnIndex(0x8A); + /// One-hop contested-ness: pops (list of pairs, axis), pushes the + /// four-state Shannon entropy of the children's stances on that axis. + pub const STANCE_ENTROPY: FnIndex = FnIndex(0x8B); + /// Is this a **shared computational** operation — one that means the same /// thing in every vocabulary? /// diff --git a/crates/ogar-loco/src/vocabulary.rs b/crates/ogar-loco/src/vocabulary.rs index 68dc24b1..15c30485 100644 --- a/crates/ogar-loco/src/vocabulary.rs +++ b/crates/ogar-loco/src/vocabulary.rs @@ -89,6 +89,17 @@ pub mod shared_core { | FnIndex::FOR_EACH => 1, // from, to, by — then a body. FnIndex::FOR_RANGE => 3, + // ── epistemic mask algebra (0x86..0x8B). TERNLOG pops three + // masks; its truth table rides as the call's value byte, never + // as an operand. The two list-consuming ops take the LIST as + // one operand (the arity of the call, not of the children — + // which is how the variadic-refusal rule stays satisfied). + FnIndex::TERNLOG => 3, + FnIndex::BELNAP_JOIN + | FnIndex::INFO_GAIN + | FnIndex::SIGMA_TENSION + | FnIndex::STANCE_ENTROPY => 2, + FnIndex::ACCUMULATE => 1, // Leave the enclosing loop / iteration. No operand, no body. FnIndex::BREAK | FnIndex::CONTINUE => 0, // ── leaves — they push, they do not consume. @@ -337,6 +348,12 @@ pub mod shared_core { FnIndex::ACOS => "ACOS", FnIndex::ATAN => "ATAN", FnIndex::ATAN2 => "ATAN2", + FnIndex::TERNLOG => "TERNLOG", + FnIndex::BELNAP_JOIN => "BELNAP_JOIN", + FnIndex::INFO_GAIN => "INFO_GAIN", + FnIndex::SIGMA_TENSION => "SIGMA_TENSION", + FnIndex::ACCUMULATE => "ACCUMULATE", + FnIndex::STANCE_ENTROPY => "STANCE_ENTROPY", FnIndex::RANDOM_INT => "RANDOM_INT", FnIndex::RANDOM_FLOAT => "RANDOM_FLOAT", FnIndex::CONSTRAIN => "CONSTRAIN", @@ -1417,8 +1434,11 @@ mod coverage { ); } - // And the census itself, pinned: 95 named operations (96 constants - // minus NOP, which is not an operation), 5 refused, 90 covered. - assert_eq!(named, 95, "the named census moved — re-pin deliberately"); + // And the census itself, pinned: 101 named operations (102 constants + // minus NOP, which is not an operation), 5 refused, 96 covered. + // Re-pinned 2026-09-01: +6 for the epistemic mask-algebra band + // (0x86..0x8B — TERNLOG, BELNAP_JOIN, INFO_GAIN, SIGMA_TENSION, + // ACCUMULATE, STANCE_ENTROPY), minted into the reserved core slots. + assert_eq!(named, 101, "the named census moved — re-pin deliberately"); } }