relmath-rs 0.7.0

Relation-first mathematics and scientific computing in Rust.
Documentation
//! Shared read-only relation views for the deterministic exact core.
//!
//! This module is intentionally narrow. It gives generic code a deterministic
//! read-only boundary over the shipped exact unary, binary, and n-ary
//! relations without flattening their differences in tuple shape. When code
//! needs to forget provenance, annotation, or temporal support first, pair
//! this module with [`crate::ExactSupport`] or the `ToExact*Relation` traits.

use crate::core::{BinaryRelation, NaryRelation, UnaryRelation};

use super::FiniteRelation;

/// A shared read-only view over a finite exact relation.
///
/// `RelationView` is the first G6 shared convergence boundary. It lets generic
/// code inspect tuple count and iterate over stored tuples in deterministic
/// order across the exact unary, binary, and n-ary relation types.
///
/// This first layer intentionally does not cover mutation, membership queries,
/// domain/range inspection, schema access, support materialization,
/// provenance, annotations, temporal support, or backend abstraction. Exact
/// support materialization now lives in the separate G6 capability traits such
/// as [`crate::ExactSupport`] and the `ToExact*Relation` family.
///
/// Iteration order follows the deterministic storage order documented by the
/// implementing relation type. Tuple shapes remain concrete:
///
/// - unary relations yield `&T`;
/// - binary relations yield `&(A, B)`;
/// - n-ary relations yield `&[T]`.
///
/// # Examples
///
/// ```rust
/// use relmath::{FiniteRelation, RelationView, UnaryRelation};
///
/// let values = UnaryRelation::from_values([3, 1, 2]);
///
/// assert_eq!(values.len(), 3);
/// assert_eq!(values.tuples().copied().collect::<Vec<_>>(), vec![1, 2, 3]);
/// ```
pub trait RelationView: FiniteRelation {
    /// Borrowed tuple item yielded by [`Self::tuples`].
    type Tuple<'a>
    where
        Self: 'a;

    /// Returns the stored tuples in deterministic order.
    fn tuples(&self) -> impl Iterator<Item = Self::Tuple<'_>>;
}

impl<T: Ord> RelationView for UnaryRelation<T> {
    type Tuple<'a>
        = &'a T
    where
        Self: 'a;

    fn tuples(&self) -> impl Iterator<Item = Self::Tuple<'_>> {
        UnaryRelation::iter(self)
    }
}

impl<A: Ord, B: Ord> RelationView for BinaryRelation<A, B> {
    type Tuple<'a>
        = &'a (A, B)
    where
        Self: 'a;

    fn tuples(&self) -> impl Iterator<Item = Self::Tuple<'_>> {
        BinaryRelation::iter(self)
    }
}

impl<T: Ord> RelationView for NaryRelation<T> {
    type Tuple<'a>
        = &'a [T]
    where
        Self: 'a;

    fn tuples(&self) -> impl Iterator<Item = Self::Tuple<'_>> {
        NaryRelation::iter(self)
    }
}