set_theory 1.0.0

A comprehensive mathematical set theory library implementing standard set operations, multisets, and set laws verification
Documentation
//! # Basic Set Operations
//!
//! Provides fundamental set operations as defined in set theory.
//!
//! All operations follow standard mathematical notation and properties.

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

/// Provides basic set operations as defined in set theory.
///
/// This struct contains static methods for fundamental set operations
/// including intersection, union, complement, difference, and symmetric difference.
///
/// # Examples
///
/// ```rust
/// use set_theory::models::CustomSet;
/// use set_theory::operations::SetOperations;
///
/// let a = CustomSet::from(vec![1, 2, 3]);
/// let b = CustomSet::from(vec![3, 4, 5]);
///
/// let union = SetOperations::union(&a, &b);
/// let intersection = SetOperations::intersection(&a, &b);
/// ```
pub struct SetOperations;

impl SetOperations {
    /// Returns the intersection of two sets.
    ///
    /// # Notation
    ///
    /// A ∩ B = {x | x ∈ A and x ∈ B}
    ///
    /// # Arguments
    ///
    /// * `a` - First set
    /// * `b` - Second set
    ///
    /// # Returns
    ///
    /// A new `CustomSet` containing elements present in both sets.
    ///
    /// # Complexity
    ///
    /// O(min(|A|, |B|)) average case
    ///
    /// # Examples
    ///
    /// ```rust
    /// use set_theory::models::CustomSet;
    /// use set_theory::operations::SetOperations;
    ///
    /// let a = CustomSet::from(vec![2, 4, 6, 8, 10]);
    /// let b = CustomSet::from(vec![4, 10, 14, 18]);
    /// let result = SetOperations::intersection(&a, &b);
    /// assert_eq!(result.cardinality(), 2);
    /// ```
    pub fn intersection<T: Eq + Hash + Clone>(a: &CustomSet<T>, b: &CustomSet<T>) -> CustomSet<T> {
        a.intersection(b)
    }

    /// Returns the union of two sets.
    ///
    /// # Notation
    ///
    /// A ∪ B = {x | x ∈ A or x ∈ B}
    ///
    /// # Arguments
    ///
    /// * `a` - First set
    /// * `b` - Second set
    ///
    /// # Returns
    ///
    /// A new `CustomSet` containing all elements from both sets.
    ///
    /// # Complexity
    ///
    /// O(|A| + |B|) average case
    ///
    /// # Examples
    ///
    /// ```rust
    /// use set_theory::models::CustomSet;
    /// use set_theory::operations::SetOperations;
    ///
    /// let a = CustomSet::from(vec![2, 5, 8]);
    /// let b = CustomSet::from(vec![7, 5, 22]);
    /// let result = SetOperations::union(&a, &b);
    /// assert_eq!(result.cardinality(), 5);
    /// ```
    pub fn union<T: Eq + Hash + Clone>(a: &CustomSet<T>, b: &CustomSet<T>) -> CustomSet<T> {
        a.union(b)
    }

    /// Returns the complement of a set with respect to a universal set.
    ///
    /// # Notation
    ///
    /// A' = {x | x ∈ U and x ∉ A}
    ///
    /// # Arguments
    ///
    /// * `a` - The set to complement
    /// * `universal` - The universal set
    ///
    /// # Returns
    ///
    /// A new `CustomSet` containing elements in universal but not in a.
    ///
    /// # Complexity
    ///
    /// O(|U|) where U is the universal set
    ///
    /// # Examples
    ///
    /// ```rust
    /// use set_theory::models::CustomSet;
    /// use set_theory::operations::SetOperations;
    ///
    /// let universal = CustomSet::from(vec![1, 2, 3, 4, 5, 6, 7, 8, 9]);
    /// let a = CustomSet::from(vec![1, 3, 7, 9]);
    /// let result = SetOperations::complement(&a, &universal);
    /// assert_eq!(result.cardinality(), 5);
    /// ```
    pub fn complement<T: Eq + Hash + Clone>(
        a: &CustomSet<T>,
        universal: &CustomSet<T>,
    ) -> CustomSet<T> {
        a.complement(universal)
    }

    /// Returns the difference of two sets.
    ///
    /// # Notation
    ///
    /// A - B = {x | x ∈ A and x ∉ B}
    ///
    /// # Arguments
    ///
    /// * `a` - First set (minuend)
    /// * `b` - Second set (subtrahend)
    ///
    /// # Returns
    ///
    /// A new `CustomSet` containing elements in a but not in b.
    ///
    /// # Complexity
    ///
    /// O(|A|) average case
    ///
    /// # Examples
    ///
    /// ```rust
    /// use set_theory::models::CustomSet;
    /// use set_theory::operations::SetOperations;
    ///
    /// let a = CustomSet::from(vec![1, 2, 3, 4, 5]);
    /// let b = CustomSet::from(vec![2, 4]);
    /// let result = SetOperations::difference(&a, &b);
    /// assert_eq!(result.cardinality(), 3);
    /// ```
    pub fn difference<T: Eq + Hash + Clone>(a: &CustomSet<T>, b: &CustomSet<T>) -> CustomSet<T> {
        a.difference(b)
    }

