import numpy as np

class HDGLPage:
    def __init__(self, name, initial_value=0.0):
        self.name = name
        self.energy = initial_value   # analog value of the page
        self.tension = 0.0
        self.trace = initial_value

    def read(self):
        # reading excites the lattice analogically
        self.tension = self.energy ** 1.2
        return self.energy

    def write(self, value):
        # writing propagates energy into the lattice
        self.trace = self.trace * 0.9 + value * 0.1
        self.energy = self.trace
        self.tension = self.energy ** 1.2

class HDGLLattice:
    def __init__(self, num_channels=32):
        self.channels = [0.0] * num_channels   # analog channel values
        self.pages = {}                         # page_name -> HDGLPage

    def register_page(self, page_name, initial_value=0.0):
        self.pages[page_name] = HDGLPage(page_name, initial_value)

    def access_page(self, page_name, value=None):
        """If value is None -> read, else write"""
        page = self.pages[page_name]
        if value is None:
            return page.read()
        else:
            page.write(value)

    def propagate(self):
        """Harmonic fusion: cross-channel propagation"""
        energies = np.array([p.energy for p in self.pages.values()])
        avg_energy = np.mean(energies)
        # blend each channel with lattice average
        for i in range(len(self.channels)):
            self.channels[i] = self.channels[i] * 0.95 + avg_energy * 0.05
        # update pages with lattice feedback
        for page in self.pages.values():
            page.trace = page.trace * 0.97 + np.mean(self.channels) * 0.03
            page.energy = page.trace
            page.tension = page.energy ** 1.2

    def status(self):
        return {name: page.energy for name, page in self.pages.items()}

# -----------------------------
# Instantiate HDGL lattice
# -----------------------------
lattice = HDGLLattice(num_channels=32)

# Register kernel + initramfs pages
for i in range(64):
    lattice.register_page(f"kernel_page_{i}", initial_value=np.random.rand()*0.8)
for i in range(128):
    lattice.register_page(f"initramfs_page_{i}", initial_value=np.random.rand()*0.6)

# -----------------------------
# Example analog access
# -----------------------------
# Write some pages
lattice.access_page("kernel_page_0", 0.9)
lattice.access_page("initramfs_page_5", 0.7)

# Read a page
val = lattice.access_page("kernel_page_1")

# Evolve harmonic lattice
for step in range(16):
    lattice.propagate()
    print(f"Step {step}: Channel energies -> {lattice.channels[:8]}")
