// field_test.el — Proof of concept: Hebbian field model // // Tests the core mechanics: // 1. Nodes with 2D semantic positions and temporal coordinates // 2. Edges with weights that grow via co-activation (Hebb's rule) // 3. Spreading activation with path strength // 4. Temporal decay in path strength // 5. Epistemic confidence = node confidence * path strength // // No storage — pure in-memory demonstration using print output. // ── Math helpers ────────────────────────────────────────────────────────────── fn clamp_f(v: Float, lo: Float, hi: Float) -> Float { if v < lo { return lo } if v > hi { return hi } return v } // L2 distance squared — no sqrt needed for proximity comparison fn dist_sq(ax: Float, ay: Float, bx: Float, by: Float) -> Float { let dx: Float = ax - bx let dy: Float = ay - by return dx * dx + dy * dy } // Proximity score: 1 / (1 + dist_sq) — range (0, 1], closer = higher fn proximity(ax: Float, ay: Float, bx: Float, by: Float) -> Float { let d: Float = dist_sq(ax, ay, bx, by) return 1.0 / (1.0 + d) } // Linear temporal decay: 1.0 at t=0, decaying toward 0 // decay_rate: fraction lost per time unit fn temporal_decay(age: Float, decay_rate: Float) -> Float { let d: Float = 1.0 - decay_rate * age return clamp_f(d, 0.0, 1.0) } // ── Hebbian learning ────────────────────────────────────────────────────────── // New edge weight after co-activation event // w_new = clamp(w + lr * a_i * a_j, 0, 1) fn hebbian_update(weight: Float, act_i: Float, act_j: Float, lr: Float) -> Float { let delta: Float = lr * act_i * act_j return clamp_f(weight + delta, 0.0, 1.0) } // Edge decay between activations // w_new = w * (1 - decay_rate) fn edge_decay(weight: Float, decay_rate: Float) -> Float { return clamp_f(weight * (1.0 - decay_rate), 0.0, 1.0) } // ── Path strength ───────────────────────────────────────────────────────────── // Path strength = edge_weight * temporal_decay(node_age) // This is the confidence qualifier on a retrieval result fn path_strength(edge_weight: Float, node_age: Float, decay_rate: Float) -> Float { let td: Float = temporal_decay(node_age, decay_rate) return edge_weight * td } // Epistemic confidence = node_confidence * path_strength fn epistemic_confidence(node_confidence: Float, ps: Float) -> Float { return node_confidence * ps } // ── Simulation ──────────────────────────────────────────────────────────────── fn run_test() -> String { println("=== Engram Field Model — Proof of Concept ===") println("") // ── Nodes ── // Each node: id, label, semantic position (x, y), temporal coordinate, confidence // Semantic space: 2D for demonstration // x=0..1: concrete←→abstract // y=0..1: negative←→positive valence println("── Nodes ──────────────────────────────────────") println("A: 'patient has fever' pos=(0.2, 0.4) t=100") println("B: 'influenza' pos=(0.3, 0.5) t=90") println("C: 'drug interaction warning' pos=(0.6, 0.3) t=10 (old, unactivated)") println("D: 'ibuprofen' pos=(0.65, 0.3) t=10 (old, unactivated)") println("") // Semantic positions let ax: Float = 0.2 let ay: Float = 0.4 let bx: Float = 0.3 let by: Float = 0.5 let cx: Float = 0.6 let cy: Float = 0.3 let dx_pos: Float = 0.65 let dy_pos: Float = 0.3 // Initial proximity (latent gradient — implicit from positions) let prox_ab: Float = proximity(ax, ay, bx, by) let prox_ac: Float = proximity(ax, ay, cx, cy) let prox_cd: Float = proximity(cx, cy, dx_pos, dy_pos) println("── Initial latent gradients (proximity) ───────") println("A↔B proximity: " + float_to_str(prox_ab) + " (semantically close — fever/flu)") println("A↔C proximity: " + float_to_str(prox_ac) + " (semantically distant)") println("C↔D proximity: " + float_to_str(prox_cd) + " (close — drug interaction/ibuprofen)") println("") // ── Initial edge weights (all start near zero — no co-activation yet) ── let w_ab: Float = 0.0 let w_ac: Float = 0.0 let w_cd: Float = 0.0 println("── Initial edge weights ────────────────────────") println("A→B: " + float_to_str(w_ab) + " (no co-activation yet)") println("A→C: " + float_to_str(w_ac)) println("C→D: " + float_to_str(w_cd)) println("") // ── Co-activation events ── // The doctor CGI processes a patient with fever. // A (fever) and B (influenza) co-activate — the diagnosis fires both. // Learning rate: 0.3 let lr: Float = 0.3 let act_strength: Float = 1.0 // full activation println("── Co-activation event 1: patient with fever → flu diagnosis ──") let w_ab_1: Float = hebbian_update(w_ab, act_strength, act_strength, lr) println("A and B fire together (strength=1.0)") println("A→B weight: " + float_to_str(w_ab) + " → " + float_to_str(w_ab_1)) println("") println("── Co-activation event 2: another flu case ──") let w_ab_2: Float = hebbian_update(w_ab_1, act_strength, act_strength, lr) println("A and B fire together again") println("A→B weight: " + float_to_str(w_ab_1) + " → " + float_to_str(w_ab_2)) println("") println("── Co-activation event 3: third flu case ──") let w_ab_3: Float = hebbian_update(w_ab_2, act_strength, act_strength, lr) println("A and B fire together again") println("A→B weight: " + float_to_str(w_ab_2) + " → " + float_to_str(w_ab_3)) println("") // C and D have never been activated in this context — weights stay near zero // (In practice, proximity means a latent gradient exists, but no learned edge yet) // ── Query: activate A (fever), what spreads? ── println("── Query: activate A (fever) ───────────────────") println("Spreading activation from A...") println("") // Decay rates let temporal_decay_rate: Float = 0.005 // per time unit let current_t: Int = 200 // Node ages (current_t - node_t) let age_b: Float = 110.0 // t=90, current=200 let age_c: Float = 190.0 // t=10, current=200 let age_d: Float = 190.0 // t=10, current=200 // Path strength to B: strong edge, recently relevant let ps_b: Float = path_strength(w_ab_3, age_b, temporal_decay_rate) let conf_b: Float = epistemic_confidence(0.9, ps_b) // Path strength to C: no learned edge — only latent proximity gradient // Spreading activation from A can weakly reach C via proximity alone let latent_ac: Float = prox_ac * 0.1 // proximity contributes small initial signal let ps_c: Float = path_strength(latent_ac, age_c, temporal_decay_rate) let conf_c: Float = epistemic_confidence(0.9, ps_c) // Path strength to D via C: chain of weak signals let ps_d: Float = path_strength(latent_ac * prox_cd * 0.1, age_d, temporal_decay_rate) let conf_d: Float = epistemic_confidence(0.9, ps_d) println("Result: B (influenza)") println(" Edge weight: " + float_to_str(w_ab_3)) println(" Node age: " + float_to_str(age_b) + " time units") println(" Temporal decay: " + float_to_str(temporal_decay(age_b, temporal_decay_rate))) println(" Path strength: " + float_to_str(ps_b)) println(" Confidence: " + float_to_str(conf_b)) println(" → STRONG: B surfaces with high confidence") println("") println("Result: C (drug interaction warning)") println(" Edge weight: " + float_to_str(latent_ac) + " (latent only — never co-activated)") println(" Node age: " + float_to_str(age_c) + " time units") println(" Temporal decay: " + float_to_str(temporal_decay(age_c, temporal_decay_rate))) println(" Path strength: " + float_to_str(ps_c)) println(" Confidence: " + float_to_str(conf_c)) println(" → WEAK: C is distant and old — attenuated path triggers refresh signal") println("") println("Result: D (ibuprofen) via C") println(" Path strength: " + float_to_str(ps_d)) println(" Confidence: " + float_to_str(conf_d)) println(" → VERY WEAK: chain of attenuated edges") println("") // ── Refresh trigger ── println("── Attenuation trigger ─────────────────────────") let threshold: Float = 0.2 println("Confidence threshold: " + float_to_str(threshold)) if conf_c < threshold { println("C is below threshold (" + float_to_str(conf_c) + " < " + float_to_str(threshold) + ")") println("→ Trigger: 'drug interaction warning node found but path is weak.") println(" Last activated " + float_to_str(age_c) + " time units ago.") println(" Recommend fetching current information before acting.'") } println("") // ── After refresh: C and D co-activate with A ── println("── Refresh: doctor looks up drug interactions ──") println("A, C, D all co-activate during research") let w_ac_new: Float = hebbian_update(0.0, act_strength, act_strength, lr) let w_cd_new: Float = hebbian_update(0.0, act_strength, act_strength, lr) let age_c_new: Float = 0.0 // just activated let age_d_new: Float = 0.0 let ps_c_new: Float = path_strength(w_ac_new, age_c_new, temporal_decay_rate) let conf_c_new: Float = epistemic_confidence(0.9, ps_c_new) println("A→C weight after refresh: " + float_to_str(w_ac_new)) println("C→D weight after refresh: " + float_to_str(w_cd_new)) println("C confidence after refresh: " + float_to_str(conf_c_new)) println("→ Edges strengthened. Drug interaction now reachable with high confidence.") println("") println("=== Result ===") println("Perfect memory: all nodes present throughout.") println("Calibrated confidence: B (flu) high, C/D (drug interaction) low until refreshed.") println("Self-correcting: attenuation triggered fetch, fetch strengthened edges.") println("The field works.") return "ok" } let result: String = run_test()