oxirs-arq 0.2.4

Jena-style SPARQL algebra with extension points and query optimization
Documentation
//! Demonstration of SciRS2 Advanced Capabilities
//!
//! This module showcases how OxiRS leverages SciRS2's cutting-edge scientific computing capabilities.

use anyhow::Result;
use scirs2_core::array;  // Array macro from scirs2-core
use scirs2_core::ndarray_ext::{Array1, Array2, ArrayView1};
use scirs2_core::random::{
    Rng, Random, seeded_rng, ThreadLocalRngPool, ScientificSliceRandom,
    distributions::{Dirichlet, Beta, MultivariateNormal, Categorical, WeightedChoice, VonMises},
};
use scirs2_core::core::scientific::{DeterministicState, ReproducibleSequence};
use std::sync::Arc;

/// Demonstration of SciRS2 advanced capabilities
pub struct SciRS2CapabilitiesDemo {
    rng_pool: Arc<ThreadLocalRngPool>,
    deterministic_state: DeterministicState,
}

impl Beta3CapabilitiesDemo {
    pub fn new(seed: u64) -> Self {
        Self {
            rng_pool: Arc::new(ThreadLocalRngPool::new(seed)),
            deterministic_state: DeterministicState::new(seed),
        }
    }

    /// Demonstrate the array macro
    pub fn demo_array_macro(&self) -> Result<()> {
        // ✅ Direct array macro access from scirs2-core
        let matrix = array![[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]];

        println!("✅ Array macro works directly: {:?}", matrix.shape());
        Ok(())
    }

    /// Demonstrate deterministic random number generation
    pub fn demo_deterministic_rng(&self) -> Result<()> {
        // ✅ Beta.3 Feature: Seeded RNG for reproducible experiments
        let mut rng1 = seeded_rng(12345);
        let mut rng2 = seeded_rng(12345);

        let sample1: Vec<f64> = (0..10).map(|_| rng1.random::<f64>()).collect();
        let sample2: Vec<f64> = (0..10).map(|_| rng2.random::<f64>()).collect();

        assert_eq!(sample1, sample2);
        println!("✅ Deterministic RNG: Reproducible sequences verified");
        Ok(())
    }

    /// Demonstrate advanced scientific distributions
    pub fn demo_advanced_distributions(&self) -> Result<()> {
        let mut rng = self.rng_pool.get();

        // ✅ Beta.3 Feature: Dirichlet distribution for probabilistic reasoning
        let dirichlet = Dirichlet::new(vec![1.0, 2.0, 3.0])?;
        let dirichlet_sample = dirichlet.sample(&mut rng);
        println!("✅ Dirichlet sample: {:?}", dirichlet_sample);

        // ✅ Beta.3 Feature: Multivariate Normal for embeddings
        let mvn = MultivariateNormal::new(
            vec![0.0, 0.0],
            vec![vec![1.0, 0.5], vec![0.5, 1.0]]
        )?;
        let mvn_sample = mvn.sample(&mut rng);
        println!("✅ Multivariate Normal sample: {:?}", mvn_sample);

        // ✅ Beta.3 Feature: Von Mises for circular statistics
        let von_mises = VonMises::new(0.0, 2.0)?;
        let vm_sample = von_mises.sample(&mut rng);
        println!("✅ Von Mises sample: {:.4}", vm_sample);

        Ok(())
    }

    /// Demonstrate collection sampling and shuffling
    pub fn demo_collection_operations(&self) -> Result<()> {
        let mut rng = self.rng_pool.get();

        // ✅ Beta.3 Feature: Scientific shuffle with Fisher-Yates algorithm
        let mut data = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
        data.scientific_shuffle(&mut rng);
        println!("✅ Scientific shuffle: {:?}", data);

        // ✅ Beta.3 Feature: Floyd's algorithm for sampling without replacement
        let original = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
        let sample = original.scientific_choose_multiple(&mut rng, 5);
        println!("✅ Floyd's sampling: {:?}", sample);

        // ✅ Beta.3 Feature: Weighted sampling
        let items = vec!["apple", "banana", "cherry", "date"];
        let weights = vec![0.1, 0.3, 0.4, 0.2];
        let weighted_sample = items.scientific_weighted_sample(&mut rng, &weights, 3)?;
        println!("✅ Weighted sampling: {:?}", weighted_sample);

        // ✅ Beta.3 Feature: Reservoir sampling for streaming data
        let stream_data = (1..1000).collect::<Vec<_>>();
        let reservoir = stream_data.scientific_reservoir_sample(&mut rng, 10);
        println!("✅ Reservoir sampling: {:?}", reservoir);

        Ok(())
    }

    /// Demonstrate optimized array operations (ndarray-rand replacement)
    pub fn demo_array_operations(&self) -> Result<()> {
        let mut rng = self.rng_pool.get();

        // ✅ Beta.3 Feature: Bulk random array generation
        let random_matrix = Array2::<f64>::random((100, 50), &mut rng);
        println!("✅ Random matrix shape: {:?}", random_matrix.shape());

        // ✅ Beta.3 Feature: Standard normal arrays
        let normal_array = Array1::<f64>::standard_normal(1000, &mut rng);
        let mean = normal_array.sum() / normal_array.len() as f64;
        println!("✅ Standard normal mean: {:.4} (should be ~0.0)", mean);

        // ✅ Beta.3 Feature: Uniform distribution arrays
        let uniform_array = Array2::<f64>::uniform((50, 50), -1.0, 1.0, &mut rng);
        println!("✅ Uniform array shape: {:?}", uniform_array.shape());

        // ✅ Beta.3 Feature: Beta distribution arrays
        let beta_array = Array1::<f64>::beta(100, 2.0, 5.0, &mut rng);
        println!("✅ Beta array length: {}", beta_array.len());

        // ✅ Beta.3 Feature: Advanced scientific arrays
        let dirichlet_samples = Array2::<f64>::dirichlet((10, 3), &[1.0, 2.0, 3.0], &mut rng);
        println!("✅ Dirichlet samples shape: {:?}", dirichlet_samples.shape());

        Ok(())
    }

