import numpy as np

class StabilizedHDGL_VM:
    def __init__(self):
        # Upper Field
        self.upper = {
            'prism': 105.0,
            'recursion_mode': 99.9999999999,
            'inf_recursion': 9.9999999999,
            'p3': 4.2360679775,
            'pi': 3.1415926535,
            'phi_phi': 2.6180339887,
            'phi': 1.6180339887
        }

        # D1..D8 + dimensionality switch
        self.D = np.array([1.,2.,3.,4.,5.,6.,7.,8.,1.], dtype=float)

        # Fibonacci / DNA braids
        self.P = np.zeros(8)
        self.P[4:] = [6.8541019662, 11.0901699437, 17.9442719100, 29.0344465435]

        # The Void
        self.void = 0.0

        # Ω global tension field
        self.omega = 1.0

        # Lower Field
        self.lower = {
            'neg_inf': 1e-10,
            'inv_P7': 0.0344465435,
            'inv_P6': 0.0557280900,
            'inv_P5': 0.0901699437,
            'inv_P4': 0.1458980338,
            'inv_P3': 0.2360679775,
            'inv_phi_phi': 0.3819660113,
            'inv_phi': 0.6180339887
        }

        # Instruction stream
        self.program = []
        self.ip = 0

        # Prime weights for first 8 D registers
        primes = [2,3,5,7,11,13,17,19]
        self.weights = np.array([2**n + p for n,p in enumerate(primes)], dtype=float)
        self.weights /= np.sum(self.weights)  # Normalize

        # φ powers with decay factor
        self.phi_decay = 0.5
        self.phi_powers = np.array([self.upper['phi']**(n) * (self.phi_decay**n) for n in range(len(self.D))])

        # Fibonacci recursive weights for multi-layer blending
        self.fib_weights = np.array([1,1,2,3,5,8,13,21,34], dtype=float)
        self.fib_weights /= np.sum(self.fib_weights)

        # Stabilization parameters
        self.max_D_mean = 10.0
        self.max_void = 1000.0
        self.max_omega = 10.0

    # --------------------------------------
    # Stabilized harmonic superposition
    # --------------------------------------
    def harmonic_superpose(self, blend_factor=0.05):
        D_prev = self.D.copy()
        phi_phi = self.upper['phi_phi']

        # Weighted sum over first 8 D registers
        weighted_sum = np.sum(D_prev[:8] * self.weights)

        for i in range(len(self.D)):
            p_val = self.P[i] if i < len(self.P) else 0
            fib_val = self.fib_weights[i] if i < len(self.fib_weights) else 0
            phi_val = self.phi_powers[i] if i < len(self.phi_powers) else 1.0

            # Stabilized update
            self.D[i] = D_prev[i] + blend_factor * (
                phi_val * D_prev[i] +       # φ^n recursive influence
                phi_phi * p_val +           # Fibonacci braid influence
                weighted_sum * fib_val +    # Weighted prime + Fibonacci blend
                self.omega                  # Global tension field
            )

        # Normalize D registers to prevent runaway growth
        mean_D = np.mean(self.D)
        if mean_D > self.max_D_mean:
            self.D *= self.max_D_mean / mean_D

        # Update Void with cap
        self.void += np.mean(self.D) * blend_factor
        if self.void > self.max_void:
            self.void = self.max_void

        # Update Ω with additive smoothing and cap
        self.omega += 0.01 * blend_factor
        if self.omega > self.max_omega:
            self.omega = self.max_omega

    # --------------------------------------
    # VM execution
    # --------------------------------------
    def load_program(self, instructions):
        self.program = instructions
        self.ip = 0

    def step(self):
        if self.ip >= len(self.program):
            return False
        instr = self.program[self.ip]

        # Instruction codes map to blend factors
        blend_map = {0:0.02,1:0.03,2:0.04,3:0.05}
        blend_factor = blend_map.get(instr, 0.03)

        self.harmonic_superpose(blend_factor)
        self.ip += 1
        return True

    def run(self):
        while self.step():
            pass

    def state(self):
        return {
            'D': self.D.copy(),
            'P': self.P.copy(),
            'upper': self.upper.copy(),
            'void': self.void,
            'omega': self.omega,
            'lower': self.lower.copy()
        }


# --------------------------
# Example usage
# --------------------------
if __name__ == "__main__":
    vm = StabilizedHDGL_VM()
    vm.load_program([0,1,2,3,1,0,2,3,1,0])
    vm.run()
    print("Final Stabilized HDGL VM State:")
    print(vm.state())