    /// Returns the symmetric difference of two sets.
    ///
    /// # Notation
    ///
    /// A ⊕ B = (A ∪ B) - (A ∩ B)
    ///
    /// # Arguments
    ///
    /// * `a` - First set
    /// * `b` - Second set
    ///
    /// # Returns
    ///
    /// A new `CustomSet` containing elements in either set but not both.
    ///
    /// # Complexity
    ///
    /// O(|A| + |B|) average case
    ///
    /// # Examples
    ///
    /// ```rust
    /// use set_theory::models::CustomSet;
    /// use set_theory::operations::SetOperations;
    ///
    /// let a = CustomSet::from(vec![2, 4, 6]);
    /// let b = CustomSet::from(vec![2, 3, 5]);
    /// let result = SetOperations::symmetric_difference(&a, &b);
    /// assert_eq!(result.cardinality(), 4);
    /// ```
    pub fn symmetric_difference<T: Eq + Hash + Clone>(
        a: &CustomSet<T>,
        b: &CustomSet<T>,
    ) -> CustomSet<T> {
        a.symmetric_difference(b)
    }

    /// Returns the symmetric difference using alternative formula.
    ///
    /// # Notation
    ///
    /// A ⊕ B = (A - B) ∪ (B - A)
    ///
    /// # Arguments
    ///
    /// * `a` - First set
    /// * `b` - Second set
    ///
    /// # Returns
    ///
    /// A new `CustomSet` containing elements in either set but not both.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use set_theory::models::CustomSet;
    /// use set_theory::operations::SetOperations;
    ///
    /// let a = CustomSet::from(vec![2, 4, 6]);
    /// let b = CustomSet::from(vec![2, 3, 5]);
    /// let result1 = SetOperations::symmetric_difference(&a, &b);
    /// let result2 = SetOperations::symmetric_difference_alt(&a, &b);
    /// assert_eq!(result1, result2);
    /// ```
    pub fn symmetric_difference_alt<T: Eq + Hash + Clone>(
        a: &CustomSet<T>,
        b: &CustomSet<T>,
    ) -> CustomSet<T> {
        Self::union(&Self::difference(a, b), &Self::difference(b, a))
    }
}

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

    #[test]
    fn test_intersection() {
        let a = CustomSet::from(vec![2, 4, 6, 8, 10]);
        let b = CustomSet::from(vec![4, 10, 14, 18]);
        let result = SetOperations::intersection(&a, &b);
        assert_eq!(result.cardinality(), 2);
        assert!(result.contains(&4));
        assert!(result.contains(&10));
    }

    #[test]
    fn test_union() {
        let a = CustomSet::from(vec![2, 5, 8]);
        let b = CustomSet::from(vec![7, 5, 22]);
        let result = SetOperations::union(&a, &b);
        assert_eq!(result.cardinality(), 5);
    }

    #[test]
    fn test_complement() {
        let universal = CustomSet::from(vec![1, 2, 3, 4, 5, 6, 7, 8, 9]);
        let a = CustomSet::from(vec![1, 3, 7, 9]);
        let result = SetOperations::complement(&a, &universal);
        assert_eq!(result.cardinality(), 5);
    }

    #[test]
    fn test_difference() {
        let a = CustomSet::from(vec![1, 2, 3, 4, 5]);
        let b = CustomSet::from(vec![2, 4]);
        let result = SetOperations::difference(&a, &b);
        assert_eq!(result.cardinality(), 3);
    }

    #[test]
    fn test_symmetric_difference() {
        let a = CustomSet::from(vec![2, 4, 6]);
        let b = CustomSet::from(vec![2, 3, 5]);
        let result = SetOperations::symmetric_difference(&a, &b);
        assert_eq!(result.cardinality(), 4);
        assert!(!result.contains(&2));
    }

    #[test]
    fn test_symmetric_difference_alt() {
        let a = CustomSet::from(vec![2, 4, 6]);
        let b = CustomSet::from(vec![2, 3, 5]);
        let result1 = SetOperations::symmetric_difference(&a, &b);
        let result2 = SetOperations::symmetric_difference_alt(&a, &b);
        assert_eq!(result1, result2);
    }

    #[test]
    fn test_empty_set_operations() {
        let empty = CustomSet::<i32>::empty();
        let non_empty = CustomSet::from(vec![1, 2, 3]);

        assert!(SetOperations::union(&empty, &empty).is_empty());
        assert!(SetOperations::intersection(&empty, &non_empty).is_empty());
        assert_eq!(SetOperations::difference(&non_empty, &empty), non_empty);
        assert!(SetOperations::difference(&empty, &non_empty).is_empty());
    }

    #[test]
    fn test_set_with_itself() {
        let a = CustomSet::from(vec![1, 2, 3]);

        assert_eq!(SetOperations::union(&a, &a), a);
        assert_eq!(SetOperations::intersection(&a, &a), a);
        assert!(SetOperations::difference(&a, &a).is_empty());
        assert!(SetOperations::symmetric_difference(&a, &a).is_empty());
    }
}