#ifndef PROBOL_RUNTIME_H
#define PROBOL_RUNTIME_H

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_DIST_STATES 32

// Represents a probability distribution element (value: probability)
typedef struct {
    double value;       // Fixed-point value represented as double for compliance
    double probability; // Probability vector weight (0.0 to 1.0)
} ProbPair;

// The central data structure for variables and PASM registers
typedef struct {
    ProbPair states[MAX_DIST_STATES];
    int state_count;
} ProbTensor;

// Initialize a probabilistic distribution
inline void init_prob_tensor(ProbTensor* t) {
    t->state_count = 0;
    memset(t->states, 0, sizeof(t->states));
}

// Add state element safely
inline void add_state(ProbTensor* t, double val, double prob) {
    if (t->state_count < MAX_DIST_STATES) {
        t->states[t->state_count].value = val;
        t->states[t->state_count].probability = prob;
        t->state_count++;
    }
}

// Runtime Convolutions (PASM ADDP / PROBOL ADDP)
inline void cct_add(ProbTensor* dest, ProbTensor* a, ProbTensor* b) {
    ProbTensor temp;
    init_prob_tensor(&temp);
    
    for (int i = 0; i < a->state_count; i++) {
        for (int j = 0; j < b->state_count; j++) {
            double combined_val = a->states[i].value + b->states[j].value;
            double combined_prob = a->states[i].probability * b->states[j].probability;
            
            // Deduplicate and aggregate states in place
            int found = 0;
            for (int k = 0; k < temp.state_count; k++) {
                if (temp.states[k].value == combined_val) {
                    temp.states[k].probability += combined_prob;
                    found = 1;
                    break;
                }
            }
            if (!found) {
                add_state(&temp, combined_val, combined_prob);
            }
        }
    }
    *dest = temp;
}

// Runtime Collapse Measure (MEAS)
inline double cct_measure(ProbTensor* t) {
    // Basic CCT optimization: pick highest probability slice (Minimal Entropy Path)
    if (t->state_count == 0) return 0.0;
    int best_idx = 0;
    double max_p = -1.0;
    for (int i = 0; i < t->state_count; i++) {
        if (t->states[i].probability > max_p) {
            max_p = t->states[i].probability;
            best_idx = i;
        }
    }
    return t->states[best_idx].value;
}

#endif