eryon 0.0.3

eryon is a harmonic, topological framework for managing computational entities at scale.
Documentation
/*
    Appellation: runtime <example>
    Contrib: @FL03
*/
use eryon::prelude::NeuralPlant;
use eryon::rt::{Runtime, tasks::TaskType};
use rstmt::nrt::LPR;

fn main() -> anyhow::Result<()> {
    // Set up tracing for logging
    tracing_subscriber::fmt()
        .with_max_level(tracing::Level::TRACE)
        .init();

    tracing::info!("FragTonnetz Runtime Example");

    // Create and initialize the runtime
    let mut runtime = Runtime::<NeuralPlant>::new();
    runtime.init_complete_layer()?;

    tracing::info!(
        "Runtime initialized with {} partitions",
        runtime.fragment().total_partitions()
    );

    // Find specific triads we want to work with
    let c_major_id = runtime
        .fragment()
        .find_edge_by_notes([0, 4, 7])
        .expect("C major triad should exist");
    let a_minor_id = runtime
        .fragment()
        .find_edge_by_notes([9, 0, 4])
        .expect("A minor triad should exist");
    let e_minor_id = runtime
        .fragment()
        .find_edge_by_notes([4, 7, 11])
        .expect("E minor triad should exist");

    tracing::info!("Found key triads for transformation");

    // Schedule transformation tasks with different priorities
    let _task1_id = runtime.schedule_task(
        TaskType::transform(c_major_id, LPR::Relative),
        10, // High priority
    );

    let _task2_id = runtime.schedule_task(
        TaskType::transform(a_minor_id, LPR::Parallel),
        5, // Medium priority
    );

    let _task3_id = runtime.schedule_task(
        TaskType::BatchTransform(vec![(e_minor_id, vec![LPR::Leading, LPR::Parallel])]),
        8, // High-medium priority
    );

    // Schedule a compute transformations task
    let _task4_id = runtime.schedule_task(
        TaskType::ComputeTransformations,
        3, // Lower priority
    );

    tracing::info!("Scheduled 4 tasks with varying priorities");

    // Execute the tasks
    runtime.execute_tasks()?;

    // Process any inter-node messages
    runtime.process_messages()?;

    // Display the state of nodes after processing
    if let Some(c_node) = runtime.fragment().get_vnode(&c_major_id) {
        println!(
            "C node transformed to: {:?} {:?}",
            c_node.class(),
            c_node.get_notes()
        );
        // Should be A minor [9, 0, 4] after Relative transform
    }

    if let Some(a_node) = runtime.fragment().get_vnode(&a_minor_id) {
        println!(
            "A node transformed to: {:?} {:?}",
            a_node.class(),
            a_node.get_notes()
        );
        // Should be A major [9, 1, 4] after Parallel transform
    }

    if let Some(e_node) = runtime.fragment().get_vnode(&e_minor_id) {
        println!(
            "E node transformed to: {:?} {:?}",
            e_node.class(),
            e_node.get_notes()
        );
        // Should change after Leading then Parallel
    }

    // Second batch: Pattern learning and memory operations
    println!("\n--- Second batch: Pattern learning ---");

    // Schedule some pattern tasks
    let _pattern_task_id = runtime.schedule_task(
        TaskType::SharePatterns,
        7, // Priority
    );

    // Create a batch with identical transformations to establish patterns
    let repeated_pattern = vec![LPR::Relative, LPR::Parallel];
    let c_major_id = runtime
        .fragment()
        .find_edge_by_notes([0, 4, 7])
        .unwrap_or_else(|| {
            // Find A minor and use that instead if C major was transformed
            runtime
                .fragment()
                .find_edge_by_notes([9, 0, 4])
                .expect("Should find A minor triad")
        });

    // Apply the pattern several times to establish it
    for _ in 0..3 {
        let _batch_task_id = runtime.schedule_task(
            TaskType::BatchTransform(vec![(c_major_id, repeated_pattern.clone())]),
            9, // High priority
        );
        runtime.execute_tasks()?;
    }

    // Schedule memory optimization task
    let _optimize_task_id = runtime.schedule_task(
        TaskType::OptimizeMemory { max_features: 100 },
        6, // Medium priority
    );

    // Execute the memory-focused tasks
    runtime.execute_tasks()?;

    // Show memory statistics
    if let Some(node) = runtime.fragment().get_vnode(&c_major_id) {
        let stats = node.get_memory_statistics();
        println!(
            "Memory statistics for node:\n\n{}\n",
            stats.generate_report()
        );

        // Check for patterns
        if stats.pattern_count() > 0 {
            println!("  Most common patterns:");
            for (i, (pattern, count)) in stats.most_common_patterns().iter().enumerate().take(2) {
                let pattern_names: Vec<_> = pattern
                    .iter()
                    .map(|&id| match id {
                        0 => "Leading",
                        1 => "Parallel",
                        2 => "Relative",
                        _ => "Unknown",
                    })
                    .collect();
                println!(
                    "    Pattern {}: {} occurrences - {:?}",
                    i + 1,
                    count,
                    pattern_names
                );
            }
        }
    }

    // Third batch: Resource management
    println!("\n--- Third batch: Resource management ---");

    // Schedule resource balancing task
    let _balance_task_id = runtime.schedule_task(
        TaskType::BalanceResources,
        9, // High priority
    );

    runtime.execute_tasks()?;

    // Show final resource usage
    let (memory_usage, compute_usage) = runtime.fragment().calculate_resource_usage();
    println!("Final resource usage:");
    println!("  Memory units: {}", memory_usage);
    println!("  Compute units: {}", compute_usage);

    // Show system info
    let sys_info = runtime.system_info();
    println!("{sys_info}");

    tracing::info!("\nRuntime example completed successfully");

    Ok(())
}