core/core-rs/src/cga.rs
Shay 523c072818 feat: vault recall index, Rust versor parity, cognitive pack expansion
Phase 3 — vault exact recall index:
- Replace O(N) np.array_equal scan with hash-based exact-match index
- Add optional max_entries with deterministic FIFO eviction
- Index rebuilds on reproject for consistency

Phase 4 — Rust versor_apply parity:
- Fix CGA metric signature (+,+,+,+,-) and blade ordering to match Python
- Implement versor_apply_closed with null-vector preservation, f64 unitize,
  and construction seed fallback matching Python closure semantics
- Gate Rust dispatch behind CORE_BACKEND=rust; Python remains default
- Add f64 geometric product for closure-path precision

Phase 5 — cognitive quality pack expansion:
- Expand lexicon from 55 to 70 entries (evidence, inference, procedure,
  verification, distinction, relation, thought, understanding, judgment,
  principle, order, connectives)
- Improve semantic templates for cause, procedure, comparison, recall,
  verification intents
- Expand eval cases from 20 to 45 across all categories

Validation: 491 tests pass, 45 eval cases at 100% all metrics.
2026-05-15 15:34:39 -07:00

57 lines
1.7 KiB
Rust

//! CGA inner product and null-cone operations.
//!
//! Signature: (+,+,+,+,-), with Euclidean coordinates on e1,e2,e3.
//! e4^2 = +1, e5^2 = -1.
//!
//! A Euclidean point x embeds as:
//!
//! X = x + n_o + 0.5 * |x|^2 * n_inf
//!
//! with e4 coeff = 0.5*(|x|^2 - 1), e5 coeff = 0.5*(|x|^2 + 1).
//!
//! Then X·X = 0 and X·Y = -0.5 * ||x-y||^2.
//!
//! This is the ONLY distance metric in CORE-AI.
use crate::cl41::{geometric_product_raw, Cl41Error};
use thiserror::Error;
#[derive(Debug, Error)]
pub enum CgaError {
#[error("Cl41 error: {0}")]
Cl41(#[from] Cl41Error),
}
/// Symmetric CGA inner product.
/// 0.5 * scalar_part(X*Y + Y*X)
/// For null vectors: equals -d^2 / 2.
pub fn cga_inner_raw(x: &[f32; 32], y: &[f32; 32]) -> Result<f32, CgaError> {
let xy = geometric_product_raw(x, y)?;
let yx = geometric_product_raw(y, x)?;
Ok(0.5 * (xy[0] + yx[0]))
}
/// Check if X is on the null cone: |X·X| < tol.
pub fn is_null_raw(x: &[f32; 32], tol: f32) -> Result<bool, CgaError> {
Ok(cga_inner_raw(x, x)?.abs() < tol)
}
/// Re-project X onto the null cone by extracting Euclidean components
/// and re-embedding with the canonical CGA point map.
pub fn null_project_raw(x: &[f32; 32]) -> [f32; 32] {
embed_point_raw(&[x[1], x[2], x[3]])
}
/// Embed a Euclidean point [x, y, z] into the CGA null cone.
/// X = x + n_o + 0.5|x|^2 n_inf
/// where n_o = 0.5(e4 - e5), n_inf = e4 + e5.
pub fn embed_point_raw(p: &[f32; 3]) -> [f32; 32] {
let mut result = [0f32; 32];
result[1] = p[0];
result[2] = p[1];
result[3] = p[2];
let r2 = p[0] * p[0] + p[1] * p[1] + p[2] * p[2];
result[4] = 0.5 * (r2 - 1.0);
result[5] = 0.5 * (r2 + 1.0);
result
}