    /// Demonstrate thread-safe parallel operations
    pub fn demo_parallel_operations(&self) -> Result<()> {
        use rayon::prelude::*;

        // ✅ Beta.3 Feature: Thread-safe RNG pool for parallel processing
        let results: Vec<f64> = (0..1000).into_par_iter().map(|_| {
            let mut rng = self.rng_pool.get();
            rng.random::<f64>()
        }).collect();

        println!("✅ Parallel random generation: {} samples", results.len());

        // ✅ Beta.3 Feature: Deterministic parallel execution
        let deterministic_results1: Vec<f64> = (0..100).into_par_iter().map(|i| {
            let mut rng = seeded_rng(i as u64);
            rng.random::<f64>()
        }).collect();

        let deterministic_results2: Vec<f64> = (0..100).into_par_iter().map(|i| {
            let mut rng = seeded_rng(i as u64);
            rng.random::<f64>()
        }).collect();

        assert_eq!(deterministic_results1, deterministic_results2);
        println!("✅ Deterministic parallel execution verified");

        Ok(())
    }

    /// Demonstrate reproducible sequence generation
    pub fn demo_reproducible_sequences(&self) -> Result<()> {
        // ✅ Beta.3 Feature: Reproducible sequence for scientific experiments
        let sequence = ReproducibleSequence::new(42, 1000);
        let samples1 = sequence.generate_f64_sequence();
        let samples2 = sequence.generate_f64_sequence();

        assert_eq!(samples1, samples2);
        println!("✅ Reproducible sequences: {} samples match", samples1.len());

        Ok(())
    }

    /// Run comprehensive demonstration of all beta.3 capabilities
    pub fn run_full_demo(&self) -> Result<()> {
        println!("🚀 SciRS2 Beta.3 Capabilities Demonstration");
        println!("==========================================");

        self.demo_array_macro_fix()?;
        self.demo_deterministic_rng()?;
        self.demo_advanced_distributions()?;
        self.demo_collection_operations()?;
        self.demo_array_operations()?;
        self.demo_parallel_operations()?;
        self.demo_reproducible_sequences()?;

        println!("🎯 All SciRS2 Beta.3 features successfully demonstrated!");
        Ok(())
    }
}

/// Example of how OxiRS query optimization leverages beta.3 capabilities
pub struct QueryOptimizationWithBeta3 {
    rng_pool: Arc<ThreadLocalRngPool>,
}

impl QueryOptimizationWithBeta3 {
    pub fn new(seed: u64) -> Self {
        Self {
            rng_pool: Arc::new(ThreadLocalRngPool::new(seed)),
        }
    }

    /// Demonstrate ML-powered cardinality estimation with advanced distributions
    pub fn estimate_cardinality_with_ml(&self, table_size: usize, selectivity: f64) -> Result<f64> {
        let mut rng = self.rng_pool.get();

        // ✅ Use Beta distribution for selectivity modeling
        let beta_dist = Beta::new(selectivity * 10.0, (1.0 - selectivity) * 10.0)?;
        let estimated_selectivity = beta_dist.sample(&mut rng);

        // ✅ Use array operations for efficient computation
        let samples = Array1::<f64>::beta(1000, selectivity * 10.0, (1.0 - selectivity) * 10.0, &mut rng);
        let confidence_interval = samples.mapv(|x| x * table_size as f64);

        let mean_estimate = confidence_interval.mean().unwrap_or(0.0);
        println!("✅ ML cardinality estimate: {:.0} (table size: {})", mean_estimate, table_size);

        Ok(mean_estimate)
    }

    /// Demonstrate join order optimization with weighted sampling
    pub fn optimize_join_order(&self, tables: Vec<&str>) -> Result<Vec<&str>> {
        let mut rng = self.rng_pool.get();

        // ✅ Use weighted sampling based on table statistics
        let weights: Vec<f64> = tables.iter().enumerate()
            .map(|(i, _)| 1.0 / (i + 1) as f64)  // Smaller tables get higher weight
            .collect();

        let mut optimized_order = Vec::new();
        let mut remaining_tables = tables;

        while !remaining_tables.is_empty() {
            let selected = remaining_tables.scientific_weighted_sample(&mut rng, &weights, 1)?;
            if let Some(&table) = selected.first() {
                optimized_order.push(table);
                remaining_tables.retain(|&t| t != table);
            }
        }

        println!("✅ Optimized join order: {:?}", optimized_order);
        Ok(optimized_order)
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_beta3_capabilities() -> Result<()> {
        let demo = Beta3CapabilitiesDemo::new(12345);
        demo.run_full_demo()
    }

    #[test]
    fn test_query_optimization() -> Result<()> {
        let optimizer = QueryOptimizationWithBeta3::new(54321);

        let tables = vec!["users", "orders", "products", "reviews"];
        let _order = optimizer.optimize_join_order(tables)?;

        let _cardinality = optimizer.estimate_cardinality_with_ml(100000, 0.15)?;

        Ok(())
    }

    #[test]
    fn test_deterministic_reproducibility() -> Result<()> {
        // ✅ Verify that seeded RNG produces identical results
        let mut rng1 = seeded_rng(999);
        let mut rng2 = seeded_rng(999);

        for _ in 0..100 {
            assert_eq!(rng1.random::<f64>(), rng2.random::<f64>());
        }

        Ok(())
    }
}