# hdgl_16Mx_active_with_display.py
import math
import random
import hashlib

# -------------------------------
# Constants
# -------------------------------
phi = 1.6180339887
sqrt_phi = math.sqrt(phi)

MAX_VECTORS = 16_777_216  # 16M per dimension
V_DIM = 3                  # Exponent x for 16M^x virtual vectors
BITS_PER_VECTOR = 4
OPS_PER_VECTOR = 40

FIBS = [1,1,2,3,5,8,13,21,34,55,89,144,233,377,610]
PRIMES = [2,3,5,7,11,13,17,19,23,29,31]

# -------------------------------
# Virtual Vector (Iceberg)
# -------------------------------
def virtual_index(*indices, block_hash:str):
    hash_int = int(block_hash[:16],16)
    result = hash_int
    for i, val in enumerate(indices):
        result += val * (MAX_VECTORS**i)
    return result % (MAX_VECTORS**V_DIM)

def virtual_to_hdgl(*indices, block_hash:str):
    v_idx = virtual_index(*indices, block_hash=block_hash)
    inst_index = indices[0] % 8

    fib_val = FIBS[sum(indices)%len(FIBS)]
    phi_scale = phi**((indices[0]%16)/16)
    r_dim = 0.3 + 0.7*((fib_val*phi_scale)%1)
    slot_scale = [(FIBS[(sum(indices)+i)%len(FIBS)]/PRIMES[i%len(PRIMES)])*phi_scale for i in range(4)]

    seed = 0
    for i,val in enumerate(indices):
        seed |= val << (24*i)
    random.seed(seed)
    program = [
        {'op':'LOAD','args':[0,random.uniform(0,2)]},
        {'op':'ADD','args':[2,0,1]},
        {'op':'JMP','args':[2,0]},
        {'op':'NOP'}
    ]
    return inst_index, program, r_dim, slot_scale

# -------------------------------
# Active Vector Execution (Tip)
# -------------------------------
def execute_vector(indices, block_hash:str, ticks:int=1):
    inst_index, program, r_dim, slot_scale = virtual_to_hdgl(*indices, block_hash=block_hash)
    D = [0.0]*4
    binary = [0]*4

    for tick in range(ticks):
        for instr in program:
            op = instr['op']
            args = instr.get('args',[])
            if op=='LOAD':
                D[args[0]] = args[1]
            elif op=='ADD':
                D[args[0]] = D[args[1]] + D[args[2]]
            elif op=='JMP' and D[args[0]]>=sqrt_phi:
                pass
        for i in range(4):
            D[i] += 0.05*r_dim*slot_scale[i]
        binary = [1 if d>=sqrt_phi else 0 for d in D]

    return inst_index, D, binary

# -------------------------------
# HDGL Lattice Executor
# -------------------------------
class HDGLLatticeExecutor:
    def __init__(self, block_hash:str, active_limit:int):
        self.block_hash = block_hash
        self.active_limit = active_limit
        self.active_vectors = []
        self.virtual_ceiling = MAX_VECTORS**V_DIM  # Compute total virtual vectors

    def display_virtual_ceiling(self):
        print(f"Ceiling virtual vectors (16M^{V_DIM}): {self.virtual_ceiling:,}")

    def select_active_vectors(self, seed:int=0):
        random.seed(seed)
        self.active_vectors = []
        for _ in range(self.active_limit):
            indices = tuple(random.randint(0, MAX_VECTORS-1) for _ in range(V_DIM))
            self.active_vectors.append(indices)

    def step(self, ticks:int=1):
        lattice_bin = []
        for indices in self.active_vectors:
            _,_,binary = execute_vector(indices, self.block_hash, ticks)
            lattice_bin.extend(binary)
        lattice_str = ''.join(str(b) for b in reversed(lattice_bin))
        lattice_hex = hex(int(lattice_str,2))
        return lattice_str, lattice_hex

# -------------------------------
# Example Usage
# -------------------------------
if __name__=="__main__":
    block_hash = hashlib.sha256(b"example_block").hexdigest()
    active_limit = 73_000_000  # RX 480 optimal saturation

    lattice_executor = HDGLLatticeExecutor(block_hash, active_limit)
    
    # Display ceiling of virtual vectors
    lattice_executor.display_virtual_ceiling()
    
    # Select active vectors (optimal tip)
    lattice_executor.select_active_vectors(seed=42)

    lattice_str, lattice_hex = lattice_executor.step(ticks=1)

    print(f"Active vectors executed: {len(lattice_executor.active_vectors)}")
    print(f"Lattice hex (sample first 64 chars): {lattice_hex[:64]}")
