/*
 * Tutorial: Basics of Ternary Neural Networks
 * This tutorial demonstrates a single-layer perceptron using ternary weights.
 * 
 * RFI-IRFOS · PUBLIC repo · v1.0
 */

// Ternary Activation Function (Signum)
fn activate(sum: float) -> trit {
    if sum > 0.5 {
        return 1;
    } else if sum < -0.5 {
        return -1;
    }
    return 0;
}

// Predict output for a given input and weight vector
fn predict(inputs: trit[3], weights: float[3], bias: float) -> trit {
    let sum: float = bias;
    let i: int = 0;
    while i < 3 {
        // cast(trit) to float for calculation
        let in_val: float = 0.0;
        match inputs[i] {
            1 => { in_val = 1.0; }
            -1 => { in_val = -1.0; }
            0 => { in_val = 0.0; }
        }
        sum = sum + (in_val * weights[i]);
        i = i + 1;
    }
    
    println("Weighted sum:");
    println(sum);
    
    return activate(sum);
}

fn main() -> trit {
    println("=== Ternary Neural Network Tutorial ===");
    
    // Inputs: Affirm, Reject, Tend
    let inputs: trit[3] = [1, -1, 0];
    
    // Weights: 0.8, 0.4, -0.5
    let weights: float[3];
    weights[0] = 0.8; weights[1] = 0.4; weights[2] = -0.5;
    let bias: float = 0.1;
    
    // sum = 0.1 + (1 * 0.8) + (-1 * 0.4) + (0 * -0.5)
    // sum = 0.1 + 0.8 - 0.4 + 0 = 0.5
    
    let p: trit = predict(inputs, weights, bias);
    println("Prediction:");
    match p {
        1 => { println("Affirm"); }
        0 => { println("Tend"); }
        -1 => { println("Reject"); }
    }
    
    // With sum = 0.5, activate returns 0 (Tend) because 0.5 is not > 0.5
    if p == 0 {
        println("Tutorial result: PASSED");
        return 1;
    }
    
    println("Tutorial result: FAILED");
    return -1;
}
