set_theory 1.0.0

A comprehensive mathematical set theory library implementing standard set operations, multisets, and set laws verification
Documentation
//! # Lazy Operations
//!
//! Provides lazy evaluation for expensive set operations.
//!
//! This module implements iterator-based operations that avoid
//! memory explosion for large sets (e.g., power set).

use crate::models::CustomSet;
use std::hash::Hash;

/// Lazy power set iterator.
///
/// Generates subsets one by one instead of computing all at once,
/// preventing memory explosion for large sets.
///
/// # Type Parameters
///
/// * `T` - The type of elements in the original set
///
/// # Examples
///
/// ```rust
/// use set_theory::models::CustomSet;
///
/// let set = CustomSet::from(vec![1, 2, 3]);
/// for subset in set.power_set() {
///     println!("{}", subset);
/// }
/// ```
pub struct PowerSet<T: Eq + Hash + Clone> {
    elements: Vec<T>,
    current: usize,
    total: usize,
}

impl<T: Eq + Hash + Clone> PowerSet<T> {
    /// Creates a new PowerSet iterator.
    ///
    /// # Arguments
    ///
    /// * `set` - Reference to the set to generate power set from
    ///
    /// # Examples
    ///
    /// ```rust
    /// use set_theory::models::CustomSet;
    /// use set_theory::operations::lazy_ops::PowerSet;
    ///
    /// let set = CustomSet::from(vec![1, 2]);
    /// let power_set = PowerSet::new(&set);
    /// ```
    pub fn new(set: &CustomSet<T>) -> Self {
        let elements: Vec<T> = set.iter().cloned().collect();
        let total = 1 << elements.len(); // 2^n

        Self {
            elements,
            current: 0,
            total,
        }
    }
}

impl<T: Eq + Hash + Clone> Iterator for PowerSet<T> {
    type Item = CustomSet<T>;

    fn next(&mut self) -> Option<Self::Item> {
        if self.current >= self.total {
            return None;
        }

        let mut subset = Vec::new();
        for j in 0..self.elements.len() {
            if (self.current & (1 << j)) != 0 {
                subset.push(self.elements[j].clone());
            }
        }

        self.current += 1;
        Some(CustomSet::new(subset))
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        let remaining = self.total - self.current;
        (remaining, Some(remaining))
    }
}

impl<T: Eq + Hash + Clone> ExactSizeIterator for PowerSet<T> {}

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

    #[test]
    fn test_power_set_iterator() {
        let set = CustomSet::from(vec![1, 2]);
        let power_set: Vec<_> = set.power_set().collect();
        assert_eq!(power_set.len(), 4); // 2^2 = 4
    }

    #[test]
    fn test_power_set_empty() {
        let empty = CustomSet::<i32>::empty();
        let power_set: Vec<_> = empty.power_set().collect();
        assert_eq!(power_set.len(), 1); // 2^0 = 1, contains {∅}
    }

    #[test]
    fn test_power_set_three_elements() {
        let set = CustomSet::from(vec![1, 2, 3]);
        let power_set: Vec<_> = set.power_set().collect();
        assert_eq!(power_set.len(), 8); // 2^3 = 8
    }

    #[test]
    fn test_power_set_contains_empty() {
        let set = CustomSet::from(vec![1, 2]);
        let power_set: Vec<_> = set.power_set().collect();
        assert!(power_set.iter().any(|s| s.is_empty()));
    }

    #[test]
    fn test_power_set_contains_original() {
        let set = CustomSet::from(vec![1, 2]);
        let power_set: Vec<_> = set.power_set().collect();
        assert!(power_set.iter().any(|s| s.equals(&set)));
    }

    #[test]
    fn test_power_set_size_hint() {
        let set = CustomSet::from(vec![1, 2, 3]);
        let mut power_set = set.power_set();
        assert_eq!(power_set.size_hint(), (8, Some(8)));

        power_set.next();
        assert_eq!(power_set.size_hint(), (7, Some(7)));
    }
}