UNPKG

@sschepis/resolang

Version:

ResoLang - Core quantum resonance computation library for browser and Node.js

394 lines (311 loc) 12.7 kB
/** * Tests for TinyAleph ported modules * * Tests: * - Fano plane multiplication tables * - Hypercomplex algebra (Complex, Quaternion, Octonion, Sedenion) * - Prime Hilbert Space * - SparsePrimeState and PR-Graph Memory */ import { multiplyIndices, FANO_LINES } from '../fano'; import { Hypercomplex, complex, quaternion, octonion, getDimensionName } from '../hypercomplex'; import { PrimeHilbertState, ResonanceOperators, encodeMemory, DominantPrime } from '../hilbert'; import { SparsePrimeState, resonanceScore, resonantAttention, PRGraphMemory } from '../rformer'; // ============================================================================ // Test Utilities // ============================================================================ let passed = 0; let failed = 0; function assert(condition: bool, message: string): void { if (condition) { passed++; } else { failed++; trace("FAILED: " + message); } } function assertApprox(a: f64, b: f64, epsilon: f64, message: string): void { const diff = Math.abs(a - b); if (diff < epsilon) { passed++; } else { failed++; trace("FAILED: " + message + " | Expected: " + b.toString() + ", Got: " + a.toString()); } } function printTestResults(): void { trace("================================"); trace("Test Results: " + passed.toString() + " passed, " + failed.toString() + " failed"); trace("================================"); } // ============================================================================ // Fano Plane Tests // ============================================================================ export function testFanoMultiplication(): void { trace("--- Testing Fano Plane Multiplication ---"); // Test quaternion multiplication (i * j = k) const ij = multiplyIndices(4, 1, 2); // i * j in quaternions assert(ij.index == 3, "i * j should give k (index 3)"); assert(ij.sign == 1, "i * j should have positive sign"); // Test j * i = -k const ji = multiplyIndices(4, 2, 1); assert(ji.index == 3, "j * i should give k (index 3)"); assert(ji.sign == -1, "j * i should have negative sign"); // Test unit element const oneOne = multiplyIndices(4, 0, 0); assert(oneOne.index == 0, "1 * 1 = 1"); assert(oneOne.sign == 1, "1 * 1 has positive sign"); // Test octonion multiplication const e1e2 = multiplyIndices(8, 1, 2); assert(e1e2.index != 0, "e1 * e2 should not be 1"); } // ============================================================================ // Hypercomplex Tests // ============================================================================ export function testComplex(): void { trace("--- Testing Complex Numbers ---"); const c1 = complex(3.0, 4.0); const c2 = complex(1.0, 2.0); // Test magnitude assertApprox(c1.norm(), 5.0, 0.001, "Complex magnitude"); // Test addition const sum = c1.add(c2); assertApprox(sum.get(0), 4.0, 0.001, "Complex addition real"); assertApprox(sum.get(1), 6.0, 0.001, "Complex addition imag"); // Test multiplication const prod = c1.mul(c2); // (3 + 4i)(1 + 2i) = 3 + 6i + 4i + 8i² = 3 + 10i - 8 = -5 + 10i assertApprox(prod.get(0), -5.0, 0.001, "Complex multiplication real"); assertApprox(prod.get(1), 10.0, 0.001, "Complex multiplication imag"); // Test conjugate const conj = c1.conjugate(); assertApprox(conj.get(0), 3.0, 0.001, "Complex conjugate real"); assertApprox(conj.get(1), -4.0, 0.001, "Complex conjugate imag"); } export function testQuaternion(): void { trace("--- Testing Quaternions ---"); const q1 = quaternion(1.0, 2.0, 3.0, 4.0); const q2 = quaternion(5.0, 6.0, 7.0, 8.0); // Test dimension name assert(getDimensionName(4) == "Quaternion", "Dimension name"); // Test norm const n = q1.norm(); const expectedNorm = Math.sqrt(1 + 4 + 9 + 16); // sqrt(30) assertApprox(n, expectedNorm, 0.001, "Quaternion norm"); // Test non-commutativity: q1 * q2 ≠ q2 * q1 const p12 = q1.mul(q2); const p21 = q2.mul(q1); const diff = p12.sub(p21); assert(diff.norm() > 0.1, "Quaternion multiplication is non-commutative"); // Test inverse const inv = q1.inverse(); const identity = q1.mul(inv); assertApprox(identity.get(0), 1.0, 0.01, "Quaternion inverse real part"); assertApprox(identity.get(1), 0.0, 0.01, "Quaternion inverse i part"); assertApprox(identity.get(2), 0.0, 0.01, "Quaternion inverse j part"); assertApprox(identity.get(3), 0.0, 0.01, "Quaternion inverse k part"); } export function testOctonion(): void { trace("--- Testing Octonions ---"); const o1 = octonion(1, 0, 0, 0, 0, 0, 0, 0); // Unit const o2 = octonion(0, 1, 0, 0, 0, 0, 0, 0); // e1 const o3 = octonion(0, 0, 1, 0, 0, 0, 0, 0); // e2 // Test dimension name assert(getDimensionName(8) == "Octonion", "Octonion dimension name"); // Test unit multiplication const prod = o1.mul(o2); assertApprox(prod.get(1), 1.0, 0.001, "Unit * e1 = e1"); // Test non-associativity: (e1 * e2) * e4 ≠ e1 * (e2 * e4) const e4 = octonion(0, 0, 0, 0, 1, 0, 0, 0); const left = o2.mul(o3).mul(e4); const right = o2.mul(o3.mul(e4)); const assocDiff = left.sub(right).norm(); // Note: Octonions can be associative for some combinations trace("Octonion associativity difference: " + assocDiff.toString()); } export function testSedenion(): void { trace("--- Testing Sedenions ---"); // Create sedenions (16-dimensional) const s = Hypercomplex.basis(16, 0); // Unit sedenion assert(s.dim == 16, "Sedenion dimension"); assert(getDimensionName(16) == "Sedenion", "Sedenion dimension name"); // Test entropy - unit sedenion should have 0 entropy assertApprox(s.entropy(), 0.0, 0.001, "Unit sedenion entropy"); // Create a superposition const mixed = Hypercomplex.zero(16); mixed.set(0, 0.5); mixed.set(1, 0.5); mixed.set(2, 0.5); mixed.set(3, 0.5); const mixedNormalized = mixed.normalize(); assert(mixedNormalized.entropy() > 0, "Mixed sedenion has positive entropy"); } // ============================================================================ // Prime Hilbert Space Tests // ============================================================================ export function testPrimeHilbertState(): void { trace("--- Testing Prime Hilbert State ---"); // Test basis state const basis2 = PrimeHilbertState.basis(2, null); assertApprox(basis2.norm(), 1.0, 0.001, "Basis state is normalized"); // Test uniform superposition const uniform = PrimeHilbertState.uniform(null); assertApprox(uniform.norm(), 1.0, 0.001, "Uniform state is normalized"); assert(uniform.entropy() > 0, "Uniform state has positive entropy"); // Test composite state const comp12 = PrimeHilbertState.composite(12, null); // 12 = 2² × 3 const dom = comp12.dominant(2); assert(dom.length >= 2, "Composite state has dominant primes"); } export function testResonanceOperators(): void { trace("--- Testing Resonance Operators ---"); // Test P operator (prime eigenvalue) const basis3 = PrimeHilbertState.basis(3, null); const pResult = ResonanceOperators.P(basis3); // P|3⟩ = 3|3⟩, so amplitude at 3 should be 3× original // Test H operator (Hadamard-like) const hResult = ResonanceOperators.H(basis3); assertApprox(hResult.norm(), 1.0, 0.01, "H preserves norm"); // Test R operator const rResult = ResonanceOperators.R(basis3, 6); // R(6)|ψ⟩ assertApprox(rResult.norm(), 1.0, 0.01, "R preserves norm"); } export function testMemoryEncoding(): void { trace("--- Testing Memory Encoding ---"); const state = encodeMemory("hello", null); assertApprox(state.norm(), 1.0, 0.001, "Encoded memory is normalized"); assert(state.entropy() > 0, "Encoded memory has positive entropy"); // Different texts should produce different states const state2 = encodeMemory("world", null); const similarity = state.coherence(state2); trace("Similarity between 'hello' and 'world': " + similarity.toString()); } // ============================================================================ // SparsePrimeState Tests // ============================================================================ export function testSparsePrimeState(): void { trace("--- Testing SparsePrimeState ---"); // Test basis state const basis = SparsePrimeState.basis(2); assertApprox(basis.norm(), 1.0, 0.001, "Sparse basis is normalized"); assert(basis.size() == 1, "Sparse basis has one entry"); // Test from number const from12 = SparsePrimeState.fromNumber(12); // 12 = 2² × 3 assert(from12.has(2), "12 contains factor 2"); assert(from12.has(3), "12 contains factor 3"); // Test uniform const uniform = SparsePrimeState.uniform(5); assert(uniform.size() == 5, "Uniform has 5 entries"); assertApprox(uniform.norm(), 1.0, 0.001, "Uniform is normalized"); // Test text encoding const text = SparsePrimeState.fromText("test"); assert(text.size() > 0, "Text encoding produces non-empty state"); assertApprox(text.norm(), 1.0, 0.001, "Text encoding is normalized"); } export function testResonantAttention(): void { trace("--- Testing Resonant Attention ---"); // Create query and key/value pairs const query = SparsePrimeState.basis(2); const keys = new Array<SparsePrimeState>(3); const values = new Array<SparsePrimeState>(3); keys[0] = SparsePrimeState.basis(2); // Same as query keys[1] = SparsePrimeState.basis(3); // Different keys[2] = SparsePrimeState.basis(5); // Different values[0] = SparsePrimeState.fromNumber(4); values[1] = SparsePrimeState.fromNumber(9); values[2] = SparsePrimeState.fromNumber(25); // Test resonance score const score1 = resonanceScore(query, keys[0]); const score2 = resonanceScore(query, keys[1]); assert(score1 > score2, "Same basis has higher resonance"); // Test attention const attended = resonantAttention(query, keys, values, 1.0); assert(attended.size() > 0, "Attention produces non-empty state"); } export function testPRGraphMemory(): void { trace("--- Testing PR-Graph Memory ---"); const memory = new PRGraphMemory(100, 0.01); // Store some states const id1 = memory.put(SparsePrimeState.fromNumber(6)); const id2 = memory.put(SparsePrimeState.fromNumber(12)); const id3 = memory.put(SparsePrimeState.fromNumber(15)); assert(memory.size() == 3, "Memory has 3 entries"); // Retrieve by ID const retrieved = memory.getById(id1); assert(retrieved !== null, "Can retrieve by ID"); // Content-addressable retrieval const query = SparsePrimeState.fromNumber(6); const results = memory.get(query, 2); assert(results.length >= 1, "Content retrieval returns results"); // Advance time and test decay memory.tick(10.0); const results2 = memory.get(query, 2); trace("Results after decay: " + results2.length.toString()); // Test deletion const deleted = memory.delete(id1); assert(deleted, "Can delete entry"); assert(memory.size() == 2, "Memory size reduced after delete"); } // ============================================================================ // Integration Tests // ============================================================================ export function testIntegration(): void { trace("--- Testing Integration ---"); // Create hypercomplex numbers and use them in sparse states const q = quaternion(1.0, 0.0, 0.0, 0.0); assertApprox(q.norm(), 1.0, 0.001, "Quaternion unit norm"); // Create a sparse state and evolve it const state = SparsePrimeState.uniform(10); const rotated = state.rotate(0.5); assertApprox(rotated.norm(), 1.0, 0.01, "Rotation preserves norm"); // Test prime-dependent phase const phased = state.primePhase(12); assertApprox(phased.norm(), 1.0, 0.01, "Prime phase preserves norm"); } // ============================================================================ // Main Test Runner // ============================================================================ export function runAllTests(): void { trace("========================================"); trace("Running TinyAleph Port Tests"); trace("========================================"); // Fano tests testFanoMultiplication(); // Hypercomplex tests testComplex(); testQuaternion(); testOctonion(); testSedenion(); // Prime Hilbert tests testPrimeHilbertState(); testResonanceOperators(); testMemoryEncoding(); // SparsePrimeState tests testSparsePrimeState(); testResonantAttention(); testPRGraphMemory(); // Integration testIntegration(); printTestResults(); } // Export for running export { runAllTests as test };