File size: 4,388 Bytes
5d07399 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | """
Symbolic recursion operators from the Primal Logic preprint:
Dx(t) = ∫₀ᵗ a · Q(τ) dτ where Q(t) = DT + DP + DEM + DW
O(f)(t) = ∫₀ᵗ b · f(τ) dτ meta-operator with intent modulation b
"""
from __future__ import annotations
import math
from dataclasses import dataclass, field
from typing import Callable, Dict, List, Sequence
import numpy as np
# Lightfoot constant — shared with 3IA Atlas / gateway STK
MU_DEFAULT = 0.16905
D_ATTRACTOR = 149.999
def composite_q(
dt_dev: float,
dp_dev: float,
dem_dev: float,
dw_dev: float,
*,
weights: Sequence[float] = (1.0, 1.0, 1.0, 1.0),
) -> float:
"""Q(t) = DT + DP + DEM + DW (weighted composite input)."""
w_dt, w_dp, w_dem, w_dw = weights
return w_dt * dt_dev + w_dp * dp_dev + w_dem * dem_dev + w_dw * dw_dev
@dataclass
class SymbolicRecursionKernel:
"""
Primary kernel: Dx(t) = ∫ a · Q(t) dt with recursive phase coherence.
"""
a: float = 1.0
mu: float = MU_DEFAULT
state: float = 0.0
history: List[float] = field(default_factory=list)
def step(self, q_t: float, *, dt: float = 0.01) -> float:
"""Discrete integral with exponential memory decay (3IA Atlas kernel)."""
decay = math.exp(-self.mu * dt)
self.state = decay * self.state + self.a * q_t * dt
self.history.append(self.state)
return self.state
def integrate_series(self, q_series: np.ndarray, *, dt: float = 0.01) -> np.ndarray:
self.state = 0.0
self.history.clear()
out = np.empty_like(q_series, dtype=float)
for i, q in enumerate(q_series):
out[i] = self.step(float(q), dt=dt)
return out
@dataclass
class MetaOperator:
"""
O(f)(t) = ∫ b · f(t) dt — embeds symbolic recursion and intent modulation.
"""
b: float = 0.091 # intent modulation (STK_BETA from gateway)
mu: float = MU_DEFAULT
state: float = 0.0
def apply(self, f_t: float, *, dt: float = 0.01) -> float:
decay = math.exp(-self.mu * dt)
self.state = decay * self.state + self.b * f_t * dt
return self.state
def apply_series(self, f_series: np.ndarray, *, dt: float = 0.01) -> np.ndarray:
self.state = 0.0
out = np.empty_like(f_series, dtype=float)
for i, f in enumerate(f_series):
out[i] = self.apply(float(f), dt=dt)
return out
def collapse_to_attractor(self, signal_history: Sequence[float], *, dt: float = 0.01) -> float:
"""SREC collapse — gateway-compatible echo integral."""
total = 0.0
for val in signal_history:
total += self.b * val * dt
return total if abs(total) < D_ATTRACTOR else 0.0
def forcing_functions(t: np.ndarray) -> Dict[str, np.ndarray]:
"""Worked examples from the preprint."""
return {
"oscillatory": np.sin(t) + np.cos(t),
"decaying": np.exp(-t),
"accelerating": t**2,
"fractal_impulse": _fractal_impulse(t),
"hybrid_echo": _hybrid_echo(t),
}
def _fractal_impulse(t: np.ndarray, depth: int = 4) -> np.ndarray:
out = np.zeros_like(t, dtype=float)
for k in range(depth):
scale = 2**k
out += np.sin(scale * np.pi * t) / scale
return out
def _hybrid_echo(t: np.ndarray, delay: float = 0.5) -> np.ndarray:
primary = np.sin(2 * np.pi * 0.5 * t)
echo = np.zeros_like(t)
dt = t[1] - t[0] if len(t) > 1 else 0.01
lag_steps = max(1, int(delay / dt))
echo[lag_steps:] = 0.6 * primary[:-lag_steps]
return primary + echo
def run_worked_examples(
*,
t_end: float = 10.0,
n_points: int = 500,
a: float = 1.0,
b: float = 0.091,
) -> Dict[str, Dict[str, object]]:
"""Evaluate Dx and O(f) under all forcing functions."""
t = np.linspace(0, t_end, n_points)
dt = t[1] - t[0]
kernel = SymbolicRecursionKernel(a=a)
meta = MetaOperator(b=b)
results: Dict[str, Dict[str, object]] = {}
for name, f_series in forcing_functions(t).items():
dx = kernel.integrate_series(f_series, dt=dt)
of = meta.apply_series(f_series, dt=dt)
results[name] = {
"final_dx": float(dx[-1]),
"final_of": float(of[-1]),
"max_dx": float(np.max(np.abs(dx))),
"bounded": bool(np.max(np.abs(dx)) < D_ATTRACTOR * 2),
}
return results |